914ea28980
- Fixes SIGFPE crash for some banning configuration (bz849792) - Fixes affinity_hint values processing (bz832815) - Adds banirq and bansript options (bz837049) - imake isn't needed for building any more (bz844359) - Fixes clogging of syslog (bz837646) - Added IRQBALANCE_ARGS variable for passing arguments via systemd(bz837048) - Fixes --hint-policy=subset behavior (bz844381)
219 lines
6.5 KiB
Diff
219 lines
6.5 KiB
Diff
From b18eb8f6b28cc9b0816be0fb8fe3468c9f64f345 Mon Sep 17 00:00:00 2001
|
|
From: Neil Horman <nhorman@tuxdriver.com>
|
|
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 <nhorman@tuxdriver.com>
|
|
|
|
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=<script>
|
|
+Execute the specified script for each irq that is discovered, passing the sysfs
|
|
+path to the associated device as the first argument, and the irq vector as the
|
|
+second. An exit value of 0 tells irqbalance that this interrupt should balanced
|
|
+and managed as a normal irq, while a non-zero exit code indicates this irq
|
|
+should be ignored by irqbalance completely (see --banirq above). Use of this
|
|
+script provides users the ability to dynamically select which irqs get exluded
|
|
+from balancing, and provides an opportunity for manual affinity setting in one
|
|
+single code point.
|
|
+
|
|
.SH "ENVIRONMENT VARIABLES"
|
|
.TP
|
|
.B IRQBALANCE_ONESHOT
|
|
diff --git a/irqbalance.c b/irqbalance.c
|
|
index 5d40321..0184f0f 100644
|
|
--- a/irqbalance.c
|
|
+++ b/irqbalance.c
|
|
@@ -1,5 +1,6 @@
|
|
/*
|
|
* Copyright (C) 2006, Intel Corporation
|
|
+ * Copyright (C) 2012, Neil Horman <nhorman@tuxdriver.com>
|
|
*
|
|
* This file is part of irqbalance
|
|
*
|
|
@@ -45,6 +46,7 @@ extern cpumask_t banned_cpus;
|
|
enum hp_e hint_policy = HINT_POLICY_SUBSET;
|
|
unsigned long power_thresh = ULONG_MAX;
|
|
unsigned long long cycle_count = 0;
|
|
+char *banscript = NULL;
|
|
|
|
void sleep_approx(int seconds)
|
|
{
|
|
@@ -66,6 +68,8 @@ struct option lopts[] = {
|
|
{"debug", 0, NULL, 'd'},
|
|
{"hintpolicy", 1, NULL, 'h'},
|
|
{"powerthresh", 1, NULL, 'p'},
|
|
+ {"banirq", 1 , NULL, 'i'},
|
|
+ {"banscript", 1, NULL, 'b'},
|
|
{0, 0, 0, 0}
|
|
};
|
|
|
|
@@ -79,9 +83,10 @@ static void parse_command_line(int argc, char **argv)
|
|
{
|
|
int opt;
|
|
int longind;
|
|
+ unsigned long val;
|
|
|
|
while ((opt = getopt_long(argc, argv,
|
|
- "odh:p:b:",
|
|
+ "odh:i:p:b:",
|
|
lopts, &longind)) != -1) {
|
|
|
|
switch(opt) {
|
|
@@ -193,6 +198,12 @@ int main(int argc, char** argv)
|
|
if (argc>1 && strstr(argv[1],"--oneshot"))
|
|
one_shot_mode=1;
|
|
#endif
|
|
+
|
|
+ /*
|
|
+ * Open the syslog connection
|
|
+ */
|
|
+ openlog(argv[0], 0, LOG_DAEMON);
|
|
+
|
|
if (getenv("IRQBALANCE_BANNED_CPUS")) {
|
|
cpumask_parse_user(getenv("IRQBALANCE_BANNED_CPUS"), strlen(getenv("IRQBALANCE_BANNED_CPUS")), banned_cpus);
|
|
}
|
|
@@ -221,8 +232,16 @@ int main(int argc, char** argv)
|
|
|
|
|
|
/* On single core UP systems irqbalance obviously has no work to do */
|
|
- if (core_count<2)
|
|
+ if (core_count<2) {
|
|
+ char *msg = "Balancing is ineffective on systems with a "
|
|
+ "single cache domain. Shutting down\n";
|
|
+
|
|
+ if (debug_mode)
|
|
+ printf("%s", msg);
|
|
+ else
|
|
+ syslog(LOG_INFO, "%s", msg);
|
|
exit(EXIT_SUCCESS);
|
|
+ }
|
|
/* On dual core/hyperthreading shared cache systems just do a one shot setup */
|
|
if (cache_domain_count==1)
|
|
one_shot_mode = 1;
|
|
@@ -231,8 +250,6 @@ int main(int argc, char** argv)
|
|
if (daemon(0,0))
|
|
exit(EXIT_FAILURE);
|
|
|
|
- openlog(argv[0], 0, LOG_DAEMON);
|
|
-
|
|
#ifdef HAVE_LIBCAP_NG
|
|
// Drop capabilities
|
|
capng_clear(CAPNG_SELECT_BOTH);
|
|
diff --git a/irqbalance.h b/irqbalance.h
|
|
index 043bfe6..425e0dd 100644
|
|
--- a/irqbalance.h
|
|
+++ b/irqbalance.h
|
|
@@ -68,6 +68,7 @@ extern int need_rescan;
|
|
extern enum hp_e hint_policy;
|
|
extern unsigned long long cycle_count;
|
|
extern unsigned long power_thresh;
|
|
+extern char *banscript;
|
|
|
|
/*
|
|
* Numa node access routines
|
|
--
|
|
1.7.11.4
|
|
|