Detect manually changed affinities of non-excluded interrupts

If an administrator manually changes the affinity of an irq, irqbalance doesn't
detect that, which can lead to erroneous load calculations when rebalancing.
Since the irq that was changed wasn't explicitly excluded, restore the affinity
that irqbalance has recorded for it, so we stay in sync.

Signed-off-by: Shaohua Li <shli@fusionio.com>
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>

Resolves: http://code.google.com/p/irqbalance/issues/detail?id=34
This commit is contained in:
Neil Horman 2012-07-05 15:11:15 -04:00
parent 65169e022c
commit 544bc8443d

View file

@ -32,34 +32,60 @@
#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;
}
/*
* 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)
return;
sprintf(buf, "/proc/irq/%i/smp_affinity", info->irq);
file = fopen(buf, "w");
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);