Improve rescan ability for newly allocated interrupts

When an interrupt is registered after irqbalance starts we just add it as a misc
interrupt, even if its something that we want to balance.  Instead, lets add the
irq to a temp list, force a rescan, then make sure the newly discovered irqs get
added properly on the rescan.

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
This commit is contained in:
Neil Horman 2012-08-09 14:18:23 -04:00
parent 638d405bee
commit fd24d8f300
3 changed files with 35 additions and 14 deletions

View file

@ -52,6 +52,7 @@ static short class_codes[MAX_CLASS] = {
};
static GList *interrupts_db;
static GList *new_irq_list;
static GList *banned_irqs;
#define SYSDEV_DIR "/sys/bus/pci/devices"
@ -326,6 +327,8 @@ void rebuild_irq_db(void)
{
DIR *devdir = opendir(SYSDEV_DIR);
struct dirent *entry;
GList *gentry;
struct irq_info *ninfo, *iinfo;
free_irq_db();
@ -341,22 +344,46 @@ void rebuild_irq_db(void)
build_one_dev_entry(entry->d_name);
} while (entry != NULL);
closedir(devdir);
if (!new_irq_list)
return;
gentry = g_list_first(new_irq_list);
while(gentry) {
ninfo = gentry->data;
iinfo = get_irq_info(ninfo->irq);
new_irq_list = g_list_remove(gentry, ninfo);
if (!iinfo) {
if (debug_mode)
printf("Adding untracked IRQ %d to database\n", ninfo->irq);
interrupts_db = g_list_append(interrupts_db, ninfo);
} else
free(ninfo);
gentry = g_list_first(new_irq_list);
}
g_list_free(new_irq_list);
new_irq_list = NULL;
}
struct irq_info *add_misc_irq(int irq)
struct irq_info *add_new_irq(int irq)
{
struct irq_info *new;
struct irq_info *new, *nnew;
new = calloc(sizeof(struct irq_info), 1);
if (!new)
nnew = calloc(sizeof(struct irq_info), 1);
if (!new || !nnew)
return NULL;
new->irq = irq;
new->type = IRQ_TYPE_LEGACY;
new->class = IRQ_OTHER;
new->numa_node = get_numa_node(-1);
memcpy(nnew, new, sizeof(struct irq_info));
interrupts_db = g_list_append(interrupts_db, new);
new_irq_list = g_list_append(new_irq_list, nnew);
return new;
}

View file

@ -108,7 +108,7 @@ extern void add_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 struct irq_info *add_misc_irq(int irq);
extern struct irq_info *add_new_irq(int irq);
#define irq_numa_node(irq) ((irq)->numa_node)

View file

@ -84,16 +84,10 @@ void parse_proc_interrupts(void)
number = strtoul(line, NULL, 10);
info = get_irq_info(number);
if (!info) {
/*
* If this is our 0th pass through this routine
* this is an irq that wasn't reported in sysfs
* and we should just add it. If we've been running
* a while then this irq just appeared and its time
* to rescan our irqs
*/
if (cycle_count)
need_rescan = 1;
info = add_misc_irq(number);
if (!cycle_count)
continue;
need_rescan = 1;
info = add_new_irq(number);
}
count = 0;