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