[irqbalance] [PATCH v2] irqbalance: introduced new --banmod option

  • From: Petr Holasek <pholasek@xxxxxxxxxx>
  • To: irqbalance@xxxxxxxxxxxxx
  • Date: Thu, 19 Mar 2015 16:09:07 +0100

New --banmod option works similar as --banirq, i.e. user can specify
module names whose interrupts should be banned. Every irq_info struct
also now includes name of the modele parsed from /proc/interrupts.

Signed-off-by: Petr Holasek <pholasek@xxxxxxxxxx>
---
 classify.c       | 77 ++++++++++++++++++++++++++++++++++++++++++++------------
 irqbalance.c     | 10 ++++++--
 irqbalance.h     |  2 ++
 procinterrupts.c |  9 ++++---
 types.h          |  5 ++--
 5 files changed, 79 insertions(+), 24 deletions(-)

diff --git a/classify.c b/classify.c
index e780136..7012907 100644
--- a/classify.c
+++ b/classify.c
@@ -37,6 +37,7 @@ struct user_irq_policy {
 static GList *interrupts_db = NULL;
 static GList *banned_irqs = NULL;
 static GList *cl_banned_irqs = NULL;
+static GList *cl_banned_modules = NULL;
 
 #define SYSDEV_DIR "/sys/bus/pci/devices"
 
@@ -284,6 +285,7 @@ static void add_banned_irq(int irq, GList **list)
        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 +294,6 @@ void add_cl_banned_irq(int irq)
        add_banned_irq(irq, &cl_banned_irqs);
 }
 
-
 static int is_banned_irq(int irq)
 {
        GList *entry;
@@ -304,6 +305,29 @@ static int is_banned_irq(int irq)
        return entry ? 1:0;
 }
 
+static void add_banned_module(char *modname, GList **modlist)
+{
+       GList *entry;
+       char *newmod;
+       
+       entry = g_list_find(*modlist, modname);
+       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
@@ -522,11 +546,29 @@ static void get_irq_user_policy(char *path, int irq, 
struct user_irq_policy *pol
        pclose(output);
 }
 
-static int check_for_irq_ban(char *path, int irq)
+gint substr_find(gconstpointer a, gconstpointer b)
+{
+       if (strstr(b, a))
+               return 0;
+       else
+               return 1;
+}
+
+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;
 
        /*
@@ -548,6 +590,9 @@ static int check_for_irq_ban(char *path, int irq)
        }
 
 #ifdef INCLUDE_BANSCRIPT
+       char *cmd;
+       int rc;
+
        if (!banscript)
                return 0;
 
@@ -578,9 +623,9 @@ static int check_for_irq_ban(char *path, int irq)
 }
 
 /*
- * 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;
@@ -607,7 +652,7 @@ static void build_one_dev_entry(const char *dirname)
                                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;
                                }
@@ -636,7 +681,7 @@ static void build_one_dev_entry(const char *dirname)
                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;
                }
@@ -686,7 +731,7 @@ static void add_new_irq(int irq, struct irq_info *hint, 
GList *proc_interrupts)
                return;
 
        get_irq_user_policy("/sys", irq, &pol);
-       if ((pol.ban == 1) || check_for_irq_ban(NULL, irq)) {
+       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
@@ -708,13 +753,13 @@ static void add_new_irq(int irq, struct irq_info *hint, 
GList *proc_interrupts)
        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);
 }
 
 
@@ -725,7 +770,7 @@ void rebuild_irq_db(void)
        GList *tmp_irqs = NULL;
 
        free_irq_db();
-               
+
        tmp_irqs = collect_full_irq_list();
 
        devdir = opendir(SYSDEV_DIR);
@@ -738,14 +783,14 @@ void rebuild_irq_db(void)
                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, tmp_irqs);
 
 free:
        g_list_free_full(tmp_irqs, free);
diff --git a/irqbalance.c b/irqbalance.c
index 226fcc6..6a4c74d 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -86,13 +86,15 @@ struct option lopts[] = {
        {"policyscript", 1, NULL, 'l'},
        {"pid", 1, NULL, 's'},
        {"journal", 0, NULL, 'j'},
+       {"banmod", 1 , NULL, 'm'},
        {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= | -l <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>]\n");
 }
 
 static void parse_command_line(int argc, char **argv)
@@ -102,7 +104,7 @@ static void parse_command_line(int argc, char **argv)
        unsigned long val;
 
        while ((opt = getopt_long(argc, argv,
-               "odfjh:i:p:s:c:b:l:",
+               "odfjh:i:p:s:c:b:l:m:",
                lopts, &longind)) != -1) {
 
                switch(opt) {
@@ -159,6 +161,9 @@ static void parse_command_line(int argc, char **argv)
                        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;
@@ -209,6 +214,7 @@ static void free_object_tree(void)
        free_numa_node_list();
        clear_cpu_tree();
        free_irq_db();
+       free_cl_opts();
 }
 
 static void dump_object_tree(void)
diff --git a/irqbalance.h b/irqbalance.h
index a498dc2..adcc518 100644
--- a/irqbalance.h
+++ b/irqbalance.h
@@ -116,6 +116,8 @@ extern void add_cl_banned_irq(int irq);
 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)
 
 
diff --git a/procinterrupts.c b/procinterrupts.c
index 3476473..f4dcdc7 100644
--- a/procinterrupts.c
+++ b/procinterrupts.c
@@ -42,7 +42,7 @@ GList* collect_full_irq_list()
        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;
 
        file = fopen("/proc/interrupts", "r");
        if (!file)
@@ -68,7 +68,7 @@ GList* collect_full_irq_list()
                c = line;
                while (isblank(*(c)))
                        c++;
-                       
+
                if (!(*c>='0' && *c<='9'))
                        break;
                c = strchr(line, ':');
@@ -83,6 +83,7 @@ GList* collect_full_irq_list()
                        irq_name = last_token;
                        last_token = p;
                }
+               irq_mod = last_token;
 
                *c = 0;
                c++;
@@ -97,11 +98,11 @@ GList* collect_full_irq_list()
                        } else {
                                info->type = IRQ_TYPE_LEGACY;
                                info->class = IRQ_OTHER;
-                       } 
+                       }
                        info->hint_policy = global_hint_policy;
+                       info->name = strdupa(irq_mod);
                        tmp_list = g_list_append(tmp_list, info);
                }
-
        }
        fclose(file);
        free(line);
diff --git a/types.h b/types.h
index 47f5477..71ce6a2 100644
--- a/types.h
+++ b/types.h
@@ -70,8 +70,9 @@ struct irq_info {
        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
-- 
2.1.0


Other related posts:

  • » [irqbalance] [PATCH v2] irqbalance: introduced new --banmod option - Petr Holasek