Hello community,

here is the log from the commit of package irqbalance for openSUSE:Factory 
checked in at 2016-02-03 10:18:45
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/irqbalance (Old)
 and      /work/SRC/openSUSE:Factory/.irqbalance.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "irqbalance"

Changes:
--------
--- /work/SRC/openSUSE:Factory/irqbalance/irqbalance.changes    2015-11-24 
22:31:26.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.irqbalance.new/irqbalance.changes       
2016-02-03 10:18:46.000000000 +0100
@@ -1,0 +2,14 @@
+Sun Jan 17 11:46:01 UTC 2016 - mplus...@suse.com
+
+- Update to 1.1.0
+  * Banning support fixes
+  * Load calculation improvements
+  * Documentation fixes
+  * Fix command line preservation across re-scan
+  * Memory leak fixes
+  * Misc. bug fixes
+  * ARM irq support
+  * New --banmod option
+  * New sleep interval option
+
+-------------------------------------------------------------------

Old:
----
  v1.0.9.tar.gz

New:
----
  v1.1.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ irqbalance.spec ++++++
--- /var/tmp/diff_new_pack.f4EHgN/_old  2016-02-03 10:18:47.000000000 +0100
+++ /var/tmp/diff_new_pack.f4EHgN/_new  2016-02-03 10:18:47.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package irqbalance
 #
-# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2016 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
@@ -17,7 +17,7 @@
 
 
 Name:           irqbalance
-Version:        1.0.9
+Version:        1.1.0
 Release:        0
 Summary:        Balance IRQs on SMP Machines
 License:        GPL-2.0+
@@ -26,9 +26,6 @@
 Source:         
https://github.com/Irqbalance/irqbalance/archive/v%{version}.tar.gz
 Source3:        sysconfig.irqbalance
 BuildRequires:  libcap-ng-devel
-%ifnarch %arm
-BuildRequires:  libnuma-devel
-%endif
 BuildRequires:  libtool
 BuildRequires:  systemd-rpm-macros
 BuildRequires:  pkgconfig(glib-2.0)
@@ -36,6 +33,9 @@
 Requires(pre):  fillup
 ExcludeArch:    s390 s390x
 %{?systemd_requires}
+%ifnarch %arm
+BuildRequires:  libnuma-devel
+%endif
 
 %description
 irqbalance dynamically switches the CPUs for IRQs to prevent cpu0 from

++++++ v1.0.9.tar.gz -> v1.1.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/irqbalance-1.0.9/README new/irqbalance-1.1.0/README
--- old/irqbalance-1.0.9/README 2015-03-16 14:31:53.000000000 +0100
+++ new/irqbalance-1.1.0/README 1970-01-01 01:00:00.000000000 +0100
@@ -1,14 +0,0 @@
-What is Irqbalance
-
-Irqbalance is a daemon to help balance the cpu load generated by interrupts
-across all of a systems cpus.  Irqbalance identifies the highest volume
-interrupt sources, and isolates them to a single unique cpu, so that load is
-spread as much as possible over an entire processor set, while minimizing cache
-hit rates for irq handlers.
-
-Building and Installing
-./autogen.sh
-./configure [options]
-make
-make install
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/irqbalance-1.0.9/README.md 
new/irqbalance-1.1.0/README.md
--- old/irqbalance-1.0.9/README.md      1970-01-01 01:00:00.000000000 +0100
+++ new/irqbalance-1.1.0/README.md      2015-12-04 16:17:37.000000000 +0100
@@ -0,0 +1,40 @@
+What is Irqbalance
+==================
+
+Irqbalance is a daemon to help balance the cpu load generated by interrupts
+across all of a systems cpus.  Irqbalance identifies the highest volume
+interrupt sources, and isolates them to a single unique cpu, so that load is
+spread as much as possible over an entire processor set, while minimizing cache
+miss rates for irq handlers.
+
+## Building and Installing
+
+```bash
+./autogen.sh
+./configure [options]
+make
+make install
+```
+
+## Developing Irqbalance
+
+Irqbalance is currently hosted on github, and so developers are welcome to use
+the issue/pull request/etc infrastructure found there.  However, most
+development discussions take place on the irqbalance mailing list, which can be
+subscribed to at:
+http://lists.infradead.org/mailman/listinfo/irqbalance
+
+New Developers are encouraged to use this mailing list to discuss ideas and
+propose patches.
+
+## Bug reporting
+
+When something goes wrong, feel free to send us bugreport by one of the ways
+described above. Your report should include:
+
+* Irqbalance version you've been using (or commit hash)
+* `/proc/interrupts` output
+* `irqbalance --debug` output
+* content of smp_affinity files - can be obtained by e.g.:
+       `$ for i in $(seq 0 300); do grep . /proc/irq/$i/smp_affinity /dev/null 
2>/dev/null; done`
+* your hw hierarchy - e.g. `lstopo-no-graphics` output
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/irqbalance-1.0.9/classify.c 
new/irqbalance-1.1.0/classify.c
--- old/irqbalance-1.0.9/classify.c     2015-03-16 14:31:53.000000000 +0100
+++ new/irqbalance-1.1.0/classify.c     2015-12-04 16:17:37.000000000 +0100
@@ -37,7 +37,9 @@
 static GList *interrupts_db = NULL;
 static GList *banned_irqs = NULL;
 static GList *cl_banned_irqs = NULL;
