Commit 02a3f03c authored by Petr Holasek's avatar Petr Holasek Committed by Neil Horman

irqbalance: introduced new --banmod option

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: 's avatarPetr Holasek <pholasek@redhat.com>
parent face8aa6
......@@ -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);
......
......@@ -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)
......
......@@ -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)
......
......@@ -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);
......
......@@ -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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment