From 7475c3e26d14bb210eb3524396adef77021e696f Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 7 Aug 2012 02:54:34 -0400 Subject: [PATCH 7/8] apply affinity hint also if the current policy is subset --hintpolicy=subset chooses an object that has a non-empty intersection with the affinity hint, but it never restricts the object's CPU mask with the hint itself. As a result, there is no guarantee that the object's CPU mask is a subset of the hint. This is visible for interrupts whose balancing policy is not BALANCE_CORE. For example, if there is only one cache domain and the interrupt's policy is BALANCE_CACHE, the chosen object will correspond to "all CPUs" and the affinity hint will be effectively ignored. Signed-off-by: Paolo Bonzini Signed-off-by: Neil Horman --- activate.c | 45 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/activate.c b/activate.c index 292c44a..97d84a8 100644 --- a/activate.c +++ b/activate.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2006, Intel Corporation + * Copyright (C) 2012, Neil Horman * * This file is part of irqbalance * @@ -31,17 +32,53 @@ #include "irqbalance.h" +static int check_affinity(struct irq_info *info, cpumask_t applied_mask) +{ + cpumask_t current_mask; + char buf[PATH_MAX]; + char *line = NULL; + size_t size = 0; + FILE *file; + + sprintf(buf, "/proc/irq/%i/smp_affinity", info->irq); + file = fopen(buf, "r"); + if (!file) + return 1; + if (getline(&line, &size, file)==0) { + free(line); + fclose(file); + return 1; + } + cpumask_parse_user(line, strlen(line), current_mask); + fclose(file); + free(line); + + return cpus_equal(applied_mask, current_mask); +} static void activate_mapping(struct irq_info *info, void *data __attribute__((unused))) { char buf[PATH_MAX]; FILE *file; cpumask_t applied_mask; + int valid_mask = 0; + + if ((hint_policy == HINT_POLICY_EXACT) && + (!cpus_empty(info->affinity_hint))) { + applied_mask = info->affinity_hint; + valid_mask = 1; + } else if (info->assigned_obj) { + applied_mask = info->assigned_obj->mask; + valid_mask = 1; + if ((hint_policy == HINT_POLICY_SUBSET) && + (!cpus_empty(info->affinity_hint))) + cpus_and(applied_mask, applied_mask, info->affinity_hint); + } /* * only activate mappings for irqs that have moved */ - if (!info->moved) + if (!info->moved && (!valid_mask || check_affinity(info, applied_mask))) return; if (!info->assigned_obj) @@ -53,12 +90,6 @@ static void activate_mapping(struct irq_info *info, void *data __attribute__((un if (!file) return; - if ((hint_policy == HINT_POLICY_EXACT) && - (!cpus_empty(info->affinity_hint))) - applied_mask = info->affinity_hint; - else - applied_mask = info->assigned_obj->mask; - cpumask_scnprintf(buf, PATH_MAX, applied_mask); fprintf(file, "%s", buf); fclose(file); -- 1.7.11.4