import irqbalance-1.9.0-3.el8
This commit is contained in:
parent
ea3068a0a0
commit
6e4506a5be
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
|||||||
SOURCES/irqbalance-1.4.0.tar.gz
|
SOURCES/irqbalance-1.9.0.tar.gz
|
||||||
|
@ -1 +1 @@
|
|||||||
4eb861313d6b93b3be5d5933a7f45ee7b51c7ddb SOURCES/irqbalance-1.4.0.tar.gz
|
828952ed5fa3b502c4b07703395cdf33faa6a60a SOURCES/irqbalance-1.9.0.tar.gz
|
||||||
|
@ -0,0 +1,71 @@
|
|||||||
|
From ff48ac9c84f0b318dfce665605d72e86dfcfe008 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Chao Liu <liuchao173@huawei.com>
|
||||||
|
Date: Tue, 7 Jun 2022 15:15:15 +0800
|
||||||
|
Subject: [PATCH 01/14] get irq->module relationship from /sys/bus/pci/*/driver
|
||||||
|
|
||||||
|
Signed-off-by: Chao Liu <liuchao173@huawei.com>
|
||||||
|
---
|
||||||
|
classify.c | 19 +++++++++++++++++--
|
||||||
|
1 file changed, 17 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/classify.c b/classify.c
|
||||||
|
index 9b4640c..526a66b 100644
|
||||||
|
--- a/classify.c
|
||||||
|
+++ b/classify.c
|
||||||
|
@@ -7,6 +7,7 @@
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
+#include <libgen.h>
|
||||||
|
|
||||||
|
#include "irqbalance.h"
|
||||||
|
#include "types.h"
|
||||||
|
@@ -578,7 +579,7 @@ static int check_for_module_ban(char *name)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int check_for_irq_ban(int irq, GList *proc_interrupts)
|
||||||
|
+static int check_for_irq_ban(int irq, char *mod, GList *proc_interrupts)
|
||||||
|
{
|
||||||
|
struct irq_info find, *res;
|
||||||
|
GList *entry;
|
||||||
|
@@ -594,6 +595,9 @@ static int check_for_irq_ban(int irq, GList *proc_interrupts)
|
||||||
|
/*
|
||||||
|
* Check to see if we banned module which the irq belongs to.
|
||||||
|
*/
|
||||||
|
+ if (mod != NULL && strlen(mod) > 0 && check_for_module_ban(mod))
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
entry = g_list_find_custom(proc_interrupts, &find, compare_ints);
|
||||||
|
if (entry) {
|
||||||
|
res = entry->data;
|
||||||
|
@@ -609,14 +613,25 @@ static void add_new_irq(char *path, struct irq_info *hint, GList *proc_interrupt
|
||||||
|
struct irq_info *new;
|
||||||
|
struct user_irq_policy pol;
|
||||||
|
int irq = hint->irq;
|
||||||
|
+ char buf[PATH_MAX], drvpath[PATH_MAX];
|
||||||
|
+ char *mod = NULL;
|
||||||
|
+ int ret;
|
||||||
|
|
||||||
|
new = get_irq_info(irq);
|
||||||
|
if (new)
|
||||||
|
return;
|
||||||
|
|
||||||
|
+ if (path) {
|
||||||
|
+ sprintf(buf, "%s/driver", path);
|
||||||
|
+ ret = readlink(buf, drvpath, PATH_MAX);
|
||||||
|
+ if (ret > 0 && ret < PATH_MAX) {
|
||||||
|
+ drvpath[ret] = '\0';
|
||||||
|
+ mod = basename(drvpath);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
/* Set NULL devpath for the irq has no sysfs entries */
|
||||||
|
get_irq_user_policy(path, irq, &pol);
|
||||||
|
- if ((pol.ban == 1) || check_for_irq_ban(irq, proc_interrupts)) { /*FIXME*/
|
||||||
|
+ if ((pol.ban == 1) || check_for_irq_ban(irq, mod, proc_interrupts)) { /*FIXME*/
|
||||||
|
__add_banned_irq(irq, &banned_irqs);
|
||||||
|
new = get_irq_info(irq);
|
||||||
|
} else
|
||||||
|
--
|
||||||
|
2.33.1
|
||||||
|
|
@ -0,0 +1,64 @@
|
|||||||
|
From c8d1fff0f16ad906cca153a22faac11516ccc0dd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Liu Chao <liuchao173@huawei.com>
|
||||||
|
Date: Mon, 18 Jul 2022 16:54:53 +0800
|
||||||
|
Subject: [PATCH] irqbalance-ui: skip ',' in parse_setup to avoid coredump
|
||||||
|
|
||||||
|
When processing the ',' in hex_to_bitmap, it returns '0000\ 0' directly.
|
||||||
|
The return value will be freed in parse_setup, but it is not requested
|
||||||
|
through malloc.
|
||||||
|
|
||||||
|
Fixes: 85d37098a551 ("Fix several memleak problems found by covscan")
|
||||||
|
|
||||||
|
And it treat ',' as "0000", which cause irqbalance-ui will display wrong
|
||||||
|
Banned CPU numbers.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
# IRQBALANCE_BANNED_CPUS="00000002,00000000,00000000" ./irqbalance
|
||||||
|
or
|
||||||
|
# IRQBALANCE_BANNED_CPULIST="65" ./irqbalance
|
||||||
|
|
||||||
|
# ./irqbalance-ui
|
||||||
|
Banned CPU numbers: 73
|
||||||
|
|
||||||
|
Fixes: 76d1c9d73935 ("Add main user interface files")
|
||||||
|
|
||||||
|
Signed-off-by: Liu Chao <liuchao173@huawei.com>
|
||||||
|
---
|
||||||
|
ui/irqbalance-ui.c | 7 +++++--
|
||||||
|
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ui/irqbalance-ui.c b/ui/irqbalance-ui.c
|
||||||
|
index 47b6c88..b7f9b62 100644
|
||||||
|
--- a/ui/irqbalance-ui.c
|
||||||
|
+++ b/ui/irqbalance-ui.c
|
||||||
|
@@ -142,7 +142,7 @@ try_again:
|
||||||
|
void parse_setup(char *setup_data)
|
||||||
|
{
|
||||||
|
char *token, *ptr;
|
||||||
|
- int i,j;
|
||||||
|
+ int i,j, cpu = 0;
|
||||||
|
char *copy;
|
||||||
|
irq_t *new_irq = NULL;
|
||||||
|
if((setup_data == NULL) || (strlen(setup_data) == 0)) return;
|
||||||
|
@@ -179,14 +179,17 @@ void parse_setup(char *setup_data)
|
||||||
|
if(strncmp(token, "BANNED", strlen("BANNED"))) goto out;
|
||||||
|
token = strtok_r(NULL, " ", &ptr);
|
||||||
|
for(i = strlen(token) - 1; i >= 0; i--) {
|
||||||
|
+ if (token[i] == ',')
|
||||||
|
+ continue;
|
||||||
|
char *map = hex_to_bitmap(token[i]);
|
||||||
|
for(j = 3; j >= 0; j--) {
|
||||||
|
if(map[j] == '1') {
|
||||||
|
uint64_t *banned_cpu = malloc(sizeof(uint64_t));
|
||||||
|
- *banned_cpu = (4 * (strlen(token) - (i + 1)) + (4 - (j + 1)));
|
||||||
|
+ *banned_cpu = cpu;
|
||||||
|
setup.banned_cpus = g_list_append(setup.banned_cpus,
|
||||||
|
banned_cpu);
|
||||||
|
}
|
||||||
|
+ cpu++;
|
||||||
|
}
|
||||||
|
free(map);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.33.1
|
||||||
|
|
@ -0,0 +1,28 @@
|
|||||||
|
From 522883505d3b02e3294f045f49007b61c00e2c31 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Chao Liu <liuchao173@huawei.com>
|
||||||
|
Date: Wed, 8 Jun 2022 10:04:02 +0800
|
||||||
|
Subject: [PATCH 02/14] check whether savedptr is NULL before invoking strlen
|
||||||
|
|
||||||
|
savedptr can be null in musl libc, so the strlen(NULL) will segfault
|
||||||
|
|
||||||
|
Signed-off-by: Chao Liu <liuchao173@huawei.com>
|
||||||
|
---
|
||||||
|
procinterrupts.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/procinterrupts.c b/procinterrupts.c
|
||||||
|
index 9015177..57c8801 100644
|
||||||
|
--- a/procinterrupts.c
|
||||||
|
+++ b/procinterrupts.c
|
||||||
|
@@ -178,7 +178,7 @@ void init_irq_class_and_type(char *savedline, struct irq_info *info, int irq)
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef AARCH64
|
||||||
|
- if (strlen(savedptr) > 0) {
|
||||||
|
+ if (savedptr && strlen(savedptr) > 0) {
|
||||||
|
snprintf(irq_fullname, PATH_MAX, "%s %s", last_token, savedptr);
|
||||||
|
tmp = strchr(irq_fullname, '\n');
|
||||||
|
if (tmp)
|
||||||
|
--
|
||||||
|
2.33.1
|
||||||
|
|
96
SOURCES/0003-add-meson.patch
Normal file
96
SOURCES/0003-add-meson.patch
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
From 378d4707c26acf05e551219d8b09ddf440bdba2a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rosen Penev <rosenp@gmail.com>
|
||||||
|
Date: Fri, 10 Jun 2022 23:14:27 -0700
|
||||||
|
Subject: [PATCH 03/14] add meson
|
||||||
|
|
||||||
|
Simpler build system. Placing in contrib for now.
|
||||||
|
|
||||||
|
Signed-off-by: Rosen Penev <rosenp@gmail.com>
|
||||||
|
---
|
||||||
|
contrib/README | 2 ++
|
||||||
|
contrib/meson.build | 45 +++++++++++++++++++++++++++++++++++++++
|
||||||
|
contrib/meson_options.txt | 11 ++++++++++
|
||||||
|
3 files changed, 58 insertions(+)
|
||||||
|
create mode 100644 contrib/README
|
||||||
|
create mode 100644 contrib/meson.build
|
||||||
|
create mode 100644 contrib/meson_options.txt
|
||||||
|
|
||||||
|
diff --git a/contrib/README b/contrib/README
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..2158dac
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/contrib/README
|
||||||
|
@@ -0,0 +1,2 @@
|
||||||
|
+This directory contains meson build instructions for irqbalance. This is here to see if there is any interest from
|
||||||
|
+the general community.
|
||||||
|
diff --git a/contrib/meson.build b/contrib/meson.build
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..d813233
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/contrib/meson.build
|
||||||
|
@@ -0,0 +1,45 @@
|
||||||
|
+project('irqbalance', 'c', version: '1.9.0', default_options: ['warning_level=1'])
|
||||||
|
+cc = meson.get_compiler('c')
|
||||||
|
+
|
||||||
|
+glib_dep = dependency('glib-2.0')
|
||||||
|
+m_dep = cc.find_library('m', required: false)
|
||||||
|
+capng_dep = dependency('libcap-ng', required: get_option('capng'))
|
||||||
|
+ncurses_dep = dependency('curses', required: get_option('ui'))
|
||||||
|
+systemd_dep = dependency('libsystemd', required: get_option('systemd'))
|
||||||
|
+
|
||||||
|
+cdata = configuration_data()
|
||||||
|
+cdata.set('HAVE_GETOPT_LONG', cc.has_function('getopt_long'))
|
||||||
|
+cdata.set('HAVE_IRQBALANCEUI', ncurses_dep.found())
|
||||||
|
+cdata.set('HAVE_NUMA_H', cc.has_header('numa.h'))
|
||||||
|
+cdata.set('HAVE_LIBCAP_NG', capng_dep.found())
|
||||||
|
+cdata.set('HAVE_LIBSYSTEMD', systemd_dep.found())
|
||||||
|
+cdata.set_quoted('VERSION', meson.project_version())
|
||||||
|
+cfile = configure_file(output: 'config.h', configuration: cdata)
|
||||||
|
+
|
||||||
|
+if cdata.get('HAVE_IRQBALANCEUI')
|
||||||
|
+ add_project_arguments('-D_GNU_SOURCE', language: 'c')
|
||||||
|
+
|
||||||
|
+ executable(
|
||||||
|
+ 'irqbalance-ui',
|
||||||
|
+ '../ui/helpers.c',
|
||||||
|
+ '../ui/irqbalance-ui.c',
|
||||||
|
+ '../ui/ui.c',
|
||||||
|
+ dependencies: [glib_dep, ncurses_dep],
|
||||||
|
+ install: true,
|
||||||
|
+ )
|
||||||
|
+endif
|
||||||
|
+
|
||||||
|
+executable(
|
||||||
|
+ 'irqbalance',
|
||||||
|
+ '../activate.c',
|
||||||
|
+ '../bitmap.c',
|
||||||
|
+ '../classify.c',
|
||||||
|
+ '../cputree.c',
|
||||||
|
+ '../irqbalance.c',
|
||||||
|
+ '../irqlist.c',
|
||||||
|
+ '../numa.c',
|
||||||
|
+ '../placement.c',
|
||||||
|
+ '../procinterrupts.c',
|
||||||
|
+ dependencies: [glib_dep, m_dep, capng_dep, systemd_dep],
|
||||||
|
+ install: true,
|
||||||
|
+)
|
||||||
|
diff --git a/contrib/meson_options.txt b/contrib/meson_options.txt
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..3515dc3
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/contrib/meson_options.txt
|
||||||
|
@@ -0,0 +1,11 @@
|
||||||
|
+option('capng', type : 'feature',
|
||||||
|
+ description : 'Build with libcap-ng support',
|
||||||
|
+)
|
||||||
|
+
|
||||||
|
+option('systemd', type : 'feature',
|
||||||
|
+ description : 'Build with systemd support',
|
||||||
|
+)
|
||||||
|
+
|
||||||
|
+option('ui', type : 'feature',
|
||||||
|
+ description : 'Build the UI component',
|
||||||
|
+)
|
||||||
|
--
|
||||||
|
2.33.1
|
||||||
|
|
259
SOURCES/0004-Prepare-to-handle-thermal-event.patch
Normal file
259
SOURCES/0004-Prepare-to-handle-thermal-event.patch
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
From b66647ab757c580b2532c117bd345d1bad3b2bd5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Chang S. Bae" <chang.seok.bae@intel.com>
|
||||||
|
Date: Thu, 10 Feb 2022 14:46:01 -0800
|
||||||
|
Subject: [PATCH 04/14] Prepare to handle thermal event
|
||||||
|
|
||||||
|
Intel's new hardware supports Hardware Feedback Interface to provide CPU
|
||||||
|
performance and energy efficiency information. Every update on this is
|
||||||
|
delivered via thermal event interrupt. The thermal framework in the Linux
|
||||||
|
kernel relays these notifications to userspace via a Netlink interface.
|
||||||
|
|
||||||
|
When a CPU's performance and efficiency are zero, irqbalance needs to mask
|
||||||
|
the CPU from interrupts. Introduce a new CPU mask to indicate banned CPUs
|
||||||
|
for this.
|
||||||
|
|
||||||
|
Before supporting this event handling, define functions. Their
|
||||||
|
implementation will be on the following patches.
|
||||||
|
|
||||||
|
This event is available only on x86-64 systems. And it can be subscribed
|
||||||
|
with help of Netlink libraries. So check them before building it.
|
||||||
|
|
||||||
|
Also add a new build option so users may opt out this support. Setting this
|
||||||
|
option on other systems will result in a build failure.
|
||||||
|
|
||||||
|
Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
|
||||||
|
---
|
||||||
|
Makefile.am | 7 +++--
|
||||||
|
configure.ac | 22 ++++++++++++++
|
||||||
|
cputree.c | 6 ++++
|
||||||
|
irqbalance.c | 4 +++
|
||||||
|
thermal.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
thermal.h | 15 ++++++++++
|
||||||
|
6 files changed, 135 insertions(+), 2 deletions(-)
|
||||||
|
create mode 100644 thermal.c
|
||||||
|
create mode 100644 thermal.h
|
||||||
|
|
||||||
|
diff --git a/Makefile.am b/Makefile.am
|
||||||
|
index 84e7d46..9181a34 100644
|
||||||
|
--- a/Makefile.am
|
||||||
|
+++ b/Makefile.am
|
||||||
|
@@ -27,7 +27,7 @@ EXTRA_DIST = COPYING autogen.sh misc/irqbalance.service misc/irqbalance.env
|
||||||
|
SUBDIRS = tests
|
||||||
|
|
||||||
|
UI_DIR = ui
|
||||||
|
-AM_CFLAGS = $(LIBCAP_NG_CFLAGS) $(GLIB2_CFLAGS) $(NUMA_CFLAGS)
|
||||||
|
+AM_CFLAGS = $(LIBCAP_NG_CFLAGS) $(GLIB2_CFLAGS) $(NUMA_CFLAGS) $(LIBNL3_CFLAGS)
|
||||||
|
AM_CPPFLAGS = -I${top_srcdir} -W -Wall -Wshadow -Wformat -Wundef -D_GNU_SOURCE
|
||||||
|
noinst_HEADERS = bitmap.h constants.h cpumask.h irqbalance.h non-atomic.h \
|
||||||
|
types.h $(UI_DIR)/helpers.h $(UI_DIR)/irqbalance-ui.h $(UI_DIR)/ui.h
|
||||||
|
@@ -39,7 +39,10 @@ endif
|
||||||
|
|
||||||
|
irqbalance_SOURCES = activate.c bitmap.c classify.c cputree.c irqbalance.c \
|
||||||
|
irqlist.c numa.c placement.c procinterrupts.c
|
||||||
|
-irqbalance_LDADD = $(LIBCAP_NG_LIBS) $(GLIB2_LIBS) $(NUMA_LIBS)
|
||||||
|
+if THERMAL
|
||||||
|
+irqbalance_SOURCES += thermal.c
|
||||||
|
+endif
|
||||||
|
+irqbalance_LDADD = $(LIBCAP_NG_LIBS) $(GLIB2_LIBS) $(NUMA_LIBS) $(LIBNL3_LIBS)
|
||||||
|
if IRQBALANCEUI
|
||||||
|
irqbalance_ui_SOURCES = $(UI_DIR)/helpers.c $(UI_DIR)/irqbalance-ui.c \
|
||||||
|
$(UI_DIR)/ui.c
|
||||||
|
diff --git a/configure.ac b/configure.ac
|
||||||
|
index 32082fc..15532c1 100644
|
||||||
|
--- a/configure.ac
|
||||||
|
+++ b/configure.ac
|
||||||
|
@@ -36,6 +36,28 @@ AS_IF([test "x$has_ncursesw" = "xyes"], [
|
||||||
|
AC_SUBST([LIBS])
|
||||||
|
])
|
||||||
|
|
||||||
|
+AC_CANONICAL_HOST
|
||||||
|
+
|
||||||
|
+AC_ARG_ENABLE(thermal,
|
||||||
|
+ AS_HELP_STRING([--enable-thermal], [enable thermal event support [default=auto]]),,
|
||||||
|
+ AS_IF([test x"$host_cpu" = x"x86_64"], [enable_thermal=yes], [enable_thermal=no])
|
||||||
|
+)
|
||||||
|
+
|
||||||
|
+AS_IF([test x"$enable_thermal" = x"yes" && test x"$host_cpu" != x"x86_64"],
|
||||||
|
+ AC_MSG_ERROR([no thermal events support on $host_cpu systems.]),
|
||||||
|
+)
|
||||||
|
+
|
||||||
|
+AS_IF([test x"$enable_thermal" = x"yes"],
|
||||||
|
+ [PKG_CHECK_MODULES([LIBNL3], [libnl-3.0 libnl-genl-3.0], [have_thermal=yes],
|
||||||
|
+ AC_MSG_NOTICE([no thermal event support as libnl-3.0 is unavailable.])
|
||||||
|
+ )]
|
||||||
|
+)
|
||||||
|
+
|
||||||
|
+AS_IF([test "x$have_thermal" = xyes],
|
||||||
|
+ AC_DEFINE([HAVE_THERMAL], 1, [Build irqbalance to support thermal events])
|
||||||
|
+)
|
||||||
|
+AM_CONDITIONAL([THERMAL], [test "x$have_thermal" = xyes])
|
||||||
|
+
|
||||||
|
AC_C_CONST
|
||||||
|
AC_C_INLINE
|
||||||
|
AM_PROG_CC_C_O
|
||||||
|
diff --git a/cputree.c b/cputree.c
|
||||||
|
index b716a8f..c250977 100644
|
||||||
|
--- a/cputree.c
|
||||||
|
+++ b/cputree.c
|
||||||
|
@@ -38,6 +38,7 @@
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "irqbalance.h"
|
||||||
|
+#include "thermal.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_IRQBALANCEUI
|
||||||
|
extern char *banned_cpumask_from_ui;
|
||||||
|
@@ -162,6 +163,11 @@ static void setup_banned_cpus(void)
|
||||||
|
cpumask_scnprintf(buffer, 4096, nohz_full);
|
||||||
|
log(TO_CONSOLE, LOG_INFO, "Adaptive-ticks CPUs: %s\n", buffer);
|
||||||
|
out:
|
||||||
|
+#ifdef HAVE_THERMAL
|
||||||
|
+ cpus_or(banned_cpus, banned_cpus, thermal_banned_cpus);
|
||||||
|
+ cpumask_scnprintf(buffer, 4096, thermal_banned_cpus);
|
||||||
|
+ log(TO_CONSOLE, LOG_INFO, "Thermal-banned CPUs: %s\n", buffer);
|
||||||
|
+#endif
|
||||||
|
cpumask_scnprintf(buffer, 4096, banned_cpus);
|
||||||
|
log(TO_CONSOLE, LOG_INFO, "Banned CPUs: %s\n", buffer);
|
||||||
|
}
|
||||||
|
diff --git a/irqbalance.c b/irqbalance.c
|
||||||
|
index e8d9ba9..c520c11 100644
|
||||||
|
--- a/irqbalance.c
|
||||||
|
+++ b/irqbalance.c
|
||||||
|
@@ -44,6 +44,7 @@
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#include "irqbalance.h"
|
||||||
|
+#include "thermal.h"
|
||||||
|
|
||||||
|
volatile int keep_going = 1;
|
||||||
|
int one_shot_mode;
|
||||||
|
@@ -703,6 +704,8 @@ int main(int argc, char** argv)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
+ if (init_thermal())
|
||||||
|
+ log(TO_ALL, LOG_WARNING, "Failed to initialize thermal events.\n");
|
||||||
|
main_loop = g_main_loop_new(NULL, FALSE);
|
||||||
|
last_interval = sleep_interval;
|
||||||
|
g_timeout_add_seconds(sleep_interval, scan, NULL);
|
||||||
|
@@ -711,6 +714,7 @@ int main(int argc, char** argv)
|
||||||
|
g_main_loop_quit(main_loop);
|
||||||
|
|
||||||
|
out:
|
||||||
|
+ deinit_thermal();
|
||||||
|
free_object_tree();
|
||||||
|
free_cl_opts();
|
||||||
|
free(polscript);
|
||||||
|
diff --git a/thermal.c b/thermal.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..308bc48
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/thermal.c
|
||||||
|
@@ -0,0 +1,83 @@
|
||||||
|
+/*
|
||||||
|
+ * This program is free software; you can redistribute it and/or modify
|
||||||
|
+ * it under the terms of the GNU General Public License version 2 as
|
||||||
|
+ * published by the Free Software Foundation.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <stdio.h>
|
||||||
|
+
|
||||||
|
+#include <netlink/genl/genl.h>
|
||||||
|
+#include <netlink/genl/family.h>
|
||||||
|
+#include <netlink/genl/ctrl.h>
|
||||||
|
+
|
||||||
|
+#include "irqbalance.h"
|
||||||
|
+
|
||||||
|
+cpumask_t thermal_banned_cpus;
|
||||||
|
+
|
||||||
|
+static gboolean prepare_netlink(void)
|
||||||
|
+{
|
||||||
|
+ gboolean error = TRUE;
|
||||||
|
+
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: not yet implement to alloc memory for netlink.\n");
|
||||||
|
+ return error;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define NL_FAMILY_NAME "nlctrl"
|
||||||
|
+
|
||||||
|
+static gboolean establish_netlink(void)
|
||||||
|
+{
|
||||||
|
+ gboolean error = TRUE;
|
||||||
|
+
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: not yet implemented to establish netlink.\n");
|
||||||
|
+ return error;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static gboolean register_netlink_handler(nl_recvmsg_msg_cb_t handler __attribute__((unused)))
|
||||||
|
+{
|
||||||
|
+ gboolean error = TRUE;
|
||||||
|
+
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: not yet implemented to register thermal handler.\n");
|
||||||
|
+ return error;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static gboolean set_netlink_nonblocking(void)
|
||||||
|
+{
|
||||||
|
+ gboolean error = TRUE;
|
||||||
|
+
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: not yet implemented to set nonblocking socket.\n");
|
||||||
|
+ return error;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void deinit_thermal(void)
|
||||||
|
+{
|
||||||
|
+ return;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * return value: TRUE with an error; otherwise, FALSE
|
||||||
|
+ */
|
||||||
|
+gboolean init_thermal(void)
|
||||||
|
+{
|
||||||
|
+ gboolean error;
|
||||||
|
+
|
||||||
|
+ error = prepare_netlink();
|
||||||
|
+ if (error)
|
||||||
|
+ goto err_out;
|
||||||
|
+
|
||||||
|
+ error = establish_netlink();
|
||||||
|
+ if (error)
|
||||||
|
+ goto err_out;
|
||||||
|
+
|
||||||
|
+ error = register_netlink_handler(NULL);
|
||||||
|
+ if (error)
|
||||||
|
+ goto err_out;
|
||||||
|
+
|
||||||
|
+ error = set_netlink_nonblocking();
|
||||||
|
+ if (error)
|
||||||
|
+ goto err_out;
|
||||||
|
+
|
||||||
|
+ return FALSE;
|
||||||
|
+err_out:
|
||||||
|
+ deinit_thermal();
|
||||||
|
+ return TRUE;
|
||||||
|
+}
|
||||||
|
diff --git a/thermal.h b/thermal.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..657d54e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/thermal.h
|
||||||
|
@@ -0,0 +1,15 @@
|
||||||
|
+#ifndef __LINUX_THERMAL_H_
|
||||||
|
+#define __LINUX_THERMAL_H_
|
||||||
|
+
|
||||||
|
+#include <glib.h>
|
||||||
|
+
|
||||||
|
+#ifdef HAVE_THERMAL
|
||||||
|
+gboolean init_thermal(void);
|
||||||
|
+void deinit_thermal(void);
|
||||||
|
+extern cpumask_t thermal_banned_cpus;
|
||||||
|
+#else
|
||||||
|
+static inline gboolean init_thermal(void) { return FALSE; }
|
||||||
|
+#define deinit_thermal() do { } while (0)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#endif /* __LINUX_THERMAL_H_ */
|
||||||
|
--
|
||||||
|
2.33.1
|
||||||
|
|
@ -0,0 +1,392 @@
|
|||||||
|
From c65cda183609116760c54f1c2ad458eef9f44d56 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Chang S. Bae" <chang.seok.bae@intel.com>
|
||||||
|
Date: Fri, 11 Feb 2022 12:27:00 -0800
|
||||||
|
Subject: [PATCH 05/14] Implement Netlink helper functions to subscribe thermal
|
||||||
|
events
|
||||||
|
|
||||||
|
Establish Netlink socket connection in a nonblocking mode and callback
|
||||||
|
notification.
|
||||||
|
|
||||||
|
Tolerate a few times on failures from receiving events. In practice, such
|
||||||
|
delivery failure is rare. But it may indicate more fundamental issues if
|
||||||
|
it repeats. So disconnect it unless the failure is transient.
|
||||||
|
|
||||||
|
Event-specific handler will be implemented in the next patch.
|
||||||
|
|
||||||
|
Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
|
||||||
|
---
|
||||||
|
thermal.c | 327 +++++++++++++++++++++++++++++++++++++++++++++++++++---
|
||||||
|
1 file changed, 313 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/thermal.c b/thermal.c
|
||||||
|
index 308bc48..16a6f39 100644
|
||||||
|
--- a/thermal.c
|
||||||
|
+++ b/thermal.c
|
||||||
|
@@ -14,43 +14,342 @@
|
||||||
|
|
||||||
|
cpumask_t thermal_banned_cpus;
|
||||||
|
|
||||||
|
+#define INVALID_NL_FD -1
|
||||||
|
+#define MAX_RECV_ERRS 2
|
||||||
|
+
|
||||||
|
+#define THERMAL_GENL_FAMILY_NAME "thermal"
|
||||||
|
+#define THERMAL_GENL_EVENT_GROUP_NAME "event"
|
||||||
|
+#define NL_FAMILY_NAME "nlctrl"
|
||||||
|
+
|
||||||
|
+struct family_data {
|
||||||
|
+ const char *group;
|
||||||
|
+ int id;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct nl_sock *sock;
|
||||||
|
+static struct nl_cb *callback;
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * return value: TRUE with an error; otherwise, FALSE
|
||||||
|
+ */
|
||||||
|
static gboolean prepare_netlink(void)
|
||||||
|
{
|
||||||
|
- gboolean error = TRUE;
|
||||||
|
+ int rc;
|
||||||
|
|
||||||
|
- log(TO_ALL, LOG_ERR, "thermal: not yet implement to alloc memory for netlink.\n");
|
||||||
|
- return error;
|
||||||
|
+ sock = nl_socket_alloc();
|
||||||
|
+ if (!sock) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: socket allocation failed.\n");
|
||||||
|
+ return TRUE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rc = genl_connect(sock);
|
||||||
|
+ if (rc) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: socket bind failed.\n");
|
||||||
|
+ return TRUE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ callback = nl_cb_alloc(NL_CB_DEFAULT);
|
||||||
|
+ if (!callback) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: callback allocation failed.\n");
|
||||||
|
+ return TRUE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
-#define NL_FAMILY_NAME "nlctrl"
|
||||||
|
+static int handle_groupid(struct nl_msg *msg, void *arg)
|
||||||
|
+{
|
||||||
|
+ struct nlattr *attrhdr, *mcgrp, *cur_mcgrp;
|
||||||
|
+ struct nlattr *attrs[CTRL_ATTR_MAX + 1];
|
||||||
|
+ struct nla_policy *policy = NULL;
|
||||||
|
+ struct genlmsghdr *gnlhdr = NULL;
|
||||||
|
+ struct family_data *data = NULL;
|
||||||
|
+ struct nlmsghdr *msghdr = NULL;
|
||||||
|
+ int attrlen, rc, i;
|
||||||
|
+
|
||||||
|
+ if (!arg) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: group id - failed to receive argument.\n");
|
||||||
|
+ return NL_SKIP;
|
||||||
|
+ }
|
||||||
|
+ data = arg;
|
||||||
|
+
|
||||||
|
+ /* get actual netlink message header */
|
||||||
|
+ msghdr = nlmsg_hdr(msg);
|
||||||
|
+
|
||||||
|
+ /* get the start of the message payload */
|
||||||
|
+ gnlhdr = nlmsg_data(msghdr);
|
||||||
|
+
|
||||||
|
+ /* get the start of the message attribute section */
|
||||||
|
+ attrhdr = genlmsg_attrdata(gnlhdr, 0);
|
||||||
|
+
|
||||||
|
+ /* get the length of the message attribute section */
|
||||||
|
+ attrlen = genlmsg_attrlen(gnlhdr, 0);
|
||||||
|
+
|
||||||
|
+ /* create attribute index based on a stream of attributes */
|
||||||
|
+ rc = nla_parse(
|
||||||
|
+ attrs, /* index array to be filled */
|
||||||
|
+ CTRL_ATTR_MAX, /* the maximum acceptable attribute type */
|
||||||
|
+ attrhdr, /* head of attribute stream */
|
||||||
|
+ attrlen, /* length of attribute stream */
|
||||||
|
+ policy); /* validation policy */
|
||||||
|
+ if (rc) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: group id - failed to create attributes.\n");
|
||||||
|
+ return NL_SKIP;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* start of the multi-cast group attribute */
|
||||||
|
+ mcgrp = attrs[CTRL_ATTR_MCAST_GROUPS];
|
||||||
|
+ if (!mcgrp) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: group id - no multi-cast group attributes.\n");
|
||||||
|
+ return NL_SKIP;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* iterate a stream of nested attributes to get the group id */
|
||||||
|
+ nla_for_each_nested(cur_mcgrp, mcgrp, i) {
|
||||||
|
+ struct nlattr *nested_attrs[CTRL_ATTR_MCAST_GRP_MAX + 1];
|
||||||
|
+ struct nlattr *name, *id;
|
||||||
|
+
|
||||||
|
+ /* get start and length of payload section */
|
||||||
|
+ attrhdr = nla_data(cur_mcgrp);
|
||||||
|
+ attrlen = nla_len(cur_mcgrp);
|
||||||
|
+
|
||||||
|
+ rc = nla_parse(nested_attrs, CTRL_ATTR_MCAST_GRP_MAX, attrhdr, attrlen, policy);
|
||||||
|
+ if (rc)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ name = nested_attrs[CTRL_ATTR_MCAST_GRP_NAME];
|
||||||
|
+ id = nested_attrs[CTRL_ATTR_MCAST_GRP_ID];
|
||||||
|
+ if (!name || !id)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ if (strncmp(nla_data(name), data->group, nla_len(name)) != 0)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ data->id = nla_get_u32(id);
|
||||||
|
+ log(TO_ALL, LOG_DEBUG, "thermal: received group id (%d).\n", data->id);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ return NL_OK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int handle_error(struct sockaddr_nl *sk_addr __attribute__((unused)),
|
||||||
|
+ struct nlmsgerr *err, void *arg)
|
||||||
|
+{
|
||||||
|
+ if (arg) {
|
||||||
|
+ log(TO_ALL, LOG_INFO, "thermal: received a netlink error (%s).\n",
|
||||||
|
+ nl_geterror(err->error));
|
||||||
|
+ *((int *)arg) = err->error;
|
||||||
|
+ }
|
||||||
|
+ return NL_SKIP;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int handle_end(struct nl_msg *msg __attribute__((unused)), void *arg)
|
||||||
|
+{
|
||||||
|
+ if (arg)
|
||||||
|
+ *((int *)arg) = 0;
|
||||||
|
+ return NL_SKIP;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+struct msgheader {
|
||||||
|
+ unsigned char cmd, version;
|
||||||
|
+ unsigned int port, seq;
|
||||||
|
+ int id, hdrlen, flags;
|
||||||
|
+};
|
||||||
|
|
||||||
|
static gboolean establish_netlink(void)
|
||||||
|
{
|
||||||
|
+ struct msgheader msghdr = { CTRL_CMD_GETFAMILY, 0, 0, 0, 0, 0, 0 };
|
||||||
|
+ struct family_data nldata = { THERMAL_GENL_EVENT_GROUP_NAME, -ENOENT };
|
||||||
|
+ struct nl_cb *cloned_callback = NULL;
|
||||||
|
+ int rc, group_id, callback_rc = 1;
|
||||||
|
+ struct nl_msg *msg = NULL;
|
||||||
|
gboolean error = TRUE;
|
||||||
|
+ void *hdr;
|
||||||
|
+
|
||||||
|
+ msg = nlmsg_alloc();
|
||||||
|
+ if (!msg) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: message allocation failed.\n");
|
||||||
|
+ goto err_out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ msghdr.id = genl_ctrl_resolve(sock, NL_FAMILY_NAME);
|
||||||
|
+ if (msghdr.id < 0) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: message id enumeration failed.\n");
|
||||||
|
+ goto err_out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ hdr = genlmsg_put(msg, msghdr.port, msghdr.seq, msghdr.id, msghdr.hdrlen,
|
||||||
|
+ msghdr.flags, msghdr.cmd, msghdr.version);
|
||||||
|
+ if (!hdr) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: netlink header setup failed.\n");
|
||||||
|
+ goto err_out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rc = nla_put_string(msg, CTRL_ATTR_FAMILY_NAME, THERMAL_GENL_FAMILY_NAME);
|
||||||
|
+ if (rc) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: message setup failed.\n");
|
||||||
|
+ goto err_out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ cloned_callback = nl_cb_clone(callback);
|
||||||
|
+ if (!cloned_callback) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: callback handle duplication failed.\n");
|
||||||
|
+ goto err_out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rc = nl_send_auto(sock, msg);
|
||||||
|
+ if (rc < 0) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: failed to send the first message.\n");
|
||||||
|
+ goto err_out;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- log(TO_ALL, LOG_ERR, "thermal: not yet implemented to establish netlink.\n");
|
||||||
|
+ rc = nl_cb_err(cloned_callback, NL_CB_CUSTOM, handle_error, &callback_rc);
|
||||||
|
+ if (rc) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: error callback setup failed.\n");
|
||||||
|
+ goto err_out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rc = nl_cb_set(cloned_callback, NL_CB_ACK, NL_CB_CUSTOM, handle_end, &callback_rc);
|
||||||
|
+ if (rc) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: ack callback setup failed.\n");
|
||||||
|
+ goto err_out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rc = nl_cb_set(cloned_callback, NL_CB_FINISH, NL_CB_CUSTOM, handle_end, &callback_rc);
|
||||||
|
+ if (rc) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: finish callback setup failed.\n");
|
||||||
|
+ goto err_out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rc = nl_cb_set(cloned_callback, NL_CB_VALID, NL_CB_CUSTOM, handle_groupid, &nldata);
|
||||||
|
+ if (rc) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: group id callback setup failed.\n");
|
||||||
|
+ goto err_out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ while (callback_rc != 0) {
|
||||||
|
+ rc = nl_recvmsgs(sock, cloned_callback);
|
||||||
|
+ if (rc < 0) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: failed to receive messages.\n");
|
||||||
|
+ goto err_out;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ group_id = nldata.id;
|
||||||
|
+ if (group_id < 0) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: invalid group_id was received.\n");
|
||||||
|
+ goto err_out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rc = nl_socket_add_membership(sock, group_id);
|
||||||
|
+ if (rc) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: failed to join the netlink group.\n");
|
||||||
|
+ goto err_out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ error = FALSE;
|
||||||
|
+err_out:
|
||||||
|
+ nl_cb_put(cloned_callback);
|
||||||
|
+ nlmsg_free(msg);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static gboolean register_netlink_handler(nl_recvmsg_msg_cb_t handler __attribute__((unused)))
|
||||||
|
+static int handle_thermal_event(struct nl_msg *msg __attribute__((unused)),
|
||||||
|
+ void *arg __attribute__((unused)))
|
||||||
|
{
|
||||||
|
- gboolean error = TRUE;
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: not yet implemented to process thermal event.\n");
|
||||||
|
+ return NL_SKIP;
|
||||||
|
+}
|
||||||
|
|
||||||
|
- log(TO_ALL, LOG_ERR, "thermal: not yet implemented to register thermal handler.\n");
|
||||||
|
- return error;
|
||||||
|
+static int handler_for_debug(struct nl_msg *msg __attribute__((unused)),
|
||||||
|
+ void *arg __attribute__((unused)))
|
||||||
|
+{
|
||||||
|
+ return NL_SKIP;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * return value: TRUE with an error; otherwise, FALSE
|
||||||
|
+ */
|
||||||
|
+static gboolean register_netlink_handler(void)
|
||||||
|
+{
|
||||||
|
+ int rc;
|
||||||
|
+
|
||||||
|
+ rc = nl_cb_set(callback, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, handler_for_debug, NULL);
|
||||||
|
+ if (rc) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: debug handler registration failed.\n");
|
||||||
|
+ return TRUE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ rc = nl_cb_set(callback, NL_CB_VALID, NL_CB_CUSTOM, handle_thermal_event, NULL);
|
||||||
|
+ if (rc) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: thermal handler registration failed.\n");
|
||||||
|
+ return TRUE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * return value: TRUE to keep the source; FALSE to disconnect.
|
||||||
|
+ */
|
||||||
|
+gboolean receive_thermal_event(gint fd __attribute__((unused)),
|
||||||
|
+ GIOCondition condition,
|
||||||
|
+ gpointer user_data __attribute__((unused)))
|
||||||
|
+{
|
||||||
|
+ if (condition == G_IO_IN) {
|
||||||
|
+ static unsigned int retry = 0;
|
||||||
|
+ int err;
|
||||||
|
+
|
||||||
|
+ err = nl_recvmsgs(sock, callback);
|
||||||
|
+ if (err) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: failed to receive messages (rc=%d).\n", err);
|
||||||
|
+ retry++;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Pass a few failures then turn off if it keeps
|
||||||
|
+ * failing down.
|
||||||
|
+ */
|
||||||
|
+ if (retry <= MAX_RECV_ERRS) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: but keep the connection.\n");
|
||||||
|
+ } else {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: disconnect now with %u failures.\n",
|
||||||
|
+ retry);
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return TRUE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * return value: TRUE with an error; otherwise, FALSE
|
||||||
|
+ */
|
||||||
|
static gboolean set_netlink_nonblocking(void)
|
||||||
|
{
|
||||||
|
- gboolean error = TRUE;
|
||||||
|
+ int rc, fd;
|
||||||
|
|
||||||
|
- log(TO_ALL, LOG_ERR, "thermal: not yet implemented to set nonblocking socket.\n");
|
||||||
|
- return error;
|
||||||
|
+ rc = nl_socket_set_nonblocking(sock);
|
||||||
|
+ if (rc) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: non-blocking mode setup failed.\n");
|
||||||
|
+ return TRUE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ fd = nl_socket_get_fd(sock);
|
||||||
|
+ if (fd == INVALID_NL_FD) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: file descriptor setup failed.\n");
|
||||||
|
+ return TRUE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ g_unix_fd_add(fd, G_IO_IN, receive_thermal_event, NULL);
|
||||||
|
+
|
||||||
|
+ return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deinit_thermal(void)
|
||||||
|
{
|
||||||
|
- return;
|
||||||
|
+ nl_cb_put(callback);
|
||||||
|
+ nl_socket_free(sock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -68,7 +367,7 @@ gboolean init_thermal(void)
|
||||||
|
if (error)
|
||||||
|
goto err_out;
|
||||||
|
|
||||||
|
- error = register_netlink_handler(NULL);
|
||||||
|
+ error = register_netlink_handler();
|
||||||
|
if (error)
|
||||||
|
goto err_out;
|
||||||
|
|
||||||
|
--
|
||||||
|
2.33.1
|
||||||
|
|
242
SOURCES/0006-Handle-thermal-events-to-mask-CPUs.patch
Normal file
242
SOURCES/0006-Handle-thermal-events-to-mask-CPUs.patch
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
From 560291389e33db108d2fb6d954ef059f953c6e33 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Chang S. Bae" <chang.seok.bae@intel.com>
|
||||||
|
Date: Fri, 11 Feb 2022 13:48:01 -0800
|
||||||
|
Subject: [PATCH 06/14] Handle thermal events to mask CPUs
|
||||||
|
|
||||||
|
The Hardware Feedback Interface event is delivered as the Netlink's
|
||||||
|
THERMAL_GENL_ATTR_CPU_CAPABILITY attribute. Add code to receive and parse
|
||||||
|
these attributes: logical CPU number, performance, and efficiency
|
||||||
|
enumeration values (0-1023).
|
||||||
|
|
||||||
|
When an event indicates CPU performance and efficiency are zeros, then the
|
||||||
|
CPU needs to be banned from IRQs. Rebuild object tree to make this banned
|
||||||
|
list effective.
|
||||||
|
|
||||||
|
Creating the banned CPU list here is a bit tricky here because the amount
|
||||||
|
of data that each Netlink notification can carry out is not enough in some
|
||||||
|
systems with many cores. This means the handler has to wait for multiple
|
||||||
|
notifications to determine banned CPUs per thermal event.
|
||||||
|
|
||||||
|
Establish a logic to maintain the list based on the kernel behaviors. Also,
|
||||||
|
always push the current list as of the banned CPUs, because there is no
|
||||||
|
clear line whether each notification is at the end of a thermal event or
|
||||||
|
not.
|
||||||
|
|
||||||
|
Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
|
||||||
|
---
|
||||||
|
thermal.c | 172 +++++++++++++++++++++++++++++++++++++++++++++++++++---
|
||||||
|
1 file changed, 165 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/thermal.c b/thermal.c
|
||||||
|
index 16a6f39..64a9cdf 100644
|
||||||
|
--- a/thermal.c
|
||||||
|
+++ b/thermal.c
|
||||||
|
@@ -6,6 +6,7 @@
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
+#include <sys/sysinfo.h>
|
||||||
|
#include <netlink/genl/genl.h>
|
||||||
|
#include <netlink/genl/family.h>
|
||||||
|
#include <netlink/genl/ctrl.h>
|
||||||
|
@@ -14,8 +15,62 @@
|
||||||
|
|
||||||
|
cpumask_t thermal_banned_cpus;
|
||||||
|
|
||||||
|
-#define INVALID_NL_FD -1
|
||||||
|
-#define MAX_RECV_ERRS 2
|
||||||
|
+/* Events of thermal_genl_family */
|
||||||
|
+enum thermal_genl_event {
|
||||||
|
+ THERMAL_GENL_EVENT_UNSPEC,
|
||||||
|
+ THERMAL_GENL_EVENT_TZ_CREATE, /* Thermal zone creation */
|
||||||
|
+ THERMAL_GENL_EVENT_TZ_DELETE, /* Thermal zone deletion */
|
||||||
|
+ THERMAL_GENL_EVENT_TZ_DISABLE, /* Thermal zone disabled */
|
||||||
|
+ THERMAL_GENL_EVENT_TZ_ENABLE, /* Thermal zone enabled */
|
||||||
|
+ THERMAL_GENL_EVENT_TZ_TRIP_UP, /* Trip point crossed the way up */
|
||||||
|
+ THERMAL_GENL_EVENT_TZ_TRIP_DOWN, /* Trip point crossed the way down */
|
||||||
|
+ THERMAL_GENL_EVENT_TZ_TRIP_CHANGE, /* Trip point changed */
|
||||||
|
+ THERMAL_GENL_EVENT_TZ_TRIP_ADD, /* Trip point added */
|
||||||
|
+ THERMAL_GENL_EVENT_TZ_TRIP_DELETE, /* Trip point deleted */
|
||||||
|
+ THERMAL_GENL_EVENT_CDEV_ADD, /* Cdev bound to the thermal zone */
|
||||||
|
+ THERMAL_GENL_EVENT_CDEV_DELETE, /* Cdev unbound */
|
||||||
|
+ THERMAL_GENL_EVENT_CDEV_STATE_UPDATE, /* Cdev state updated */
|
||||||
|
+ THERMAL_GENL_EVENT_TZ_GOV_CHANGE, /* Governor policy changed */
|
||||||
|
+ THERMAL_GENL_EVENT_CAPACITY_CHANGE, /* CPU capacity changed */
|
||||||
|
+ __THERMAL_GENL_EVENT_MAX,
|
||||||
|
+};
|
||||||
|
+#define THERMAL_GENL_EVENT_MAX (__THERMAL_GENL_EVENT_MAX - 1)
|
||||||
|
+
|
||||||
|
+/* Attributes of thermal_genl_family */
|
||||||
|
+enum thermal_genl_attr {
|
||||||
|
+ THERMAL_GENL_ATTR_UNSPEC,
|
||||||
|
+ THERMAL_GENL_ATTR_TZ,
|
||||||
|
+ THERMAL_GENL_ATTR_TZ_ID,
|
||||||
|
+ THERMAL_GENL_ATTR_TZ_TEMP,
|
||||||
|
+ THERMAL_GENL_ATTR_TZ_TRIP,
|
||||||
|
+ THERMAL_GENL_ATTR_TZ_TRIP_ID,
|
||||||
|
+ THERMAL_GENL_ATTR_TZ_TRIP_TYPE,
|
||||||
|
+ THERMAL_GENL_ATTR_TZ_TRIP_TEMP,
|
||||||
|
+ THERMAL_GENL_ATTR_TZ_TRIP_HYST,
|
||||||
|
+ THERMAL_GENL_ATTR_TZ_MODE,
|
||||||
|
+ THERMAL_GENL_ATTR_TZ_NAME,
|
||||||
|
+ THERMAL_GENL_ATTR_TZ_CDEV_WEIGHT,
|
||||||
|
+ THERMAL_GENL_ATTR_TZ_GOV,
|
||||||
|
+ THERMAL_GENL_ATTR_TZ_GOV_NAME,
|
||||||
|
+ THERMAL_GENL_ATTR_CDEV,
|
||||||
|
+ THERMAL_GENL_ATTR_CDEV_ID,
|
||||||
|
+ THERMAL_GENL_ATTR_CDEV_CUR_STATE,
|
||||||
|
+ THERMAL_GENL_ATTR_CDEV_MAX_STATE,
|
||||||
|
+ THERMAL_GENL_ATTR_CDEV_NAME,
|
||||||
|
+ THERMAL_GENL_ATTR_GOV_NAME,
|
||||||
|
+ THERMAL_GENL_ATTR_CAPACITY,
|
||||||
|
+ THERMAL_GENL_ATTR_CAPACITY_CPU_COUNT,
|
||||||
|
+ THERMAL_GENL_ATTR_CAPACITY_CPU_ID,
|
||||||
|
+ THERMAL_GENL_ATTR_CAPACITY_CPU_PERF,
|
||||||
|
+ THERMAL_GENL_ATTR_CAPACITY_CPU_EFF,
|
||||||
|
+ __THERMAL_GENL_ATTR_MAX,
|
||||||
|
+};
|
||||||
|
+#define THERMAL_GENL_ATTR_MAX (__THERMAL_GENL_ATTR_MAX - 1)
|
||||||
|
+
|
||||||
|
+#define INVALID_NL_FD -1
|
||||||
|
+#define MAX_RECV_ERRS 2
|
||||||
|
+#define SYSCONF_ERR -1
|
||||||
|
+#define INVALID_EVENT_VALUE -1
|
||||||
|
|
||||||
|
#define THERMAL_GENL_FAMILY_NAME "thermal"
|
||||||
|
#define THERMAL_GENL_EVENT_GROUP_NAME "event"
|
||||||
|
@@ -254,17 +309,115 @@ err_out:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int handle_thermal_event(struct nl_msg *msg __attribute__((unused)),
|
||||||
|
- void *arg __attribute__((unused)))
|
||||||
|
+enum {
|
||||||
|
+ INDEX_CPUNUM,
|
||||||
|
+ INDEX_PERF,
|
||||||
|
+ INDEX_EFFI,
|
||||||
|
+ INDEX_MAX
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Single netlink notification is not guaranteed to fully deliver all of
|
||||||
|
+ * the CPU updates per thermal event, due to the implementation choice in
|
||||||
|
+ * the kernel code. So, this function is intended to manage a CPU list in a
|
||||||
|
+ * stream of relevant notifications.
|
||||||
|
+ */
|
||||||
|
+static void update_banned_cpus(int cur_cpuidx, gboolean need_to_ban)
|
||||||
|
{
|
||||||
|
- log(TO_ALL, LOG_ERR, "thermal: not yet implemented to process thermal event.\n");
|
||||||
|
- return NL_SKIP;
|
||||||
|
+ static cpumask_t banmask = { 0 }, itrmask = { 0 };
|
||||||
|
+ long max_cpunum = sysconf(_SC_NPROCESSORS_ONLN);
|
||||||
|
+
|
||||||
|
+ if (need_to_ban)
|
||||||
|
+ cpu_set(cur_cpuidx, banmask);
|
||||||
|
+
|
||||||
|
+ cpu_set(cur_cpuidx, itrmask);
|
||||||
|
+ if (cpus_weight(itrmask) < max_cpunum)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (cpus_equal(thermal_banned_cpus, banmask))
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
+ cpus_copy(thermal_banned_cpus, banmask);
|
||||||
|
+ need_rescan = 1;
|
||||||
|
+out:
|
||||||
|
+ cpus_clear(banmask);
|
||||||
|
+ cpus_clear(itrmask);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int handle_thermal_event(struct nl_msg *msg, void *arg __attribute__((unused)))
|
||||||
|
+{
|
||||||
|
+ int event_data[INDEX_MAX] = { INVALID_EVENT_VALUE };
|
||||||
|
+ struct nlattr *attrs[THERMAL_GENL_ATTR_MAX + 1];
|
||||||
|
+ struct genlmsghdr *genlhdr;
|
||||||
|
+ struct nlmsghdr *msnlh;
|
||||||
|
+ struct nlattr *cap;
|
||||||
|
+ int i, remain, rc;
|
||||||
|
+ void *pos;
|
||||||
|
+
|
||||||
|
+ /* get actual netlink message header */
|
||||||
|
+ msnlh = nlmsg_hdr(msg);
|
||||||
|
+
|
||||||
|
+ /* get a pointer to generic netlink header */
|
||||||
|
+ genlhdr = genlmsg_hdr(msnlh);
|
||||||
|
+ if (genlhdr->cmd != THERMAL_GENL_EVENT_CAPACITY_CHANGE) {
|
||||||
|
+ log(TO_ALL, LOG_DEBUG, "thermal: no CPU capacity change.\n");
|
||||||
|
+ return NL_SKIP;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* parse generic netlink message including attributes */
|
||||||
|
+ rc = genlmsg_parse(
|
||||||
|
+ msnlh, /* a pointer to netlink message header */
|
||||||
|
+ 0, /* length of user header */
|
||||||
|
+ attrs, /* array to store parsed attributes */
|
||||||
|
+ THERMAL_GENL_ATTR_MAX, /* maximum attribute id as expected */
|
||||||
|
+ NULL); /* validation policy */
|
||||||
|
+ if (rc) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: failed to parse message for thermal event.\n");
|
||||||
|
+ return NL_SKIP;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* get start and length of payload section */
|
||||||
|
+ cap = attrs[THERMAL_GENL_ATTR_CAPACITY];
|
||||||
|
+ pos = nla_data(cap);
|
||||||
|
+ remain = nla_len(cap);
|
||||||
|
+
|
||||||
|
+ for (i = 0; nla_ok(pos, remain); pos = nla_next(pos, &remain), i++) {
|
||||||
|
+ gboolean valid_event = TRUE, need_to_ban;
|
||||||
|
+ unsigned int value = nla_get_u32(pos);
|
||||||
|
+ int idx = i % INDEX_MAX;
|
||||||
|
+ int cur_cpuidx;
|
||||||
|
+
|
||||||
|
+ event_data[idx] = value;
|
||||||
|
+
|
||||||
|
+ if (idx != INDEX_EFFI)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ cur_cpuidx = event_data[INDEX_CPUNUM];
|
||||||
|
+ valid_event = !!(cur_cpuidx <= NR_CPUS);
|
||||||
|
+ if (!valid_event) {
|
||||||
|
+ log(TO_ALL, LOG_WARNING, "thermal: invalid event - CPU %d\n",
|
||||||
|
+ cur_cpuidx);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * A CPU with no performance and no efficiency cannot
|
||||||
|
+ * handle IRQs:
|
||||||
|
+ */
|
||||||
|
+ need_to_ban = !!(!event_data[INDEX_PERF] && !event_data[INDEX_EFFI]);
|
||||||
|
+ update_banned_cpus(cur_cpuidx, need_to_ban);
|
||||||
|
+
|
||||||
|
+ log(TO_ALL, LOG_DEBUG, "thermal: event - CPU %d, efficiency %d, perf %d.\n",
|
||||||
|
+ cur_cpuidx, event_data[INDEX_PERF], event_data[INDEX_EFFI]);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return NL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int handler_for_debug(struct nl_msg *msg __attribute__((unused)),
|
||||||
|
void *arg __attribute__((unused)))
|
||||||
|
{
|
||||||
|
- return NL_SKIP;
|
||||||
|
+ return NL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -274,6 +427,11 @@ static gboolean register_netlink_handler(void)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
+ if (sysconf(_SC_NPROCESSORS_ONLN) == SYSCONF_ERR) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "thermal: _SC_NPROCESSORS_ONLN not available.\n");
|
||||||
|
+ return TRUE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
rc = nl_cb_set(callback, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, handler_for_debug, NULL);
|
||||||
|
if (rc) {
|
||||||
|
log(TO_ALL, LOG_ERR, "thermal: debug handler registration failed.\n");
|
||||||
|
--
|
||||||
|
2.33.1
|
||||||
|
|
@ -0,0 +1,27 @@
|
|||||||
|
From 028082a6a1ff650d5cdf796ac55ac26a3874372a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Liu Chao <liuchao173@huawei.com>
|
||||||
|
Date: Sat, 25 Jun 2022 14:13:10 +0800
|
||||||
|
Subject: [PATCH 07/14] add keep_going check to prevent irqbalance from failing
|
||||||
|
to exit after SIGTERM
|
||||||
|
|
||||||
|
Signed-off-by: Liu Chao <liuchao173@huawei.com>
|
||||||
|
---
|
||||||
|
irqbalance.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/irqbalance.c b/irqbalance.c
|
||||||
|
index c520c11..5eae5b6 100644
|
||||||
|
--- a/irqbalance.c
|
||||||
|
+++ b/irqbalance.c
|
||||||
|
@@ -290,7 +290,7 @@ gboolean scan(gpointer data __attribute__((unused)))
|
||||||
|
|
||||||
|
|
||||||
|
/* cope with cpu hotplug -- detected during /proc/interrupts parsing */
|
||||||
|
- while (need_rescan || need_rebuild) {
|
||||||
|
+ while (keep_going && (need_rescan || need_rebuild)) {
|
||||||
|
int try_times = 0;
|
||||||
|
|
||||||
|
need_rescan = 0;
|
||||||
|
--
|
||||||
|
2.33.1
|
||||||
|
|
@ -0,0 +1,26 @@
|
|||||||
|
From 0a82dddbaf5702caded0d0d83a6eafaca743254d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andreas Schwab <schwab@suse.de>
|
||||||
|
Date: Mon, 27 Jun 2022 13:43:04 +0200
|
||||||
|
Subject: [PATCH 08/14] parse_proc_interrupts: fix parsing interrupt counts
|
||||||
|
|
||||||
|
The name of an interrupt chip can start with a number, stop before it.
|
||||||
|
---
|
||||||
|
procinterrupts.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/procinterrupts.c b/procinterrupts.c
|
||||||
|
index 57c8801..d90bf6d 100644
|
||||||
|
--- a/procinterrupts.c
|
||||||
|
+++ b/procinterrupts.c
|
||||||
|
@@ -331,7 +331,7 @@ void parse_proc_interrupts(void)
|
||||||
|
while (1) {
|
||||||
|
uint64_t C;
|
||||||
|
C = strtoull(c, &c2, 10);
|
||||||
|
- if (c==c2) /* end of numbers */
|
||||||
|
+ if (c==c2 || !strchr(" \t", *c2)) /* end of numbers */
|
||||||
|
break;
|
||||||
|
count += C;
|
||||||
|
c=c2;
|
||||||
|
--
|
||||||
|
2.33.1
|
||||||
|
|
@ -0,0 +1,50 @@
|
|||||||
|
From 7f1caca47aee32084c319db07d9a236684b818a3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Liu Chao <liuchao173@huawei.com>
|
||||||
|
Date: Tue, 28 Jun 2022 16:42:10 +0800
|
||||||
|
Subject: [PATCH 09/14] irqbalance-ui: move 'ASSIGNED TO CPUS' to the last
|
||||||
|
column
|
||||||
|
|
||||||
|
Signed-off-by: Liu Chao <liuchao173@huawei.com>
|
||||||
|
---
|
||||||
|
ui/ui.c | 10 +++++-----
|
||||||
|
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ui/ui.c b/ui/ui.c
|
||||||
|
index 6ff3305..beafe3a 100644
|
||||||
|
--- a/ui/ui.c
|
||||||
|
+++ b/ui/ui.c
|
||||||
|
@@ -331,7 +331,7 @@ void print_assigned_objects_string(irq_t *irq, int *line_offset)
|
||||||
|
char assigned_to[128] = "\0";
|
||||||
|
for_each_int(irq->assigned_to, copy_assigned_obj, assigned_to);
|
||||||
|
assigned_to[strlen(assigned_to) - 2] = '\0';
|
||||||
|
- mvprintw(*line_offset, 36, "%s", assigned_to);
|
||||||
|
+ mvprintw(*line_offset, 68, "%s", assigned_to);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_irq_line(irq_t *irq, void *data)
|
||||||
|
@@ -364,9 +364,9 @@ void print_irq_line(irq_t *irq, void *data)
|
||||||
|
}
|
||||||
|
mvprintw(*line_offset, 3, "IRQ %d", irq->vector);
|
||||||
|
mvprintw(*line_offset, 19, "%s", irq->is_banned ? "YES" : "NO ");
|
||||||
|
- print_assigned_objects_string(irq, line_offset);
|
||||||
|
- mvprintw(*line_offset, 84, "%s",
|
||||||
|
+ mvprintw(*line_offset, 36, "%s",
|
||||||
|
irq->class < 0 ? "Unknown" : IRQ_CLASS_TO_STR[irq->class]);
|
||||||
|
+ print_assigned_objects_string(irq, line_offset);
|
||||||
|
(*line_offset)++;
|
||||||
|
|
||||||
|
}
|
||||||
|
@@ -377,8 +377,8 @@ void print_all_irqs()
|
||||||
|
*line = 4;
|
||||||
|
attrset(COLOR_PAIR(0));
|
||||||
|
mvprintw(2, 3,
|
||||||
|
- "NUMBER IS BANNED ASSIGNED TO CPUS \
|
||||||
|
- CLASS");
|
||||||
|
+ "NUMBER IS BANNED CLASS \
|
||||||
|
+ ASSIGNED TO CPUS");
|
||||||
|
for_each_irq(all_irqs, print_irq_line, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.33.1
|
||||||
|
|
@ -0,0 +1,347 @@
|
|||||||
|
From b65faa2b658e3cf4edf6d39e4bb1e103a47ac0de Mon Sep 17 00:00:00 2001
|
||||||
|
From: Liu Chao <liuchao173@huawei.com>
|
||||||
|
Date: Thu, 30 Jun 2022 10:19:00 +0800
|
||||||
|
Subject: [PATCH 10/14] irqbalance-ui: can't change window when in editing
|
||||||
|
state
|
||||||
|
|
||||||
|
when invoking setup_irqs in settings or invoking settings in setup_irqs, it
|
||||||
|
doesn't break but enters another while loop.
|
||||||
|
For example:
|
||||||
|
# gdb program `pidof irqbalance-ui`
|
||||||
|
(gdb) bt
|
||||||
|
#0 0x0000ffffb0dcc7b0 in poll () from /usr/lib64/libc.so.6
|
||||||
|
#1 0x0000ffffb0e9097c in _nc_timed_wait () from /usr/lib64/libtinfo.so.6
|
||||||
|
#2 0x0000ffffb0ecc154 in _nc_wgetch () from /usr/lib64/libncursesw.so.6
|
||||||
|
#3 0x0000ffffb0eccb18 in wgetch () from /usr/lib64/libncursesw.so.6
|
||||||
|
#4 0x00000000004045d4 in setup_irqs () at ui/ui.c:637
|
||||||
|
#5 0x0000000000404084 in settings () at ui/ui.c:614
|
||||||
|
#6 0x0000000000404084 in settings () at ui/ui.c:614
|
||||||
|
#7 0x0000000000404084 in settings () at ui/ui.c:614
|
||||||
|
#8 0x0000000000404084 in settings () at ui/ui.c:614
|
||||||
|
#9 0x0000000000404084 in settings () at ui/ui.c:614
|
||||||
|
#10 0x0000000000404084 in settings () at ui/ui.c:614
|
||||||
|
#11 0x0000000000404084 in settings () at ui/ui.c:614
|
||||||
|
#12 0x0000000000401fac in key_loop (data=<optimized out>) at ui/irqbalance-ui.c:387
|
||||||
|
#13 0x0000ffffb105371c in ?? () from /usr/lib64/libglib-2.0.so.0
|
||||||
|
#14 0x0000ffffb1052a84 in g_main_context_dispatch () from /usr/lib64/libglib-2.0.so.0
|
||||||
|
#15 0x0000ffffb1052e38 in ?? () from /usr/lib64/libglib-2.0.so.0
|
||||||
|
#16 0x0000ffffb1053188 in g_main_loop_run () from /usr/lib64/libglib-2.0.so.0
|
||||||
|
#17 0x000000000040196c in main (argc=<optimized out>, argv=<optimized out>) at ui/irqbalance-ui.c:445
|
||||||
|
|
||||||
|
Signed-off-by: Liu Chao <liuchao173@huawei.com>
|
||||||
|
---
|
||||||
|
ui/irqbalance-ui.c | 39 ++++++++++---
|
||||||
|
ui/ui.c | 137 ++++++++++++---------------------------------
|
||||||
|
ui/ui.h | 2 +-
|
||||||
|
3 files changed, 69 insertions(+), 109 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ui/irqbalance-ui.c b/ui/irqbalance-ui.c
|
||||||
|
index 3ad3553..89ed94a 100644
|
||||||
|
--- a/ui/irqbalance-ui.c
|
||||||
|
+++ b/ui/irqbalance-ui.c
|
||||||
|
@@ -16,11 +16,16 @@
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
|
|
||||||
|
+enum states {
|
||||||
|
+ STATE_TREE,
|
||||||
|
+ STATE_SETTINGS,
|
||||||
|
+ STATE_SETUP_IRQS
|
||||||
|
+};
|
||||||
|
+int state;
|
||||||
|
int irqbalance_pid = -1;
|
||||||
|
GList *tree = NULL;
|
||||||
|
setup_t setup;
|
||||||
|
GMainLoop *main_loop;
|
||||||
|
-int is_tree = 1;
|
||||||
|
static int default_bufsz = 8192;
|
||||||
|
|
||||||
|
struct msghdr * create_credentials_msg()
|
||||||
|
@@ -359,7 +364,7 @@ gboolean rescan_tree(gpointer data __attribute__((unused)))
|
||||||
|
parse_setup(setup_data);
|
||||||
|
char *irqbalance_data = get_data(STATS);
|
||||||
|
parse_into_tree(irqbalance_data);
|
||||||
|
- if(is_tree) {
|
||||||
|
+ if(state == STATE_TREE) {
|
||||||
|
display_tree();
|
||||||
|
}
|
||||||
|
free(setup_data);
|
||||||
|
@@ -375,16 +380,35 @@ gboolean key_loop(gpointer data __attribute__((unused)))
|
||||||
|
close_window(0);
|
||||||
|
break;
|
||||||
|
case KEY_F(3):
|
||||||
|
- is_tree = 1;
|
||||||
|
- display_tree();
|
||||||
|
+ if (state == STATE_SETTINGS || state == STATE_SETUP_IRQS) {
|
||||||
|
+ state = STATE_TREE;
|
||||||
|
+ display_tree();
|
||||||
|
+ }
|
||||||
|
break;
|
||||||
|
case KEY_F(4):
|
||||||
|
- is_tree = 0;
|
||||||
|
+ if (state == STATE_TREE || state == STATE_SETUP_IRQS) {
|
||||||
|
+ state = STATE_SETTINGS;
|
||||||
|
+ settings();
|
||||||
|
+ }
|
||||||
|
settings();
|
||||||
|
break;
|
||||||
|
case KEY_F(5):
|
||||||
|
- is_tree = 0;
|
||||||
|
- setup_irqs();
|
||||||
|
+ if (state == STATE_TREE || state == STATE_SETTINGS) {
|
||||||
|
+ state = STATE_SETUP_IRQS;
|
||||||
|
+ setup_irqs();
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ case 'c':
|
||||||
|
+ if (state == STATE_SETTINGS)
|
||||||
|
+ handle_cpu_banning();
|
||||||
|
+ break;
|
||||||
|
+ case 'i':
|
||||||
|
+ if (state == STATE_SETUP_IRQS)
|
||||||
|
+ handle_irq_banning();
|
||||||
|
+ break;
|
||||||
|
+ case 's':
|
||||||
|
+ if (state == STATE_SETTINGS)
|
||||||
|
+ handle_sleep_setting();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
@@ -437,6 +461,7 @@ int main(int argc, char **argv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ state = STATE_TREE;
|
||||||
|
init();
|
||||||
|
|
||||||
|
main_loop = g_main_loop_new(NULL, FALSE);
|
||||||
|
diff --git a/ui/ui.c b/ui/ui.c
|
||||||
|
index beafe3a..1e211de 100644
|
||||||
|
--- a/ui/ui.c
|
||||||
|
+++ b/ui/ui.c
|
||||||
|
@@ -273,7 +273,8 @@ void handle_cpu_banning()
|
||||||
|
attrset(COLOR_PAIR(5));
|
||||||
|
mvprintw(LINES - 2, 1,
|
||||||
|
"Press <S> for changing sleep setup, <C> for CPU ban setup. ");
|
||||||
|
- move(LINES - 1, COLS - 1);
|
||||||
|
+ show_frame();
|
||||||
|
+ show_footer();
|
||||||
|
refresh();
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
@@ -287,8 +288,8 @@ void handle_cpu_banning()
|
||||||
|
attrset(COLOR_PAIR(5));
|
||||||
|
mvprintw(LINES - 2, 1,
|
||||||
|
"Press <S> for changing sleep setup, <C> for CPU ban setup. ");
|
||||||
|
- attrset(COLOR_PAIR(3));
|
||||||
|
- move(LINES - 1, COLS - 1);
|
||||||
|
+ show_frame();
|
||||||
|
+ show_footer();
|
||||||
|
refresh();
|
||||||
|
char settings_string[1024] = "settings cpus \0";
|
||||||
|
for_each_cpu(all_cpus, get_new_cpu_ban_values, settings_string);
|
||||||
|
@@ -302,16 +303,6 @@ void handle_cpu_banning()
|
||||||
|
processing = 0;
|
||||||
|
close_window(0);
|
||||||
|
break;
|
||||||
|
- case KEY_F(3):
|
||||||
|
- is_tree = 1;
|
||||||
|
- processing = 0;
|
||||||
|
- display_tree();
|
||||||
|
- break;
|
||||||
|
- case KEY_F(5):
|
||||||
|
- is_tree = 0;
|
||||||
|
- processing = 0;
|
||||||
|
- setup_irqs();
|
||||||
|
- break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
@@ -475,7 +466,8 @@ void handle_irq_banning()
|
||||||
|
attrset(COLOR_PAIR(5));
|
||||||
|
mvprintw(LINES - 2, 1, "Press <I> for setting up IRQ banning.\
|
||||||
|
");
|
||||||
|
- move(LINES - 1, COLS - 1);
|
||||||
|
+ show_frame();
|
||||||
|
+ show_footer();
|
||||||
|
refresh();
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
@@ -490,7 +482,8 @@ void handle_irq_banning()
|
||||||
|
mvprintw(LINES - 2, 1, "Press <I> for setting up IRQ banning.\
|
||||||
|
");
|
||||||
|
attrset(COLOR_PAIR(3));
|
||||||
|
- move(LINES - 1, COLS - 1);
|
||||||
|
+ show_frame();
|
||||||
|
+ show_footer();
|
||||||
|
refresh();
|
||||||
|
char settings_string[1024] = BAN_IRQS;
|
||||||
|
for_each_irq(all_irqs, get_new_irq_ban_values, settings_string);
|
||||||
|
@@ -504,22 +497,35 @@ void handle_irq_banning()
|
||||||
|
processing = 0;
|
||||||
|
close_window(0);
|
||||||
|
break;
|
||||||
|
- case KEY_F(3):
|
||||||
|
- is_tree = 1;
|
||||||
|
- processing = 0;
|
||||||
|
- display_tree();
|
||||||
|
- break;
|
||||||
|
- case KEY_F(4):
|
||||||
|
- is_tree = 0;
|
||||||
|
- processing = 0;
|
||||||
|
- settings();
|
||||||
|
- break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+void handle_sleep_setting()
|
||||||
|
+{
|
||||||
|
+ char info[128] = "Current sleep interval between rebalancing: \0";
|
||||||
|
+ uint8_t sleep_input_offset = strlen(info) + 3;
|
||||||
|
+ mvprintw(LINES - 1, 1, "Press ESC for discarding your input.\
|
||||||
|
+ ");
|
||||||
|
+ attrset(COLOR_PAIR(0));
|
||||||
|
+ mvprintw(LINES - 2, 1, " \
|
||||||
|
+ ");
|
||||||
|
+ uint64_t new_sleep = get_valid_sleep_input(sleep_input_offset);
|
||||||
|
+ if(new_sleep != setup.sleep) {
|
||||||
|
+ setup.sleep = new_sleep;
|
||||||
|
+ char settings_data[128];
|
||||||
|
+ snprintf(settings_data, 128, "%s %" PRIu64, SET_SLEEP, new_sleep);
|
||||||
|
+ send_settings(settings_data);
|
||||||
|
+ }
|
||||||
|
+ attrset(COLOR_PAIR(5));
|
||||||
|
+ mvprintw(LINES - 2, 1, "Press <S> for changing sleep setup, <C> for CPU ban setup. ");
|
||||||
|
+ show_frame();
|
||||||
|
+ show_footer();
|
||||||
|
+ refresh();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void init()
|
||||||
|
{
|
||||||
|
signal(SIGINT, close_window);
|
||||||
|
@@ -563,60 +569,15 @@ void settings()
|
||||||
|
parse_setup(setup_data);
|
||||||
|
|
||||||
|
char info[128] = "Current sleep interval between rebalancing: \0";
|
||||||
|
- uint8_t sleep_input_offset = strlen(info) + 3;
|
||||||
|
snprintf(info + strlen(info), 128 - strlen(info), "%" PRIu64 "\n", setup.sleep);
|
||||||
|
attrset(COLOR_PAIR(1));
|
||||||
|
mvprintw(2, 3, "%s", info);
|
||||||
|
print_all_cpus();
|
||||||
|
-
|
||||||
|
- int user_input = 1;
|
||||||
|
- while(user_input) {
|
||||||
|
- attrset(COLOR_PAIR(5));
|
||||||
|
- mvprintw(LINES - 2, 1,
|
||||||
|
- "Press <S> for changing sleep setup, <C> for CPU ban setup. ");
|
||||||
|
- show_frame();
|
||||||
|
- show_footer();
|
||||||
|
- refresh();
|
||||||
|
- int c = getch();
|
||||||
|
- switch(c) {
|
||||||
|
- case 's': {
|
||||||
|
- mvprintw(LINES - 1, 1, "Press ESC for discarding your input.\
|
||||||
|
- ");
|
||||||
|
- attrset(COLOR_PAIR(0));
|
||||||
|
- mvprintw(LINES - 2, 1, " \
|
||||||
|
- ");
|
||||||
|
- uint64_t new_sleep = get_valid_sleep_input(sleep_input_offset);
|
||||||
|
- if(new_sleep != setup.sleep) {
|
||||||
|
- setup.sleep = new_sleep;
|
||||||
|
- char settings_data[128];
|
||||||
|
- snprintf(settings_data, 128, "%s %" PRIu64, SET_SLEEP, new_sleep);
|
||||||
|
- send_settings(settings_data);
|
||||||
|
- }
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
- case 'c':
|
||||||
|
- handle_cpu_banning();
|
||||||
|
- break;
|
||||||
|
- /* We need to include window changing options as well because the
|
||||||
|
- * related char was eaten up by getch() already */
|
||||||
|
- case 'q':
|
||||||
|
- user_input = 0;
|
||||||
|
- close_window(0);
|
||||||
|
- break;
|
||||||
|
- case KEY_F(3):
|
||||||
|
- is_tree = 1;
|
||||||
|
- user_input = 0;
|
||||||
|
- display_tree();
|
||||||
|
- break;
|
||||||
|
- case KEY_F(5):
|
||||||
|
- is_tree = 0;
|
||||||
|
- user_input = 0;
|
||||||
|
- setup_irqs();
|
||||||
|
- break;
|
||||||
|
- default:
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ attrset(COLOR_PAIR(5));
|
||||||
|
+ mvprintw(LINES - 2, 1, "Press <S> for changing sleep setup, <C> for CPU ban setup. ");
|
||||||
|
+ show_frame();
|
||||||
|
+ show_footer();
|
||||||
|
+ refresh();
|
||||||
|
free(setup_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -631,32 +592,6 @@ void setup_irqs()
|
||||||
|
show_frame();
|
||||||
|
show_footer();
|
||||||
|
refresh();
|
||||||
|
-
|
||||||
|
- int user_input = 1;
|
||||||
|
- while(user_input) {
|
||||||
|
- int c = getch();
|
||||||
|
- switch(c) {
|
||||||
|
- case 'i':
|
||||||
|
- handle_irq_banning();
|
||||||
|
- break;
|
||||||
|
- case 'q':
|
||||||
|
- user_input = 0;
|
||||||
|
- close_window(0);
|
||||||
|
- break;
|
||||||
|
- case KEY_F(3):
|
||||||
|
- is_tree = 1;
|
||||||
|
- user_input = 0;
|
||||||
|
- display_tree();
|
||||||
|
- break;
|
||||||
|
- case KEY_F(4):
|
||||||
|
- is_tree = 0;
|
||||||
|
- user_input = 0;
|
||||||
|
- settings();
|
||||||
|
- break;
|
||||||
|
- default:
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
}
|
||||||
|
|
||||||
|
void display_tree_node_irqs(irq_t *irq, void *data)
|
||||||
|
diff --git a/ui/ui.h b/ui/ui.h
|
||||||
|
index 0aa8280..ca2a3a6 100644
|
||||||
|
--- a/ui/ui.h
|
||||||
|
+++ b/ui/ui.h
|
||||||
|
@@ -13,7 +13,6 @@
|
||||||
|
|
||||||
|
extern GList *tree;
|
||||||
|
extern setup_t setup;
|
||||||
|
-extern int is_tree;
|
||||||
|
|
||||||
|
void show_frame();
|
||||||
|
void show_footer();
|
||||||
|
@@ -29,6 +28,7 @@ void display_banned_cpus();
|
||||||
|
int toggle_cpu(GList *cpu_list, int cpu_number);
|
||||||
|
void get_new_cpu_ban_values(cpu_ban_t *cpu, void *data);
|
||||||
|
void get_cpu();
|
||||||
|
+void handle_sleep_setting();
|
||||||
|
void handle_cpu_banning();
|
||||||
|
|
||||||
|
void copy_assigned_obj(int *number, void *data);
|
||||||
|
--
|
||||||
|
2.33.1
|
||||||
|
|
47
SOURCES/0011-fix-memory-leak-in-ui-ui.c.patch
Normal file
47
SOURCES/0011-fix-memory-leak-in-ui-ui.c.patch
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
From a61b382805961934c6425f19a762a6ab99884c24 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Liu Chao <liuchao173@huawei.com>
|
||||||
|
Date: Thu, 30 Jun 2022 11:30:43 +0800
|
||||||
|
Subject: [PATCH 11/14] fix memory leak in ui/ui.c
|
||||||
|
|
||||||
|
Signed-off-by: Liu Chao <liuchao173@huawei.com>
|
||||||
|
---
|
||||||
|
ui/ui.c | 10 ++++------
|
||||||
|
1 file changed, 4 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ui/ui.c b/ui/ui.c
|
||||||
|
index 1e211de..6b1c689 100644
|
||||||
|
--- a/ui/ui.c
|
||||||
|
+++ b/ui/ui.c
|
||||||
|
@@ -156,11 +156,10 @@ void print_all_cpus()
|
||||||
|
for_each_int(setup.banned_cpus, get_banned_cpu, NULL);
|
||||||
|
all_cpus = g_list_sort(all_cpus, sort_all_cpus);
|
||||||
|
}
|
||||||
|
- int *line = malloc(sizeof(int));
|
||||||
|
- *line = 6;
|
||||||
|
+ int line = 6;
|
||||||
|
attrset(COLOR_PAIR(2));
|
||||||
|
mvprintw(4, 3, "NUMBER IS BANNED");
|
||||||
|
- for_each_cpu(all_cpus, print_cpu_line, line);
|
||||||
|
+ for_each_cpu(all_cpus, print_cpu_line, &line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_banned_cpu(int *banned_cpu, void *data)
|
||||||
|
@@ -364,13 +363,12 @@ void print_irq_line(irq_t *irq, void *data)
|
||||||
|
|
||||||
|
void print_all_irqs()
|
||||||
|
{
|
||||||
|
- int *line = malloc(sizeof(int));
|
||||||
|
- *line = 4;
|
||||||
|
+ int line = 4;
|
||||||
|
attrset(COLOR_PAIR(0));
|
||||||
|
mvprintw(2, 3,
|
||||||
|
"NUMBER IS BANNED CLASS \
|
||||||
|
ASSIGNED TO CPUS");
|
||||||
|
- for_each_irq(all_irqs, print_irq_line, line);
|
||||||
|
+ for_each_irq(all_irqs, print_irq_line, &line);
|
||||||
|
}
|
||||||
|
|
||||||
|
int toggle_irq(GList *irq_list, int position)
|
||||||
|
--
|
||||||
|
2.33.1
|
||||||
|
|
@ -0,0 +1,583 @@
|
|||||||
|
From db7dc03388a20ba2d873a81c3e14b933e2b09551 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Liu Chao <liuchao173@huawei.com>
|
||||||
|
Date: Mon, 4 Jul 2022 16:25:14 +0800
|
||||||
|
Subject: [PATCH 12/14] irqbalance-ui: support scroll under tui mode of
|
||||||
|
irqbalance-ui
|
||||||
|
|
||||||
|
support using Up, Down, PageUp, PageDown to scroll in view mode
|
||||||
|
support using Up and Down in edit mode
|
||||||
|
|
||||||
|
Signed-off-by: Liu Chao <liuchao173@huawei.com>
|
||||||
|
---
|
||||||
|
ui/helpers.c | 2 +
|
||||||
|
ui/irqbalance-ui.c | 138 ++++++++++++++++++++++++---------
|
||||||
|
ui/irqbalance-ui.h | 2 +
|
||||||
|
ui/ui.c | 187 ++++++++++++++++++++++++++++++++++++---------
|
||||||
|
ui/ui.h | 3 +
|
||||||
|
5 files changed, 262 insertions(+), 70 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ui/helpers.c b/ui/helpers.c
|
||||||
|
index 5d71275..0e9f76c 100644
|
||||||
|
--- a/ui/helpers.c
|
||||||
|
+++ b/ui/helpers.c
|
||||||
|
@@ -89,6 +89,7 @@ gpointer copy_cpu_ban(gconstpointer src, gpointer data __attribute__((unused)))
|
||||||
|
cpu_ban_t *new = malloc(sizeof(cpu_ban_t));
|
||||||
|
new->number = old->number;
|
||||||
|
new->is_banned = old->is_banned;
|
||||||
|
+ new->is_changed = 0;
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -100,6 +101,7 @@ gpointer copy_irq(gconstpointer src, gpointer data __attribute__((unused)))
|
||||||
|
new->load = old->load;
|
||||||
|
new->diff = old->diff;
|
||||||
|
new->is_banned = old->is_banned;
|
||||||
|
+ new->is_changed = 0;
|
||||||
|
new->class = old->class;
|
||||||
|
new->assigned_to = g_list_copy(old->assigned_to);
|
||||||
|
return new;
|
||||||
|
diff --git a/ui/irqbalance-ui.c b/ui/irqbalance-ui.c
|
||||||
|
index 89ed94a..47b6c88 100644
|
||||||
|
--- a/ui/irqbalance-ui.c
|
||||||
|
+++ b/ui/irqbalance-ui.c
|
||||||
|
@@ -371,48 +371,116 @@ gboolean rescan_tree(gpointer data __attribute__((unused)))
|
||||||
|
free(irqbalance_data);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
-gboolean key_loop(gpointer data __attribute__((unused)))
|
||||||
|
-{
|
||||||
|
- int c = getch();
|
||||||
|
- switch(c) {
|
||||||
|
- case 'q':
|
||||||
|
- close_window(0);
|
||||||
|
- break;
|
||||||
|
- case KEY_F(3):
|
||||||
|
- if (state == STATE_SETTINGS || state == STATE_SETUP_IRQS) {
|
||||||
|
- state = STATE_TREE;
|
||||||
|
- display_tree();
|
||||||
|
- }
|
||||||
|
+void scroll_window() {
|
||||||
|
+ switch(state) {
|
||||||
|
+ case STATE_TREE:
|
||||||
|
+ display_tree();
|
||||||
|
break;
|
||||||
|
- case KEY_F(4):
|
||||||
|
- if (state == STATE_TREE || state == STATE_SETUP_IRQS) {
|
||||||
|
- state = STATE_SETTINGS;
|
||||||
|
- settings();
|
||||||
|
- }
|
||||||
|
+ case STATE_SETTINGS:
|
||||||
|
settings();
|
||||||
|
break;
|
||||||
|
- case KEY_F(5):
|
||||||
|
- if (state == STATE_TREE || state == STATE_SETTINGS) {
|
||||||
|
- state = STATE_SETUP_IRQS;
|
||||||
|
- setup_irqs();
|
||||||
|
- }
|
||||||
|
- break;
|
||||||
|
- case 'c':
|
||||||
|
- if (state == STATE_SETTINGS)
|
||||||
|
- handle_cpu_banning();
|
||||||
|
- break;
|
||||||
|
- case 'i':
|
||||||
|
- if (state == STATE_SETUP_IRQS)
|
||||||
|
- handle_irq_banning();
|
||||||
|
- break;
|
||||||
|
- case 's':
|
||||||
|
- if (state == STATE_SETTINGS)
|
||||||
|
- handle_sleep_setting();
|
||||||
|
+ case STATE_SETUP_IRQS:
|
||||||
|
+ setup_irqs();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+gboolean key_loop(gpointer data __attribute__((unused)))
|
||||||
|
+{
|
||||||
|
+ while(1) {
|
||||||
|
+ int c = getch();
|
||||||
|
+ switch(c) {
|
||||||
|
+ case 'q':
|
||||||
|
+ close_window(0);
|
||||||
|
+ break;
|
||||||
|
+ case KEY_UP:
|
||||||
|
+ if (offset > 0) {
|
||||||
|
+ offset--;
|
||||||
|
+ scroll_window();
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ case KEY_DOWN:
|
||||||
|
+ if (offset < max_offset) {
|
||||||
|
+ offset++;
|
||||||
|
+ scroll_window();
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ case KEY_NPAGE:
|
||||||
|
+ switch (state) {
|
||||||
|
+ case STATE_TREE:
|
||||||
|
+ offset += LINES - 5;
|
||||||
|
+ break;
|
||||||
|
+ case STATE_SETTINGS:
|
||||||
|
+ offset += LINES - 8;
|
||||||
|
+ break;
|
||||||
|
+ case STATE_SETUP_IRQS:
|
||||||
|
+ offset += LINES - 6;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ if (offset > max_offset)
|
||||||
|
+ offset = max_offset;
|
||||||
|
+ scroll_window();
|
||||||
|
+ break;
|
||||||
|
+ case KEY_PPAGE:
|
||||||
|
+ switch (state) {
|
||||||
|
+ case STATE_TREE:
|
||||||
|
+ offset -= LINES - 5;
|
||||||
|
+ break;
|
||||||
|
+ case STATE_SETTINGS:
|
||||||
|
+ offset -= LINES - 8;
|
||||||
|
+ break;
|
||||||
|
+ case STATE_SETUP_IRQS:
|
||||||
|
+ offset -= LINES - 6;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ if (offset < 0)
|
||||||
|
+ offset = 0;
|
||||||
|
+ scroll_window();
|
||||||
|
+ break;
|
||||||
|
+ case KEY_F(3):
|
||||||
|
+ if (state == STATE_SETTINGS || state == STATE_SETUP_IRQS) {
|
||||||
|
+ state = STATE_TREE;
|
||||||
|
+ offset = 0;
|
||||||
|
+ display_tree();
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ case KEY_F(4):
|
||||||
|
+ if (state == STATE_TREE || state == STATE_SETUP_IRQS) {
|
||||||
|
+ state = STATE_SETTINGS;
|
||||||
|
+ offset = 0;
|
||||||
|
+ settings();
|
||||||
|
+ }
|
||||||
|
+ settings();
|
||||||
|
+ break;
|
||||||
|
+ case KEY_F(5):
|
||||||
|
+ if (state == STATE_TREE || state == STATE_SETTINGS) {
|
||||||
|
+ state = STATE_SETUP_IRQS;
|
||||||
|
+ offset = 0;
|
||||||
|
+ setup_irqs();
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ case 'c':
|
||||||
|
+ if (state == STATE_SETTINGS)
|
||||||
|
+ handle_cpu_banning();
|
||||||
|
+ break;
|
||||||
|
+ case 'i':
|
||||||
|
+ if (state == STATE_SETUP_IRQS)
|
||||||
|
+ handle_irq_banning();
|
||||||
|
+ break;
|
||||||
|
+ case 's':
|
||||||
|
+ if (state == STATE_SETTINGS)
|
||||||
|
+ handle_sleep_setting();
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/ui/irqbalance-ui.h b/ui/irqbalance-ui.h
|
||||||
|
index fba7e7c..dc24083 100644
|
||||||
|
--- a/ui/irqbalance-ui.h
|
||||||
|
+++ b/ui/irqbalance-ui.h
|
||||||
|
@@ -41,6 +41,7 @@ typedef struct irq {
|
||||||
|
uint64_t load;
|
||||||
|
uint64_t diff;
|
||||||
|
char is_banned;
|
||||||
|
+ char is_changed;
|
||||||
|
GList *assigned_to;
|
||||||
|
int class;
|
||||||
|
} irq_t;
|
||||||
|
@@ -60,6 +61,7 @@ typedef struct cpu_node {
|
||||||
|
typedef struct cpu_ban {
|
||||||
|
int number;
|
||||||
|
char is_banned;
|
||||||
|
+ char is_changed;
|
||||||
|
} cpu_ban_t;
|
||||||
|
|
||||||
|
typedef struct setup {
|
||||||
|
diff --git a/ui/ui.c b/ui/ui.c
|
||||||
|
index 6b1c689..2dad442 100644
|
||||||
|
--- a/ui/ui.c
|
||||||
|
+++ b/ui/ui.c
|
||||||
|
@@ -3,6 +3,8 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include "ui.h"
|
||||||
|
|
||||||
|
+int offset;
|
||||||
|
+int max_offset;
|
||||||
|
|
||||||
|
GList *all_cpus = NULL;
|
||||||
|
GList *all_irqs = NULL;
|
||||||
|
@@ -134,32 +136,54 @@ void get_banned_cpu(int *cpu, void *data __attribute__((unused)))
|
||||||
|
all_cpus = g_list_append(all_cpus, new);
|
||||||
|
}
|
||||||
|
|
||||||
|
-void print_cpu_line(cpu_ban_t *cpu, void *data)
|
||||||
|
+void print_tmp_cpu_line(cpu_ban_t *cpu, void *data __attribute__((unused)))
|
||||||
|
{
|
||||||
|
- int *line_offset = data;
|
||||||
|
- if(cpu->is_banned) {
|
||||||
|
- attrset(COLOR_PAIR(10));
|
||||||
|
- } else {
|
||||||
|
- attrset(COLOR_PAIR(9));
|
||||||
|
+ int line = max_offset - offset + 6;
|
||||||
|
+ if (max_offset >= offset && line < LINES - 3) {
|
||||||
|
+ if (cpu->is_changed)
|
||||||
|
+ attrset(COLOR_PAIR(3));
|
||||||
|
+ else if(cpu->is_banned)
|
||||||
|
+ attrset(COLOR_PAIR(10));
|
||||||
|
+ else
|
||||||
|
+ attrset(COLOR_PAIR(9));
|
||||||
|
+ mvprintw(line, 3, "CPU %d ", cpu->number);
|
||||||
|
+ mvprintw(line, 19, "%s", cpu->is_banned ?
|
||||||
|
+ "YES " :
|
||||||
|
+ "NO ");
|
||||||
|
}
|
||||||
|
- mvprintw(*line_offset, 3, "CPU %d", cpu->number);
|
||||||
|
- mvprintw(*line_offset, 19, "%s", cpu->is_banned ?
|
||||||
|
- "YES " :
|
||||||
|
- "NO ");
|
||||||
|
- (*line_offset)++;
|
||||||
|
+ max_offset++;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void print_cpu_line(cpu_ban_t *cpu, void *data __attribute__((unused)))
|
||||||
|
+{
|
||||||
|
+ int line = max_offset - offset + 6;
|
||||||
|
+ if (max_offset >= offset && line < LINES - 2) {
|
||||||
|
+ if(cpu->is_banned)
|
||||||
|
+ attrset(COLOR_PAIR(10));
|
||||||
|
+ else
|
||||||
|
+ attrset(COLOR_PAIR(9));
|
||||||
|
+ mvprintw(line, 3, "CPU %d ", cpu->number);
|
||||||
|
+ mvprintw(line, 19, "%s", cpu->is_banned ?
|
||||||
|
+ "YES " :
|
||||||
|
+ "NO ");
|
||||||
|
+ }
|
||||||
|
+ max_offset++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_all_cpus()
|
||||||
|
{
|
||||||
|
+ max_offset = 0;
|
||||||
|
if(all_cpus == NULL) {
|
||||||
|
for_each_node(tree, get_cpu, NULL);
|
||||||
|
for_each_int(setup.banned_cpus, get_banned_cpu, NULL);
|
||||||
|
all_cpus = g_list_sort(all_cpus, sort_all_cpus);
|
||||||
|
}
|
||||||
|
- int line = 6;
|
||||||
|
attrset(COLOR_PAIR(2));
|
||||||
|
mvprintw(4, 3, "NUMBER IS BANNED");
|
||||||
|
- for_each_cpu(all_cpus, print_cpu_line, &line);
|
||||||
|
+ for_each_cpu(all_cpus, print_cpu_line, NULL);
|
||||||
|
+ max_offset -= LINES - 8;
|
||||||
|
+ if (max_offset < 0)
|
||||||
|
+ max_offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_banned_cpu(int *banned_cpu, void *data)
|
||||||
|
@@ -195,6 +219,7 @@ int toggle_cpu(GList *cpu_list, int cpu_number)
|
||||||
|
} else {
|
||||||
|
((cpu_ban_t *)(entry->data))->is_banned = 1;
|
||||||
|
}
|
||||||
|
+ ((cpu_ban_t *)(entry->data))->is_changed = 1;
|
||||||
|
return ((cpu_ban_t *)(entry->data))->is_banned;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -239,18 +264,37 @@ void handle_cpu_banning()
|
||||||
|
if(position > 6) {
|
||||||
|
position--;
|
||||||
|
move(position, 19);
|
||||||
|
+ } else if (offset > 0) {
|
||||||
|
+ offset--;
|
||||||
|
+ max_offset = 0;
|
||||||
|
+ for_each_cpu(tmp, print_tmp_cpu_line, NULL);
|
||||||
|
+ max_offset -= LINES - 9;
|
||||||
|
+ if (max_offset < 0)
|
||||||
|
+ max_offset = 0;
|
||||||
|
+ move(position, 19);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEY_DOWN:
|
||||||
|
- if(position <= g_list_length(all_cpus) + 4) {
|
||||||
|
- position++;
|
||||||
|
+ if(position < (size_t)(LINES - 4)) {
|
||||||
|
+ if (position <= g_list_length(all_cpus) + 4 - offset) {
|
||||||
|
+ position++;
|
||||||
|
+ move(position, 19);
|
||||||
|
+ }
|
||||||
|
+ } else if (offset < max_offset) {
|
||||||
|
+ offset++;
|
||||||
|
+ max_offset = 0;
|
||||||
|
+ for_each_cpu(tmp, print_tmp_cpu_line, NULL);
|
||||||
|
+ max_offset -= LINES - 9;
|
||||||
|
+ if (max_offset < 0)
|
||||||
|
+ max_offset = 0;
|
||||||
|
move(position, 19);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
case '\r': {
|
||||||
|
attrset(COLOR_PAIR(3));
|
||||||
|
- int banned = toggle_cpu(tmp, position - 6);
|
||||||
|
+ int banned = toggle_cpu(tmp, position + offset - 6);
|
||||||
|
+ mvprintw(position, 3, "CPU %d ", position + offset - 6);
|
||||||
|
if(banned) {
|
||||||
|
mvprintw(position, 19, "YES");
|
||||||
|
} else {
|
||||||
|
@@ -263,8 +307,7 @@ void handle_cpu_banning()
|
||||||
|
case 27:
|
||||||
|
processing = 0;
|
||||||
|
curs_set(0);
|
||||||
|
- /* Forget the changes */
|
||||||
|
- tmp = g_list_copy_deep(all_cpus, copy_cpu_ban, NULL);
|
||||||
|
+ g_list_free(tmp);
|
||||||
|
print_all_cpus();
|
||||||
|
attrset(COLOR_PAIR(0));
|
||||||
|
mvprintw(LINES - 3, 1, " \
|
||||||
|
@@ -278,6 +321,7 @@ void handle_cpu_banning()
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
processing = 0;
|
||||||
|
+ g_list_free(all_cpus);
|
||||||
|
all_cpus = tmp;
|
||||||
|
curs_set(0);
|
||||||
|
print_all_cpus();
|
||||||
|
@@ -324,9 +368,12 @@ void print_assigned_objects_string(irq_t *irq, int *line_offset)
|
||||||
|
mvprintw(*line_offset, 68, "%s", assigned_to);
|
||||||
|
}
|
||||||
|
|
||||||
|
-void print_irq_line(irq_t *irq, void *data)
|
||||||
|
+void print_tmp_irq_line(irq_t *irq, void *data __attribute__((unused)))
|
||||||
|
{
|
||||||
|
- int *line_offset = data;
|
||||||
|
+ int line = max_offset - offset + 4;
|
||||||
|
+ max_offset++;
|
||||||
|
+ if (line < 4 || line >= LINES - 3)
|
||||||
|
+ return;
|
||||||
|
switch(irq->class) {
|
||||||
|
case(IRQ_OTHER):
|
||||||
|
attrset(COLOR_PAIR(1));
|
||||||
|
@@ -352,23 +399,62 @@ void print_irq_line(irq_t *irq, void *data)
|
||||||
|
attrset(COLOR_PAIR(0));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- mvprintw(*line_offset, 3, "IRQ %d", irq->vector);
|
||||||
|
- mvprintw(*line_offset, 19, "%s", irq->is_banned ? "YES" : "NO ");
|
||||||
|
- mvprintw(*line_offset, 36, "%s",
|
||||||
|
+ mvprintw(line, 3, "IRQ %d ", irq->vector);
|
||||||
|
+ mvprintw(line, 19, "%s", irq->is_banned ? "YES" : "NO ");
|
||||||
|
+ mvprintw(line, 36, "%s ",
|
||||||
|
irq->class < 0 ? "Unknown" : IRQ_CLASS_TO_STR[irq->class]);
|
||||||
|
- print_assigned_objects_string(irq, line_offset);
|
||||||
|
- (*line_offset)++;
|
||||||
|
+ print_assigned_objects_string(irq, &line);
|
||||||
|
+}
|
||||||
|
|
||||||
|
+void print_irq_line(irq_t *irq, void *data __attribute__((unused)))
|
||||||
|
+{
|
||||||
|
+ int line = max_offset - offset + 4;
|
||||||
|
+ max_offset++;
|
||||||
|
+ if (line < 4 || line >= LINES - 2)
|
||||||
|
+ return;
|
||||||
|
+ switch(irq->class) {
|
||||||
|
+ case(IRQ_OTHER):
|
||||||
|
+ attrset(COLOR_PAIR(1));
|
||||||
|
+ break;
|
||||||
|
+ case(IRQ_LEGACY):
|
||||||
|
+ attrset(COLOR_PAIR(2));
|
||||||
|
+ break;
|
||||||
|
+ case(IRQ_SCSI):
|
||||||
|
+ attrset(COLOR_PAIR(3));
|
||||||
|
+ break;
|
||||||
|
+ case(IRQ_VIDEO):
|
||||||
|
+ attrset(COLOR_PAIR(8));
|
||||||
|
+ break;
|
||||||
|
+ case(IRQ_ETH):
|
||||||
|
+ case(IRQ_GBETH):
|
||||||
|
+ case(IRQ_10GBETH):
|
||||||
|
+ attrset(COLOR_PAIR(9));
|
||||||
|
+ break;
|
||||||
|
+ case(IRQ_VIRT_EVENT):
|
||||||
|
+ attrset(COLOR_PAIR(10));
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ attrset(COLOR_PAIR(0));
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ mvprintw(line, 3, "IRQ %d", irq->vector);
|
||||||
|
+ mvprintw(line, 19, "%s", irq->is_banned ? "YES" : "NO ");
|
||||||
|
+ mvprintw(line, 36, "%s ",
|
||||||
|
+ irq->class < 0 ? "Unknown" : IRQ_CLASS_TO_STR[irq->class]);
|
||||||
|
+ print_assigned_objects_string(irq, &line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_all_irqs()
|
||||||
|
{
|
||||||
|
- int line = 4;
|
||||||
|
+ max_offset = 0;
|
||||||
|
attrset(COLOR_PAIR(0));
|
||||||
|
mvprintw(2, 3,
|
||||||
|
"NUMBER IS BANNED CLASS \
|
||||||
|
ASSIGNED TO CPUS");
|
||||||
|
- for_each_irq(all_irqs, print_irq_line, &line);
|
||||||
|
+ for_each_irq(all_irqs, print_irq_line, NULL);
|
||||||
|
+ max_offset -= LINES - 6;
|
||||||
|
+ if (max_offset < 0)
|
||||||
|
+ max_offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int toggle_irq(GList *irq_list, int position)
|
||||||
|
@@ -384,6 +470,7 @@ int toggle_irq(GList *irq_list, int position)
|
||||||
|
} else {
|
||||||
|
((irq_t *)(entry->data))->is_banned = 1;
|
||||||
|
}
|
||||||
|
+ ((irq_t *)(entry->data))->is_changed = 1;
|
||||||
|
return ((irq_t *)(entry->data))->is_banned;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -431,18 +518,36 @@ void handle_irq_banning()
|
||||||
|
if(position > 4) {
|
||||||
|
position--;
|
||||||
|
move(position, 19);
|
||||||
|
+ } else if (offset > 0) {
|
||||||
|
+ offset--;
|
||||||
|
+ max_offset = 0;
|
||||||
|
+ for_each_irq(tmp, print_tmp_irq_line, NULL);
|
||||||
|
+ max_offset -= LINES - 7;
|
||||||
|
+ if (max_offset < 0)
|
||||||
|
+ max_offset = 0;
|
||||||
|
+ move(position, 19);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEY_DOWN:
|
||||||
|
- if(position < g_list_length(all_irqs) + 3) {
|
||||||
|
- position++;
|
||||||
|
+ if (position < (size_t)(LINES - 4)) {
|
||||||
|
+ if(position < g_list_length(all_irqs) + 3) {
|
||||||
|
+ position++;
|
||||||
|
+ move(position, 19);
|
||||||
|
+ }
|
||||||
|
+ } else if (offset < max_offset) {
|
||||||
|
+ offset++;
|
||||||
|
+ max_offset = 0;
|
||||||
|
+ for_each_irq(tmp, print_tmp_irq_line, NULL);
|
||||||
|
+ max_offset -= LINES - 7;
|
||||||
|
+ if (max_offset < 0)
|
||||||
|
+ max_offset = 0;
|
||||||
|
move(position, 19);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
case '\r': {
|
||||||
|
attrset(COLOR_PAIR(3));
|
||||||
|
- int banned = toggle_irq(tmp, position - 4);
|
||||||
|
+ int banned = toggle_irq(tmp, position + offset - 4);
|
||||||
|
if(banned) {
|
||||||
|
mvprintw(position, 19, "YES");
|
||||||
|
} else {
|
||||||
|
@@ -456,7 +561,7 @@ void handle_irq_banning()
|
||||||
|
processing = 0;
|
||||||
|
curs_set(0);
|
||||||
|
/* Forget the changes */
|
||||||
|
- tmp = g_list_copy_deep(all_irqs, copy_irq, NULL);
|
||||||
|
+ g_list_free(tmp);
|
||||||
|
print_all_irqs();
|
||||||
|
attrset(COLOR_PAIR(0));
|
||||||
|
mvprintw(LINES - 3, 1, " \
|
||||||
|
@@ -470,6 +575,7 @@ void handle_irq_banning()
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
processing = 0;
|
||||||
|
+ g_list_free(all_irqs);
|
||||||
|
all_irqs = tmp;
|
||||||
|
curs_set(0);
|
||||||
|
print_all_irqs();
|
||||||
|
@@ -548,11 +654,13 @@ void init()
|
||||||
|
init_pair(10, COLOR_MAGENTA, COLOR_BLACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ offset = 0;
|
||||||
|
display_tree();
|
||||||
|
}
|
||||||
|
|
||||||
|
void close_window(int sig __attribute__((unused)))
|
||||||
|
{
|
||||||
|
+ g_list_free(all_cpus);
|
||||||
|
g_list_free(setup.banned_irqs);
|
||||||
|
g_list_free(setup.banned_cpus);
|
||||||
|
g_list_free_full(tree, free);
|
||||||
|
@@ -595,10 +703,13 @@ void setup_irqs()
|
||||||
|
void display_tree_node_irqs(irq_t *irq, void *data)
|
||||||
|
{
|
||||||
|
char indent[32] = " \0";
|
||||||
|
- snprintf(indent + strlen(indent), 32 - strlen(indent), "%s", (char *)data);
|
||||||
|
- attrset(COLOR_PAIR(3));
|
||||||
|
- printw("%sIRQ %u, IRQs since last rebalance %lu\n",
|
||||||
|
+ if (max_offset >= offset && max_offset - offset < LINES - 5) {
|
||||||
|
+ snprintf(indent + strlen(indent), 32 - strlen(indent), "%s", (char *)data);
|
||||||
|
+ attrset(COLOR_PAIR(3));
|
||||||
|
+ printw("%sIRQ %u, IRQs since last rebalance %lu\n",
|
||||||
|
indent, irq->vector, irq->diff);
|
||||||
|
+ }
|
||||||
|
+ max_offset++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void display_tree_node(cpu_node_t *node, void *data)
|
||||||
|
@@ -644,7 +755,9 @@ void display_tree_node(cpu_node_t *node, void *data)
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- printw("%s", copy_to);
|
||||||
|
+ if (max_offset >= offset)
|
||||||
|
+ printw("%s", copy_to);
|
||||||
|
+ max_offset++;
|
||||||
|
if(g_list_length(node->irqs) > 0) {
|
||||||
|
for_each_irq(node->irqs, display_tree_node_irqs, indent);
|
||||||
|
}
|
||||||
|
@@ -661,7 +774,11 @@ void display_tree()
|
||||||
|
char *irqbalance_data = get_data(STATS);
|
||||||
|
parse_into_tree(irqbalance_data);
|
||||||
|
display_banned_cpus();
|
||||||
|
+ max_offset = 0;
|
||||||
|
for_each_node(tree, display_tree_node, NULL);
|
||||||
|
+ max_offset -= LINES - 5;
|
||||||
|
+ if (max_offset < 0)
|
||||||
|
+ max_offset = 0;
|
||||||
|
show_frame();
|
||||||
|
show_footer();
|
||||||
|
refresh();
|
||||||
|
diff --git a/ui/ui.h b/ui/ui.h
|
||||||
|
index ca2a3a6..da5b4b9 100644
|
||||||
|
--- a/ui/ui.h
|
||||||
|
+++ b/ui/ui.h
|
||||||
|
@@ -14,6 +14,9 @@
|
||||||
|
extern GList *tree;
|
||||||
|
extern setup_t setup;
|
||||||
|
|
||||||
|
+extern int offset;
|
||||||
|
+extern int max_offset;
|
||||||
|
+
|
||||||
|
void show_frame();
|
||||||
|
void show_footer();
|
||||||
|
|
||||||
|
--
|
||||||
|
2.33.1
|
||||||
|
|
66
SOURCES/0013-irqbalance-ui-print-cpulist-in-SETUP-IRQS.patch
Normal file
66
SOURCES/0013-irqbalance-ui-print-cpulist-in-SETUP-IRQS.patch
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
From 577796abe7337c8df446c082688816ec22804876 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Liu Chao <liuchao173@huawei.com>
|
||||||
|
Date: Mon, 11 Jul 2022 11:12:06 +0800
|
||||||
|
Subject: [PATCH 13/14] irqbalance-ui: print cpulist in SETUP IRQS
|
||||||
|
|
||||||
|
save space for printing interrupt names
|
||||||
|
|
||||||
|
Signed-off-by: Liu Chao <liuchao173@huawei.com>
|
||||||
|
---
|
||||||
|
ui/ui.c | 30 +++++++++++++++++++++++++++---
|
||||||
|
1 file changed, 27 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ui/ui.c b/ui/ui.c
|
||||||
|
index 2dad442..f1490d5 100644
|
||||||
|
--- a/ui/ui.c
|
||||||
|
+++ b/ui/ui.c
|
||||||
|
@@ -352,9 +352,32 @@ void handle_cpu_banning()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int rbot, rtop;
|
||||||
|
+
|
||||||
|
+static inline void bsnl_emit(char *buf, int buflen)
|
||||||
|
+{
|
||||||
|
+ int len = strlen(buf);
|
||||||
|
+ if (len > 0) {
|
||||||
|
+ snprintf(buf + len, buflen - len, ",");
|
||||||
|
+ len++;
|
||||||
|
+ }
|
||||||
|
+ if (rbot == rtop)
|
||||||
|
+ snprintf(buf + len, buflen - len, "%d", rbot);
|
||||||
|
+ else
|
||||||
|
+ snprintf(buf + len, buflen - len, "%d-%d", rbot, rtop);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void copy_assigned_obj(int *number, void *data)
|
||||||
|
{
|
||||||
|
- snprintf(data + strlen(data), 128 - strlen(data), "%d, ", *number);
|
||||||
|
+ if (rtop == -1) {
|
||||||
|
+ rbot = rtop = *number;
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ if (*number > rtop + 1) {
|
||||||
|
+ bsnl_emit(data, 128);
|
||||||
|
+ rbot = *number;
|
||||||
|
+ }
|
||||||
|
+ rtop = *number;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_assigned_objects_string(irq_t *irq, int *line_offset)
|
||||||
|
@@ -363,9 +386,10 @@ void print_assigned_objects_string(irq_t *irq, int *line_offset)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char assigned_to[128] = "\0";
|
||||||
|
+ rtop = -1;
|
||||||
|
for_each_int(irq->assigned_to, copy_assigned_obj, assigned_to);
|
||||||
|
- assigned_to[strlen(assigned_to) - 2] = '\0';
|
||||||
|
- mvprintw(*line_offset, 68, "%s", assigned_to);
|
||||||
|
+ bsnl_emit(assigned_to, 128);
|
||||||
|
+ mvprintw(*line_offset, 68, "%s ", assigned_to);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_tmp_irq_line(irq_t *irq, void *data __attribute__((unused)))
|
||||||
|
--
|
||||||
|
2.33.1
|
||||||
|
|
@ -0,0 +1,72 @@
|
|||||||
|
From cfb15f0bb95ebfd4357708eae42febe9f2121fba Mon Sep 17 00:00:00 2001
|
||||||
|
From: Tao Liu <ltao@redhat.com>
|
||||||
|
Date: Wed, 13 Jul 2022 17:11:40 +0800
|
||||||
|
Subject: [PATCH 14/14] Improve documentation and logging for banned cpus
|
||||||
|
|
||||||
|
This patch have no functional modification. Just improve the doc and log
|
||||||
|
for isolcpu, nohz_full and numa node banning cpus, for providing more
|
||||||
|
info for users.
|
||||||
|
|
||||||
|
Signed-off-by: Tao Liu <ltao@redhat.com>
|
||||||
|
---
|
||||||
|
cputree.c | 6 +++---
|
||||||
|
irqbalance.1 | 2 +-
|
||||||
|
placement.c | 6 +++++-
|
||||||
|
3 files changed, 9 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/cputree.c b/cputree.c
|
||||||
|
index c250977..eb1981e 100644
|
||||||
|
--- a/cputree.c
|
||||||
|
+++ b/cputree.c
|
||||||
|
@@ -159,14 +159,14 @@ static void setup_banned_cpus(void)
|
||||||
|
cpus_or(banned_cpus, nohz_full, isolated_cpus);
|
||||||
|
|
||||||
|
cpumask_scnprintf(buffer, 4096, isolated_cpus);
|
||||||
|
- log(TO_CONSOLE, LOG_INFO, "Isolated CPUs: %s\n", buffer);
|
||||||
|
+ log(TO_CONSOLE, LOG_INFO, "Prevent irq assignment to these isolated CPUs: %s\n", buffer);
|
||||||
|
cpumask_scnprintf(buffer, 4096, nohz_full);
|
||||||
|
- log(TO_CONSOLE, LOG_INFO, "Adaptive-ticks CPUs: %s\n", buffer);
|
||||||
|
+ log(TO_CONSOLE, LOG_INFO, "Prevent irq assignment to these adaptive-ticks CPUs: %s\n", buffer);
|
||||||
|
out:
|
||||||
|
#ifdef HAVE_THERMAL
|
||||||
|
cpus_or(banned_cpus, banned_cpus, thermal_banned_cpus);
|
||||||
|
cpumask_scnprintf(buffer, 4096, thermal_banned_cpus);
|
||||||
|
- log(TO_CONSOLE, LOG_INFO, "Thermal-banned CPUs: %s\n", buffer);
|
||||||
|
+ log(TO_CONSOLE, LOG_INFO, "Prevent irq assignment to these thermal-banned CPUs: %s\n", buffer);
|
||||||
|
#endif
|
||||||
|
cpumask_scnprintf(buffer, 4096, banned_cpus);
|
||||||
|
log(TO_CONSOLE, LOG_INFO, "Banned CPUs: %s\n", buffer);
|
||||||
|
diff --git a/irqbalance.1 b/irqbalance.1
|
||||||
|
index 361faea..4c75362 100644
|
||||||
|
--- a/irqbalance.1
|
||||||
|
+++ b/irqbalance.1
|
||||||
|
@@ -167,7 +167,7 @@ Same as --debug.
|
||||||
|
.B IRQBALANCE_BANNED_CPUS
|
||||||
|
Provides a mask of CPUs which irqbalance should ignore and never assign interrupts to.
|
||||||
|
If not specified, irqbalance use mask of isolated and adaptive-ticks CPUs on the
|
||||||
|
-system as the default value.
|
||||||
|
+system as the default value. The "isolcpus=" boot parameter specifies the isolated CPUs. The "nohz_full=" boot parameter specifies the adaptive-ticks CPUs. By default, no CPU will be an isolated or adaptive-ticks CPU.
|
||||||
|
This is a hexmask without the leading ’0x’. On systems with large numbers of
|
||||||
|
processors, each group of eight hex digits is separated by a comma ’,’. i.e.
|
||||||
|
‘export IRQBALANCE_BANNED_CPUS=fc0‘ would prevent irqbalance from assigning irqs
|
||||||
|
diff --git a/placement.c b/placement.c
|
||||||
|
index 17a9f2e..9fde8cb 100644
|
||||||
|
--- a/placement.c
|
||||||
|
+++ b/placement.c
|
||||||
|
@@ -135,8 +135,12 @@ static void place_irq_in_node(struct irq_info *info, void *data __attribute__((u
|
||||||
|
* Need to make sure this node is elligible for migration
|
||||||
|
* given the banned cpu list
|
||||||
|
*/
|
||||||
|
- if (!cpus_intersects(irq_numa_node(info)->mask, unbanned_cpus))
|
||||||
|
+ if (!cpus_intersects(irq_numa_node(info)->mask, unbanned_cpus)) {
|
||||||
|
+ log(TO_CONSOLE, LOG_WARNING, "There is no suitable CPU in node:%d.\n", irq_numa_node(info)->number);
|
||||||
|
+ log(TO_CONSOLE, LOG_WARNING, "Irqbalance dispatch irq:%d to other node.\n", info->irq);
|
||||||
|
goto find_placement;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* This irq belongs to a device with a preferred numa node
|
||||||
|
* put it on that node
|
||||||
|
--
|
||||||
|
2.33.1
|
||||||
|
|
@ -1,12 +0,0 @@
|
|||||||
diff -up ./misc/irqbalance.service.path ./misc/irqbalance.service
|
|
||||||
--- ./misc/irqbalance.service.path 2017-11-14 13:09:56.011146473 -0500
|
|
||||||
+++ ./misc/irqbalance.service 2017-11-14 13:10:13.480075654 -0500
|
|
||||||
@@ -4,7 +4,7 @@ After=syslog.target
|
|
||||||
ConditionVirtualization=!container
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
-EnvironmentFile=/path/to/irqbalance.env
|
|
||||||
+EnvironmentFile=/etc/sysconfig/irqbalance
|
|
||||||
ExecStart=/usr/sbin/irqbalance --foreground $IRQBALANCE_ARGS
|
|
||||||
|
|
||||||
[Install]
|
|
@ -1,73 +0,0 @@
|
|||||||
From 721460664afad79e2d96bbcb173eda68eed9743b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Gerd Rausch <gerd.rausch@oracle.com>
|
|
||||||
Date: Thu, 18 Oct 2018 11:21:40 -0700
|
|
||||||
Subject: [PATCH] Fix ambiguous parsing of *node* entries in /sys.
|
|
||||||
|
|
||||||
The code used to use strstr(..., "node") while iterating over
|
|
||||||
sysfs directories such as /sys/devices/system/cpu/cpu*.
|
|
||||||
It then made an assumption that the entry would start with "node",
|
|
||||||
which is not necessarily the case (e.g. the "firmware_node" entry).
|
|
||||||
|
|
||||||
The code happened to work for as long as the node[0-9]* entry
|
|
||||||
would be processed before the "firmware_node" entry shows up.
|
|
||||||
|
|
||||||
A change to the linux kernel "end_name_hash" function resulted
|
|
||||||
in a different hash, and ultimately in a different order
|
|
||||||
by which entries were returned by readdir(3).
|
|
||||||
|
|
||||||
This led to the exposure of this bug.
|
|
||||||
|
|
||||||
Signed-off-by: Gerd Rausch <gerd.rausch@oracle.com>
|
|
||||||
---
|
|
||||||
cputree.c | 11 ++++++++---
|
|
||||||
numa.c | 5 ++++-
|
|
||||||
2 files changed, 12 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cputree.c b/cputree.c
|
|
||||||
index c88143f..f08ce84 100644
|
|
||||||
--- a/cputree.c
|
|
||||||
+++ b/cputree.c
|
|
||||||
@@ -368,9 +368,14 @@ static void do_one_cpu(char *path)
|
|
||||||
entry = readdir(dir);
|
|
||||||
if (!entry)
|
|
||||||
break;
|
|
||||||
- if (strstr(entry->d_name, "node")) {
|
|
||||||
- nodeid = strtoul(&entry->d_name[4], NULL, 10);
|
|
||||||
- break;
|
|
||||||
+ if (strncmp(entry->d_name, "node", 4) == 0) {
|
|
||||||
+ char *end;
|
|
||||||
+ int num;
|
|
||||||
+ num = strtol(entry->d_name + 4, &end, 10);
|
|
||||||
+ if (!*end && num >= 0) {
|
|
||||||
+ nodeid = num;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
} while (entry);
|
|
||||||
closedir(dir);
|
|
||||||
diff --git a/numa.c b/numa.c
|
|
||||||
index cd67ec8..f0b1a98 100644
|
|
||||||
--- a/numa.c
|
|
||||||
+++ b/numa.c
|
|
||||||
@@ -29,6 +29,7 @@
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
+#include <ctype.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
|
|
||||||
@@ -115,7 +116,9 @@ void build_numa_node_list(void)
|
|
||||||
entry = readdir(dir);
|
|
||||||
if (!entry)
|
|
||||||
break;
|
|
||||||
- if ((entry->d_type == DT_DIR) && (strstr(entry->d_name, "node"))) {
|
|
||||||
+ if ((entry->d_type == DT_DIR) &&
|
|
||||||
+ (strncmp(entry->d_name, "node", 4) == 0) &&
|
|
||||||
+ isdigit(entry->d_name[4])) {
|
|
||||||
add_one_node(entry->d_name);
|
|
||||||
}
|
|
||||||
} while (entry);
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
|||||||
From 16cb6df56960f58df61ec35ef3be45286eb3c788 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Kairui Song <kasong@redhat.com>
|
|
||||||
Date: Sun, 2 Sep 2018 23:40:45 +0800
|
|
||||||
Subject: [PATCH 2/4] Fix an possible overflow error
|
|
||||||
|
|
||||||
Got:
|
|
||||||
"specified bound 2048 exceeds the size 19 of the destination"
|
|
||||||
when -O2 is used, and a "*** buffer overflow detected ***" error output
|
|
||||||
with no backtrace.
|
|
||||||
|
|
||||||
With -O0, it's gone, guess it's some gcc optimization problem, and the
|
|
||||||
size there is wrong anyway, this patch could fix it.
|
|
||||||
---
|
|
||||||
irqbalance.c | 4 ++--
|
|
||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/irqbalance.c b/irqbalance.c
|
|
||||||
index 4b3de54..c89c3c0 100644
|
|
||||||
--- a/irqbalance.c
|
|
||||||
+++ b/irqbalance.c
|
|
||||||
@@ -457,8 +457,8 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
|
||||||
}
|
|
||||||
if (!strncmp(buff, "setup", strlen("setup"))) {
|
|
||||||
char banned[512];
|
|
||||||
- char *setup = calloc(strlen("SLEEP ") + 11 +1, 1);
|
|
||||||
- snprintf(setup, 2048, "SLEEP %d ", sleep_interval);
|
|
||||||
+ char *setup = calloc(strlen("SLEEP ") + 11 + 1, 1);
|
|
||||||
+ snprintf(setup, strlen("SLEEP ") + 11 + 1, "SLEEP %d ", sleep_interval);
|
|
||||||
if(g_list_length(cl_banned_irqs) > 0) {
|
|
||||||
for_each_irq(cl_banned_irqs, get_irq_data, setup);
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.17.1
|
|
||||||
|
|
@ -1,253 +0,0 @@
|
|||||||
From 9ed5c269bd59c95f41829aedf0520930c97b08d3 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Kairui Song <kasong@redhat.com>
|
|
||||||
Date: Thu, 30 Aug 2018 17:45:53 +0800
|
|
||||||
Subject: Fix several memleak problems found by covscan
|
|
||||||
|
|
||||||
Some memleak issues is found by static analysis tools, and can confirm
|
|
||||||
irqbalance is leaking memory slowly when there are incomming connection
|
|
||||||
to socket.
|
|
||||||
|
|
||||||
This patch could solve the memleak problem.
|
|
||||||
---
|
|
||||||
irqbalance.c | 16 ++++++++++++----
|
|
||||||
ui/irqbalance-ui.c | 31 +++++++++++++++++++++++++++----
|
|
||||||
ui/ui.c | 2 ++
|
|
||||||
3 files changed, 41 insertions(+), 8 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/irqbalance.c b/irqbalance.c
|
|
||||||
index 6412447..4b3de54 100644
|
|
||||||
--- a/irqbalance.c
|
|
||||||
+++ b/irqbalance.c
|
|
||||||
@@ -385,11 +385,11 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
|
||||||
sock = accept(fd, NULL, NULL);
|
|
||||||
if (sock < 0) {
|
|
||||||
log(TO_ALL, LOG_WARNING, "Connection couldn't be accepted.\n");
|
|
||||||
- return TRUE;
|
|
||||||
+ goto out;
|
|
||||||
}
|
|
||||||
if ((recv_size = recvmsg(sock, &msg, 0)) < 0) {
|
|
||||||
log(TO_ALL, LOG_WARNING, "Error while receiving data.\n");
|
|
||||||
- return TRUE;
|
|
||||||
+ goto out;
|
|
||||||
}
|
|
||||||
cmsg = CMSG_FIRSTHDR(&msg);
|
|
||||||
if ((cmsg->cmsg_level == SOL_SOCKET) &&
|
|
||||||
@@ -401,7 +401,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
|
||||||
}
|
|
||||||
if (!valid_user) {
|
|
||||||
log(TO_ALL, LOG_INFO, "Permission denied for user to connect to socket.\n");
|
|
||||||
- return TRUE;
|
|
||||||
+ goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strncmp(buff, "stats", strlen("stats"))) {
|
|
||||||
@@ -421,6 +421,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
|
||||||
if (new_iterval >= 1) {
|
|
||||||
sleep_interval = new_iterval;
|
|
||||||
}
|
|
||||||
+ free(sleep_string);
|
|
||||||
} else if (!(strncmp(buff + strlen("settings "), "ban irqs ",
|
|
||||||
strlen("ban irqs ")))) {
|
|
||||||
char *end;
|
|
||||||
@@ -432,12 +433,14 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
|
||||||
cl_banned_irqs = NULL;
|
|
||||||
need_rescan = 1;
|
|
||||||
if (!strncmp(irq_string, "NONE", strlen("NONE"))) {
|
|
||||||
- return TRUE;
|
|
||||||
+ free(irq_string);
|
|
||||||
+ goto out;
|
|
||||||
}
|
|
||||||
int irq = strtoul(irq_string, &end, 10);
|
|
||||||
do {
|
|
||||||
add_cl_banned_irq(irq);
|
|
||||||
} while((irq = strtoul(end, &end, 10)));
|
|
||||||
+ free(irq_string);
|
|
||||||
} else if (!(strncmp(buff + strlen("settings "), "cpus ",
|
|
||||||
strlen("cpus")))) {
|
|
||||||
char *cpu_ban_string = malloc(
|
|
||||||
@@ -449,6 +452,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
|
||||||
banned_cpumask_from_ui = NULL;
|
|
||||||
}
|
|
||||||
need_rescan = 1;
|
|
||||||
+ free(cpu_ban_string);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!strncmp(buff, "setup", strlen("setup"))) {
|
|
||||||
@@ -463,10 +467,14 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
|
||||||
snprintf(setup + strlen(setup), strlen(banned) + 7 + 1,
|
|
||||||
"BANNED %s", banned);
|
|
||||||
send(sock, setup, strlen(setup), 0);
|
|
||||||
+ free(setup);
|
|
||||||
}
|
|
||||||
|
|
||||||
close(sock);
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+out:
|
|
||||||
+ free(msg.msg_control);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/ui/irqbalance-ui.c b/ui/irqbalance-ui.c
|
|
||||||
index 3fc46af..99f2ca2 100644
|
|
||||||
--- a/ui/irqbalance-ui.c
|
|
||||||
+++ b/ui/irqbalance-ui.c
|
|
||||||
@@ -41,6 +41,7 @@ struct msghdr * create_credentials_msg()
|
|
||||||
cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred));
|
|
||||||
memcpy(CMSG_DATA(cmsg), credentials, sizeof(struct ucred));
|
|
||||||
|
|
||||||
+ free(credentials);
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -87,6 +88,8 @@ void send_settings(char *data)
|
|
||||||
sendmsg(socket_fd, msg, 0);
|
|
||||||
|
|
||||||
close(socket_fd);
|
|
||||||
+ free(msg->msg_control);
|
|
||||||
+ free(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
char * get_data(char *string)
|
|
||||||
@@ -115,6 +118,8 @@ char * get_data(char *string)
|
|
||||||
int len = recv(socket_fd, data, 8192, 0);
|
|
||||||
close(socket_fd);
|
|
||||||
data[len] = '\0';
|
|
||||||
+ free(msg->msg_control);
|
|
||||||
+ free(msg);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -123,6 +128,7 @@ void parse_setup(char *setup_data)
|
|
||||||
char *token, *ptr;
|
|
||||||
int i,j;
|
|
||||||
char *copy;
|
|
||||||
+ irq_t *new_irq = NULL;
|
|
||||||
if((setup_data == NULL) || (strlen(setup_data) == 0)) return;
|
|
||||||
copy = strdup(setup_data);
|
|
||||||
if (!copy)
|
|
||||||
@@ -136,7 +142,7 @@ void parse_setup(char *setup_data)
|
|
||||||
token = strtok_r(NULL, " ", &ptr);
|
|
||||||
/* Parse banned IRQ data */
|
|
||||||
while(!strncmp(token, "IRQ", strlen("IRQ"))) {
|
|
||||||
- irq_t *new_irq = malloc(sizeof(irq_t));
|
|
||||||
+ new_irq = malloc(sizeof(irq_t));
|
|
||||||
new_irq->vector = strtol(strtok_r(NULL, " ", &ptr), NULL, 10);
|
|
||||||
token = strtok_r(NULL, " ", &ptr);
|
|
||||||
if(strncmp(token, "LOAD", strlen("LOAD"))) goto out;
|
|
||||||
@@ -151,6 +157,7 @@ void parse_setup(char *setup_data)
|
|
||||||
new_irq->assigned_to = NULL;
|
|
||||||
setup.banned_irqs = g_list_append(setup.banned_irqs, new_irq);
|
|
||||||
token = strtok_r(NULL, " ", &ptr);
|
|
||||||
+ new_irq = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(strncmp(token, "BANNED", strlen("BANNED"))) goto out;
|
|
||||||
@@ -165,6 +172,7 @@ void parse_setup(char *setup_data)
|
|
||||||
banned_cpu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+ free(map);
|
|
||||||
|
|
||||||
}
|
|
||||||
free(copy);
|
|
||||||
@@ -173,6 +181,9 @@ void parse_setup(char *setup_data)
|
|
||||||
out: {
|
|
||||||
/* Invalid data presented */
|
|
||||||
printf("Invalid data sent. Unexpected token: %s", token);
|
|
||||||
+ if (new_irq) {
|
|
||||||
+ free(new_irq);
|
|
||||||
+ }
|
|
||||||
free(copy);
|
|
||||||
g_list_free(tree);
|
|
||||||
exit(1);
|
|
||||||
@@ -240,7 +251,9 @@ void parse_into_tree(char *data)
|
|
||||||
cpu_node_t *parent = NULL;
|
|
||||||
char *copy;
|
|
||||||
tree = NULL;
|
|
||||||
-
|
|
||||||
+ irq_t *new_irq = NULL;
|
|
||||||
+ cpu_node_t *new = NULL;
|
|
||||||
+
|
|
||||||
if (!data || strlen(data) == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
@@ -255,7 +268,7 @@ void parse_into_tree(char *data)
|
|
||||||
free(copy);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
- cpu_node_t *new = malloc(sizeof(cpu_node_t));
|
|
||||||
+ new = malloc(sizeof(cpu_node_t));
|
|
||||||
new->irqs = NULL;
|
|
||||||
new->children = NULL;
|
|
||||||
new->cpu_list = NULL;
|
|
||||||
@@ -279,7 +292,7 @@ void parse_into_tree(char *data)
|
|
||||||
|
|
||||||
/* Parse assigned IRQ data */
|
|
||||||
while((token != NULL) && (!strncmp(token, "IRQ", strlen("IRQ")))) {
|
|
||||||
- irq_t *new_irq = malloc(sizeof(irq_t));
|
|
||||||
+ new_irq = malloc(sizeof(irq_t));
|
|
||||||
new_irq->vector = strtol(strtok_r(NULL, " ", &ptr), NULL, 10);
|
|
||||||
token = strtok_r(NULL, " ", &ptr);
|
|
||||||
if(strncmp(token, "LOAD", strlen("LOAD"))) goto out;
|
|
||||||
@@ -293,6 +306,7 @@ void parse_into_tree(char *data)
|
|
||||||
new_irq->is_banned = 0;
|
|
||||||
new->irqs = g_list_append(new->irqs, new_irq);
|
|
||||||
token = strtok_r(NULL, " ", &ptr);
|
|
||||||
+ new_irq = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((token == NULL) || (strncmp(token, "IRQ", strlen("IRQ")))) {
|
|
||||||
@@ -306,6 +320,8 @@ void parse_into_tree(char *data)
|
|
||||||
parent = new;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ new = NULL;
|
|
||||||
}
|
|
||||||
free(copy);
|
|
||||||
for_each_node(tree, assign_cpu_lists, NULL);
|
|
||||||
@@ -315,6 +331,12 @@ void parse_into_tree(char *data)
|
|
||||||
out: {
|
|
||||||
/* Invalid data presented */
|
|
||||||
printf("Invalid data sent. Unexpected token: %s\n", token);
|
|
||||||
+ if (new_irq) {
|
|
||||||
+ free(new_irq);
|
|
||||||
+ }
|
|
||||||
+ if (new) {
|
|
||||||
+ free(new);
|
|
||||||
+ }
|
|
||||||
g_list_free(tree);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
@@ -330,6 +352,7 @@ gboolean rescan_tree(gpointer data __attribute__((unused)))
|
|
||||||
display_tree();
|
|
||||||
}
|
|
||||||
free(setup_data);
|
|
||||||
+ free(irqbalance_data);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/ui/ui.c b/ui/ui.c
|
|
||||||
index 4054f0e..06ec472 100644
|
|
||||||
--- a/ui/ui.c
|
|
||||||
+++ b/ui/ui.c
|
|
||||||
@@ -71,6 +71,7 @@ char * check_control_in_sleep_input(int max_len, int column_offest, int line_off
|
|
||||||
attrset(COLOR_PAIR(6));
|
|
||||||
break;
|
|
||||||
case 27:
|
|
||||||
+ free(input_to);
|
|
||||||
return NULL;
|
|
||||||
default:
|
|
||||||
input_to[iteration] = new;
|
|
||||||
@@ -115,6 +116,7 @@ int get_valid_sleep_input(int column_offest)
|
|
||||||
input);
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
+ free(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
attrset(COLOR_PAIR(1));
|
|
||||||
--
|
|
||||||
2.17.1
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
|||||||
From 3eae2edd136540898f8e51546eedfb56729f938d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Xiao Liang <xiliang@redhat.com>
|
|
||||||
Date: Thu, 18 Oct 2018 21:50:33 +0800
|
|
||||||
Subject: procinterrupts: check xen-dyn-event more flexible
|
|
||||||
|
|
||||||
In current /proc/interrupts, the 'xen-dyn-event' was split to 'xen-dyn -event'.
|
|
||||||
It causes interrupts not balanced inside xen guest.
|
|
||||||
|
|
||||||
Below result is without this patch:
|
|
||||||
70: 29 0 0 0 xen-dyn -event vif0-q0-tx
|
|
||||||
71: 120 0 0 0 xen-dyn -event vif0-q0-rx
|
|
||||||
72: 586350 0 0 0 xen-dyn -event vif0-q1-tx
|
|
||||||
73: 44 0 0 0 xen-dyn -event vif0-q1-rx
|
|
||||||
74: 19 0 0 0 xen-dyn -event vif0-q2-tx
|
|
||||||
75: 179 0 0 0 xen-dyn -event vif0-q2-rx
|
|
||||||
76: 67 0 0 0 xen-dyn -event vif0-q3-tx
|
|
||||||
77: 299637 0 0 0 xen-dyn -event vif0-q3-rx
|
|
||||||
|
|
||||||
Below result is with this patch:
|
|
||||||
[root@dhcp-3-194 ~]# grep vif0 /proc/interrupts
|
|
||||||
70: 30 0 0 0 xen-dyn -event vif0-q0-tx
|
|
||||||
71: 305 0 11 0 xen-dyn -event vif0-q0-rx
|
|
||||||
72: 586354 0 27 0 xen-dyn -event vif0-q1-tx
|
|
||||||
73: 49 7 5 0 xen-dyn -event vif0-q1-rx
|
|
||||||
74: 27 0 0 509373 xen-dyn -event vif0-q2-tx
|
|
||||||
75: 420 0 5 0 xen-dyn -event vif0-q2-rx
|
|
||||||
76: 179 0 38 0 xen-dyn -event vif0-q3-tx
|
|
||||||
77: 299803 281433 0 0 xen-dyn -event vif0-q3-rx
|
|
||||||
|
|
||||||
Signed-off-by: Xiao Liang <xiliang@redhat.com>
|
|
||||||
---
|
|
||||||
procinterrupts.c | 7 ++++++-
|
|
||||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/procinterrupts.c b/procinterrupts.c
|
|
||||||
index eb84a1c..ca9533b 100644
|
|
||||||
--- a/procinterrupts.c
|
|
||||||
+++ b/procinterrupts.c
|
|
||||||
@@ -167,6 +167,7 @@ GList* collect_full_irq_list()
|
|
||||||
|
|
||||||
while (!feof(file)) {
|
|
||||||
int number;
|
|
||||||
+ int is_xen_dyn = 0;
|
|
||||||
struct irq_info *info;
|
|
||||||
char *c;
|
|
||||||
char savedline[1024];
|
|
||||||
@@ -187,9 +188,13 @@ GList* collect_full_irq_list()
|
|
||||||
|
|
||||||
strncpy(savedline, line, sizeof(savedline));
|
|
||||||
irq_name = strtok_r(savedline, " ", &savedptr);
|
|
||||||
+ if (strstr(irq_name, "xen-dyn") != NULL)
|
|
||||||
+ is_xen_dyn = 1;
|
|
||||||
last_token = strtok_r(NULL, " ", &savedptr);
|
|
||||||
while ((p = strtok_r(NULL, " ", &savedptr))) {
|
|
||||||
irq_name = last_token;
|
|
||||||
+ if (strstr(irq_name, "xen-dyn") != NULL)
|
|
||||||
+ is_xen_dyn = 1;
|
|
||||||
last_token = p;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -209,7 +214,7 @@ GList* collect_full_irq_list()
|
|
||||||
info = calloc(sizeof(struct irq_info), 1);
|
|
||||||
if (info) {
|
|
||||||
info->irq = number;
|
|
||||||
- if (strstr(irq_name, "xen-dyn-event") != NULL) {
|
|
||||||
+ if (strstr(irq_name, "-event") != NULL && is_xen_dyn == 1) {
|
|
||||||
info->type = IRQ_TYPE_VIRT_EVENT;
|
|
||||||
info->class = IRQ_VIRT_EVENT;
|
|
||||||
} else {
|
|
||||||
--
|
|
||||||
2.17.1
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
|||||||
From ce71f0cc2255aba072eabb2af26f6cb0e31f8189 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Kairui Song <kasong@redhat.com>
|
|
||||||
Date: Tue, 6 Nov 2018 10:37:15 +0800
|
|
||||||
Subject: Don't leak socket fd on connection error
|
|
||||||
|
|
||||||
Signed-off-by: Kairui Song <kasong@redhat.com>
|
|
||||||
---
|
|
||||||
irqbalance.c | 7 ++++---
|
|
||||||
ui/irqbalance-ui.c | 1 +
|
|
||||||
2 files changed, 5 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/irqbalance.c b/irqbalance.c
|
|
||||||
index c89c3c0..a77f842 100644
|
|
||||||
--- a/irqbalance.c
|
|
||||||
+++ b/irqbalance.c
|
|
||||||
@@ -389,7 +389,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
|
||||||
}
|
|
||||||
if ((recv_size = recvmsg(sock, &msg, 0)) < 0) {
|
|
||||||
log(TO_ALL, LOG_WARNING, "Error while receiving data.\n");
|
|
||||||
- goto out;
|
|
||||||
+ goto out_close;
|
|
||||||
}
|
|
||||||
cmsg = CMSG_FIRSTHDR(&msg);
|
|
||||||
if ((cmsg->cmsg_level == SOL_SOCKET) &&
|
|
||||||
@@ -401,7 +401,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
|
||||||
}
|
|
||||||
if (!valid_user) {
|
|
||||||
log(TO_ALL, LOG_INFO, "Permission denied for user to connect to socket.\n");
|
|
||||||
- goto out;
|
|
||||||
+ goto out_close;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strncmp(buff, "stats", strlen("stats"))) {
|
|
||||||
@@ -434,7 +434,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
|
||||||
need_rescan = 1;
|
|
||||||
if (!strncmp(irq_string, "NONE", strlen("NONE"))) {
|
|
||||||
free(irq_string);
|
|
||||||
- goto out;
|
|
||||||
+ goto out_close;
|
|
||||||
}
|
|
||||||
int irq = strtoul(irq_string, &end, 10);
|
|
||||||
do {
|
|
||||||
@@ -470,6 +470,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
|
||||||
free(setup);
|
|
||||||
}
|
|
||||||
|
|
||||||
+out_close:
|
|
||||||
close(sock);
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/ui/irqbalance-ui.c b/ui/irqbalance-ui.c
|
|
||||||
index 99f2ca2..6d4c845 100644
|
|
||||||
--- a/ui/irqbalance-ui.c
|
|
||||||
+++ b/ui/irqbalance-ui.c
|
|
||||||
@@ -62,6 +62,7 @@ int init_connection()
|
|
||||||
|
|
||||||
if(connect(socket_fd, (struct sockaddr *)&addr,
|
|
||||||
sizeof(sa_family_t) + strlen(socket_name) + 1) < 0) {
|
|
||||||
+ close(socket_fd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
2.17.1
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
|||||||
From a1abba7b070587cc5fa69597081dcc80f4addef3 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Kairui Song <kasong@redhat.com>
|
|
||||||
Date: Tue, 26 Feb 2019 16:26:51 +0800
|
|
||||||
Subject: [PATCH] Refine document about IRQBALANCE_BANNED_CPUS
|
|
||||||
|
|
||||||
There is no declaration about how irqbalance deal with isolated CPUs or
|
|
||||||
adaptive-ticks CPUs, and how IRQBALANCE_BANNED_CPUS will override the
|
|
||||||
behavior of auto-banning of such CPUs. Refine the document to avoid
|
|
||||||
confusion.
|
|
||||||
|
|
||||||
Signed-off-by: Kairui Song <kasong@redhat.com>
|
|
||||||
---
|
|
||||||
irqbalance.1 | 2 ++
|
|
||||||
1 file changed, 2 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/irqbalance.1 b/irqbalance.1
|
|
||||||
index 11eb498..d272b6f 100644
|
|
||||||
--- a/irqbalance.1
|
|
||||||
+++ b/irqbalance.1
|
|
||||||
@@ -155,6 +155,8 @@ Same as --debug.
|
|
||||||
.TP
|
|
||||||
.B IRQBALANCE_BANNED_CPUS
|
|
||||||
Provides a mask of CPUs which irqbalance should ignore and never assign interrupts to.
|
|
||||||
+If not specified, irqbalance use mask of isolated and adaptive-ticks CPUs on the
|
|
||||||
+system as the default value.
|
|
||||||
|
|
||||||
.SH "SIGNALS"
|
|
||||||
.TP
|
|
||||||
--
|
|
||||||
2.28.0
|
|
||||||
|
|
@ -1,109 +0,0 @@
|
|||||||
From 5f8ed87f36381569725c67445f12226f41861d1f Mon Sep 17 00:00:00 2001
|
|
||||||
From: Kairui Song <kasong@redhat.com>
|
|
||||||
Date: Fri, 9 Nov 2018 11:36:12 +0800
|
|
||||||
Subject: [PATCH] Update document and remove dead options
|
|
||||||
|
|
||||||
This is the stash of following three commits:
|
|
||||||
|
|
||||||
commit ea743009f69ad4800c60bf26c776ef4944c6af8b
|
|
||||||
Author: Kairui Song <kasong@redhat.com>
|
|
||||||
Date: Mon Mar 25 19:58:58 2019 +0800
|
|
||||||
|
|
||||||
Remove a duplicated word in manpage
|
|
||||||
|
|
||||||
Just noticed a warning in a manpage scan report, trivial but let's
|
|
||||||
fix it.
|
|
||||||
|
|
||||||
Signed-off-by: Kairui Song <kasong@redhat.com>
|
|
||||||
|
|
||||||
commit 0b95593b19ff13e7e271d5b0b8219e7c70bf773c
|
|
||||||
Author: Kairui Song <kasong@redhat.com>
|
|
||||||
Date: Fri Nov 9 12:26:29 2018 +0800
|
|
||||||
|
|
||||||
Update document for option --banmod and --deepestcache
|
|
||||||
|
|
||||||
'--banmod' is not documented, and '--deepestcache's alias '-c' is
|
|
||||||
missing.
|
|
||||||
|
|
||||||
Also fix an typo.
|
|
||||||
|
|
||||||
Signed-off-by: Kairui Song <kasong@redhat.com>
|
|
||||||
|
|
||||||
commit 3ae01f5bd5ef3ed3080c9b06fc63bb02cc03bf1a
|
|
||||||
Author: Kairui Song <kasong@redhat.com>
|
|
||||||
Date: Fri Nov 9 11:36:12 2018 +0800
|
|
||||||
|
|
||||||
Remove hintpolicy related options in help message
|
|
||||||
|
|
||||||
hintpolicy was dropped sometime ago so related help message should be
|
|
||||||
dropped as well.
|
|
||||||
|
|
||||||
Signed-off-by: Kairui Song <kasong@redhat.com>
|
|
||||||
|
|
||||||
Signed-off-by: Kairui Song <kasong@redhat.com>
|
|
||||||
---
|
|
||||||
irqbalance.1 | 15 ++++++++++++---
|
|
||||||
irqbalance.c | 3 +--
|
|
||||||
2 files changed, 13 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/irqbalance.1 b/irqbalance.1
|
|
||||||
index 68e3cf8..61ae35e 100644
|
|
||||||
--- a/irqbalance.1
|
|
||||||
+++ b/irqbalance.1
|
|
||||||
@@ -62,12 +62,21 @@ in an effort to prevent that CPU from waking up without need.
|
|
||||||
.B -i, --banirq=<irqnum>
|
|
||||||
Add the specified IRQ to the set of banned IRQs. irqbalance will not affect
|
|
||||||
the affinity of any IRQs on the banned list, allowing them to be specified
|
|
||||||
-manually. This option is addative and can be specified multiple times. For
|
|
||||||
+manually. This option is additive and can be specified multiple times. For
|
|
||||||
example to ban IRQs 43 and 44 from balancing, use the following command line:
|
|
||||||
.B irqbalance --banirq=43 --banirq=44
|
|
||||||
|
|
||||||
.TP
|
|
||||||
-.B --deepestcache=<integer>
|
|
||||||
+.B -m, --banmod=<module_name>
|
|
||||||
+Add the specified module to the set of banned modules, similiar to --banirq.
|
|
||||||
+irqbalance will not affect the affinity of any IRQs of given modules, allowing
|
|
||||||
+them to be specified manually. This option is additive and can be specified
|
|
||||||
+multiple times. For example to ban all IRQs of module foo and module bar from
|
|
||||||
+balancing, use the following command line:
|
|
||||||
+.B irqbalance --banmod=foo --banmod=bar
|
|
||||||
+
|
|
||||||
+.TP
|
|
||||||
+.B -c, --deepestcache=<integer>
|
|
||||||
This allows a user to specify the cache level at which irqbalance partitions
|
|
||||||
cache domains. Specifying a deeper cache may allow a greater degree of
|
|
||||||
flexibility for irqbalance to assign IRQ affinity to achieve greater performance
|
|
||||||
@@ -148,7 +157,7 @@ each assigned IRQ type, it's number, load, number of IRQs since last rebalancing
|
|
||||||
and it's class are sent. Refer to types.h file for explanation of defines.
|
|
||||||
.TP
|
|
||||||
.B setup
|
|
||||||
-Get the current value of sleep interval, mask of banned CPUs and and list of banned IRQs.
|
|
||||||
+Get the current value of sleep interval, mask of banned CPUs and list of banned IRQs.
|
|
||||||
.TP
|
|
||||||
.B settings sleep <s>
|
|
||||||
Set new value of sleep interval, <s> >= 1.
|
|
||||||
diff --git a/irqbalance.c b/irqbalance.c
|
|
||||||
index 6412447..7713cd0 100644
|
|
||||||
--- a/irqbalance.c
|
|
||||||
+++ b/irqbalance.c
|
|
||||||
@@ -84,7 +84,6 @@ struct option lopts[] = {
|
|
||||||
{"oneshot", 0, NULL, 'o'},
|
|
||||||
{"debug", 0, NULL, 'd'},
|
|
||||||
{"foreground", 0, NULL, 'f'},
|
|
||||||
- {"hintpolicy", 1, NULL, 'h'},
|
|
||||||
{"powerthresh", 1, NULL, 'p'},
|
|
||||||
{"banirq", 1 , NULL, 'i'},
|
|
||||||
{"banscript", 1, NULL, 'b'},
|
|
||||||
@@ -100,7 +99,7 @@ struct option lopts[] = {
|
|
||||||
|
|
||||||
static void usage(void)
|
|
||||||
{
|
|
||||||
- log(TO_CONSOLE, LOG_INFO, "irqbalance [--oneshot | -o] [--debug | -d] [--foreground | -f] [--journal | -j] [--hintpolicy= | -h [exact|subset|ignore]]\n");
|
|
||||||
+ log(TO_CONSOLE, LOG_INFO, "irqbalance [--oneshot | -o] [--debug | -d] [--foreground | -f] [--journal | -j]\n");
|
|
||||||
log(TO_CONSOLE, LOG_INFO, " [--powerthresh= | -p <off> | <n>] [--banirq= | -i <n>] [--banmod= | -m <module>] [--policyscript= | -l <script>]\n");
|
|
||||||
log(TO_CONSOLE, LOG_INFO, " [--pid= | -s <file>] [--deepestcache= | -c <n>] [--interval= | -t <n>]\n");
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.20.1
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
|||||||
From acb0c2057952fa8bb502bf6b4222b327efe44c4c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Kairui Song <kasong@redhat.com>
|
|
||||||
Date: Mon, 26 Oct 2020 17:26:52 +0800
|
|
||||||
Subject: [PATCH] Add some examples for IRQBALANCE_BANNED_CPUS
|
|
||||||
|
|
||||||
Signed-off-by: Kairui Song <kasong@redhat.com>
|
|
||||||
---
|
|
||||||
irqbalance.1 | 7 +++++++
|
|
||||||
1 file changed, 7 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/irqbalance.1 b/irqbalance.1
|
|
||||||
index d272b6f..330c12b 100644
|
|
||||||
--- a/irqbalance.1
|
|
||||||
+++ b/irqbalance.1
|
|
||||||
@@ -157,6 +157,13 @@ Same as --debug.
|
|
||||||
Provides a mask of CPUs which irqbalance should ignore and never assign interrupts to.
|
|
||||||
If not specified, irqbalance use mask of isolated and adaptive-ticks CPUs on the
|
|
||||||
system as the default value.
|
|
||||||
+This is a hexmask without the leading ’0x’. On systems with large numbers of
|
|
||||||
+processors, each group of eight hex digits is separated by a comma ’,’. i.e.
|
|
||||||
+‘export IRQBALANCE_BANNED_CPUS=fc0‘ would prevent irqbalance from assigning irqs
|
|
||||||
+to the 7th-12th cpus (cpu6-cpu11) or ‘export IRQBALANCE_BANNED_CPUS=ff000000,00000001‘
|
|
||||||
+would prevent irqbalance from assigning irqs to the 1st (cpu0) and 57th-64th cpus
|
|
||||||
+(cpu56-cpu63).
|
|
||||||
+
|
|
||||||
|
|
||||||
.SH "SIGNALS"
|
|
||||||
.TP
|
|
||||||
--
|
|
||||||
2.28.0
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
|||||||
From a1f83a563475bd77843c4b44ee44a7d764bc9bba Mon Sep 17 00:00:00 2001
|
|
||||||
From: Kairui Song <kasong@redhat.com>
|
|
||||||
Date: Thu, 28 Jan 2021 15:24:32 +0800
|
|
||||||
Subject: [PATCH] Also fetch node info for non-PCI devices
|
|
||||||
|
|
||||||
non-PCI devices could also be bind to a certain node. So if failed to
|
|
||||||
fetch the info from sysfs, try to get it from /proc/irq/<irq>/node.
|
|
||||||
---
|
|
||||||
classify.c | 5 ++++-
|
|
||||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/classify.c b/classify.c
|
|
||||||
index df8a89b..92f43cc 100644
|
|
||||||
--- a/classify.c
|
|
||||||
+++ b/classify.c
|
|
||||||
@@ -395,7 +395,10 @@ static struct irq_info *add_one_irq_to_db(const char *devpath, int irq, struct u
|
|
||||||
get_numa_node:
|
|
||||||
numa_node = -1;
|
|
||||||
if (numa_avail) {
|
|
||||||
- sprintf(path, "%s/numa_node", devpath);
|
|
||||||
+ if (devpath)
|
|
||||||
+ sprintf(path, "%s/numa_node", devpath);
|
|
||||||
+ else
|
|
||||||
+ sprintf(path, "/proc/irq/%i/node", irq);
|
|
||||||
fd = fopen(path, "r");
|
|
||||||
if (fd) {
|
|
||||||
fscanf(fd, "%d", &numa_node);
|
|
||||||
--
|
|
||||||
2.29.2
|
|
||||||
|
|
13
SOURCES/irqbalance-1.8.0-env-file-path.patch
Normal file
13
SOURCES/irqbalance-1.8.0-env-file-path.patch
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
diff --git a/misc/irqbalance.service b/misc/irqbalance.service
|
||||||
|
index 0f79c3e..18c7e9b 100644
|
||||||
|
--- a/misc/irqbalance.service
|
||||||
|
+++ b/misc/irqbalance.service
|
||||||
|
@@ -7,7 +7,7 @@ ConditionCPUs=>1
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
EnvironmentFile=-/usr/lib/irqbalance/defaults.env
|
||||||
|
-EnvironmentFile=-/path/to/irqbalance.env
|
||||||
|
+EnvironmentFile=-/etc/sysconfig/irqbalance
|
||||||
|
ExecStart=/usr/sbin/irqbalance --foreground $IRQBALANCE_ARGS
|
||||||
|
ReadOnlyPaths=/
|
||||||
|
ReadWritePaths=/proc/irq
|
@ -1,6 +1,6 @@
|
|||||||
Name: irqbalance
|
Name: irqbalance
|
||||||
Version: 1.4.0
|
Version: 1.9.0
|
||||||
Release: 6%{?dist}
|
Release: 3%{?dist}
|
||||||
Epoch: 2
|
Epoch: 2
|
||||||
Summary: IRQ balancing daemon
|
Summary: IRQ balancing daemon
|
||||||
|
|
||||||
@ -23,16 +23,22 @@ Requires: numactl-libs
|
|||||||
|
|
||||||
ExcludeArch: s390 s390x
|
ExcludeArch: s390 s390x
|
||||||
|
|
||||||
Patch1: irqbalance-1.0.4-env-file-path.patch
|
Patch1: irqbalance-1.8.0-env-file-path.patch
|
||||||
Patch2: irqbalance-1.4.0-Fix-several-memleak-problems-found-by-covscan.patch
|
Patch2: 0001-get-irq-module-relationship-from-sys-bus-pci-driver.patch
|
||||||
Patch3: irqbalance-1.4.0-Fix-an-possible-overflow-error.patch
|
Patch3: 0002-check-whether-savedptr-is-NULL-before-invoking-strle.patch
|
||||||
Patch4: irqbalance-1.5.0-Don-t-leak-socket-fd-on-connection-error.patch
|
Patch4: 0003-add-meson.patch
|
||||||
Patch5: irqbalance-1.4.0-procinterrupts-check-xen-dyn-event-more-flexible.patch
|
Patch5: 0004-Prepare-to-handle-thermal-event.patch
|
||||||
Patch6: irqbalance-1.5.0-Update-document-and-remove-dead-options.patch
|
Patch6: 0005-Implement-Netlink-helper-functions-to-subscribe-ther.patch
|
||||||
Patch7: irqbalance-1.4.0-Fix-ambiguous-parsing-of-node-entries-in-sys.patch
|
Patch7: 0006-Handle-thermal-events-to-mask-CPUs.patch
|
||||||
Patch8: irqbalance-1.5.0-Refine-document-about-IRQBALANCE_BANNED_CPUS.patch
|
Patch8: 0007-add-keep_going-check-to-prevent-irqbalance-from-fail.patch
|
||||||
Patch9: irqbalance-1.7.0-Add-some-examples-for-IRQBALANCE_BANNED_CPUS.patch
|
Patch9: 0008-parse_proc_interrupts-fix-parsing-interrupt-counts.patch
|
||||||
Patch10: irqbalance-1.7.0-Also-fetch-node-info-for-non-PCI-devices.patch
|
Patch10: 0009-irqbalance-ui-move-ASSIGNED-TO-CPUS-to-the-last-colu.patch
|
||||||
|
Patch11: 0010-irqbalance-ui-can-t-change-window-when-in-editing-st.patch
|
||||||
|
Patch12: 0011-fix-memory-leak-in-ui-ui.c.patch
|
||||||
|
Patch13: 0012-irqbalance-ui-support-scroll-under-tui-mode-of-irqba.patch
|
||||||
|
Patch14: 0013-irqbalance-ui-print-cpulist-in-SETUP-IRQS.patch
|
||||||
|
Patch15: 0014-Improve-documentation-and-logging-for-banned-cpus.patch
|
||||||
|
Patch16: 0001-irqbalance-ui-skip-in-parse_setup-to-avoid-coredump.patch
|
||||||
|
|
||||||
%description
|
%description
|
||||||
irqbalance is a daemon that evenly distributes IRQ load across
|
irqbalance is a daemon that evenly distributes IRQ load across
|
||||||
@ -50,6 +56,12 @@ multiple CPUs for enhanced performance.
|
|||||||
%patch8 -p1
|
%patch8 -p1
|
||||||
%patch9 -p1
|
%patch9 -p1
|
||||||
%patch10 -p1
|
%patch10 -p1
|
||||||
|
%patch11 -p1
|
||||||
|
%patch12 -p1
|
||||||
|
%patch13 -p1
|
||||||
|
%patch14 -p1
|
||||||
|
%patch15 -p1
|
||||||
|
%patch16 -p1
|
||||||
|
|
||||||
%build
|
%build
|
||||||
./autogen.sh
|
./autogen.sh
|
||||||
@ -58,6 +70,7 @@ CFLAGS="%{optflags}" make %{?_smp_mflags}
|
|||||||
|
|
||||||
%install
|
%install
|
||||||
install -D -p -m 0755 %{name} %{buildroot}%{_sbindir}/%{name}
|
install -D -p -m 0755 %{name} %{buildroot}%{_sbindir}/%{name}
|
||||||
|
install -D -p -m 0755 %{name}-ui %{buildroot}%{_sbindir}/%{name}-ui
|
||||||
install -D -p -m 0644 ./misc/irqbalance.service %{buildroot}/%{_unitdir}/irqbalance.service
|
install -D -p -m 0644 ./misc/irqbalance.service %{buildroot}/%{_unitdir}/irqbalance.service
|
||||||
install -D -p -m 0644 %{SOURCE1} %{buildroot}%{_sysconfdir}/sysconfig/%{name}
|
install -D -p -m 0644 %{SOURCE1} %{buildroot}%{_sysconfdir}/sysconfig/%{name}
|
||||||
|
|
||||||
@ -70,6 +83,7 @@ make check
|
|||||||
%files
|
%files
|
||||||
%doc COPYING AUTHORS
|
%doc COPYING AUTHORS
|
||||||
%{_sbindir}/irqbalance
|
%{_sbindir}/irqbalance
|
||||||
|
%{_sbindir}/irqbalance-ui
|
||||||
%{_unitdir}/irqbalance.service
|
%{_unitdir}/irqbalance.service
|
||||||
%{_mandir}/man1/*
|
%{_mandir}/man1/*
|
||||||
%config(noreplace) %{_sysconfdir}/sysconfig/irqbalance
|
%config(noreplace) %{_sysconfdir}/sysconfig/irqbalance
|
||||||
@ -90,6 +104,15 @@ fi
|
|||||||
/sbin/chkconfig --del irqbalance >/dev/null 2>&1 || :
|
/sbin/chkconfig --del irqbalance >/dev/null 2>&1 || :
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Jul 19 2022 Tao Liu <ltao@redhat.com> - 2:1.9.0-3
|
||||||
|
- Rebase to latest upstream commit (c8d1fff0f1)
|
||||||
|
|
||||||
|
* Thu Jul 14 2022 Tao Liu <ltao@redhat.com> - 2:1.9.0-2
|
||||||
|
- Rebase to latest upstream commit (167580790c)
|
||||||
|
|
||||||
|
* Fri Jul 1 2022 Tao Liu <ltao@redhat.com> - 2:1.9.0-1
|
||||||
|
- Rebase to latest upstream release v1.9.0. Resolves:rhbz2098629
|
||||||
|
|
||||||
* Fri Jan 29 2021 Kairui Song <kasong@redhat.com> 2:1.4.0-6
|
* Fri Jan 29 2021 Kairui Song <kasong@redhat.com> 2:1.4.0-6
|
||||||
- Also fetch node info for non-PCI devices
|
- Also fetch node info for non-PCI devices
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user