diff --git a/activate.c b/activate.c index ab9702d..065f880 100644 --- a/activate.c +++ b/activate.c @@ -48,6 +48,7 @@ static void activate_mapping(struct irq_info *info, void *data __attribute__((un { char buf[PATH_MAX]; FILE *file; + int ret = 0; /* * only activate mappings for irqs that have moved @@ -70,7 +71,12 @@ static void activate_mapping(struct irq_info *info, void *data __attribute__((un return; cpumask_scnprintf(buf, PATH_MAX, info->assigned_obj->mask); - fprintf(file, "%s", buf); + ret = fprintf(file, "%s", buf); + if (ret < 0) { + log(TO_ALL, LOG_WARNING, "cannot change irq %i's affinity, add it to banned list", info->irq); + add_banned_irq(info->irq); + remove_one_irq_from_db(info->irq); + } fclose(file); info->moved = 0; /*migration is done*/ } diff --git a/classify.c b/classify.c index fa900f4..9f588bc 100644 --- a/classify.c +++ b/classify.c @@ -256,7 +256,7 @@ static gint compare_ints(gconstpointer a, gconstpointer b) return ai->irq - bi->irq; } -static void add_banned_irq(int irq, GList **list) +static void __add_banned_irq(int irq, GList **list) { struct irq_info find, *new; GList *entry; @@ -280,9 +280,14 @@ static void add_banned_irq(int irq, GList **list) return; } +void add_banned_irq(int irq) +{ + __add_banned_irq(irq, &banned_irqs); +} + void add_cl_banned_irq(int irq) { - add_banned_irq(irq, &cl_banned_irqs); + __add_banned_irq(irq, &cl_banned_irqs); } gint substr_find(gconstpointer a, gconstpointer b) @@ -376,6 +381,23 @@ get_numa_node: return new; } +void remove_one_irq_from_db(int irq) +{ + struct irq_info find, *tmp; + GList *entry = NULL; + + find.irq = irq; + entry = g_list_find_custom(interrupts_db, &find, compare_ints); + if (!entry) + return; + + tmp = entry->data; + interrupts_db = g_list_remove(interrupts_db, tmp); + free(tmp); + log(TO_CONSOLE, LOG_INFO, "IRQ %d was removed from db.\n", irq); + return; +} + static void parse_user_policy_key(char *buf, int irq, struct user_irq_policy *pol) { char *key, *value, *end; @@ -585,7 +607,7 @@ static void add_new_irq(char *path, struct irq_info *hint, GList *proc_interrupt /* Set NULL devpath for the irq has no sysfs entries */ get_irq_user_policy(path, irq, &pol); if ((pol.ban == 1) || check_for_irq_ban(irq, proc_interrupts)) { /*FIXME*/ - add_banned_irq(irq, &banned_irqs); + __add_banned_irq(irq, &banned_irqs); new = get_irq_info(irq); } else new = add_one_irq_to_db(path, hint, &pol); diff --git a/irqbalance.h b/irqbalance.h index cd93167..bc34d7e 100644 --- a/irqbalance.h +++ b/irqbalance.h @@ -106,6 +106,8 @@ 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); +extern void add_banned_irq(int irq); +extern void remove_one_irq_from_db(int irq); #define irq_numa_node(irq) ((irq)->numa_node)