From feeb95206e1f178e2bbf0393483861f364bd7d5b Mon Sep 17 00:00:00 2001 From: liuchao173 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; static GList *vm_banned_irqs = NULL; +extern int need_add_single; #define SYSFS_DIR "/sys" #define SYSPCI_DIR "/sys/bus/pci/devices" @@ -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