Hello community, here is the log from the commit of package irqbalance for openSUSE:Factory checked in at 2018-10-11 11:40:01 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/irqbalance (Old) and /work/SRC/openSUSE:Factory/.irqbalance.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "irqbalance" Thu Oct 11 11:40:01 2018 rev:50 rq:639963 version:1.4.0 Changes: -------- --- /work/SRC/openSUSE:Factory/irqbalance/irqbalance.changes 2017-11-30 12:41:18.802814379 +0100 +++ /work/SRC/openSUSE:Factory/.irqbalance.new/irqbalance.changes 2018-10-11 11:40:16.175182611 +0200 @@ -1,0 +2,42 @@ +Thu Oct 4 09:51:31 UTC 2018 - tr...@suse.de + +- Allow compilation with SLE-12 and before by: + * removing -std=C99 Latest compiler version does not complain + anymore, SLE12 SPx and before did. + * Fix a possible buffer overflow compiler warning +A fix_buffer_overflow_compiler.patch + +------------------------------------------------------------------- +Mon Oct 1 09:12:52 UTC 2018 - egotth...@suse.com + +- Removed aarch64-compile-fixes.patch because it is mainline now. + +- Update to version 1.4.0: + * Fixed an erroneous calculation of min_load that restricted candidates to a + subset of objects + * Fixed powerpc hotplug detection + * Cleaned up syslog target dependency + * Added some self test infrastructure (via make check) + +- Update to version 1.3.0 + * New features in this release: + optimization of platform device irq detection + Added sample udev rules to trigger irq rescans on device add/remove + Made irqbalance ui an optional compile component + Added support for Intel CoD + Add -v | --version option to command line + * Bug fixes in this release: + Misc compiler warning fixes and spelling errors + Compilation error fix on aarch64 + Compilation error fix when using clang in c99 mode + Unused variable cleanup + Lots of memory leak cleanup in irqbalance-ui + Prevent irqbalance from running in a container + Fix irq affinity assignment in some cases to wrong numa node + Fix oneshot mode + exclude legacy irq 255 + * Deprecations: + without-glib2 is removed, we just need it enough that we can't dummy it up + anymore + +------------------------------------------------------------------- Old: ---- aarch64-compile-fixes.patch v1.2.0.tar.gz New: ---- _service _servicedata fix_buffer_overflow_compiler.patch v1.4.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ irqbalance.spec ++++++ --- /var/tmp/diff_new_pack.WQGlvA/_old 2018-10-11 11:40:19.447178445 +0200 +++ /var/tmp/diff_new_pack.WQGlvA/_new 2018-10-11 11:40:19.487178395 +0200 @@ -1,7 +1,7 @@ # # spec file for package irqbalance # -# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,31 +18,31 @@ #Compat macro for new _fillupdir macro introduced in Nov 2017 %if ! %{defined _fillupdir} - %define _fillupdir /var/adm/fillup-templates + %define _fillupdir %{_localstatedir}/adm/fillup-templates %endif - Name: irqbalance -Version: 1.2.0 +Version: 1.4.0 Release: 0 Summary: Balance IRQs on SMP Machines -License: GPL-2.0+ +License: GPL-2.0-or-later Group: System/Daemons Url: https://github.com/Irqbalance/irqbalance Source: https://github.com/Irqbalance/irqbalance/archive/v%{version}.tar.gz Source3: sysconfig.irqbalance -Patch2: Set-fd-limit.patch -Patch3: install-man-pages.patch -Patch4: aarch64-compile-fixes.patch +Patch1: Set-fd-limit.patch +Patch2: install-man-pages.patch +Patch3: fix_buffer_overflow_compiler.patch BuildRequires: libcap-ng-devel BuildRequires: libtool BuildRequires: ncurses-devel +BuildRequires: pkgconfig BuildRequires: systemd-rpm-macros BuildRequires: pkgconfig(glib-2.0) Requires(pre): coreutils Requires(pre): fillup ExcludeArch: s390 s390x %{?systemd_requires} -%ifnarch %arm +%ifnarch %{arm} BuildRequires: libnuma-devel %endif @@ -52,14 +52,12 @@ %prep %setup -q -%patch2 -p1 -%patch3 -%patch4 -p1 +%autopatch -p1 %build NOCONFIGURE=1 ./autogen.sh %configure -make %{?_smp_mflags} LDFLAGS="-Wl,-z,relro,-z,now" CFLAGS="%{optflags} -fPIE -pie -std=c99 $(ncurses6-config --cflags)" LDFLAGS="$(ncurses6-config --libs)" +make %{?_smp_mflags} LDFLAGS="-Wl,-z,relro,-z,now" CFLAGS="%{optflags} -fPIE -pie $(ncurses6-config --cflags)" LDFLAGS="$(ncurses6-config --libs)" cp %{SOURCE3} . %install @@ -87,12 +85,11 @@ %service_del_postun irqbalance.service %files -%defattr(-,root,root,-) %{_sbindir}/irqbalance %{_sbindir}/irqbalance-ui %{_sbindir}/rcirqbalance %{_unitdir}/irqbalance.service -%{_mandir}/man1/irqbalance.1.gz +%{_mandir}/man1/irqbalance.1%{?ext_man} %{_fillupdir}/sysconfig.irqbalance %changelog ++++++ Set-fd-limit.patch ++++++ --- /var/tmp/diff_new_pack.WQGlvA/_old 2018-10-11 11:40:19.647178191 +0200 +++ /var/tmp/diff_new_pack.WQGlvA/_new 2018-10-11 11:40:19.647178191 +0200 @@ -1,7 +1,8 @@ -diff -ur irqbalance-1.0.7.orig/misc/irqbalance.service irqbalance-1.0.7/misc/irqbalance.service ---- irqbalance-1.0.7.orig/misc/irqbalance.service 2013-09-25 13:32:23.000000000 +0200 -+++ irqbalance-1.0.7/misc/irqbalance.service 2016-10-14 15:30:11.873319592 +0200 -@@ -5,6 +5,7 @@ +Index: irqbalance-1.4.0/misc/irqbalance.service +=================================================================== +--- irqbalance-1.4.0.orig/misc/irqbalance.service ++++ irqbalance-1.4.0/misc/irqbalance.service +@@ -5,6 +5,7 @@ ConditionVirtualization=!container [Service] EnvironmentFile=/path/to/irqbalance.env ExecStart=/usr/sbin/irqbalance --foreground $IRQBALANCE_ARGS ++++++ _service ++++++ <services> <service mode="disabled" name="tar_scm"> <param name="url">https://github.com/Irqbalance/irqbalance.git</param> <param name="scm">git</param> <param name="changesgenerate">enable</param> <param name="filename">irqbalance</param> <param name="versionformat">1.4.0</param> </service> </services> ++++++ _servicedata ++++++ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/Irqbalance/irqbalance.git</param> <param name="changesrevision">5a1c7b89f7c9b928f6307ea50fc46fd7ce0cd061</param></service></servicedata>++++++ fix_buffer_overflow_compiler.patch ++++++ From: Thomas Renninger <tr...@suse.de> Fix compiler warning Avoid: In function ‘snprintf’, inlined from ‘sock_handle’ at irqbalance.c:457:12: /usr/include/bits/stdio2.h:64:3: warning: call to __builtin___snprintf_chk will always overflow destination buffer [enabled by default] return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, Index: irqbalance-1.4.0/irqbalance.c =================================================================== --- irqbalance-1.4.0.orig/irqbalance.c 2018-05-14 21:06:54.000000000 +0200 +++ irqbalance-1.4.0/irqbalance.c 2018-10-04 14:16:54.982803686 +0200 @@ -454,7 +454,7 @@ gboolean sock_handle(gint fd, GIOConditi if (!strncmp(buff, "setup", strlen("setup"))) { char banned[512]; char *setup = calloc(strlen("SLEEP ") + 11 +1, 1); - snprintf(setup, 2048, "SLEEP %d ", sleep_interval); + sprintf(setup, "SLEEP %d ", sleep_interval); if(g_list_length(cl_banned_irqs) > 0) { for_each_irq(cl_banned_irqs, get_irq_data, setup); } ++++++ install-man-pages.patch ++++++ --- /var/tmp/diff_new_pack.WQGlvA/_old 2018-10-11 11:40:20.075177646 +0200 +++ /var/tmp/diff_new_pack.WQGlvA/_new 2018-10-11 11:40:20.087177631 +0200 @@ -1,9 +1,11 @@ ---- Makefile.am -+++ Makefile.am -@@ -36,7 +36,7 @@ - irqbalance_ui_SOURCES = $(UI_DIR)/helpers.c $(UI_DIR)/irqbalance-ui.c \ - $(UI_DIR)/ui.c - irqbalance_ui_LDADD = $(GLIB_LIBS) $(CURSES_LIBS) +Index: irqbalance-1.4.0/Makefile.am +=================================================================== +--- irqbalance-1.4.0.orig/Makefile.am ++++ irqbalance-1.4.0/Makefile.am +@@ -46,7 +46,7 @@ irqbalance_ui_SOURCES = $(UI_DIR)/helper + irqbalance_ui_LDADD = $(GLIB2_LIBS) $(CURSES_LIBS) + endif + -dist_man_MANS = irqbalance.1 +man_MANS = irqbalance.1 ++++++ v1.2.0.tar.gz -> v1.4.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/irqbalance-1.2.0/.travis.yml new/irqbalance-1.4.0/.travis.yml --- old/irqbalance-1.2.0/.travis.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/irqbalance-1.4.0/.travis.yml 2018-05-14 21:06:54.000000000 +0200 @@ -0,0 +1,11 @@ +language: c +dist: trusty + +compiler: + - clang + - gcc + +script: ./autogen.sh && ./configure && make && make check + +after_script: cat ./tests/runoneshot.sh.log + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/irqbalance-1.2.0/Makefile.am new/irqbalance-1.4.0/Makefile.am --- old/irqbalance-1.2.0/Makefile.am 2017-01-09 14:41:02.000000000 +0100 +++ new/irqbalance-1.4.0/Makefile.am 2018-05-14 21:06:54.000000000 +0200 @@ -24,18 +24,28 @@ ACLOCAL_AMFLAGS = -I m4 EXTRA_DIST = COPYING autogen.sh misc/irqbalance.service misc/irqbalance.env +SUBDIRS = tests + UI_DIR = ui -AM_CFLAGS = $(LIBCAP_NG_CFLAGS) $(GLIB_CFLAGS) +AM_CFLAGS = $(LIBCAP_NG_CFLAGS) $(GLIB2_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 -sbin_PROGRAMS = irqbalance irqbalance-ui +sbin_PROGRAMS = irqbalance + +if IRQBALANCEUI +sbin_PROGRAMS += irqbalance-ui +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) $(GLIB_LIBS) +irqbalance_LDADD = $(LIBCAP_NG_LIBS) $(GLIB2_LIBS) +if IRQBALANCEUI irqbalance_ui_SOURCES = $(UI_DIR)/helpers.c $(UI_DIR)/irqbalance-ui.c \ $(UI_DIR)/ui.c -irqbalance_ui_LDADD = $(GLIB_LIBS) $(CURSES_LIBS) +irqbalance_ui_LDADD = $(GLIB2_LIBS) $(CURSES_LIBS) +endif + dist_man_MANS = irqbalance.1 CONFIG_CLEAN_FILES = debug*.list config/* @@ -43,6 +53,3 @@ rm -rf autom4te*.cache rm -f *.rej *.orig *~ -if LOCAL_GLIB -SUBDIRS = glib-local -endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/irqbalance-1.2.0/README.md new/irqbalance-1.4.0/README.md --- old/irqbalance-1.2.0/README.md 2017-01-09 14:41:02.000000000 +0100 +++ new/irqbalance-1.4.0/README.md 2018-05-14 21:06:54.000000000 +0200 @@ -7,7 +7,7 @@ spread as much as possible over an entire processor set, while minimizing cache miss rates for irq handlers. -## Building and Installing +## Building and Installing [![Build Status](https://travis-ci.org/Irqbalance/irqbalance.svg?branch=master)](https://travis-ci.org/Irqbalance/irqbalance) ```bash ./autogen.sh diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/irqbalance-1.2.0/classify.c new/irqbalance-1.4.0/classify.c --- old/irqbalance-1.2.0/classify.c 2017-01-09 14:41:02.000000000 +0100 +++ new/irqbalance-1.4.0/classify.c 2018-05-14 21:06:54.000000000 +0200 @@ -655,8 +655,13 @@ /* * no pci device has irq 0 + * irq 255 is invalid on x86/x64 architectures */ +#if defined(__i386__) || defined(__x86_64__) + if (irqnum && irqnum != 255) { +#else if (irqnum) { +#endif new = get_irq_info(irqnum); if (new) goto done; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/irqbalance-1.2.0/configure.ac new/irqbalance-1.4.0/configure.ac --- old/irqbalance-1.2.0/configure.ac 2017-01-09 14:41:02.000000000 +0100 +++ new/irqbalance-1.4.0/configure.ac 2018-05-14 21:06:54.000000000 +0200 @@ -1,4 +1,4 @@ -AC_INIT(irqbalance,1.2.0) +AC_INIT(irqbalance,1.3.0) AC_PREREQ(2.12)dnl AM_CONFIG_HEADER(config.h) @@ -26,12 +26,27 @@ AC_CHECK_LIB(numa, numa_available) AC_CHECK_LIB(m, floor) -AC_CHECK_LIB(curses, mvprintw) +PKG_CHECK_MODULES([GLIB2], [glib-2.0], [], [AC_MSG_ERROR([glib-2.0 is required])]) + +PKG_CHECK_MODULES([NCURSESW], [ncursesw], [has_ncursesw=yes], [AC_CHECK_LIB(curses, mvprintw)]) +AS_IF([test "x$has_ncursesw" = "xyes"], [ + AC_SUBST([NCURSESW_CFLAGS]) + AC_SUBST([NCURSESW_LIBS]) + LIBS="$LIBS $NCURSESW_LIBS" + AC_SUBST([LIBS]) +]) AC_C_CONST AC_C_INLINE AM_PROG_CC_C_O +AC_ARG_WITH([irqbalance-ui], + [AC_HELP_STRING([--without-irqbalance-ui], + [Dont build the irqbalance ui component])], + [with_irqbalanceui=false], [with_irqbalanceui=true]) + +AM_CONDITIONAL([IRQBALANCEUI], [test x$with_irqbalanceui = xtrue]) + AC_ARG_WITH([systemd], [ AS_HELP_STRING([--with-systemd],[Add systemd-lib support])] ) @@ -46,36 +61,6 @@ AC_CHECK_LIB([systemd], [sd_journal_print]) ]) -AC_ARG_WITH([glib2], - [AS_HELP_STRING([--without-glib2], - [Don't use system glib2 library. Use local implementation instead.])], - [], - [with_glib2=check]) - -local_glib2= -AS_IF( - [test "x$with_glib2" = xyes], - [PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.28])], - - [test "x$with_glib2" = xno], - [local_glib2="yes"], - - [PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.28], [], [local_glib2="yes"])] -) - -AS_IF( - [test "x$local_glib2" = xyes], - [ - GLIB_CFLAGS=-I./glib-local - GLIB_LIBS=glib-local/libglib.a - AC_SUBST(GLIB_CFLAGS) - AC_SUBST(GLIB_LIBS) - AC_MSG_WARN(Using locale implementation of GList functions) - ] -) - -AM_CONDITIONAL([LOCAL_GLIB], [test "x$local_glib2" = "xyes"]) - AC_ARG_WITH([libcap-ng], AS_HELP_STRING([libcap-ng], [Add libcap-ng-support @<:@default=auto@:>@])) @@ -96,7 +81,7 @@ ] ) -AC_OUTPUT(Makefile glib-local/Makefile) +AC_OUTPUT(Makefile tests/Makefile) AC_MSG_NOTICE() AC_MSG_NOTICE([irqbalance Version: $VERSION]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/irqbalance-1.2.0/cputree.c new/irqbalance-1.4.0/cputree.c --- old/irqbalance-1.2.0/cputree.c 2017-01-09 14:41:02.000000000 +0100 +++ new/irqbalance-1.4.0/cputree.c 2018-05-14 21:06:54.000000000 +0200 @@ -121,8 +121,32 @@ log(TO_CONSOLE, LOG_INFO, "Banned CPUs: %s\n", buffer); } -static struct topo_obj* add_cache_domain_to_package(struct topo_obj *cache, - int packageid, cpumask_t package_mask) +static void add_numa_node_to_topo_obj(struct topo_obj *obj, int nodeid) +{ + GList *entry; + struct topo_obj *node; + struct topo_obj *cand_node; + + node = get_numa_node(nodeid); + if (!node || node->number == -1) + return; + + entry = g_list_first(obj->numa_nodes); + while (entry) { + cand_node = entry->data; + if (cand_node == node) + break; + entry = g_list_next(entry); + } + + if (!entry) + obj->numa_nodes = g_list_append(obj->numa_nodes, node); +} + +static struct topo_obj* add_cache_domain_to_package(struct topo_obj *cache, + int packageid, + cpumask_t package_mask, + int nodeid) { GList *entry; struct topo_obj *package; @@ -165,10 +189,14 @@ cache->parent = package; } + if (nodeid > -1) + add_numa_node_to_topo_obj(package, nodeid); + return package; } static struct topo_obj* add_cpu_to_cache_domain(struct topo_obj *cpu, - cpumask_t cache_mask) + cpumask_t cache_mask, + int nodeid) { GList *entry; struct topo_obj *cache; @@ -208,6 +236,9 @@ cpu->parent = (struct topo_obj *)cache; } + if (nodeid > -1) + add_numa_node_to_topo_obj(cache, nodeid); + return cache; } @@ -218,7 +249,6 @@ char new_path[PATH_MAX]; cpumask_t cache_mask, package_mask; struct topo_obj *cache; - struct topo_obj *package; DIR *dir; struct dirent *entry; int nodeid; @@ -324,6 +354,8 @@ nodeid=-1; if (numa_avail) { + struct topo_obj *node; + dir = opendir(path); do { entry = readdir(dir); @@ -335,6 +367,14 @@ } } while (entry); closedir(dir); + + /* + * In case of multiple NUMA nodes within a CPU package, + * we override package_mask with node mask. + */ + node = get_numa_node(nodeid); + if (node && (cpus_weight(package_mask) > cpus_weight(node->mask))) + cpus_and(package_mask, package_mask, node->mask); } /* @@ -344,9 +384,9 @@ cpus_and(cache_mask, cache_mask, unbanned_cpus); cpus_and(package_mask, package_mask, unbanned_cpus); - cache = add_cpu_to_cache_domain(cpu, cache_mask); - package = add_cache_domain_to_package(cache, packageid, package_mask); - add_package_to_node(package, nodeid); + cache = add_cpu_to_cache_domain(cpu, cache_mask, nodeid); + add_cache_domain_to_package(cache, packageid, package_mask, + nodeid); cpu->obj_type_list = &cpus; cpus = g_list_append(cpus, cpu); @@ -368,12 +408,18 @@ free(indent); } +static void dump_numa_node_num(struct topo_obj *p, void *data __attribute__((unused))) +{ + log(TO_CONSOLE, LOG_INFO, "%d ", p->number); +} + static void dump_balance_obj(struct topo_obj *d, void *data __attribute__((unused))) { struct topo_obj *c = (struct topo_obj *)d; - log(TO_CONSOLE, LOG_INFO, "%s%s%s%sCPU number %i numa_node is %d (load %lu)\n", - log_indent, log_indent, log_indent, log_indent, - c->number, cpu_numa_node(c)->number , (unsigned long)c->load); + log(TO_CONSOLE, LOG_INFO, "%s%s%s%sCPU number %i numa_node is ", + log_indent, log_indent, log_indent, log_indent, c->number); + for_each_object(cpu_numa_node(c), dump_numa_node_num, NULL); + log(TO_CONSOLE, LOG_INFO, "(load %lu)\n", (unsigned long)c->load); if (c->interrupts) for_each_irq(c->interrupts, dump_irq, (void *)18); } @@ -382,9 +428,11 @@ { char *buffer = data; cpumask_scnprintf(buffer, 4095, d->mask); - log(TO_CONSOLE, LOG_INFO, "%s%sCache domain %i: numa_node is %d cpu mask is %s (load %lu) \n", - log_indent, log_indent, - d->number, cache_domain_numa_node(d)->number, buffer, (unsigned long)d->load); + log(TO_CONSOLE, LOG_INFO, "%s%sCache domain %i: numa_node is ", + log_indent, log_indent, d->number); + for_each_object(d->numa_nodes, dump_numa_node_num, NULL); + log(TO_CONSOLE, LOG_INFO, "cpu mask is %s (load %lu) \n", buffer, + (unsigned long)d->load); if (d->children) for_each_object(d->children, dump_balance_obj, NULL); if (g_list_length(d->interrupts) > 0) @@ -395,8 +443,10 @@ { char *buffer = data; cpumask_scnprintf(buffer, 4096, d->mask); - log(TO_CONSOLE, LOG_INFO, "Package %i: numa_node is %d cpu mask is %s (load %lu)\n", - d->number, package_numa_node(d)->number, buffer, (unsigned long)d->load); + log(TO_CONSOLE, LOG_INFO, "Package %i: numa_node ", d->number); + for_each_object(d->numa_nodes, dump_numa_node_num, NULL); + log(TO_CONSOLE, LOG_INFO, "cpu mask is %s (load %lu)\n", + buffer, (unsigned long)d->load); if (d->children) for_each_object(d->children, dump_cache_domain, buffer); if (g_list_length(d->interrupts) > 0) @@ -448,9 +498,9 @@ char pad; entry = readdir(dir); /* - * We only want to count real cpus, not cpufreq and - * cpuidle - */ + * We only want to count real cpus, not cpufreq and + * cpuidle + */ if (entry && sscanf(entry->d_name, "cpu%d%c", &num, &pad) == 1 && !strchr(entry->d_name, ' ')) { @@ -459,7 +509,8 @@ do_one_cpu(new_path); } } while (entry); - closedir(dir); + closedir(dir); + for_each_object(packages, connect_cpu_mem_topo, NULL); if (debug_mode) dump_tree(); @@ -483,6 +534,7 @@ package = item->data; g_list_free(package->children); g_list_free(package->interrupts); + g_list_free(package->numa_nodes); free(package); packages = g_list_delete_link(packages, item); } @@ -493,6 +545,7 @@ cache_domain = item->data; g_list_free(cache_domain->children); g_list_free(cache_domain->interrupts); + g_list_free(cache_domain->numa_nodes); free(cache_domain); cache_domains = g_list_delete_link(cache_domains, item); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/irqbalance-1.2.0/glib-local/Makefile.am new/irqbalance-1.4.0/glib-local/Makefile.am --- old/irqbalance-1.2.0/glib-local/Makefile.am 2017-01-09 14:41:02.000000000 +0100 +++ new/irqbalance-1.4.0/glib-local/Makefile.am 1970-01-01 01:00:00.000000000 +0100 @@ -1,8 +0,0 @@ -## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libglib.a - -libglib_a_SOURCES = glist.c - -libglib_a_CFLAGS = @GLIB_CFLAGS@ - -noinst_HEADERS = glib.h glist.h diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/irqbalance-1.2.0/glib-local/glib.h new/irqbalance-1.4.0/glib-local/glib.h --- old/irqbalance-1.2.0/glib-local/glib.h 2017-01-09 14:41:02.000000000 +0100 +++ new/irqbalance-1.4.0/glib-local/glib.h 1970-01-01 01:00:00.000000000 +0100 @@ -1 +0,0 @@ -#include <glist.h> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/irqbalance-1.2.0/glib-local/glist.c new/irqbalance-1.4.0/glib-local/glist.c --- old/irqbalance-1.2.0/glib-local/glist.c 2017-01-09 14:41:02.000000000 +0100 +++ new/irqbalance-1.4.0/glib-local/glist.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,415 +0,0 @@ -#include <stdlib.h> - -#include "glist.h" - -/** - * g_list_free: - * @list: a #GList - * - * Frees all of the memory used by a #GList. - * The freed elements are returned to the slice allocator. - * - * <note><para> - * If list elements contain dynamically-allocated memory, - * you should either use g_list_free_full() or free them manually - * first. - * </para></note> - */ -void -g_list_free (GList *list) -{ - GList *l = list; - - while(l) { - GList *tmp = l->next; - free(l); - l = tmp; - } -} - -/** - * g_list_last: - * @list: a #GList - * - * Gets the last element in a #GList. - * - * Returns: the last element in the #GList, - * or %NULL if the #GList has no elements - */ -GList* -g_list_last (GList *list) -{ - if (list) - { - while (list->next) - list = list->next; - } - - return list; -} - -/** - * g_list_append: - * @list: a pointer to a #GList - * @data: the data for the new element - * - * Adds a new element on to the end of the list. - * - * <note><para> - * The return value is the new start of the list, which - * may have changed, so make sure you store the new value. - * </para></note> - * - * <note><para> - * Note that g_list_append() has to traverse the entire list - * to find the end, which is inefficient when adding multiple - * elements. A common idiom to avoid the inefficiency is to prepend - * the elements and reverse the list when all elements have been added. - * </para></note> - * - * |[ - * /* Notice that these are initialized to the empty list. */ - * GList *list = NULL, *number_list = NULL; - * - * /* This is a list of strings. */ - * list = g_list_append (list, "first"); - * list = g_list_append (list, "second"); - * - * /* This is a list of integers. */ - * number_list = g_list_append (number_list, GINT_TO_POINTER (27)); - * number_list = g_list_append (number_list, GINT_TO_POINTER (14)); - * ]| - * - * Returns: the new start of the #GList - */ -GList* -g_list_append (GList *list, - gpointer data) -{ - GList *new_list; - GList *last; - - new_list = malloc(sizeof(*new_list)); - new_list->data = data; - new_list->next = NULL; - - if (list) - { - last = g_list_last (list); - /* g_assert (last != NULL); */ - last->next = new_list; - new_list->prev = last; - - return list; - } - else - { - new_list->prev = NULL; - return new_list; - } -} - -static inline GList* -_g_list_remove_link (GList *list, - GList *link) -{ - if (link) - { - if (link->prev) - link->prev->next = link->next; - if (link->next) - link->next->prev = link->prev; - - if (link == list) - list = list->next; - - link->next = NULL; - link->prev = NULL; - } - - return list; -} - -/** - * g_list_delete_link: - * @list: a #GList - * @link_: node to delete from @list - * - * Removes the node link_ from the list and frees it. - * Compare this to g_list_remove_link() which removes the node - * without freeing it. - * - * Returns: the new head of @list - */ -GList* -g_list_delete_link (GList *list, - GList *link_) -{ - list = _g_list_remove_link (list, link_); - free (link_); - - return list; -} - -/** - * g_list_first: - * @list: a #GList - * - * Gets the first element in a #GList. - * - * Returns: the first element in the #GList, - * or %NULL if the #GList has no elements - */ -GList* -g_list_first (GList *list) -{ - if (list) - { - while (list->prev) - list = list->prev; - } - - return list; -} - -static GList * -g_list_sort_merge (GList *l1, - GList *l2, - GFunc compare_func, - gpointer user_data) -{ - GList list, *l, *lprev; - gint cmp; - - l = &list; - lprev = NULL; - - while (l1 && l2) - { - cmp = ((GCompareDataFunc) compare_func) (l1->data, l2->data, user_data); - - if (cmp <= 0) - { - l->next = l1; - l1 = l1->next; - } - else - { - l->next = l2; - l2 = l2->next; - } - l = l->next; - l->prev = lprev; - lprev = l; - } - l->next = l1 ? l1 : l2; - l->next->prev = l; - - return list.next; -} - -static GList* -g_list_sort_real (GList *list, - GFunc compare_func, - gpointer user_data) -{ - GList *l1, *l2; - - if (!list) - return NULL; - if (!list->next) - return list; - - l1 = list; - l2 = list->next; - - while ((l2 = l2->next) != NULL) - { - if ((l2 = l2->next) == NULL) - break; - l1 = l1->next; - } - l2 = l1->next; - l1->next = NULL; - - return g_list_sort_merge (g_list_sort_real (list, compare_func, user_data), - g_list_sort_real (l2, compare_func, user_data), - compare_func, - user_data); -} - -/** - * g_list_sort: - * @list: a #GList - * @compare_func: the comparison function used to sort the #GList. - * This function is passed the data from 2 elements of the #GList - * and should return 0 if they are equal, a negative value if the - * first element comes before the second, or a positive value if - * the first element comes after the second. - * - * Sorts a #GList using the given comparison function. - * - * Returns: the start of the sorted #GList - */ -/** - * GCompareFunc: - * @a: a value. - * @b: a value to compare with. - * @Returns: negative value if @a < @b; zero if @a = @b; positive - * value if @a > @b. - * - * Specifies the type of a comparison function used to compare two - * values. The function should return a negative integer if the first - * value comes before the second, 0 if they are equal, or a positive - * integer if the first value comes after the second. - **/ -GList * -g_list_sort (GList *list, - GCompareFunc compare_func) -{ - return g_list_sort_real (list, (GFunc) compare_func, NULL); - -} - -/** - * g_list_length: - * @list: a #GList - * - * Gets the number of elements in a #GList. - * - * <note><para> - * This function iterates over the whole list to - * count its elements. - * </para></note> - * - * Returns: the number of elements in the #GList - */ -guint -g_list_length (GList *list) -{ - guint length; - - length = 0; - while (list) - { - length++; - list = list->next; - } - - return length; -} - -/** - * g_list_foreach: - * @list: a #GList - * @func: the function to call with each element's data - * @user_data: user data to pass to the function - * - * Calls a function for each element of a #GList. - */ -/** - * GFunc: - * @data: the element's data. - * @user_data: user data passed to g_list_foreach() or - * g_slist_foreach(). - * - * Specifies the type of functions passed to g_list_foreach() and - * g_slist_foreach(). - **/ -void -g_list_foreach (GList *list, - GFunc func, - gpointer user_data) -{ - while (list) - { - GList *next = list->next; - (*func) (list->data, user_data); - list = next; - } -} - -/** - * g_list_free_full: - * @list: a pointer to a #GList - * @free_func: the function to be called to free each element's data - * - * Convenience method, which frees all the memory used by a #GList, and - * calls the specified destroy function on every element's data. - * - * Since: 2.28 - */ -void -g_list_free_full (GList *list, - GDestroyNotify free_func) -{ - g_list_foreach (list, (GFunc) free_func, NULL); - g_list_free (list); -} - -/** - * g_list_find_custom: - * @list: a #GList - * @data: user data passed to the function - * @func: the function to call for each element. - * It should return 0 when the desired element is found - * - * Finds an element in a #GList, using a supplied function to - * find the desired element. It iterates over the list, calling - * the given function which should return 0 when the desired - * element is found. The function takes two #gconstpointer arguments, - * the #GList element's data as the first argument and the - * given user data. - * - * Returns: the found #GList element, or %NULL if it is not found - */ -GList* -g_list_find_custom (GList *list, - gconstpointer data, - GCompareFunc func) -{ - g_return_val_if_fail (func != NULL, list); - - while (list) - { - if (! func (list->data, data)) - return list; - list = list->next; - } - - return NULL; -} - -/** - * g_list_remove: - * @list: a #GList - * @data: the data of the element to remove - * - * Removes an element from a #GList. - * If two elements contain the same data, only the first is removed. - * If none of the elements contain the data, the #GList is unchanged. - * - * Returns: the new start of the #GList - */ -GList* -g_list_remove (GList *list, - gconstpointer data) -{ - GList *tmp; - - tmp = list; - while (tmp) - { - if (tmp->data != data) - tmp = tmp->next; - else - { - list = _g_list_remove_link(list, tmp); - g_list_free(tmp); - - break; - } - } - return list; -} - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/irqbalance-1.2.0/glib-local/glist.h new/irqbalance-1.4.0/glib-local/glist.h --- old/irqbalance-1.2.0/glib-local/glist.h 2017-01-09 14:41:02.000000000 +0100 +++ new/irqbalance-1.4.0/glib-local/glist.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,58 +0,0 @@ -#ifndef __G_LIST_H__ -#define __G_LIST_H__ - -typedef int gint; -typedef unsigned int guint; -typedef void* gpointer; -typedef const void *gconstpointer; -typedef gint (*GCompareFunc) (gconstpointer a, - gconstpointer b); -typedef gint (*GCompareDataFunc) (gconstpointer a, - gconstpointer b, - gpointer user_data); -typedef void (*GFunc) (gpointer data, - gpointer user_data); -typedef void (*GDestroyNotify) (gpointer data); - -struct _GList; -typedef struct _GList GList; - -struct _GList -{ - gpointer data; - GList *next; - GList *prev; -}; - -/* Doubly linked lists - */ -void g_list_free (GList *list); -GList* g_list_append (GList *list, - gpointer data); -GList* g_list_delete_link (GList *list, - GList *link_); -GList* g_list_first (GList *list); -GList* g_list_sort (GList *list, - GCompareFunc compare_func); -guint g_list_length (GList *list); -void g_list_foreach (GList *list, - GFunc func, - gpointer user_data); -void g_list_free_full (GList *list, - GDestroyNotify free_func); -GList* g_list_find_custom (GList *list, - gconstpointer data, - GCompareFunc func); -GList* g_list_remove (GList *list, - gconstpointer data); - -#define g_list_previous(list) ((list) ? (((GList *)(list))->prev) : NULL) -#define g_list_next(list) ((list) ? (((GList *)(list))->next) : NULL) - -#define g_return_val_if_fail(expr,val) do { \ - if (expr) { } else \ - { \ - return (val); \ - } } while(0); - -#endif /* __G_LIST_H__ */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/irqbalance-1.2.0/irqbalance.c new/irqbalance-1.4.0/irqbalance.c --- old/irqbalance-1.2.0/irqbalance.c 2017-01-09 14:41:02.000000000 +0100 +++ new/irqbalance-1.4.0/irqbalance.c 2018-05-14 21:06:54.000000000 +0200 @@ -94,6 +94,7 @@ {"journal", 0, NULL, 'j'}, {"banmod", 1 , NULL, 'm'}, {"interval", 1 , NULL, 't'}, + {"version", 0, NULL, 'V'}, {0, 0, 0, 0} }; @@ -104,6 +105,11 @@ log(TO_CONSOLE, LOG_INFO, " [--pid= | -s <file>] [--deepestcache= | -c <n>] [--interval= | -t <n>]\n"); } +static void version(void) +{ + log(TO_CONSOLE, LOG_INFO, "irqbalance version " VERSION "\n"); +} + static void parse_command_line(int argc, char **argv) { int opt; @@ -111,7 +117,7 @@ unsigned long val; while ((opt = getopt_long(argc, argv, - "odfji:p:s:c:b:l:m:t:", + "odfji:p:s:c:b:l:m:t:V", lopts, &longind)) != -1) { switch(opt) { @@ -119,6 +125,10 @@ usage(); exit(1); break; + case 'V': + version(); + exit(1); + break; case 'b': #ifndef INCLUDE_BANSCRIPT /* @@ -193,9 +203,14 @@ #endif /* - * This builds our object tree. The Heirarchy is pretty straightforward + * This builds our object tree. The Heirarchy is typically pretty + * straightforward. * At the top are numa_nodes - * All CPU packages belong to a single numa_node + * CPU packages belong to a single numa_node, unless the cache domains are in + * separate nodes. In that case, the cache domain's parent is the package, but + * the numa nodes point to the cache domains instead of the package as their + * children. This allows us to maintain the CPU hierarchy while adjusting for + * alternate memory topologies that are present on recent processor. * All Cache domains belong to a CPU package * All CPU cores belong to a cache domain * @@ -255,7 +270,6 @@ log(TO_CONSOLE, LOG_INFO, "\n\n\n-----------------------------------------------------------------------------\n"); clear_work_stats(); parse_proc_interrupts(); - parse_proc_stat(); /* cope with cpu hotplug -- detected during /proc/interrupts parsing */ @@ -273,8 +287,9 @@ sleep_approx(sleep_interval); clear_work_stats(); parse_proc_interrupts(); - parse_proc_stat(); - } + } + + parse_proc_stat(); if (cycle_count) update_migration_status(); @@ -294,29 +309,57 @@ return FALSE; } - if (keep_going) + if (keep_going) { return TRUE; - else + } else { + g_main_loop_quit(main_loop); return FALSE; + } } void get_irq_data(struct irq_info *irq, void *data) { - sprintf(data + strlen(data), + char **irqdata = (char **)data; + if (!*irqdata) + *irqdata = calloc(24 + 1 + 11 + 20 + 20 + 11, 1); + else + *irqdata = realloc(*irqdata, strlen(*irqdata) + 24 + 1 + 11 + 20 + 20 + 11); + + sprintf(*irqdata + strlen(*irqdata), "IRQ %d LOAD %lu DIFF %lu CLASS %d ", irq->irq, irq->load, (irq->irq_count - irq->last_irq_count), irq->class); } void get_object_stat(struct topo_obj *object, void *data) { - char irq_data[1024] = "\0"; + char **stats = (char **)data; + char *irq_data = NULL; + size_t irqdlen; if (g_list_length(object->interrupts) > 0) { - for_each_irq(object->interrupts, get_irq_data, irq_data); + for_each_irq(object->interrupts, get_irq_data, &irq_data); + } + + irqdlen = irq_data ? strlen(irq_data) : 0; + /* + * Note, the size in both conditional branches below is made up as follows: + * strlen(irq_data) - self explanitory + * 31 - The size of "TYPE NUMBER LOAD SAVE_MODE " + * 11 - The maximal size of a %d printout + * 20 - The maximal size of a %lu printout + * 1 - The trailing string terminator + * This should be adjusted if the string in the sprintf is changed + */ + if (!*stats) { + *stats = calloc(irqdlen + 31 + 11 + 20 + 11 + 1, 1); + } else { + *stats = realloc(*stats, strlen(*stats) + irqdlen + 31 + 11 + 20 + 11 + 1); } - sprintf(data + strlen(data), "TYPE %d NUMBER %d LOAD %lu SAVE_MODE %d %s", + + sprintf(*stats + strlen(*stats), "TYPE %d NUMBER %d LOAD %lu SAVE_MODE %d %s", object->obj_type, object->number, object->load, - object->powersave_mode, irq_data); + object->powersave_mode, irq_data ? irq_data : ""); + free(irq_data); if (object->obj_type != OBJ_TYPE_CPU) { for_each_object(object->children, get_object_stat, data); } @@ -330,7 +373,9 @@ int valid_user = 0; struct iovec iov = { buff, 500 }; - struct msghdr msg = { NULL, 0, &iov, 1, NULL, 0, 0 }; + struct msghdr msg = { 0 }; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; msg.msg_control = malloc(CMSG_SPACE(sizeof(struct ucred))); msg.msg_controllen = CMSG_SPACE(sizeof(struct ucred)); @@ -360,9 +405,10 @@ } if (!strncmp(buff, "stats", strlen("stats"))) { - char stats[2048] = "\0"; - for_each_object(numa_nodes, get_object_stat, stats); + char *stats = NULL; + for_each_object(numa_nodes, get_object_stat, &stats); send(sock, stats, strlen(stats), 0); + free(stats); } if (!strncmp(buff, "settings ", strlen("settings "))) { if (!(strncmp(buff + strlen("settings "), "sleep ", @@ -406,14 +452,15 @@ } } if (!strncmp(buff, "setup", strlen("setup"))) { - char setup[2048] = "\0"; + char banned[512]; + char *setup = calloc(strlen("SLEEP ") + 11 +1, 1); snprintf(setup, 2048, "SLEEP %d ", sleep_interval); if(g_list_length(cl_banned_irqs) > 0) { for_each_irq(cl_banned_irqs, get_irq_data, setup); } - char banned[512]; cpumask_scnprintf(banned, 512, banned_cpus); - snprintf(setup + strlen(setup), 2048 - strlen(setup), + setup = realloc(setup, strlen(setup) + strlen(banned) + 7 + 1); + snprintf(setup + strlen(setup), strlen(banned) + 7 + 1, "BANNED %s", banned); send(sock, setup, strlen(setup), 0); } @@ -583,7 +630,7 @@ g_main_loop_run(main_loop); g_main_loop_quit(main_loop); - + free_object_tree(); free_cl_opts(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/irqbalance-1.2.0/irqbalance.h new/irqbalance-1.4.0/irqbalance.h --- old/irqbalance-1.2.0/irqbalance.h 2017-01-09 14:41:02.000000000 +0100 +++ new/irqbalance-1.4.0/irqbalance.h 2018-05-14 21:06:54.000000000 +0200 @@ -84,26 +84,13 @@ extern void build_numa_node_list(void); extern void free_numa_node_list(void); extern void dump_numa_node_info(struct topo_obj *node, void *data); -extern void add_package_to_node(struct topo_obj *p, int nodeid); +extern void connect_cpu_mem_topo(struct topo_obj *p, void *data); extern struct topo_obj *get_numa_node(int nodeid); /* - * Package functions - */ -#define package_numa_node(p) ((p)->parent) - -/* - * cache_domain functions - */ -#define cache_domain_package(c) ((c)->parent) -#define cache_domain_numa_node(c) (package_numa_node(cache_domain_package((c)))) - -/* * cpu core functions */ -#define cpu_cache_domain(cpu) ((cpu)->parent) -#define cpu_package(cpu) (cache_domain_package(cpu_cache_domain((cpu)))) -#define cpu_numa_node(cpu) (package_numa_node(cache_domain_package(cpu_cache_domain((cpu))))) +#define cpu_numa_node(cpu) ((cpu)->parent->numa_nodes) extern struct topo_obj *find_cpu_core(int cpunr); extern int get_cpu_count(void); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/irqbalance-1.2.0/irqlist.c new/irqbalance-1.4.0/irqlist.c --- old/irqbalance-1.2.0/irqlist.c 2017-01-09 14:41:02.000000000 +0100 +++ new/irqbalance-1.4.0/irqlist.c 2018-05-14 21:06:54.000000000 +0200 @@ -55,7 +55,7 @@ { struct load_balance_info *info = data; - if (info->min_load == 0 || obj->load < info->min_load) + if (info->load_sources == 0 || obj->load < info->min_load) info->min_load = obj->load; info->total_load += obj->load; info->load_sources += 1; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/irqbalance-1.2.0/misc/90-irqbalance.rules new/irqbalance-1.4.0/misc/90-irqbalance.rules --- old/irqbalance-1.2.0/misc/90-irqbalance.rules 1970-01-01 01:00:00.000000000 +0100 +++ new/irqbalance-1.4.0/misc/90-irqbalance.rules 2018-05-14 21:06:54.000000000 +0200 @@ -0,0 +1,5 @@ +# Udev rules for irqbalance. On every device add or remove, we want to rescan +# our irq list to make sure it hasn't changed +# + +ACTION=="add|remove", RUN+="/usr/bin/killall -SIGHUP irqbalance" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/irqbalance-1.2.0/misc/irqbalance.service new/irqbalance-1.4.0/misc/irqbalance.service --- old/irqbalance-1.2.0/misc/irqbalance.service 2017-01-09 14:41:02.000000000 +0100 +++ new/irqbalance-1.4.0/misc/irqbalance.service 2018-05-14 21:06:54.000000000 +0200 @@ -1,6 +1,6 @@ [Unit] Description=irqbalance daemon -After=syslog.target +ConditionVirtualization=!container [Service] EnvironmentFile=/path/to/irqbalance.env diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/irqbalance-1.2.0/numa.c new/irqbalance-1.4.0/numa.c --- old/irqbalance-1.2.0/numa.c 2017-01-09 14:41:02.000000000 +0100 +++ new/irqbalance-1.4.0/numa.c 2018-05-14 21:06:54.000000000 +0200 @@ -146,22 +146,38 @@ return (ai->number == bi->number) ? 0 : 1; } -void add_package_to_node(struct topo_obj *p, int nodeid) +void connect_cpu_mem_topo(struct topo_obj *p, void *data __attribute__((unused))) { + GList *entry; struct topo_obj *node; + struct topo_obj *lchild; + int len; - node = get_numa_node(nodeid); + len = g_list_length(p->numa_nodes); - if (!node) { - log(TO_CONSOLE, LOG_INFO, "Could not find numa node for node id %d\n", nodeid); + if (len == 0) { + return; + } else if (len > 1) { + for_each_object(p->children, connect_cpu_mem_topo, NULL); return; } + entry = g_list_first(p->numa_nodes); + node = entry->data; - if (!p->parent) { - node->children = g_list_append(node->children, p); + if (p->obj_type == OBJ_TYPE_PACKAGE && !p->parent) p->parent = node; + + entry = g_list_first(node->children); + while (entry) { + lchild = entry->data; + if (lchild == p) + break; + entry = g_list_next(entry); } + + if (!entry) + node->children = g_list_append(node->children, p); } void dump_numa_node_info(struct topo_obj *d, void *unused __attribute__((unused))) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/irqbalance-1.2.0/procinterrupts.c new/irqbalance-1.4.0/procinterrupts.c --- old/irqbalance-1.2.0/procinterrupts.c 2017-01-09 14:41:02.000000000 +0100 +++ new/irqbalance-1.4.0/procinterrupts.c 2018-05-14 21:06:54.000000000 +0200 @@ -57,7 +57,17 @@ DIR *dirfd; char path[512]; struct dirent *ent; - int rc = -ENOENT; + int rc = -ENOENT, i; + static struct pdev_irq_info { + char *d_name; + int type; + int class; + } pdev_irq_info[] = { + {"ata", IRQ_TYPE_LEGACY, IRQ_SCSI}, + {"net", IRQ_TYPE_LEGACY, IRQ_ETH}, + {"usb", IRQ_TYPE_LEGACY, IRQ_OTHER}, + {NULL}, + }; memset(path, 0, 512); @@ -74,21 +84,13 @@ while ((ent = readdir(dirfd)) != NULL) { log(TO_ALL, LOG_DEBUG, "Checking entry %s\n", ent->d_name); - if (!strncmp(ent->d_name, "ata", strlen("ata"))) { - info->type = IRQ_TYPE_LEGACY; - info->class = IRQ_SCSI; - rc = 0; - goto out; - } else if (!strncmp(ent->d_name, "net", strlen("net"))) { - info->type = IRQ_TYPE_LEGACY; - info->class = IRQ_ETH; - rc = 0; - goto out; - } else if (!strncmp(ent->d_name, "usb", strlen("net"))) { - info->type = IRQ_TYPE_LEGACY; - info->class = IRQ_OTHER; - rc = 0; - goto out; + for (i = 0; pdev_irq_info[i].d_name != NULL; i++) { + if (!strncmp(ent->d_name, pdev_irq_info[i].d_name, strlen(pdev_irq_info[i].d_name))) { + info->type = pdev_irq_info[i].type; + info->class = pdev_irq_info[i].class; + rc = 0; + goto out; + } } } @@ -148,6 +150,9 @@ char *line = NULL; size_t size = 0; char *irq_name, *irq_mod, *savedptr, *last_token, *p; +#ifdef AARCH64 + char *tmp; +#endif file = fopen("/proc/interrupts", "r"); if (!file) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/irqbalance-1.2.0/tests/Makefile.am new/irqbalance-1.4.0/tests/Makefile.am --- old/irqbalance-1.2.0/tests/Makefile.am 1970-01-01 01:00:00.000000000 +0100 +++ new/irqbalance-1.4.0/tests/Makefile.am 2018-05-14 21:06:54.000000000 +0200 @@ -0,0 +1,2 @@ +check_SCRIPTS = runoneshot.sh +TESTS = runoneshot.sh diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/irqbalance-1.2.0/tests/runoneshot.sh new/irqbalance-1.4.0/tests/runoneshot.sh --- old/irqbalance-1.2.0/tests/runoneshot.sh 1970-01-01 01:00:00.000000000 +0100 +++ new/irqbalance-1.4.0/tests/runoneshot.sh 2018-05-14 21:06:54.000000000 +0200 @@ -0,0 +1,4 @@ +#!/bin/sh + +exec ../irqbalance --debug --oneshot --foreground + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/irqbalance-1.2.0/types.h new/irqbalance-1.4.0/types.h --- old/irqbalance-1.2.0/types.h 2017-01-09 14:41:02.000000000 +0100 +++ new/irqbalance-1.4.0/types.h 2018-05-14 21:06:54.000000000 +0200 @@ -54,6 +54,7 @@ GList *interrupts; struct topo_obj *parent; GList *children; + GList *numa_nodes; GList **obj_type_list; }; @@ -65,14 +66,11 @@ int flags; struct topo_obj *numa_node; cpumask_t cpumask; - cpumask_t affinity_hint; - int hint_policy; uint64_t irq_count; uint64_t last_irq_count; uint64_t load; int moved; struct topo_obj *assigned_obj; - unsigned int warned; char *name; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/irqbalance-1.2.0/ui/helpers.c new/irqbalance-1.4.0/ui/helpers.c --- old/irqbalance-1.2.0/ui/helpers.c 2017-01-09 14:41:02.000000000 +0100 +++ new/irqbalance-1.4.0/ui/helpers.c 2018-05-14 21:06:54.000000000 +0200 @@ -75,7 +75,8 @@ char *bitmap = malloc(5 * sizeof(char)); bitmap[4] = '\0'; - for(int i = 3; i >= 0; i--) { + int i; + for(i = 3; i >= 0; i--) { bitmap[i] = digit % 2 ? '1' : '0'; digit /= 2; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/irqbalance-1.2.0/ui/irqbalance-ui.c new/irqbalance-1.4.0/ui/irqbalance-ui.c --- old/irqbalance-1.2.0/ui/irqbalance-ui.c 2017-01-09 14:41:02.000000000 +0100 +++ new/irqbalance-1.4.0/ui/irqbalance-ui.c 2018-05-14 21:06:54.000000000 +0200 @@ -3,6 +3,7 @@ #include <errno.h> #include <netdb.h> #include <stdio.h> +#include <string.h> #include <stdlib.h> #include <sys/socket.h> #include <sys/types.h> @@ -105,8 +106,13 @@ msg->msg_iov = &iov; sendmsg(socket_fd, msg, 0); - char *data = malloc(2048 * sizeof(char)); - int len = recv(socket_fd, data, 2048, 0); + /* + * This is just...horrible. Mental note to replace this + * With a select, ioctl to determine size, and malloc based + * on that + */ + char *data = malloc(8192); + int len = recv(socket_fd, data, 8192, 0); close(socket_fd); data[len] = '\0'; return data; @@ -115,39 +121,43 @@ void parse_setup(char *setup_data) { char *token, *ptr; + int i,j; + char *copy; if((setup_data == NULL) || (strlen(setup_data) == 0)) return; - char copy[strlen(setup_data) + 1]; - strncpy(copy, setup_data, strlen(setup_data) + 1); + copy = strdup(setup_data); + if (!copy) + return; + setup.banned_irqs = NULL; setup.banned_cpus = NULL; token = strtok_r(copy, " ", &ptr); if(strncmp(token, "SLEEP", strlen("SLEEP"))) goto out; - setup.sleep = strtol(strtok_r(ptr, " ", &ptr), NULL, 10); - token = strtok_r(ptr, " ", &ptr); + setup.sleep = strtol(strtok_r(NULL, " ", &ptr), NULL, 10); + 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->vector = strtol(strtok_r(ptr, " ", &ptr), NULL, 10); - token = strtok_r(ptr, " ", &ptr); + new_irq->vector = strtol(strtok_r(NULL, " ", &ptr), NULL, 10); + token = strtok_r(NULL, " ", &ptr); if(strncmp(token, "LOAD", strlen("LOAD"))) goto out; - new_irq->load = strtol(strtok_r(ptr, " ", &ptr), NULL, 10); - token = strtok_r(ptr, " ", &ptr); + new_irq->load = strtol(strtok_r(NULL, " ", &ptr), NULL, 10); + token = strtok_r(NULL, " ", &ptr); if(strncmp(token, "DIFF", strlen("DIFF"))) goto out; - new_irq->diff = strtol(strtok_r(ptr, " ", &ptr), NULL, 10); + new_irq->diff = strtol(strtok_r(NULL, " ", &ptr), NULL, 10); token = strtok_r(ptr, " ", &ptr); if(strncmp(token, "CLASS", strlen("CLASS"))) goto out; - new_irq->class = strtol(strtok_r(ptr, " ", &ptr), NULL, 10); + new_irq->class = strtol(strtok_r(NULL, " ", &ptr), NULL, 10); new_irq->is_banned = 1; new_irq->assigned_to = NULL; setup.banned_irqs = g_list_append(setup.banned_irqs, new_irq); - token = strtok_r(ptr, " ", &ptr); + token = strtok_r(NULL, " ", &ptr); } if(strncmp(token, "BANNED", strlen("BANNED"))) goto out; - token = strtok_r(ptr, " ", &ptr); - for(int i = strlen(token) - 1; i >= 0; i--) { + token = strtok_r(NULL, " ", &ptr); + for(i = strlen(token) - 1; i >= 0; i--) { char *map = hex_to_bitmap(token[i]); - for(int j = 3; j >= 0; j--) { + 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))); @@ -155,15 +165,15 @@ banned_cpu); } } + } + free(copy); return; out: { /* Invalid data presented */ - char invalid_data[128]; - snprintf(invalid_data, 128, "Invalid data sent. Unexpected token: %s\n", - token); - printf("%s\n", invalid_data); + printf("Invalid data sent. Unexpected token: %s", token); + free(copy); g_list_free(tree); exit(1); } @@ -226,55 +236,63 @@ void parse_into_tree(char *data) { - if((data == NULL) || (strlen(data) == 0)) return; char *token, *ptr; cpu_node_t *parent = NULL; - char copy[strlen(data) + 1]; - strncpy(copy, data, strlen(data) + 1); + char *copy; tree = NULL; + + if (!data || strlen(data) == 0) + return; + + copy = strdup(data); + if (!copy) + return; token = strtok_r(copy, " ", &ptr); while(token != NULL) { /* Parse node data */ - if(strncmp(token, "TYPE", strlen("TYPE"))) goto out; + if(strncmp(token, "TYPE", strlen("TYPE"))) { + free(copy); + goto out; + } cpu_node_t *new = malloc(sizeof(cpu_node_t)); new->irqs = NULL; new->children = NULL; new->cpu_list = NULL; new->cpu_mask = NULL; - new->type = strtol(strtok_r(ptr, " ", &ptr), NULL, 10); + new->type = strtol(strtok_r(NULL, " ", &ptr), NULL, 10); if(new->type == OBJ_TYPE_NODE) { parent = NULL; } else if(new->type >= parent->type) { parent = parent->parent; } - token = strtok_r(ptr, " ", &ptr); + token = strtok_r(NULL, " ", &ptr); if(strncmp(token, "NUMBER", strlen("NUMBER"))) goto out; - new->number = strtol(strtok_r(ptr, " ", &ptr), NULL, 10); - token = strtok_r(ptr, " ", &ptr); + new->number = strtol(strtok_r(NULL, " ", &ptr), NULL, 10); + token = strtok_r(NULL, " ", &ptr); if(strncmp(token, "LOAD", strlen("LOAD"))) goto out; - new->load = strtol(strtok_r(ptr, " ", &ptr), NULL, 10); - token = strtok_r(ptr, " ", &ptr); + new->load = strtol(strtok_r(NULL, " ", &ptr), NULL, 10); + token = strtok_r(NULL, " ", &ptr); if(strncmp(token, "SAVE_MODE", strlen("SAVE_MODE"))) goto out; - new->is_powersave = strtol(strtok_r(ptr, " ", &ptr), NULL, 10); - token = strtok_r(ptr, " ", &ptr); + new->is_powersave = strtol(strtok_r(NULL, " ", &ptr), NULL, 10); + token = strtok_r(NULL, " ", &ptr); /* Parse assigned IRQ data */ while((token != NULL) && (!strncmp(token, "IRQ", strlen("IRQ")))) { irq_t *new_irq = malloc(sizeof(irq_t)); - new_irq->vector = strtol(strtok_r(ptr, " ", &ptr), NULL, 10); - token = strtok_r(ptr, " ", &ptr); + new_irq->vector = strtol(strtok_r(NULL, " ", &ptr), NULL, 10); + token = strtok_r(NULL, " ", &ptr); if(strncmp(token, "LOAD", strlen("LOAD"))) goto out; - new_irq->load = strtol(strtok_r(ptr, " ", &ptr), NULL, 10); - token = strtok_r(ptr, " ", &ptr); + new_irq->load = strtol(strtok_r(NULL, " ", &ptr), NULL, 10); + token = strtok_r(NULL, " ", &ptr); if(strncmp(token, "DIFF", strlen("DIFF"))) goto out; - new_irq->diff = strtol(strtok_r(ptr, " ", &ptr), NULL, 10); - token = strtok_r(ptr, " ", &ptr); + new_irq->diff = strtol(strtok_r(NULL, " ", &ptr), NULL, 10); + token = strtok_r(NULL, " ", &ptr); if(strncmp(token, "CLASS", strlen("CLASS"))) goto out; - new_irq->class = strtol(strtok_r(ptr, " ", &ptr), NULL, 10); + new_irq->class = strtol(strtok_r(NULL, " ", &ptr), NULL, 10); new_irq->is_banned = 0; new->irqs = g_list_append(new->irqs, new_irq); - token = strtok_r(ptr, " ", &ptr); + token = strtok_r(NULL, " ", &ptr); } if((token == NULL) || (strncmp(token, "IRQ", strlen("IRQ")))) { @@ -289,17 +307,14 @@ } } } - + free(copy); for_each_node(tree, assign_cpu_lists, NULL); for_each_node(tree, assign_cpu_mask, NULL); return; out: { /* Invalid data presented */ - char invalid_data[128]; - snprintf(invalid_data, 128, "Invalid data sent. Unexpected token: %s\n", - token); - printf("%s\n", invalid_data); + printf("Invalid data sent. Unexpected token: %s\n", token); g_list_free(tree); exit(1); } @@ -314,7 +329,7 @@ if(is_tree) { display_tree(); } - + free(setup_data); return TRUE; } @@ -361,13 +376,13 @@ DIR *dir = opendir("/proc"); if(dir) { struct dirent *entry; - char cmdfile[64]; + char cmdfile[512]; char cmdstring[256]; cmdstring[255] = '\0'; do { entry = readdir(dir); if(entry) { - snprintf(cmdfile, 64, "/proc/%s/cmdline", entry->d_name); + snprintf(cmdfile, 512, "/proc/%s/cmdline", entry->d_name); FILE *f = fopen(cmdfile, "r"); if(f == NULL) { continue; @@ -397,4 +412,5 @@ g_main_loop_quit(main_loop); close_window(0); + return 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/irqbalance-1.2.0/ui/ui.c new/irqbalance-1.4.0/ui/ui.c --- old/irqbalance-1.2.0/ui/ui.c 2017-01-09 14:41:02.000000000 +0100 +++ new/irqbalance-1.4.0/ui/ui.c 2018-05-14 21:06:54.000000000 +0200 @@ -18,6 +18,7 @@ void show_frame() { + int i; attrset(COLOR_PAIR(4)); char top[COLS]; top[0] = '\0'; @@ -25,7 +26,7 @@ snprintf(top + strlen(top), COLS - strlen(top), " "); } mvprintw(0, 0, top); - for(int i = 0; i < LINES; i++) { + for(i = 0; i < LINES; i++) { mvprintw(i, 0, " "); mvprintw(i, COLS - 1, " "); } @@ -613,6 +614,7 @@ break; } } + free(setup_data); } void setup_irqs() @@ -665,6 +667,7 @@ void display_tree_node(cpu_node_t *node, void *data) { + int i; const char *node_type_to_str[] = { "CPU\0", "CACHE DOMAIN\0", @@ -674,7 +677,7 @@ char *spaces = " \0"; char indent[32] = "\0"; char *asciitree = " `--\0"; - for(int i = node->type; i <= OBJ_TYPE_NODE; i++) { + for(i = node->type; i <= OBJ_TYPE_NODE; i++) { snprintf(indent + strlen(indent), 32 - strlen(indent), "%s", spaces); if(i != OBJ_TYPE_NODE) { snprintf(indent + strlen(indent), 32 - strlen(indent), " "); @@ -726,4 +729,6 @@ show_frame(); show_footer(); refresh(); + free(setup_data); + free(irqbalance_data); }