+static GList *cl_banned_modules = NULL;
 
+#define SYSFS_DIR "/sys"
 #define SYSDEV_DIR "/sys/bus/pci/devices"
 
 #define PCI_MAX_CLASS 0x14
@@ -284,6 +286,7 @@
        new->hint_policy = HINT_POLICY_EXACT;
 
        *list = g_list_append(*list, new);
+       log(TO_CONSOLE, LOG_INFO, "IRQ %d was BANNED.\n", irq);
        return;
 }
 
@@ -292,7 +295,6 @@
        add_banned_irq(irq, &cl_banned_irqs);
 }
 
-
 static int is_banned_irq(int irq)
 {
        GList *entry;
@@ -304,11 +306,43 @@
        return entry ? 1:0;
 }
 
+gint substr_find(gconstpointer a, gconstpointer b)
+{
+       if (strstr(b, a))
+               return 0;
+       else
+               return 1;
+}
+
+static void add_banned_module(char *modname, GList **modlist)
+{
+       GList *entry;
+       char *newmod;
+       
+       entry = g_list_find_custom(*modlist, modname, substr_find);
+       if (entry)
+               return;
+
+       newmod = strdup(modname);
+       if (!newmod) {
+               log(TO_CONSOLE, LOG_WARNING, "No memory to ban module %s\n", 
modname);
+               return;
+       }
+
+       *modlist = g_list_append(*modlist, newmod);
+}
+
+void add_cl_banned_module(char *modname)
+{
+       add_banned_module(modname, &cl_banned_modules);
+}
+
                        
 /*
  * Inserts an irq_info struct into the intterupts_db list
  * devpath points to the device directory in sysfs for the 
- * related device
+ * related device. NULL devpath means no sysfs entries for
+ * this irq.
  */
 static struct irq_info *add_one_irq_to_db(const char *devpath, int irq, struct 
user_irq_policy *pol)
 {
@@ -348,10 +382,13 @@
 
        interrupts_db = g_list_append(interrupts_db, new);
 
-       /* Map PCI class code to irq class */
-       irq_class = get_irq_class(devpath);
-       if (irq_class < 0)
-               goto get_numa_node;
+       /* Some special irqs have NULL devpath */
+       if (devpath != NULL) {
+               /* Map PCI class code to irq class */
+               irq_class = get_irq_class(devpath);
+               if (irq_class < 0)
+                       goto get_numa_node;
+       }
 
        new->class = irq_class;
        if (pol->level >= 0)
@@ -503,6 +540,10 @@
        if (!polscript)
                return;
 
+       /* Use SYSFS_DIR for irq has no sysfs entries */
+       if (!path)
+               path = SYSFS_DIR;
+
        cmd = alloca(strlen(path)+strlen(polscript)+64);
        if (!cmd)
                return;
@@ -522,11 +563,21 @@
        pclose(output);
 }
 
-static int check_for_irq_ban(char *path, int irq)
+static int check_for_module_ban(char *name)
 {
-       char *cmd;
-       int rc;
-       struct irq_info find;
+       GList *entry;
+
+       entry = g_list_find_custom(cl_banned_modules, name, substr_find);
+
+       if (entry)
+               return 1;
+       else
+               return 0;
+}
+
+static int check_for_irq_ban(char *path, int irq, GList *proc_interrupts)
+{
+       struct irq_info find, *res;
        GList *entry;
 
        /*
@@ -537,6 +588,20 @@
        if (entry)
                return 1;
 
+       /*
+        * Check to see if we banned module which the irq belongs to.
+        */
+       entry = g_list_find_custom(proc_interrupts, &find, compare_ints);
+       if (entry) {
+               res = entry->data;
+               if (check_for_module_ban(res->name))
+                       return 1;
+       }
+
+#ifdef INCLUDE_BANSCRIPT
+       char *cmd;
+       int rc;
+
        if (!banscript)
                return 0;
 
@@ -562,14 +627,14 @@
                log(TO_ALL, LOG_INFO, "irq %d is baned by %s\n", irq, 
banscript);
                return 1;
        }
+#endif
        return 0;
