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 <nhorman@tuxdriver.com>
This commit is contained in:
Neil Horman 2014-05-20 10:27:52 -04:00
parent 7f072d94c9
commit b6da319b94
8 changed files with 13 additions and 9 deletions

View file

@ -69,7 +69,7 @@ static void activate_mapping(struct irq_info *info, void *data __attribute__((un
if (!info->moved) if (!info->moved)
return; return;
if ((hint_policy == HINT_POLICY_EXACT) && if ((info->hint_policy == HINT_POLICY_EXACT) &&
(!cpus_empty(info->affinity_hint))) { (!cpus_empty(info->affinity_hint))) {
if (cpus_intersects(info->affinity_hint, banned_cpus)) if (cpus_intersects(info->affinity_hint, banned_cpus))
log(TO_ALL, LOG_WARNING, 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) { } else if (info->assigned_obj) {
applied_mask = info->assigned_obj->mask; 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_empty(info->affinity_hint))) {
cpus_and(applied_mask, applied_mask, info->affinity_hint); cpus_and(applied_mask, applied_mask, info->affinity_hint);
if (!cpus_intersects(applied_mask, unbanned_cpus)) if (!cpus_intersects(applied_mask, unbanned_cpus))

View file

@ -91,6 +91,7 @@ void add_banned_irq(int irq, GList **list)
new->irq = irq; new->irq = irq;
new->flags |= IRQ_FLAG_BANNED; new->flags |= IRQ_FLAG_BANNED;
new->hint_policy = HINT_POLICY_EXACT;
*list = g_list_append(*list, new); *list = g_list_append(*list, new);
return; 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->irq = irq;
new->class = IRQ_OTHER; new->class = IRQ_OTHER;
new->hint_policy = global_hint_policy;
interrupts_db = g_list_append(interrupts_db, new); interrupts_db = g_list_append(interrupts_db, new);

View file

@ -48,7 +48,7 @@ int foreground_mode;
int numa_avail; int numa_avail;
int need_rescan; int need_rescan;
unsigned int log_mask = TO_ALL; 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 power_thresh = ULONG_MAX;
unsigned long deepest_cache = 2; unsigned long deepest_cache = 2;
unsigned long long cycle_count = 0; unsigned long long cycle_count = 0;
@ -135,11 +135,11 @@ static void parse_command_line(int argc, char **argv)
break; break;
case 'h': case 'h':
if (!strncmp(optarg, "exact", strlen(optarg))) if (!strncmp(optarg, "exact", strlen(optarg)))
hint_policy = HINT_POLICY_EXACT; global_hint_policy = HINT_POLICY_EXACT;
else if (!strncmp(optarg, "subset", strlen(optarg))) 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))) else if (!strncmp(optarg, "ignore", strlen(optarg)))
hint_policy = HINT_POLICY_IGNORE; global_hint_policy = HINT_POLICY_IGNORE;
else { else {
usage(); usage();
exit(1); exit(1);

View file

@ -62,7 +62,7 @@ enum hp_e {
extern int debug_mode; extern int debug_mode;
extern int one_shot_mode; extern int one_shot_mode;
extern int need_rescan; 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 long cycle_count;
extern unsigned long power_thresh; extern unsigned long power_thresh;
extern unsigned long deepest_cache; extern unsigned long deepest_cache;

View file

@ -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 /* never move an irq that has an afinity hint when
* hint_policy is HINT_POLICY_EXACT * 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)) if (!cpus_empty(info->affinity_hint))
return; return;

View file

@ -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 * to consider objects that are within the irqs hint, but
* only if that irq in fact has published a hint * 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)) { if (!cpus_empty(best->info->affinity_hint)) {
cpus_and(subset, best->info->affinity_hint, d->mask); cpus_and(subset, best->info->affinity_hint, d->mask);
if (cpus_empty(subset)) if (cpus_empty(subset))

View file

@ -98,6 +98,7 @@ GList* collect_full_irq_list()
info->type = IRQ_TYPE_LEGACY; info->type = IRQ_TYPE_LEGACY;
info->class = IRQ_OTHER; info->class = IRQ_OTHER;
} }
info->hint_policy = global_hint_policy;
tmp_list = g_list_append(tmp_list, info); tmp_list = g_list_append(tmp_list, info);
} }

View file

@ -64,6 +64,7 @@ struct irq_info {
struct topo_obj *numa_node; struct topo_obj *numa_node;
cpumask_t cpumask; cpumask_t cpumask;
cpumask_t affinity_hint; cpumask_t affinity_hint;
int hint_policy;
uint64_t irq_count; uint64_t irq_count;
uint64_t last_irq_count; uint64_t last_irq_count;
uint64_t load; uint64_t load;