irqbalance/bugfix-fix-new-irqs-in-hotplug-keep-stay-on-one-numa.patch
2019-12-25 22:08:07 +08:00

162 lines
4.4 KiB
Diff

From feeb95206e1f178e2bbf0393483861f364bd7d5b Mon Sep 17 00:00:00 2001
From: liuchao173 <liuchao173@huawei.com>
Date: Wed, 23 Oct 2019 11:38:17 +0000
Subject: [PATCH] irqbalance: fix new irqs in hotplug keep stay on one numa node
when the number of cpus is huge, hotplug occurs and new irqs will stay on one numa node
---
classify.c | 25 +++++++++++++++++++++++++
procinterrupts.c | 24 +++++++++++++++++++++---
rules_config.c | 4 ++++
3 files changed, 50 insertions(+), 3 deletions(-)
diff --git a/classify.c b/classify.c
index 3681c48..54f27f0 100644
--- a/classify.c
+++ b/classify.c
@@ -38,6 +38,7 @@ static GList *banned_irqs = NULL;
GList *cl_banned_irqs = NULL;
static GList *cl_banned_modules = NULL;
GList *vm_banned_irqs = NULL;
+extern int need_add_single;
pthread_mutex_t cl_banned_list_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t vm_banned_list_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -646,6 +647,21 @@ static int check_for_irq_ban(char *path __attribute__((unused)), int irq, GList
return 0;
}
+int is_proc_irq_info_exist(int irq, GList *tmp_list)
+{
+ GList *entry;
+ struct irq_info find;
+
+ if (!tmp_list) {
+ return 1;
+ }
+
+ find.irq = irq;
+ entry = g_list_find_custom(tmp_list, &find, compare_ints);
+
+ return entry ? 1 : 0;
+}
+
/*
* Figures out which interrupt(s) relate to the device we"re looking at in dirname
*/
@@ -686,6 +702,12 @@ struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list)
add_banned_irq(irqnum, &banned_irqs, 0);
continue;
}
+ if (!is_proc_irq_info_exist(irqnum, tmp_list)) {
+ continue;
+ }
+ if (need_add_single && need_add_single != irqnum) {
+ continue;
+ }
hint.irq = irqnum;
hint.type = IRQ_TYPE_MSIX;
new = add_one_irq_to_db(devpath, &hint, &pol);
@@ -723,6 +745,9 @@ struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list)
add_banned_irq(irqnum, &banned_irqs, 0);
goto done;
}
+ if (!is_proc_irq_info_exist(irqnum, tmp_list)) {
+ goto done;
+ }
hint.irq = irqnum;
hint.type = IRQ_TYPE_LEGACY;
diff --git a/procinterrupts.c b/procinterrupts.c
index c32c1b2..f0dd608 100644
--- a/procinterrupts.c
+++ b/procinterrupts.c
@@ -43,6 +43,7 @@
static int proc_int_has_msi = 0;
static int msi_found_in_sysfs = 0;
extern int ban_pci_assigned_irq;
+int need_add_single = 0;
#ifdef AARCH64
struct irq_match {
@@ -361,9 +362,10 @@ void parse_proc_interrupts(void)
uint64_t count;
char *c, *c2;
struct irq_info *info;
- struct irq_info tmp_info;
- char savedline[1024];
+ struct irq_info tmp_info = {0};
+ char *savedline = NULL;
char dirname[PATH_MAX] = {'\0'};
+ struct irq_info *lookup;
if (getline(&line, &size, file)<=0)
break;
@@ -383,7 +385,9 @@ void parse_proc_interrupts(void)
if (!c)
continue;
- strncpy(savedline, line, sizeof(savedline)-1);
+ savedline = strdup(line);
+ if (!savedline)
+ continue;
*c = 0;
c++;
@@ -391,23 +395,36 @@ void parse_proc_interrupts(void)
info = get_irq_info(number);
if (!info) {
+ init_irq_class_and_type(savedline, &tmp_info, number);
find_irq_dev_path(number, dirname, PATH_MAX);
if (strlen(dirname) > 0) {
+ need_add_single = number;
info = build_one_dev_entry(dirname, NULL);
+ need_add_single = 0;
+ lookup = get_irq_info(number);
+ if (lookup != NULL) {
+ lookup->existing = 1;
+ set_usr_irq_policy(tmp_info.name, lookup);
+ }
log(TO_CONSOLE, LOG_INFO, "new IRQ %d added into database, dirname %s\n", number, dirname);
} else {
- init_irq_class_and_type(savedline, &tmp_info, number);
info = add_new_irq(number, &tmp_info, NULL);
}
+ if (tmp_info.name) {
+ free(tmp_info.name);
+ tmp_info.name = NULL;
+ }
if (info) {
force_rebalance_irq(info, NULL);
log(TO_CONSOLE, LOG_INFO, "new IRQ %d added into rebalance list\n", number);
} else {
need_rescan = 1;
+ free(savedline);
break;
}
}
+ free(savedline);
info->existing = 1;
if (ban_pci_assigned_irq) {
diff --git a/rules_config.c b/rules_config.c
index 767e9e1..9313fc6 100644
--- a/rules_config.c
+++ b/rules_config.c
@@ -43,6 +43,10 @@ void set_usr_irq_policy(char *name, struct irq_info *info)
{
USER_IRQ_POLICY *user_policy;
+ if (user_policy_list == NULL) {
+ return;
+ }
+
user_policy = get_usr_irq_policy(name);
if (user_policy != NULL) {
if (user_policy->numa_node_set) {
--
2.19.1