-
 }
 
 /*
- * Figures out which interrupt(s) relate to the device we're looking at in 
dirname
+ * Figures out which interrupt(s) relate to the device we"re looking at in 
dirname
  */
-static void build_one_dev_entry(const char *dirname)
+static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
 {
        struct dirent *entry;
        DIR *msidir;
@@ -596,7 +661,7 @@
                                if (new)
                                        continue;
                                get_irq_user_policy(devpath, irqnum, &pol);
-                               if ((pol.ban == 1) || 
(check_for_irq_ban(devpath, irqnum))) {
+                               if ((pol.ban == 1) || 
(check_for_irq_ban(devpath, irqnum, tmp_irqs))) {
                                        add_banned_irq(irqnum, &banned_irqs);
                                        continue;
                                }
@@ -625,7 +690,7 @@
                if (new)
                        goto done;
                get_irq_user_policy(devpath, irqnum, &pol);
-               if ((pol.ban == 1) || (check_for_irq_ban(path, irqnum))) {
+               if ((pol.ban == 1) || (check_for_irq_ban(path, irqnum, 
tmp_irqs))) {
                        add_banned_irq(irqnum, &banned_irqs);
                        goto done;
                }
@@ -658,7 +723,14 @@
        rebalance_irq_list = NULL;
 }
 
-static void add_new_irq(int irq, struct irq_info *hint)
+void free_cl_opts(void)
+{
+       g_list_free_full(cl_banned_modules, free);
+       g_list_free_full(cl_banned_irqs, free);
+       g_list_free(banned_irqs);
+}
+
+static void add_new_irq(int irq, struct irq_info *hint, GList *proc_interrupts)
 {
        struct irq_info *new;
        struct user_irq_policy pol;
@@ -667,12 +739,13 @@
        if (new)
                return;
 
-       get_irq_user_policy("/sys", irq, &pol);
-       if ((pol.ban == 1) || check_for_irq_ban(NULL, irq)) {
+       /* Set NULL devpath for the irq has no sysfs entries */
+       get_irq_user_policy(NULL, irq, &pol);
+       if ((pol.ban == 1) || check_for_irq_ban(NULL, irq, proc_interrupts)) { 
/*FIXME*/
                add_banned_irq(irq, &banned_irqs);
                new = get_irq_info(irq);
        } else
-               new = add_one_irq_to_db("/sys", irq, &pol);
+               new = add_one_irq_to_db(NULL, irq, &pol);
 
        if (!new) {
                log(TO_CONSOLE, LOG_WARNING, "add_new_irq: Failed to add irq 
%d\n", irq);
@@ -690,13 +763,13 @@
        new->level = map_class_to_level[new->class];
 }
 
-static void add_missing_irq(struct irq_info *info, void *unused 
__attribute__((unused)))
+static void add_missing_irq(struct irq_info *info, void *attr)
 {
        struct irq_info *lookup = get_irq_info(info->irq);
+       GList *proc_interrupts = (GList *) attr;
 
        if (!lookup)
-               add_new_irq(info->irq, info);
-       
+               add_new_irq(info->irq, info, proc_interrupts);
 }
 
 
@@ -707,7 +780,7 @@
        GList *tmp_irqs = NULL;
 
        free_irq_db();
-               
+
        tmp_irqs = collect_full_irq_list();
 
        devdir = opendir(SYSDEV_DIR);
@@ -720,14 +793,14 @@
                if (!entry)
                        break;
 
-               build_one_dev_entry(entry->d_name);
+               build_one_dev_entry(entry->d_name, tmp_irqs);
 
        } while (entry != NULL);
 
        closedir(devdir);
 
 
-       for_each_irq(tmp_irqs, add_missing_irq, NULL);
+       for_each_irq(tmp_irqs, add_missing_irq, interrupts_db);
 
 free:
        g_list_free_full(tmp_irqs, free);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/irqbalance-1.0.9/configure.ac 
new/irqbalance-1.1.0/configure.ac
--- old/irqbalance-1.0.9/configure.ac   2015-03-16 14:31:53.000000000 +0100
+++ new/irqbalance-1.1.0/configure.ac   2015-12-04 16:17:37.000000000 +0100
@@ -1,4 +1,4 @@
-AC_INIT(irqbalance,1.0.9)
+AC_INIT(irqbalance,1.1.0)
 AC_PREREQ(2.12)dnl
 AM_CONFIG_HEADER(config.h)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/irqbalance-1.0.9/cputree.c 
new/irqbalance-1.1.0/cputree.c
--- old/irqbalance-1.0.9/cputree.c      2015-03-16 14:31:53.000000000 +0100
+++ new/irqbalance-1.1.0/cputree.c      2015-12-04 16:17:37.000000000 +0100
@@ -59,17 +59,21 @@
 cpumask_t unbanned_cpus;
 
 /*
- * By default do not place IRQs on CPUs the kernel keeps isolated,
- * as specified through the isolcpus= boot commandline. Users can
+ * By default do not place IRQs on CPUs the kernel keeps isolated or
+ * nohz_full, as specified through the boot commandline. Users can
  * override this with the IRQBALANCE_BANNED_CPUS environment variable.
  */
 static void setup_banned_cpus(void)
 {
        FILE *file;
-       char *c, *line = NULL;
+       char *line = NULL;
        size_t size = 0;
-       const char *isolcpus = "isolcpus=";
        char buffer[4096];
+       cpumask_t nohz_full;
+       cpumask_t isolated_cpus;
+
+       cpus_clear(isolated_cpus);
+       cpus_clear(nohz_full);
 
        /* A manually specified cpumask overrides auto-detection. */
        if (getenv("IRQBALANCE_BANNED_CPUS"))  {
@@ -77,27 +81,35 @@
                goto out;
        }
 
-       file = fopen("/proc/cmdline", "r");
-       if (!file)
-               goto out;
-
-       if (getline(&line, &size, file) <= 0)
-               goto out;
-
-       if ((c = strstr(line, isolcpus))) {
-               char *end;
-               int len;
-
-               c += strlen(isolcpus);
-               for (end = c; *end != ' ' && *end != '\0' && *end != '\n'; 
end++);
-               len = end - c;
+       file = fopen("/sys/devices/system/cpu/isolated", "r");
+       if (file) {
+               if (getline(&line, &size, file) > 0) {
+                       cpulist_parse(line, size, isolated_cpus);
+                       free(line);
+                       line = NULL;
+                       size = 0;
+               }
+               fclose(file);
+       }
 
-               cpulist_parse(c, len, banned_cpus);
+       file = fopen("/sys/devices/system/cpu/nohz_full", "r");
+       if (file) {
+               if (getline(&line, &size, file) > 0) {
+                       cpulist_parse(line, size, nohz_full);
+                       free(line);
+                       line = NULL;
+                       size = 0;
+               }
+               fclose(file);
        }
 
- out:
-       cpumask_scnprintf(buffer, 4096, banned_cpus);
+       cpus_or(banned_cpus, nohz_full, isolated_cpus);
+
+out:
+       cpumask_scnprintf(buffer, 4096, isolated_cpus);
        log(TO_CONSOLE, LOG_INFO, "Isolated CPUs: %s\n", buffer);
+       cpumask_scnprintf(buffer, 4096, nohz_full);
+       log(TO_CONSOLE, LOG_INFO, "Adaptive-ticks CPUs: %s\n", buffer);
 }
 
 static struct topo_obj* add_cache_domain_to_package(struct topo_obj *cache, 
@@ -342,11 +354,12 @@
                indent[i] = log_indent[0];
 
        indent[i] = '\0';
-       log(TO_CONSOLE, LOG_INFO, "%sInterrupt %i node_num is %d (%s/%u) \n", 
indent,
-           info->irq, irq_numa_node(info)->number, classes[info->class], 
(unsigned int)info->load);
+       log(TO_CONSOLE, LOG_INFO, "%sInterrupt %i node_num is %d (%s/%llu:%llu) 
\n", indent,
+           info->irq, irq_numa_node(info)->number, classes[info->class], 
info->load, (info->irq_count - info->last_irq_count));
+       free(indent);
 }
 
-static void dump_topo_obj(struct topo_obj *d, void *data 
__attribute__((unused)))
+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",
@@ -364,7 +377,7 @@
            log_indent, log_indent,
            d->number, cache_domain_numa_node(d)->number, buffer, (unsigned 
long)d->load);
        if (d->children)
-               for_each_object(d->children, dump_topo_obj, NULL);
+               for_each_object(d->children, dump_balance_obj, NULL);
        if (g_list_length(d->interrupts) > 0)
                for_each_irq(d->interrupts, dump_irq, (void *)10);
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/irqbalance-1.0.9/irqbalance.1 
new/irqbalance-1.1.0/irqbalance.1
--- old/irqbalance-1.0.9/irqbalance.1   2015-03-16 14:31:53.000000000 +0100
+++ new/irqbalance-1.1.0/irqbalance.1   2015-12-04 16:17:37.000000000 +0100
@@ -130,7 +130,10 @@
 Have irqbalance write its process id to the specified file.  By default no
 pidfile is written.  The written pidfile is automatically unlinked when
 irqbalance exits. It is ignored when used with --debug or --foreground.
-
+.TP
+.B -t, --interval=<time>
+Set the measurement time for irqbalance.  irqbalance will sleep for <time>
+seconds between samples of the irq load on the system cpus. Defaults to 10.
 .SH "ENVIRONMENT VARIABLES"
 .TP
 .B IRQBALANCE_ONESHOT
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/irqbalance-1.0.9/irqbalance.c 
new/irqbalance-1.1.0/irqbalance.c
--- old/irqbalance-1.0.9/irqbalance.c   2015-03-16 14:31:53.000000000 +0100
+++ new/irqbalance-1.1.0/irqbalance.c   2015-12-04 16:17:37.000000000 +0100
@@ -49,7 +49,7 @@
 int journal_logging = 0;
 int need_rescan;
 unsigned int log_mask = TO_ALL;
-char * log_indent;
+const char *log_indent;
 enum hp_e global_hint_policy = HINT_POLICY_IGNORE;
 unsigned long power_thresh = ULONG_MAX;
 unsigned long deepest_cache = 2;
@@ -58,6 +58,7 @@
 char *banscript = NULL;
 char *polscript = NULL;
 long HZ;
+int sleep_interval = SLEEP_INTERVAL;
 
 static void sleep_approx(int seconds)
 {
@@ -86,13 +87,16 @@
        {"policyscript", 1, NULL, 'l'},
        {"pid", 1, NULL, 's'},
        {"journal", 0, NULL, 'j'},
+       {"banmod", 1 , NULL, 'm'},
+       {"interval", 1 , NULL, 't'},
        {0, 0, 0, 0}
 };
 
 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, "     [--powerthresh= | -p <off> | <n>] 
[--banirq= | -i <n>] [--policyscript=<script>] [--pid= | -s <file>] 
[--deepestcache= | -c <n>]\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");
 }
 
 static void parse_command_line(int argc, char **argv)
@@ -102,7 +106,7 @@
        unsigned long val;
 
        while ((opt = getopt_long(argc, argv,
-               "odfjh:i:p:s:c:b:l:",
+               "odfjh:i:p:s:c:b:l:m:t:",
                lopts, &longind)) != -1) {
 
                switch(opt) {
@@ -116,7 +120,7 @@
                                 * Banscript is no longer supported unless
                                 * explicitly enabled
                                 */
-                               log(TO_CONSOLE, LOG_INFO, "--banscript is not 
supported on this version of irqbalance, please use --polscript");
+                               log(TO_CONSOLE, LOG_INFO, "--banscript is not 
supported on this version of irqbalance, please use --policyscript\n");
                                usage();
                                exit(1);
 #endif
@@ -159,6 +163,9 @@
                        case 'l':
                                polscript = strdup(optarg);
                                break;
+                       case 'm':
+                               add_cl_banned_module(optarg);
+                               break;
                        case 'p':
                                if (!strncmp(optarg, "off", strlen(optarg)))
                                        power_thresh = ULONG_MAX;
@@ -180,6 +187,13 @@
                                journal_logging=1;
                                foreground_mode=1;
                                break;
+                       case 't':
+                               sleep_interval = strtol(optarg, NULL, 10);
+                               if (sleep_interval < 1) {
+                                       usage();
+                                       exit(1);
+                               }
+                               break;
                }
        }
 }
@@ -279,17 +293,19 @@
        if (getenv("IRQBALANCE_ONESHOT")) 
                one_shot_mode=1;
 
-       if (getenv("IRQBALANCE_DEBUG")) 
+       if (getenv("IRQBALANCE_DEBUG")) {
                debug_mode=1;
+               foreground_mode=1;
+       }
 
        /*
         * If we are't in debug mode, don't dump anything to the console
         * note that everything goes to the console before we check this
         */
        if (journal_logging)
-               log_indent = strdup("....");
+               log_indent = "....";
        else
-               log_indent = strdup("    ");
+               log_indent = "    ";
 
        if (!debug_mode)
                log_mask &= ~TO_CONSOLE;
@@ -370,7 +386,7 @@
        parse_proc_stat();
 
        while (keep_going) {
-               sleep_approx(SLEEP_INTERVAL);
+               sleep_approx(sleep_interval);
                log(TO_CONSOLE, LOG_INFO, 
"\n\n\n-----------------------------------------------------------------------------\n");
 
 
@@ -390,7 +406,7 @@
                        for_each_irq(NULL, force_rebalance_irq, NULL);
                        parse_proc_interrupts();
                        parse_proc_stat();
-                       sleep_approx(SLEEP_INTERVAL);
+                       sleep_approx(sleep_interval);
                        clear_work_stats();
                        parse_proc_interrupts();
                        parse_proc_stat();
@@ -410,6 +426,7 @@
 
        }
        free_object_tree();
+       free_cl_opts();
 
        /* Remove pidfile */
        if (!foreground_mode && pidfile)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/irqbalance-1.0.9/irqbalance.h 
new/irqbalance-1.1.0/irqbalance.h
--- old/irqbalance-1.0.9/irqbalance.h   2015-03-16 14:31:53.000000000 +0100
+++ new/irqbalance-1.1.0/irqbalance.h   2015-12-04 16:17:37.000000000 +0100
@@ -13,6 +13,11 @@
 
 #include "types.h"
 #include "config.h"
+
+#ifdef __aarch64__
+#define AARCH64
+#endif
+
 #ifdef HAVE_NUMA_H
 #include <numa.h>
 #else
@@ -116,6 +121,8 @@
 extern void for_each_irq(GList *list, void (*cb)(struct irq_info *info,  void 
*data), void *data);
 extern struct irq_info *get_irq_info(int irq);
 extern void migrate_irq(GList **from, GList **to, struct irq_info *info);
+extern void free_cl_opts(void);
+extern void add_cl_banned_module(char *modname);
 #define irq_numa_node(irq) ((irq)->numa_node)
 
 
@@ -140,7 +147,7 @@
 #define TO_CONSOLE     (1 << 1)
 #define TO_ALL         (TO_SYSLOG | TO_CONSOLE)
 
-extern char * log_indent;
+extern const char * log_indent;
 extern unsigned int log_mask;
 #ifdef HAVE_LIBSYSTEMD
 #define log(mask, lvl, fmt, args...) do {                                      
\
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/irqbalance-1.0.9/irqlist.c 
new/irqbalance-1.1.0/irqlist.c
--- old/irqbalance-1.0.9/irqlist.c      2015-03-16 14:31:53.000000000 +0100
+++ new/irqbalance-1.1.0/irqlist.c      2015-12-04 16:17:37.000000000 +0100
@@ -130,7 +130,7 @@
 
        if ((obj->load > info->min_load) &&
            (g_list_length(obj->interrupts) > 1)) {
-               /* order the list from least to greatest workload */
+               /* order the list from greatest to least workload */
                sort_irq_list(&obj->interrupts);
                /*
                 * Each irq carries a weighted average amount of load
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/irqbalance-1.0.9/placement.c 
new/irqbalance-1.1.0/placement.c
--- old/irqbalance-1.0.9/placement.c    2015-03-16 14:31:53.000000000 +0100
+++ new/irqbalance-1.1.0/placement.c    2015-12-04 16:17:37.000000000 +0100
@@ -33,7 +33,6 @@
 
 struct obj_placement {
                struct topo_obj *best;
-               struct topo_obj *least_irqs;
                uint64_t best_cost;
                struct irq_info *info;
 };
@@ -78,12 +77,10 @@
        if (newload < best->best_cost) {
                best->best = d;
                best->best_cost = newload;
-               best->least_irqs = NULL;
-       }
-
-       if (newload == best->best_cost) {
-               if (g_list_length(d->interrupts) < 
g_list_length(best->best->interrupts))
-                       best->least_irqs = d;
+       } else if (newload == best->best_cost) {
+               if (g_list_length(d->interrupts) < 
g_list_length(best->best->interrupts)) {
+                       best->best = d;
+               }
        }
 }
 
@@ -120,12 +117,11 @@
 
        place.info = info;
        place.best = NULL;
-       place.least_irqs = NULL;
        place.best_cost = ULLONG_MAX;
 
        for_each_object(d->children, find_best_object, &place);
 
-       asign = place.least_irqs ? place.least_irqs : place.best;
+       asign = place.best;
 
        if (asign) {
                migrate_irq(&d->interrupts, &asign->interrupts, info);
@@ -168,12 +164,11 @@
 find_placement:
        place.best_cost = ULLONG_MAX;
        place.best = NULL;
-       place.least_irqs = NULL;
        place.info = info;
 
        for_each_object(numa_nodes, find_best_object, &place);
 
-       asign = place.least_irqs ? place.least_irqs : place.best;
+       asign = place.best;
 
        if (asign) {
                migrate_irq(&rebalance_irq_list, &asign->interrupts, info);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/irqbalance-1.0.9/procinterrupts.c 
new/irqbalance-1.1.0/procinterrupts.c
--- old/irqbalance-1.0.9/procinterrupts.c       2015-03-16 14:31:53.000000000 
+0100
+++ new/irqbalance-1.1.0/procinterrupts.c       2015-12-04 16:17:37.000000000 
+0100
@@ -27,22 +27,128 @@
 #include <string.h>
 #include <syslog.h>
 #include <ctype.h>
+#include <errno.h>
 
 #include "cpumask.h"
 #include "irqbalance.h"
 
+#ifdef AARCH64
+#include <sys/types.h>
+#include <regex.h>
+#include <dirent.h>
+#endif
+
 #define LINESIZE 4096
 
 static int proc_int_has_msi = 0;
 static int msi_found_in_sysfs = 0;
 
+#ifdef AARCH64
+struct irq_match {
+       char *matchstring;
+       regex_t rcomp;
+       int (*refine_match)(char *name, struct irq_info *info);
+       int type;
+       int class;
+};
+
+static int check_platform_device(char *name, struct irq_info *info)
+{
+       DIR *dirfd;
+       char path[512];
+       struct dirent *ent;
+       int rc = -ENOENT;
+
+       memset(path, 0, 512);
+
+       strcat(path, "/sys/devices/platform/");
+       strcat(path, name);
+       strcat(path, "/");
+       dirfd = opendir(path);
+
+       if (!dirfd) {
+               log(TO_ALL, LOG_DEBUG, "No directory %s: %s\n", path, 
strerror(errno));
+               return -ENOENT;
+       }
+
+       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->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;
+               }
+       }
+
+out:
+       closedir(dirfd);
+       log(TO_ALL, LOG_DEBUG, "IRQ %s is of type %d and class %d\n", name, 
info->type, info->class)
+       return rc;
+
+}
+
+static void guess_arm_irq_hints(char *name, struct irq_info *info)
+{
+       int i, rc;
+       static int compiled = 0;
+       static struct irq_match matches[] = {
+               { "eth.*" ,{NULL} ,NULL, IRQ_TYPE_LEGACY, IRQ_GBETH },
+               { "[A-Z0-9]{4}[0-9a-f]{4}", {NULL} ,check_platform_device, 
IRQ_TYPE_LEGACY, IRQ_OTHER},
+               { "PNP[0-9a-f]{4}", {NULL} ,check_platform_device, 
IRQ_TYPE_LEGACY, IRQ_OTHER},
+               {NULL},
+       };
+
+
+       if (!compiled) {
+               for (i=0; matches[i].matchstring != NULL; i++) {
+                       rc = regcomp(&matches[i].rcomp, matches[i].matchstring, 
REG_EXTENDED | REG_NOSUB);
+                       if (rc) {
+                               char errbuf[256];
+                               regerror(rc, &matches[i].rcomp, errbuf, 256);
+                               log(TO_ALL, LOG_WARNING, "WARNING: Failed to 
compile regex %s : %s\n",
+                                   matches[i].matchstring, errbuf);
+                               return;
+                       }
+               }
+
+               compiled = 1;
+       }
+
+       for (i=0; matches[i].matchstring != NULL; i++) {
+               if (!regexec(&matches[i].rcomp, name, 0, NULL, 0)) {
+                       info->type = matches[i].type;
+                       info->class = matches[i].class;
+                       if (matches[i].refine_match)
+                           matches[i].refine_match(name, info);
+
+                       log(TO_ALL, LOG_DEBUG, "IRQ %s(%d) is class %d\n", 
name, info->irq,info->class);
+               }       
+       }
+       
+       
+}
+#endif
+
 GList* collect_full_irq_list()
 {
        GList *tmp_list = NULL;
        FILE *file;
        char *line = NULL;
        size_t size = 0;
-       char *irq_name, *savedptr, *last_token, *p;
+       char *irq_name, *irq_mod, *savedptr, *last_token, *p;
+       char *tmp;
 
        file = fopen("/proc/interrupts", "r");
        if (!file)
@@ -68,7 +174,7 @@
                c = line;
                while (isblank(*(c)))
                        c++;
-                       
+
                if (!(*c>='0' && *c<='9'))
                        break;
                c = strchr(line, ':');
@@ -76,7 +182,6 @@
                        continue;
 
                strncpy(savedline, line, sizeof(savedline));
-
                irq_name = strtok_r(savedline, " ", &savedptr);
                last_token = strtok_r(NULL, " ", &savedptr);
                while ((p = strtok_r(NULL, " ", &savedptr))) {
@@ -84,6 +189,15 @@
                        last_token = p;
                }
 
+#ifdef AARCH64
+               /* Of course the formatting for /proc/interrupts is different 
on different arches */
+               irq_name = last_token;
+               tmp = strchr(irq_name, '\n');
+               if (tmp)
+                       *tmp = 0;
+#endif
+               irq_mod = last_token;
+
                *c = 0;
                c++;
                number = strtoul(line, NULL, 10);
@@ -95,13 +209,18 @@
                                info->type = IRQ_TYPE_VIRT_EVENT;
                                info->class = IRQ_VIRT_EVENT;
                        } else {
+#ifdef AARCH64
+                               log(TO_ALL, LOG_DEBUG, "GUESSING AARCH64 CLASS 
FOR %s\n", irq_name);
+                               guess_arm_irq_hints(irq_name, info);
+#else
                                info->type = IRQ_TYPE_LEGACY;
                                info->class = IRQ_OTHER;
-                       } 
+#endif
+                       }
                        info->hint_policy = global_hint_policy;
+                       info->name = strdupa(irq_mod);
                        tmp_list = g_list_append(tmp_list, info);
                }
-
        }
        fclose(file);
        free(line);
@@ -210,13 +329,6 @@
 }
 
 
-static void accumulate_irq_count(struct irq_info *info, void *data)
-{
-       uint64_t *acc = data;
-
-       *acc += (info->irq_count - info->last_irq_count);
-}
-
 static void assign_load_slice(struct irq_info *info, void *data)
 {
        uint64_t *load_slice = data;
@@ -242,36 +354,68 @@
                total_irq_count /= g_list_length((d->parent)->children);
        }
 
-       if (g_list_length(d->interrupts) > 0)
-               for_each_irq(d->interrupts, accumulate_irq_count, 
&total_irq_count);
+       total_irq_count += d->irq_count;
 
        return total_irq_count;
 }
 
