From b6da319b94d9f25e635c66fb02062f3559560384 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Tue, 20 May 2014 10:27:52 -0400 Subject: [PATCH] track hint policy on a per-irq basis Currently the hintpolicy for irqbalance is a global setting, applied equally to all irqs. Thats undesireable however, as different devices may want to follow different policies. Track the hint policy in each irq_info struct instead. This still just follows the global policy, but paves the way to allow overriding through the policyscript option Signed-off-by: Neil Horman --- activate.c | 4 ++-- classify.c | 2 ++ irqbalance.c | 8 ++++---- irqbalance.h | 2 +- irqlist.c | 2 +- placement.c | 2 +- procinterrupts.c | 1 + types.h | 1 + 8 files changed, 13 insertions(+), 9 deletions(-) diff --git a/activate.c b/activate.c index 5a4d55d..13366c8 100644 --- a/activate.c +++ b/activate.c @@ -69,7 +69,7 @@ static void activate_mapping(struct irq_info *info, void *data __attribute__((un if (!info->moved) return; - if ((hint_policy == HINT_POLICY_EXACT) && + if ((info->hint_policy == HINT_POLICY_EXACT) && (!cpus_empty(info->affinity_hint))) { if (cpus_intersects(info->affinity_hint, banned_cpus)) log(TO_ALL, LOG_WARNING, @@ -81,7 +81,7 @@ static void activate_mapping(struct irq_info *info, void *data __attribute__((un } } else if (info->assigned_obj) { applied_mask = info->assigned_obj->mask; - if ((hint_policy == HINT_POLICY_SUBSET) && + if ((info->hint_policy == HINT_POLICY_SUBSET) && (!cpus_empty(info->affinity_hint))) { cpus_and(applied_mask, applied_mask, info->affinity_hint); if (!cpus_intersects(applied_mask, unbanned_cpus)) diff --git a/classify.c b/classify.c index 8c7d482..c2383e8 100644 --- a/classify.c +++ b/classify.c @@ -91,6 +91,7 @@ void add_banned_irq(int irq, GList **list) new->irq = irq; new->flags |= IRQ_FLAG_BANNED; + new->hint_policy = HINT_POLICY_EXACT; *list = g_list_append(*list, new); return; @@ -153,6 +154,7 @@ static struct irq_info *add_one_irq_to_db(const char *devpath, int irq, struct u new->irq = irq; new->class = IRQ_OTHER; + new->hint_policy = global_hint_policy; interrupts_db = g_list_append(interrupts_db, new); diff --git a/irqbalance.c b/irqbalance.c index e0b3cbe..07ee50a 100644 --- a/irqbalance.c +++ b/irqbalance.c @@ -48,7 +48,7 @@ int foreground_mode; int numa_avail; int need_rescan; unsigned int log_mask = TO_ALL; -enum hp_e hint_policy = HINT_POLICY_IGNORE; +enum hp_e global_hint_policy = HINT_POLICY_IGNORE; unsigned long power_thresh = ULONG_MAX; unsigned long deepest_cache = 2; unsigned long long cycle_count = 0; @@ -135,11 +135,11 @@ static void parse_command_line(int argc, char **argv) break; case 'h': if (!strncmp(optarg, "exact", strlen(optarg))) - hint_policy = HINT_POLICY_EXACT; + global_hint_policy = HINT_POLICY_EXACT; else if (!strncmp(optarg, "subset", strlen(optarg))) - hint_policy = HINT_POLICY_SUBSET; + global_hint_policy = HINT_POLICY_SUBSET; else if (!strncmp(optarg, "ignore", strlen(optarg))) - hint_policy = HINT_POLICY_IGNORE; + global_hint_policy = HINT_POLICY_IGNORE; else { usage(); exit(1); diff --git a/irqbalance.h b/irqbalance.h index cb648a5..aa521ea 100644 --- a/irqbalance.h +++ b/irqbalance.h @@ -62,7 +62,7 @@ enum hp_e { extern int debug_mode; extern int one_shot_mode; extern int need_rescan; -extern enum hp_e hint_policy; +extern enum hp_e global_hint_policy; extern unsigned long long cycle_count; extern unsigned long power_thresh; extern unsigned long deepest_cache; diff --git a/irqlist.c b/irqlist.c index 73b1be0..6e3038b 100644 --- a/irqlist.c +++ b/irqlist.c @@ -80,7 +80,7 @@ static void move_candidate_irqs(struct irq_info *info, void *data) /* never move an irq that has an afinity hint when * hint_policy is HINT_POLICY_EXACT */ - if (hint_policy == HINT_POLICY_EXACT) + if (info->hint_policy == HINT_POLICY_EXACT) if (!cpus_empty(info->affinity_hint)) return; diff --git a/placement.c b/placement.c index 3f3fdf1..cc0d273 100644 --- a/placement.c +++ b/placement.c @@ -63,7 +63,7 @@ static void find_best_object(struct topo_obj *d, void *data) * to consider objects that are within the irqs hint, but * only if that irq in fact has published a hint */ - if (hint_policy == HINT_POLICY_SUBSET) { + if (best->info->hint_policy == HINT_POLICY_SUBSET) { if (!cpus_empty(best->info->affinity_hint)) { cpus_and(subset, best->info->affinity_hint, d->mask); if (cpus_empty(subset)) diff --git a/procinterrupts.c b/procinterrupts.c index 055c421..6a6bdaa 100644 --- a/procinterrupts.c +++ b/procinterrupts.c @@ -98,6 +98,7 @@ GList* collect_full_irq_list() info->type = IRQ_TYPE_LEGACY; info->class = IRQ_OTHER; } + info->hint_policy = global_hint_policy; tmp_list = g_list_append(tmp_list, info); } diff --git a/types.h b/types.h index b3148ed..b65b115 100644 --- a/types.h +++ b/types.h @@ -64,6 +64,7 @@ struct irq_info { struct topo_obj *numa_node; cpumask_t cpumask; cpumask_t affinity_hint; + int hint_policy; uint64_t irq_count; uint64_t last_irq_count; uint64_t load;