2019-12-25 22:08:07 +08:00
|
|
|
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;
|
2020-03-11 09:48:32 +08:00
|
|
|
static GList *vm_banned_irqs = NULL;
|
2019-12-25 22:08:07 +08:00
|
|
|
+extern int need_add_single;
|
|
|
|
|
|
2020-03-11 09:48:32 +08:00
|
|
|
#define SYSFS_DIR "/sys"
|
|
|
|
|
#define SYSPCI_DIR "/sys/bus/pci/devices"
|
2019-12-25 22:08:07 +08:00
|
|
|
@@ -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
|
|
|
|
|
|