+static void get_children_branch_irq_count(struct topo_obj *d, void *data)
+{
+       uint64_t *total_irq_count = data;
+
+       if (g_list_length(d->children) > 0)
+               for_each_object(d->children, get_children_branch_irq_count, 
total_irq_count);
+
+       *total_irq_count += d->irq_count;
+}
+
 static void compute_irq_branch_load_share(struct topo_obj *d, void *data 
__attribute__((unused)))
 {
        uint64_t local_irq_counts = 0;
        uint64_t load_slice;
-       int     load_divisor = g_list_length(d->children);
-
-       d->load /= (load_divisor ? load_divisor : 1);
 
        if (g_list_length(d->interrupts) > 0) {
                local_irq_counts = get_parent_branch_irq_count_share(d);
+               if (g_list_length(d->children) > 0)
+                       for_each_object(d->children, 
get_children_branch_irq_count, &local_irq_counts);
                load_slice = local_irq_counts ? (d->load / local_irq_counts) : 
1;
                for_each_irq(d->interrupts, assign_load_slice, &load_slice);
        }
 
-       if (d->parent)
-               d->parent->load += d->load;
 }
 
-static void reset_load(struct topo_obj *d, void *data __attribute__((unused)))
+static void accumulate_irq_count(struct irq_info *info, void *data)
+{
+       uint64_t *acc = data;
+
+       *acc += (info->irq_count - info->last_irq_count);
+}
+
+static void accumulate_interrupts(struct topo_obj *d, void *data 
__attribute__((unused)))
+{
+       if (g_list_length(d->children) > 0) {
+               for_each_object(d->children, accumulate_interrupts, NULL);
+       }
+
+       d->irq_count = 0;
+       if (g_list_length(d->interrupts) > 0)
+               for_each_irq(d->interrupts, accumulate_irq_count, 
&(d->irq_count));
+}
+
+static void accumulate_load(struct topo_obj *d, void *data)
 {
-       if (d->parent)
-               reset_load(d->parent, NULL);
+       uint64_t *load = data;
 
-       d->load = 0;
+       *load += d->load;
+}
+
+static void set_load(struct topo_obj *d, void *data __attribute__((unused)))
+{
+       if (g_list_length(d->children) > 0) {
+               for_each_object(d->children, set_load, NULL);
+               d->load = 0;
+               for_each_object(d->children, accumulate_load, &(d->load));
+       }
 }
 
 void parse_proc_stat(void)
