From b18eb8f6b28cc9b0816be0fb8fe3468c9f64f345 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Thu, 5 Jul 2012 14:54:35 -0400 Subject: [PATCH 5/8] Add banscript option Its been requested in several different ways, that irqbalance have a more robust mechanism for setting balancing policy at run time. While I don't feel its apropriate to have irqbalance be able to implement arbitrary balance policy (having a flexible mechanism to define which irqs should be placed where can become exceedingly complex), I do think we need some mechanism that easily allows users to dynamically exclude irqs from the irqbalance policy at run time. The banscript option does exactly this. It allows the user to point irqbalance toward an exacutable file that is run one for each irq deiscovered passing the sysfs path of the device and an irq vector as arguments. A zero exit code tells irqbalance to manage the irq as it normally would, while a non-zero exit tells irqbalance to ignore the interrupt entirely. This provides adminstrators a code point with which to exclude irqs dynamically based on any programatic informatino available, and to manage those irqs independently, etither via another irqbalance like program, or via static affinity setting. Signed-off-by: Neil Horman Reesolves: http://code.google.com/p/irqbalance/issues/detail?id=33 --- classify.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ irqbalance.1 | 11 +++++++++++ irqbalance.c | 25 +++++++++++++++++++++---- irqbalance.h | 1 + 4 files changed, 79 insertions(+), 4 deletions(-) diff --git a/classify.c b/classify.c index d59da7f..750d946 100644 --- a/classify.c +++ b/classify.c @@ -207,6 +207,43 @@ out: return new; } +static int check_for_irq_ban(char *path, int irq) +{ + char *cmd; + int rc; + + if (!banscript) + return 0; + + cmd = alloca(strlen(path)+strlen(banscript)+32); + if (!cmd) + return 0; + + sprintf(cmd, "%s %s %d",banscript, path, irq); + rc = system(cmd); + + /* + * The system command itself failed + */ + if (rc == -1) { + if (debug_mode) + printf("%s failed, please check the --banscript option\n", cmd); + else + syslog(LOG_INFO, "%s failed, please check the --banscript option\n", cmd); + return 0; + } + + if (WEXITSTATUS(rc)) { + if (debug_mode) + printf("irq %d is baned by %s\n", irq, banscript); + else + syslog(LOG_INFO, "irq %d is baned by %s\n", irq, banscript); + return 1; + } + return 0; + +} + /* * Figures out which interrupt(s) relate to the device we're looking at in dirname */ @@ -231,6 +268,10 @@ static void build_one_dev_entry(const char *dirname) irqnum = strtol(entry->d_name, NULL, 10); if (irqnum) { sprintf(path, "%s/%s", SYSDEV_DIR, dirname); + if (check_for_irq_ban(path, irqnum)) { + add_banned_irq(irqnum); + continue; + } new = add_one_irq_to_db(path, irqnum); if (!new) continue; @@ -253,6 +294,11 @@ static void build_one_dev_entry(const char *dirname) */ if (irqnum) { sprintf(path, "%s/%s", SYSDEV_DIR, dirname); + if (check_for_irq_ban(path, irqnum)) { + add_banned_irq(irqnum); + goto done; + } + new = add_one_irq_to_db(path, irqnum); if (!new) goto done; diff --git a/irqbalance.1 b/irqbalance.1 index 978c7c1..63b0e26 100644 --- a/irqbalance.1 +++ b/irqbalance.1 @@ -69,6 +69,17 @@ Add the specified irq list to the set of banned irqs. irqbalance will not affect the affinity of any irqs on the banned list, allowing them to be specified manually. This option is addative and can be specified multiple times +.TP +.B --banscript=