diff --git a/.gitignore b/.gitignore index 0873321..b78fd49 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ SOURCES/irqbalance-1.9.0.tar.gz /irqbalance-1.9.0.tar.gz +/irqbalance-1.9.2.tar.gz diff --git a/0001-get-irq-module-relationship-from-sys-bus-pci-driver.patch b/0001-get-irq-module-relationship-from-sys-bus-pci-driver.patch deleted file mode 100644 index 1961ea8..0000000 --- a/0001-get-irq-module-relationship-from-sys-bus-pci-driver.patch +++ /dev/null @@ -1,71 +0,0 @@ -From ff48ac9c84f0b318dfce665605d72e86dfcfe008 Mon Sep 17 00:00:00 2001 -From: Chao Liu -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 ---- - 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 - #include - #include -+#include - - #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 - diff --git a/0001-irqbalance-ui-skip-in-parse_setup-to-avoid-coredump.patch b/0001-irqbalance-ui-skip-in-parse_setup-to-avoid-coredump.patch deleted file mode 100644 index 3ed91e4..0000000 --- a/0001-irqbalance-ui-skip-in-parse_setup-to-avoid-coredump.patch +++ /dev/null @@ -1,64 +0,0 @@ -From c8d1fff0f16ad906cca153a22faac11516ccc0dd Mon Sep 17 00:00:00 2001 -From: Liu Chao -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 ---- - 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 - diff --git a/0001-optimize-getting-cpu-number.patch b/0001-optimize-getting-cpu-number.patch new file mode 100644 index 0000000..6f5fae3 --- /dev/null +++ b/0001-optimize-getting-cpu-number.patch @@ -0,0 +1,26 @@ +From 7c18ffc9d0187d4d1983a53bb166aacad2a87dcc Mon Sep 17 00:00:00 2001 +From: qyu +Date: Mon, 7 Nov 2022 17:01:38 +0800 +Subject: [PATCH 01/13] optimize getting cpu number + +cpu number has already been parsed and saved in cpunr, remove redudant strtoul(). +--- + cputree.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/cputree.c b/cputree.c +index eb1981e..d66be55 100644 +--- a/cputree.c ++++ b/cputree.c +@@ -315,7 +315,7 @@ static void do_one_cpu(char *path) + + cpu->obj_type = OBJ_TYPE_CPU; + +- cpu->number = strtoul(&path[27], NULL, 10); ++ cpu->number = cpunr; + + cpu_set(cpu->number, cpu_online_map); + +-- +2.33.1 + diff --git a/0002-allow-AF_NETLINK-in-the-systemd-service-restrictions.patch b/0002-allow-AF_NETLINK-in-the-systemd-service-restrictions.patch new file mode 100644 index 0000000..9d5ddd7 --- /dev/null +++ b/0002-allow-AF_NETLINK-in-the-systemd-service-restrictions.patch @@ -0,0 +1,31 @@ +From efec4c69157d17024c4d9194a63eb834efcd79b9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dirk=20M=C3=BCller?= +Date: Fri, 11 Nov 2022 10:38:19 +0100 +Subject: [PATCH 02/13] allow AF_NETLINK in the systemd service restrictions + +AF_NETLINK is needed for communicating with the thermald daemon, +without that the start up logs a warning + + thermal: socket bind failed, thermald may not be running. + +because systemd prevents access to NETLINK. +--- + misc/irqbalance.service | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/misc/irqbalance.service b/misc/irqbalance.service +index 0f79c3e..8544f66 100644 +--- a/misc/irqbalance.service ++++ b/misc/irqbalance.service +@@ -11,7 +11,7 @@ EnvironmentFile=-/path/to/irqbalance.env + ExecStart=/usr/sbin/irqbalance --foreground $IRQBALANCE_ARGS + ReadOnlyPaths=/ + ReadWritePaths=/proc/irq +-RestrictAddressFamilies=AF_UNIX ++RestrictAddressFamilies=AF_UNIX AF_NETLINK + RuntimeDirectory=irqbalance/ + + [Install] +-- +2.33.1 + diff --git a/0002-check-whether-savedptr-is-NULL-before-invoking-strle.patch b/0002-check-whether-savedptr-is-NULL-before-invoking-strle.patch deleted file mode 100644 index feca09a..0000000 --- a/0002-check-whether-savedptr-is-NULL-before-invoking-strle.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 522883505d3b02e3294f045f49007b61c00e2c31 Mon Sep 17 00:00:00 2001 -From: Chao Liu -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 ---- - 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 - diff --git a/0003-add-meson.patch b/0003-add-meson.patch deleted file mode 100644 index 2faf2fa..0000000 --- a/0003-add-meson.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 378d4707c26acf05e551219d8b09ddf440bdba2a Mon Sep 17 00:00:00 2001 -From: Rosen Penev -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 ---- - 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 - diff --git a/0003-thermal-Fix-the-warning-message.patch b/0003-thermal-Fix-the-warning-message.patch new file mode 100644 index 0000000..89077c9 --- /dev/null +++ b/0003-thermal-Fix-the-warning-message.patch @@ -0,0 +1,33 @@ +From 178cf3b4311fab38b9731fc929feecf45b7cb2f0 Mon Sep 17 00:00:00 2001 +From: "Chang S. Bae" +Date: Fri, 18 Nov 2022 10:14:15 -0800 +Subject: [PATCH 03/13] thermal: Fix the warning message + +The commit febe697ac321 ("change the log level in thermal.c from error to +warning") happens to insert an unneeded message: "thermald may not be +running." + +This is not true because the events come from the kernel and Netlink has +the multicast subscription model. So it has nothing to do with thermald. + +Signed-off-by: Chang S. Bae +--- + thermal.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/thermal.c b/thermal.c +index 10e1083..7cd0807 100644 +--- a/thermal.c ++++ b/thermal.c +@@ -99,7 +99,7 @@ static gboolean prepare_netlink(void) + + rc = genl_connect(sock); + if (rc) { +- log(TO_ALL, LOG_INFO, "thermal: socket bind failed, thermald may not be running.\n"); ++ log(TO_ALL, LOG_INFO, "thermal: socket bind failed.\n"); + return TRUE; + } + +-- +2.33.1 + diff --git a/0004-Prepare-to-handle-thermal-event.patch b/0004-Prepare-to-handle-thermal-event.patch deleted file mode 100644 index 2939930..0000000 --- a/0004-Prepare-to-handle-thermal-event.patch +++ /dev/null @@ -1,259 +0,0 @@ -From b66647ab757c580b2532c117bd345d1bad3b2bd5 Mon Sep 17 00:00:00 2001 -From: "Chang S. Bae" -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 ---- - 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 - - #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 - #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 -+ -+#include -+#include -+#include -+ -+#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 -+ -+#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 - diff --git a/0004-procinterrupts-Fix-IRQ-name-parsing-on-certain-arm64.patch b/0004-procinterrupts-Fix-IRQ-name-parsing-on-certain-arm64.patch new file mode 100644 index 0000000..dc95a20 --- /dev/null +++ b/0004-procinterrupts-Fix-IRQ-name-parsing-on-certain-arm64.patch @@ -0,0 +1,74 @@ +From bbcd9a42c3cec0935b960b7f2046f1fdfab4f7ef Mon Sep 17 00:00:00 2001 +From: Vignesh Raghavendra +Date: Wed, 7 Dec 2022 19:46:19 +0530 +Subject: [PATCH 04/13] procinterrupts: Fix IRQ name parsing on certain arm64 + SoC + +On arm64 SoCs like TI's K3 SoC and few other SoCs, IRQ names don't get +parsed correct due to which they end up being classified into wrong +class. Fix this by considering last token to contain IRQ name always. + +Eg.: /proc/interrupt + +cat /proc/interrupts + CPU0 CPU1 CPU2 CPU3 + 11: 7155 8882 7235 7791 GICv3 30 Level arch_timer + 14: 0 0 0 0 GICv3 23 Level arm-pmu + 15: 0 0 0 0 GICv3 208 Level 4b00000.spi + 16: 0 0 0 0 GICv3 209 Level 4b10000.spi +116: 0 0 0 0 MSI-INTA 1716234 Level 485c0100.dma-controller chan6 +134: 166 0 0 0 MSI-INTA 1970707 Level 8000000.ethernet-tx0 +224: 149 0 0 0 MSI-INTA 1971731 Level 8000000.ethernet + +W/o patch irqbalance -d +IRQ (11) guessed as class 0 +IRQ (14) guessed as class 0 +IRQ (15) guessed as class 0 +IRQ (16) guessed as class 0 +IRQ 485c0100.dma-controller chan6(116) guessed as class 0 +IRQ (134) guessed as class 0 +IRQ (224) guessed as class 0 + +W/ this patch +IRQ arch_timer(11) guessed as class 0 +IRQ arm-pmu(14) guessed as class 0 +IRQ 4b00000.spi(15) guessed as class 0 +IRQ 4b10000.spi(16) guessed as class 0 +IRQ 485c0100.dma-controller chan6(116) guessed as class 0 +IRQ 8000000.ethernet-tx0(134) guessed as class 5 +IRQ 8000000.ethernet(224) guessed as class 5 +IRQ 8000000.ethernet(257) guessed as class 5 +IRQ -davinci_gpio wl18xx(362) guessed as class + +Signed-off-by: Vignesh Raghavendra +--- + procinterrupts.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/procinterrupts.c b/procinterrupts.c +index e91b203..ec7a52b 100644 +--- a/procinterrupts.c ++++ b/procinterrupts.c +@@ -178,12 +178,14 @@ void init_irq_class_and_type(char *savedline, struct irq_info *info, int irq) + } + + #ifdef AARCH64 +- if (savedptr && 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) +- *tmp = 0; +- } ++ else ++ snprintf(irq_fullname, PATH_MAX, "%s", last_token); ++ ++ tmp = strchr(irq_fullname, '\n'); ++ if (tmp) ++ *tmp = 0; + #else + snprintf(irq_fullname, PATH_MAX, "%s", last_token); + #endif +-- +2.33.1 + diff --git a/0005-Implement-Netlink-helper-functions-to-subscribe-ther.patch b/0005-Implement-Netlink-helper-functions-to-subscribe-ther.patch deleted file mode 100644 index 60c0de7..0000000 --- a/0005-Implement-Netlink-helper-functions-to-subscribe-ther.patch +++ /dev/null @@ -1,392 +0,0 @@ -From c65cda183609116760c54f1c2ad458eef9f44d56 Mon Sep 17 00:00:00 2001 -From: "Chang S. Bae" -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 ---- - 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 - diff --git a/0005-irqbalance-fix-memory-leak-in-irq-hotplug-path.patch b/0005-irqbalance-fix-memory-leak-in-irq-hotplug-path.patch new file mode 100644 index 0000000..54fd138 --- /dev/null +++ b/0005-irqbalance-fix-memory-leak-in-irq-hotplug-path.patch @@ -0,0 +1,27 @@ +From ac4ba0667ba691985796f92e1a4b1932b03895a0 Mon Sep 17 00:00:00 2001 +From: qyu +Date: Fri, 20 Jan 2023 15:29:45 +0800 +Subject: [PATCH 05/13] irqbalance: fix memory leak in irq hotplug path + +tmp_info.name duplicate a name string in init_irq_class_and_type(), +free() it before return. +--- + classify.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/classify.c b/classify.c +index 4ea4b44..dac813c 100644 +--- a/classify.c ++++ b/classify.c +@@ -778,6 +778,8 @@ int proc_irq_hotplug(char *savedline, int irq, struct irq_info **pinfo) + /* secondly, init irq info by parse savedline */ + init_irq_class_and_type(savedline, &tmp_info, irq); + add_new_irq(NULL, &tmp_info); ++ free(tmp_info.name); ++ + *pinfo = get_irq_info(irq); + } + if (*pinfo == NULL) { +-- +2.33.1 + diff --git a/0006-Handle-thermal-events-to-mask-CPUs.patch b/0006-Handle-thermal-events-to-mask-CPUs.patch deleted file mode 100644 index 13ec85b..0000000 --- a/0006-Handle-thermal-events-to-mask-CPUs.patch +++ /dev/null @@ -1,242 +0,0 @@ -From 560291389e33db108d2fb6d954ef059f953c6e33 Mon Sep 17 00:00:00 2001 -From: "Chang S. Bae" -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 ---- - 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 - -+#include - #include - #include - #include -@@ -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 - diff --git a/0006-ui-do-not-force-black-background.patch b/0006-ui-do-not-force-black-background.patch new file mode 100644 index 0000000..f3ba54f --- /dev/null +++ b/0006-ui-do-not-force-black-background.patch @@ -0,0 +1,90 @@ +From f85c6c12d6fd9014d54cd0e3d791223723a29cdd Mon Sep 17 00:00:00 2001 +From: Alexander Monakov +Date: Sat, 21 Jan 2023 12:25:25 +0300 +Subject: [PATCH 06/13] ui: do not force black background + +Avoid repainting the entire terminal window with black background. +Instead, invoke 'use_default_colors' and use color index -1 to keep +user-configured background and foreground colors. + +For pairs 1, 2, 3, 8, 9, 10, simply change background index to -1. +Keep pair 4, but enable the 'bold' attribute for text to improve +legibility. For pair 5 (white on red) use default foreground, and +instead of pair 6 (red on white) use reverse of pair 5 with bold. + +This substantially improves legibility of the UI on a terminal +configured with a light background for me. +--- + ui/ui.c | 27 ++++++++++++++------------- + 1 file changed, 14 insertions(+), 13 deletions(-) + +diff --git a/ui/ui.c b/ui/ui.c +index 897371b..bee6868 100644 +--- a/ui/ui.c ++++ b/ui/ui.c +@@ -45,7 +45,7 @@ void show_footer() + while(strlen(footer) != (size_t)COLS - 1) { + snprintf(footer + strlen(footer), COLS - strlen(footer), " "); + } +- attrset(COLOR_PAIR(4)); ++ attrset(COLOR_PAIR(4) | A_BOLD); + mvprintw(LINES - 1, 0, "%s", footer); + } + +@@ -73,7 +73,7 @@ char * check_control_in_sleep_input(int max_len, int column_offest, int line_off + mvaddch(line_offset, column_offest + iteration, ' '); + } + move(line_offset, column_offest + iteration); +- attrset(COLOR_PAIR(6)); ++ attrset(COLOR_PAIR(5) | A_REVERSE | A_BOLD); + break; + case 27: + free(input_to); +@@ -93,7 +93,7 @@ int get_valid_sleep_input(int column_offest) + while(1) { + attrset(COLOR_PAIR(5)); + mvprintw(2, column_offest, " "); +- attrset(COLOR_PAIR(6)); ++ attrset(COLOR_PAIR(5) | A_REVERSE | A_BOLD); + refresh(); + move(2, column_offest); + curs_set(1); +@@ -115,7 +115,7 @@ int get_valid_sleep_input(int column_offest) + break; + } else { + new_sleep = setup.sleep; +- attrset(COLOR_PAIR(4)); ++ attrset(COLOR_PAIR(4) | A_BOLD); + mvprintw(LINES - 2, 1, + "Invalid input: %s ", + input); +@@ -705,16 +705,17 @@ void init() + echo(); + if(has_colors()) { + start_color(); +- init_pair(1, COLOR_RED, COLOR_BLACK); +- init_pair(2, COLOR_YELLOW, COLOR_BLACK); +- init_pair(3, COLOR_GREEN, COLOR_BLACK); ++ use_default_colors(); ++ init_pair(1, COLOR_RED, -1); ++ init_pair(2, COLOR_YELLOW, -1); ++ init_pair(3, COLOR_GREEN, -1); + init_pair(4, COLOR_WHITE, COLOR_BLUE); +- init_pair(5, COLOR_WHITE, COLOR_RED); +- init_pair(6, COLOR_RED, COLOR_WHITE); +- init_pair(7, COLOR_BLACK, COLOR_CYAN); +- init_pair(8, COLOR_BLUE, COLOR_BLACK); +- init_pair(9, COLOR_CYAN, COLOR_BLACK); +- init_pair(10, COLOR_MAGENTA, COLOR_BLACK); ++ init_pair(5, -1, COLOR_RED); ++ /* Pair 6 is unused */ ++ /* Pair 7 is unused */ ++ init_pair(8, COLOR_BLUE, -1); ++ init_pair(9, COLOR_CYAN, -1); ++ init_pair(10, COLOR_MAGENTA, -1); + } + + offset = 0; +-- +2.33.1 + diff --git a/0007-add-keep_going-check-to-prevent-irqbalance-from-fail.patch b/0007-add-keep_going-check-to-prevent-irqbalance-from-fail.patch deleted file mode 100644 index c6f2995..0000000 --- a/0007-add-keep_going-check-to-prevent-irqbalance-from-fail.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 028082a6a1ff650d5cdf796ac55ac26a3874372a Mon Sep 17 00:00:00 2001 -From: Liu Chao -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 ---- - 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 - diff --git a/0007-thermal-Fix-log-message-for-perf-and-efficiency.patch b/0007-thermal-Fix-log-message-for-perf-and-efficiency.patch new file mode 100644 index 0000000..e4df8be --- /dev/null +++ b/0007-thermal-Fix-log-message-for-perf-and-efficiency.patch @@ -0,0 +1,30 @@ +From c91bdf66e1156db0e8171a72a15b6d63148357e4 Mon Sep 17 00:00:00 2001 +From: Srinivas Pandruvada +Date: Tue, 24 Jan 2023 11:47:44 -0800 +Subject: [PATCH 07/13] thermal: Fix log message for perf and efficiency + +In the log message perf and efficiency fields are swapped. So, showing +perf field as efficiency and vice versa. Fix this to show correct +log message. + +Signed-off-by: Srinivas Pandruvada +--- + thermal.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/thermal.c b/thermal.c +index 7cd0807..a45568a 100644 +--- a/thermal.c ++++ b/thermal.c +@@ -407,7 +407,7 @@ static int handle_thermal_event(struct nl_msg *msg, void *arg __attribute__((unu + 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", ++ log(TO_ALL, LOG_DEBUG, "thermal: event - CPU %d, perf %d, efficiency %d.\n", + cur_cpuidx, event_data[INDEX_PERF], event_data[INDEX_EFFI]); + } + +-- +2.33.1 + diff --git a/0008-fix-CPU-number-condition-in-service-file.patch b/0008-fix-CPU-number-condition-in-service-file.patch new file mode 100644 index 0000000..360d064 --- /dev/null +++ b/0008-fix-CPU-number-condition-in-service-file.patch @@ -0,0 +1,25 @@ +From f166b00e732033bf0b6ea86cedc2dcea7f6c35ba Mon Sep 17 00:00:00 2001 +From: middlingphys +Date: Thu, 2 Feb 2023 16:17:38 +0900 +Subject: [PATCH 08/13] fix CPU number condition in service file + +--- + misc/irqbalance.service | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/misc/irqbalance.service b/misc/irqbalance.service +index 8544f66..a2d919c 100644 +--- a/misc/irqbalance.service ++++ b/misc/irqbalance.service +@@ -3,7 +3,7 @@ Description=irqbalance daemon + Documentation=man:irqbalance(1) + Documentation=https://github.com/Irqbalance/irqbalance + ConditionVirtualization=!container +-ConditionCPUs=>1 ++ConditionCPUs>1 + + [Service] + EnvironmentFile=-/usr/lib/irqbalance/defaults.env +-- +2.33.1 + diff --git a/0008-parse_proc_interrupts-fix-parsing-interrupt-counts.patch b/0008-parse_proc_interrupts-fix-parsing-interrupt-counts.patch deleted file mode 100644 index 3ce7467..0000000 --- a/0008-parse_proc_interrupts-fix-parsing-interrupt-counts.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0a82dddbaf5702caded0d0d83a6eafaca743254d Mon Sep 17 00:00:00 2001 -From: Andreas Schwab -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 - diff --git a/0009-Issue-259-select-NL_SKIP-NL_STOP-based-on-error.patch b/0009-Issue-259-select-NL_SKIP-NL_STOP-based-on-error.patch new file mode 100644 index 0000000..aaf14ba --- /dev/null +++ b/0009-Issue-259-select-NL_SKIP-NL_STOP-based-on-error.patch @@ -0,0 +1,35 @@ +From 0e9acb608588aaeb998bdf5f47019ce7a61cc81e Mon Sep 17 00:00:00 2001 +From: Neil Horman +Date: Thu, 9 Mar 2023 07:54:47 -0500 +Subject: [PATCH 09/13] Issue 259: select NL_SKIP / NL_STOP based on error + +the handle_error function for thermal should skip EINTR errors, but stop +for everything else +--- + thermal.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/thermal.c b/thermal.c +index a45568a..035e0ad 100644 +--- a/thermal.c ++++ b/thermal.c +@@ -190,12 +190,14 @@ static int handle_groupid(struct nl_msg *msg, void *arg) + static int handle_error(struct sockaddr_nl *sk_addr __attribute__((unused)), + struct nlmsgerr *err, void *arg) + { +- if (arg) { ++ int rc = (err->error == NLE_INTR) ? NL_SKIP : NL_STOP; ++ ++ if (arg && err->error != NLE_INTR) { + log(TO_ALL, LOG_INFO, "thermal: received a netlink error (%s).\n", + nl_geterror(err->error)); + *((int *)arg) = err->error; + } +- return NL_SKIP; ++ return rc; + } + + static int handle_end(struct nl_msg *msg __attribute__((unused)), void *arg) +-- +2.33.1 + diff --git a/0009-irqbalance-ui-move-ASSIGNED-TO-CPUS-to-the-last-colu.patch b/0009-irqbalance-ui-move-ASSIGNED-TO-CPUS-to-the-last-colu.patch deleted file mode 100644 index 2c41cda..0000000 --- a/0009-irqbalance-ui-move-ASSIGNED-TO-CPUS-to-the-last-colu.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 7f1caca47aee32084c319db07d9a236684b818a3 Mon Sep 17 00:00:00 2001 -From: Liu Chao -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 ---- - 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 - diff --git a/0010-Revert-Fix-CPU-number-condition-in-service-file.patch b/0010-Revert-Fix-CPU-number-condition-in-service-file.patch new file mode 100644 index 0000000..e6ea998 --- /dev/null +++ b/0010-Revert-Fix-CPU-number-condition-in-service-file.patch @@ -0,0 +1,25 @@ +From ea1e9a7a9105c834302ce7c72e9b4b1c90ec7866 Mon Sep 17 00:00:00 2001 +From: middlingphys <38708390+middlingphys@users.noreply.github.com> +Date: Wed, 15 Mar 2023 22:33:22 +0900 +Subject: [PATCH 10/13] Revert "Fix CPU number condition in service file" + +--- + misc/irqbalance.service | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/misc/irqbalance.service b/misc/irqbalance.service +index a2d919c..8544f66 100644 +--- a/misc/irqbalance.service ++++ b/misc/irqbalance.service +@@ -3,7 +3,7 @@ Description=irqbalance daemon + Documentation=man:irqbalance(1) + Documentation=https://github.com/Irqbalance/irqbalance + ConditionVirtualization=!container +-ConditionCPUs>1 ++ConditionCPUs=>1 + + [Service] + EnvironmentFile=-/usr/lib/irqbalance/defaults.env +-- +2.33.1 + diff --git a/0010-irqbalance-ui-can-t-change-window-when-in-editing-st.patch b/0010-irqbalance-ui-can-t-change-window-when-in-editing-st.patch deleted file mode 100644 index d3bb969..0000000 --- a/0010-irqbalance-ui-can-t-change-window-when-in-editing-st.patch +++ /dev/null @@ -1,347 +0,0 @@ -From b65faa2b658e3cf4edf6d39e4bb1e103a47ac0de Mon Sep 17 00:00:00 2001 -From: Liu Chao -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=) 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=, argv=) at ui/irqbalance-ui.c:445 - -Signed-off-by: Liu Chao ---- - 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 for changing sleep setup, 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 for changing sleep setup, 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 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 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 for changing sleep setup, 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 for changing sleep setup, 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 for changing sleep setup, 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 - diff --git a/0011-Fix-signedness-of-error-handling.patch b/0011-Fix-signedness-of-error-handling.patch new file mode 100644 index 0000000..2e58bbe --- /dev/null +++ b/0011-Fix-signedness-of-error-handling.patch @@ -0,0 +1,28 @@ +From 3920e0687deff04c52ac73ebdbd950c13ef1f77e Mon Sep 17 00:00:00 2001 +From: Neil Horman +Date: Wed, 22 Mar 2023 17:30:01 -0400 +Subject: [PATCH 11/13] Fix signedness of error handling + +--- + thermal.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/thermal.c b/thermal.c +index 035e0ad..902d7e9 100644 +--- a/thermal.c ++++ b/thermal.c +@@ -190,9 +190,9 @@ static int handle_groupid(struct nl_msg *msg, void *arg) + static int handle_error(struct sockaddr_nl *sk_addr __attribute__((unused)), + struct nlmsgerr *err, void *arg) + { +- int rc = (err->error == NLE_INTR) ? NL_SKIP : NL_STOP; ++ int rc = (err->error == -NLE_INTR) ? NL_SKIP : NL_STOP; + +- if (arg && err->error != NLE_INTR) { ++ if (arg && err->error != -NLE_INTR) { + log(TO_ALL, LOG_INFO, "thermal: received a netlink error (%s).\n", + nl_geterror(err->error)); + *((int *)arg) = err->error; +-- +2.33.1 + diff --git a/0011-fix-memory-leak-in-ui-ui.c.patch b/0011-fix-memory-leak-in-ui-ui.c.patch deleted file mode 100644 index 908aaf5..0000000 --- a/0011-fix-memory-leak-in-ui-ui.c.patch +++ /dev/null @@ -1,47 +0,0 @@ -From a61b382805961934c6425f19a762a6ab99884c24 Mon Sep 17 00:00:00 2001 -From: Liu Chao -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 ---- - 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 - diff --git a/0012-Fix-it-so-we-actually-stop-when-we-hit-an-interrupt-.patch b/0012-Fix-it-so-we-actually-stop-when-we-hit-an-interrupt-.patch new file mode 100644 index 0000000..6f64e95 --- /dev/null +++ b/0012-Fix-it-so-we-actually-stop-when-we-hit-an-interrupt-.patch @@ -0,0 +1,26 @@ +From 0e051271bbf1cd87802628f3167faafe7218606f Mon Sep 17 00:00:00 2001 +From: Neil Horman +Date: Sat, 1 Apr 2023 13:07:05 -0400 +Subject: [PATCH 12/13] Fix it so we actually stop when we hit an interrupt + condition + +--- + thermal.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/thermal.c b/thermal.c +index 902d7e9..ffff9bd 100644 +--- a/thermal.c ++++ b/thermal.c +@@ -190,7 +190,7 @@ static int handle_groupid(struct nl_msg *msg, void *arg) + static int handle_error(struct sockaddr_nl *sk_addr __attribute__((unused)), + struct nlmsgerr *err, void *arg) + { +- int rc = (err->error == -NLE_INTR) ? NL_SKIP : NL_STOP; ++ int rc = (err->error == -NLE_INTR) ? NL_STOP : NL_SKIP; + + if (arg && err->error != -NLE_INTR) { + log(TO_ALL, LOG_INFO, "thermal: received a netlink error (%s).\n", +-- +2.33.1 + diff --git a/0012-irqbalance-ui-support-scroll-under-tui-mode-of-irqba.patch b/0012-irqbalance-ui-support-scroll-under-tui-mode-of-irqba.patch deleted file mode 100644 index 65d1578..0000000 --- a/0012-irqbalance-ui-support-scroll-under-tui-mode-of-irqba.patch +++ /dev/null @@ -1,583 +0,0 @@ -From db7dc03388a20ba2d873a81c3e14b933e2b09551 Mon Sep 17 00:00:00 2001 -From: Liu Chao -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 ---- - 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 - #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 - diff --git a/0013-irqbalance-ui-print-cpulist-in-SETUP-IRQS.patch b/0013-irqbalance-ui-print-cpulist-in-SETUP-IRQS.patch deleted file mode 100644 index a625222..0000000 --- a/0013-irqbalance-ui-print-cpulist-in-SETUP-IRQS.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 577796abe7337c8df446c082688816ec22804876 Mon Sep 17 00:00:00 2001 -From: Liu Chao -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 ---- - 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 - diff --git a/0013-procinterrupts-fix-initialisation-of-regex_t-struct.patch b/0013-procinterrupts-fix-initialisation-of-regex_t-struct.patch new file mode 100644 index 0000000..a9c810f --- /dev/null +++ b/0013-procinterrupts-fix-initialisation-of-regex_t-struct.patch @@ -0,0 +1,37 @@ +From d02ec54e635da8da8439d35b0523ce2b5d5dbae1 Mon Sep 17 00:00:00 2001 +From: psykose +Date: Wed, 19 Apr 2023 19:31:19 +0000 +Subject: [PATCH 13/13] procinterrupts: fix initialisation of regex_t struct + +{NULL} utilises the null pointer, but this is not valid, because null is a pointer: + +procinterrupts.c:110:29: error: initialization of 'long unsigned int' from 'void *' makes integer from pointer without a cast [-Werror=int-conversion] + 110 | { "eth.*" ,{NULL} ,NULL, IRQ_TYPE_LEGACY, IRQ_GBETH }, + +0-initialisation should be done with '0' instead of a pointer. +--- + procinterrupts.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/procinterrupts.c b/procinterrupts.c +index ec7a52b..dfa95c6 100644 +--- a/procinterrupts.c ++++ b/procinterrupts.c +@@ -107,10 +107,10 @@ static void guess_arm_irq_hints(char *name, struct irq_info *info) + static int compiled = 0; + /* Note: Last entry is a catchall */ + static struct irq_match matches[] = { +- { "eth.*" ,{NULL} ,NULL, IRQ_TYPE_LEGACY, IRQ_GBETH }, +- { "[A-Z0-9]{4}[0-9a-f]{4}", {NULL} ,check_platform_device, IRQ_TYPE_LEGACY, IRQ_OTHER}, +- { "PNP[0-9a-f]{4}", {NULL} ,check_platform_device, IRQ_TYPE_LEGACY, IRQ_OTHER}, +- { ".*", {NULL}, NULL, IRQ_TYPE_LEGACY, IRQ_OTHER}, ++ { "eth.*" , {0},NULL, IRQ_TYPE_LEGACY, IRQ_GBETH }, ++ { "[A-Z0-9]{4}[0-9a-f]{4}", {0}, check_platform_device, IRQ_TYPE_LEGACY, IRQ_OTHER}, ++ { "PNP[0-9a-f]{4}", {0}, check_platform_device, IRQ_TYPE_LEGACY, IRQ_OTHER}, ++ { ".*", {0}, NULL, IRQ_TYPE_LEGACY, IRQ_OTHER}, + {NULL}, + }; + +-- +2.33.1 + diff --git a/0014-Improve-documentation-and-logging-for-banned-cpus.patch b/0014-Improve-documentation-and-logging-for-banned-cpus.patch deleted file mode 100644 index ac690d9..0000000 --- a/0014-Improve-documentation-and-logging-for-banned-cpus.patch +++ /dev/null @@ -1,72 +0,0 @@ -From cfb15f0bb95ebfd4357708eae42febe9f2121fba Mon Sep 17 00:00:00 2001 -From: Tao Liu -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 ---- - 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 - diff --git a/irqbalance.spec b/irqbalance.spec index 64c2276..cb5b857 100644 --- a/irqbalance.spec +++ b/irqbalance.spec @@ -1,6 +1,6 @@ Name: irqbalance -Version: 1.9.0 -Release: 4%{?dist} +Version: 1.9.2 +Release: 1%{?dist} Epoch: 2 Summary: IRQ balancing daemon @@ -24,22 +24,20 @@ Requires: numactl-libs ExcludeArch: s390 s390x Patch1: irqbalance-1.8.0-env-file-path.patch -Patch2: 0001-get-irq-module-relationship-from-sys-bus-pci-driver.patch -Patch3: 0002-check-whether-savedptr-is-NULL-before-invoking-strle.patch -Patch4: 0003-add-meson.patch -Patch5: 0004-Prepare-to-handle-thermal-event.patch -Patch6: 0005-Implement-Netlink-helper-functions-to-subscribe-ther.patch -Patch7: 0006-Handle-thermal-events-to-mask-CPUs.patch -Patch8: 0007-add-keep_going-check-to-prevent-irqbalance-from-fail.patch -Patch9: 0008-parse_proc_interrupts-fix-parsing-interrupt-counts.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 -Patch17: 0001-revert-Confine-irqbalance-to-systems-where-it-is-useful.patch +Patch2: 0001-optimize-getting-cpu-number.patch +Patch3: 0002-allow-AF_NETLINK-in-the-systemd-service-restrictions.patch +Patch4: 0003-thermal-Fix-the-warning-message.patch +Patch5: 0004-procinterrupts-Fix-IRQ-name-parsing-on-certain-arm64.patch +Patch6: 0005-irqbalance-fix-memory-leak-in-irq-hotplug-path.patch +Patch7: 0006-ui-do-not-force-black-background.patch +Patch8: 0007-thermal-Fix-log-message-for-perf-and-efficiency.patch +Patch9: 0008-fix-CPU-number-condition-in-service-file.patch +Patch10: 0009-Issue-259-select-NL_SKIP-NL_STOP-based-on-error.patch +Patch11: 0010-Revert-Fix-CPU-number-condition-in-service-file.patch +Patch12: 0011-Fix-signedness-of-error-handling.patch +Patch13: 0012-Fix-it-so-we-actually-stop-when-we-hit-an-interrupt-.patch +Patch14: 0013-procinterrupts-fix-initialisation-of-regex_t-struct.patch +Patch15: 0001-revert-Confine-irqbalance-to-systems-where-it-is-useful.patch %description irqbalance is a daemon that evenly distributes IRQ load across @@ -62,8 +60,6 @@ multiple CPUs for enhanced performance. %patch13 -p1 %patch14 -p1 %patch15 -p1 -%patch16 -p1 -%patch17 -p1 %build ./autogen.sh @@ -106,6 +102,9 @@ fi /sbin/chkconfig --del irqbalance >/dev/null 2>&1 || : %changelog +* Thu May 18 2023 Tao Liu - 2:1.9.2-1 +- Rebase to latest upstream commit (184c95029e) + * Tue Jul 19 2022 Tao Liu - 2:1.9.0-4 - revert Confine irqbalance to systems where it is useful (bz2115230) diff --git a/sources b/sources index c56e2e2..442b3fe 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (irqbalance-1.9.0.tar.gz) = 878977da5eff18e53bdceeaa4aca952f73ba8b03eb028cf176816af971ffc65f0b1f1bb3a68e3a2502491895cc2b9438652dc97d5696232bb2f64860109e9a24 +SHA512 (irqbalance-1.9.2.tar.gz) = d0fb157fbfc096fa9cfb4562e51fd4c3f4fa8788f72377c58b27df67c70073b787bba05e39809dcbe17532bb5b8e74b6d27c5e5b3d9af09bc9ce1a9b6aab9378