irqbalance/improve-irq-migrate-rule-to-avoid-high-irq-load.patch
2020-03-24 11:44:22 +08:00

122 lines
4.0 KiB
Diff

From 84a2df1c9962a87f55e1c0d3bd2118fd754a4b48 Mon Sep 17 00:00:00 2001
From: hejingxian <hejingxian@huawei.com>
Date: Fri, 3 Jan 2020 16:43:28 +0800
Subject: [PATCH] add new irq migrate rule to avoid high cpu irq load
By the old irq migrate rule, the irqs cannot be moved if the adjustment_load will become smaller then
the min_load after moving irq. However, we can accept that the delta load become smaller after moving irq.
---
irqbalance.c | 14 ++++++++++++--
irqbalance.h | 3 ++-
irqlist.c | 15 ++++++++++++++-
3 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/irqbalance.c b/irqbalance.c
index 1ca401e..15fb0fe 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -69,6 +69,8 @@ int sleep_interval = SLEEP_INTERVAL;
long HZ;
int sleep_interval = SLEEP_INTERVAL;
int last_interval;
+unsigned long migrate_val = 0;
+unsigned long load_limit = 0;
GMainLoop *main_loop;
char *cpu_ban_string = NULL;
@@ -106,6 +108,8 @@ struct option lopts[] = {
{"banmod", 1 , NULL, 'm'},
{"interval", 1 , NULL, 't'},
{"version", 0, NULL, 'V'},
+ {"migrateval", 1, NULL, 'e'},
+ {"loadlimit", 1, NULL, 'g'},
{0, 0, 0, 0}
};
@@ -114,7 +118,7 @@ static void usage(void)
{
log(TO_CONSOLE, LOG_INFO, "irqbalance [--oneshot | -o] [--debug | -d] [--foreground | -f] [--journal | -j] [--hintpolicy= | -h [exact|subset|ignore]]\n");
log(TO_CONSOLE, LOG_INFO, " [--powerthresh= | -p <off> | <n>] [--banirq= | -i <n>] [--banmod= | -m <module>] [--policyscript= | -l <script>]\n");
- log(TO_CONSOLE, LOG_INFO, " [--pid= | -s <file>] [--deepestcache= | -c <n>] [--interval= | -t <n>]\n");
+ log(TO_CONSOLE, LOG_INFO, " [--pid= | -s <file>] [--deepestcache= | -c <n>] [--interval= | -t <n>] [--migrateval= | -e <n>] [--loadlimit= | -g <n>]\n");
}
static void version(void)
@@ -129,7 +133,7 @@ static void parse_command_line(int argc, char **argv)
unsigned long val;
while ((opt = getopt_long(argc, argv,
- "odfjVi:p:s:c:b:l:m:t:",
+ "odfjVi:p:s:c:b:l:m:t:e:g:",
lopts, &longind)) != -1) {
switch(opt) {
@@ -231,6 +235,12 @@ static void parse_command_line(int argc, char **argv)
exit(1);
}
break;
+ case 'e':
+ migrate_val = strtoul(optarg, NULL, 10);
+ break;
+ case 'g':
+ load_limit = strtoul(optarg, NULL, 10);
+ break;
}
}
}
diff --git a/irqbalance.h b/irqbalance.h
index 72e141b..d4f6e7a 100644
--- a/irqbalance.h
+++ b/irqbalance.h
@@ -124,7 +124,8 @@ extern struct irq_info *add_new_irq(int irq, struct irq_info *hint, GList *proc_
extern void add_cl_banned_module(char *modname);
#define irq_numa_node(irq) ((irq)->numa_node)
-
+extern unsigned long migrate_val;
+extern unsigned long load_limit;
/*
* Generic object functions
*/
diff --git a/irqlist.c b/irqlist.c
index 95ccc7a..3c38b18 100644
--- a/irqlist.c
+++ b/irqlist.c
@@ -76,6 +76,7 @@ static void compute_deviations(struct topo_obj *obj, void *data)
static void move_candidate_irqs(struct irq_info *info, void *data)
{
struct load_balance_info *lb_info = data;
+ unsigned long delta_load = 0;
/* Don't rebalance irqs that don't want it */
if (info->level == BALANCE_NONE)
@@ -91,12 +92,24 @@ static void move_candidate_irqs(struct irq_info *info, void *data)
if (info->load <= 1)
return;
+ if (migrate_val > 0) {
+ delta_load = (lb_info->adjustment_load - lb_info->min_load) / migrate_val;
+ }
+
/* If we can migrate an irq without swapping the imbalance do it. */
if ((lb_info->adjustment_load - info->load) > (lb_info->min_load + info->load)) {
lb_info->adjustment_load -= info->load;
lb_info->min_load += info->load;
- } else
+ } else if (delta_load && load_limit && (lb_info->adjustment_load > load_limit) &&
+ (lb_info->min_load + info->load) - (lb_info->adjustment_load - info->load) < delta_load) {
+ lb_info->adjustment_load -= info->load;
+ lb_info->min_load += info->load;
+ if (lb_info->min_load > lb_info->adjustment_load) {
+ lb_info->min_load = lb_info->adjustment_load;
+ }
+ } else {
return;
+ }
log(TO_CONSOLE, LOG_INFO, "Selecting irq %d for rebalancing\n", info->irq);
--
1.8.3.1