import irqbalance-1.9.0-3.el8
This commit is contained in:
		
							parent
							
								
									fa542ab747
								
							
						
					
					
						commit
						b30b5cd7fa
					
				
							
								
								
									
										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 | ||||
| Version:        1.4.0 | ||||
| Release:        6%{?dist} | ||||
| Version:        1.9.0 | ||||
| Release:        3%{?dist} | ||||
| Epoch:          2 | ||||
| Summary:        IRQ balancing daemon | ||||
| 
 | ||||
| @ -23,16 +23,22 @@ Requires: numactl-libs | ||||
| 
 | ||||
| ExcludeArch: s390 s390x | ||||
| 
 | ||||
| Patch1: irqbalance-1.0.4-env-file-path.patch | ||||
| Patch2: irqbalance-1.4.0-Fix-several-memleak-problems-found-by-covscan.patch | ||||
| Patch3: irqbalance-1.4.0-Fix-an-possible-overflow-error.patch | ||||
| Patch4: irqbalance-1.5.0-Don-t-leak-socket-fd-on-connection-error.patch | ||||
| Patch5: irqbalance-1.4.0-procinterrupts-check-xen-dyn-event-more-flexible.patch | ||||
| Patch6: irqbalance-1.5.0-Update-document-and-remove-dead-options.patch | ||||
| Patch7: irqbalance-1.4.0-Fix-ambiguous-parsing-of-node-entries-in-sys.patch | ||||
| Patch8: irqbalance-1.5.0-Refine-document-about-IRQBALANCE_BANNED_CPUS.patch | ||||
| Patch9: irqbalance-1.7.0-Add-some-examples-for-IRQBALANCE_BANNED_CPUS.patch | ||||
| Patch10: irqbalance-1.7.0-Also-fetch-node-info-for-non-PCI-devices.patch | ||||
| 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 | ||||
| 
 | ||||
| %description | ||||
| irqbalance is a daemon that evenly distributes IRQ load across | ||||
| @ -50,6 +56,12 @@ multiple CPUs for enhanced performance. | ||||
| %patch8 -p1 | ||||
| %patch9 -p1 | ||||
| %patch10 -p1 | ||||
| %patch11 -p1 | ||||
| %patch12 -p1 | ||||
| %patch13 -p1 | ||||
| %patch14 -p1 | ||||
| %patch15 -p1 | ||||
| %patch16 -p1 | ||||
| 
 | ||||
| %build | ||||
| ./autogen.sh | ||||
| @ -58,6 +70,7 @@ CFLAGS="%{optflags}" make %{?_smp_mflags} | ||||
| 
 | ||||
| %install | ||||
| 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 %{SOURCE1} %{buildroot}%{_sysconfdir}/sysconfig/%{name} | ||||
| 
 | ||||
| @ -70,6 +83,7 @@ make check | ||||
| %files | ||||
| %doc COPYING AUTHORS | ||||
| %{_sbindir}/irqbalance | ||||
| %{_sbindir}/irqbalance-ui | ||||
| %{_unitdir}/irqbalance.service | ||||
| %{_mandir}/man1/* | ||||
| %config(noreplace) %{_sysconfdir}/sysconfig/irqbalance | ||||
| @ -90,6 +104,15 @@ fi | ||||
| /sbin/chkconfig --del irqbalance >/dev/null 2>&1 || : | ||||
| 
 | ||||
| %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 | ||||
| - Also fetch node info for non-PCI devices | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user