@@ -346,9 +490,14 @@
        }
 
        /*
-        * Reset the load values for all objects above cpus
+        * Set the load values for all objects above cpus
+        */
+       for_each_object(numa_nodes, set_load, NULL);
+
+       /*
+        * Collect local irq_count on each object
         */
-       for_each_object(cache_domains, reset_load, NULL);
+       for_each_object(numa_nodes, accumulate_interrupts, NULL);
 
        /*
         * Now that we have load for each cpu attribute a fair share of the load
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/irqbalance-1.0.9/types.h new/irqbalance-1.1.0/types.h
--- old/irqbalance-1.0.9/types.h        2015-03-16 14:31:53.000000000 +0100
+++ new/irqbalance-1.1.0/types.h        2015-12-04 16:17:37.000000000 +0100
@@ -46,6 +46,7 @@
 struct topo_obj {
        uint64_t load;
        uint64_t last_load;
+       uint64_t irq_count;
        enum obj_type_e obj_type;
        int number;
        int powersave_mode;
@@ -70,8 +71,9 @@
        uint64_t last_irq_count;
        uint64_t load;
        int moved;
-struct topo_obj *assigned_obj;
-   unsigned int warned;
+       struct topo_obj *assigned_obj;
+       unsigned int warned;
+       char *name;
 };
 
 #endif


Reply via email to