irqbalance: add irq hotplug feature for irqbalance
add irq hotplug feature for irqbalance Signed-off-by: qinyu <qinyu32@huawei.com>
This commit is contained in:
parent
f17762e55a
commit
8ff57497b3
43
backport-Add-log-for-hotplug-appropriately.patch
Normal file
43
backport-Add-log-for-hotplug-appropriately.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From 6ae114f8719a6a49cef73a32d820a77e900ddf08 Mon Sep 17 00:00:00 2001
|
||||
From: hejingxian 00273181 <hejingxian@huawei.com>
|
||||
Date: Thu, 17 Dec 2020 17:47:45 +0800
|
||||
Subject: [PATCH] Add log for hotplug appropriately
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/Irqbalance/irqbalance/commit/6ae114f8719a6a49cef73a32d820a77e900ddf08
|
||||
---
|
||||
classify.c | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/classify.c b/classify.c
|
||||
index 0d556e9..4b6ffa8 100644
|
||||
--- a/classify.c
|
||||
+++ b/classify.c
|
||||
@@ -644,12 +644,13 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs, int build_
|
||||
irqnum = strtol(entry->d_name, NULL, 10);
|
||||
/* If build_irq is valid, only add irq when it's number equals to build_irq */
|
||||
if (irqnum && ((build_irq < 0) || (irqnum == build_irq))) {
|
||||
- printf("add irq:%d %d for %s\n", irqnum, build_irq, path);
|
||||
hint.irq = irqnum;
|
||||
hint.type = IRQ_TYPE_MSIX;
|
||||
add_new_irq(devpath, &hint, tmp_irqs);
|
||||
- if (build_irq >= 0)
|
||||
+ if (build_irq >= 0) {
|
||||
+ log(TO_CONSOLE, LOG_INFO, "Hotplug dev irq: %d finished.\n", irqnum);
|
||||
break;
|
||||
+ }
|
||||
}
|
||||
} while (entry != NULL);
|
||||
closedir(msidir);
|
||||
@@ -674,6 +675,8 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs, int build_
|
||||
hint.irq = irqnum;
|
||||
hint.type = IRQ_TYPE_LEGACY;
|
||||
add_new_irq(devpath, &hint, tmp_irqs);
|
||||
+ if (build_irq >= 0)
|
||||
+ log(TO_CONSOLE, LOG_INFO, "Hotplug dev irq: %d finished.\n", irqnum);
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
352
backport-add-irq-hotplug-feature-for-irqbalance.patch
Normal file
352
backport-add-irq-hotplug-feature-for-irqbalance.patch
Normal file
@ -0,0 +1,352 @@
|
||||
From 0ba4a60a2a732150e5016389e32b2e81906a72c2 Mon Sep 17 00:00:00 2001
|
||||
From: hejingxian 00273181 <hejingxian@huawei.com>
|
||||
Date: Fri, 4 Dec 2020 10:52:57 +0800
|
||||
Subject: [PATCH] add irq hotplug feature for irqbalance
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/Irqbalance/irqbalance/commit/0ba4a60a2a732150e5016389e32b2e81906a72c2
|
||||
---
|
||||
classify.c | 70 +++++++++++++++++++++++--------
|
||||
irqbalance.c | 2 +-
|
||||
irqbalance.h | 4 +-
|
||||
procinterrupts.c | 104 ++++++++++++++++++++++++++++-------------------
|
||||
4 files changed, 120 insertions(+), 60 deletions(-)
|
||||
|
||||
diff --git a/classify.c b/classify.c
|
||||
index 9f588bc..0d556e9 100644
|
||||
--- a/classify.c
|
||||
+++ b/classify.c
|
||||
@@ -619,7 +619,7 @@ static void add_new_irq(char *path, struct irq_info *hint, GList *proc_interrupt
|
||||
/*
|
||||
* Figures out which interrupt(s) relate to the device we"re looking at in dirname
|
||||
*/
|
||||
-static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
|
||||
+static void build_one_dev_entry(const char *dirname, GList *tmp_irqs, int build_irq)
|
||||
{
|
||||
struct dirent *entry;
|
||||
DIR *msidir;
|
||||
@@ -642,10 +642,14 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
|
||||
if (!entry)
|
||||
break;
|
||||
irqnum = strtol(entry->d_name, NULL, 10);
|
||||
- if (irqnum) {
|
||||
+ /* If build_irq is valid, only add irq when it's number equals to build_irq */
|
||||
+ if (irqnum && ((build_irq < 0) || (irqnum == build_irq))) {
|
||||
+ printf("add irq:%d %d for %s\n", irqnum, build_irq, path);
|
||||
hint.irq = irqnum;
|
||||
hint.type = IRQ_TYPE_MSIX;
|
||||
add_new_irq(devpath, &hint, tmp_irqs);
|
||||
+ if (build_irq >= 0)
|
||||
+ break;
|
||||
}
|
||||
} while (entry != NULL);
|
||||
closedir(msidir);
|
||||
@@ -665,9 +669,12 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
|
||||
#else
|
||||
if (irqnum) {
|
||||
#endif
|
||||
- hint.irq = irqnum;
|
||||
- hint.type = IRQ_TYPE_LEGACY;
|
||||
- add_new_irq(devpath, &hint, tmp_irqs);
|
||||
+ /* If build_irq is valid, only add irq when it's number equals to build_irq */
|
||||
+ if ((build_irq < 0) || (irqnum == build_irq)) {
|
||||
+ hint.irq = irqnum;
|
||||
+ hint.type = IRQ_TYPE_LEGACY;
|
||||
+ add_new_irq(devpath, &hint, tmp_irqs);
|
||||
+ }
|
||||
}
|
||||
|
||||
done:
|
||||
@@ -712,31 +719,60 @@ static void free_tmp_irqs(gpointer data)
|
||||
free(info);
|
||||
}
|
||||
|
||||
-void rebuild_irq_db(void)
|
||||
+static struct irq_info * build_dev_irqs(GList *tmp_irqs, int build_irq)
|
||||
{
|
||||
DIR *devdir;
|
||||
struct dirent *entry;
|
||||
- GList *tmp_irqs = NULL;
|
||||
-
|
||||
- free_irq_db();
|
||||
-
|
||||
- tmp_irqs = collect_full_irq_list();
|
||||
+ struct irq_info *new_irq = NULL;
|
||||
|
||||
devdir = opendir(SYSPCI_DIR);
|
||||
-
|
||||
if (devdir) {
|
||||
do {
|
||||
entry = readdir(devdir);
|
||||
-
|
||||
if (!entry)
|
||||
break;
|
||||
-
|
||||
- build_one_dev_entry(entry->d_name, tmp_irqs);
|
||||
-
|
||||
+ /* when hotplug irqs, we add one irq at one time */
|
||||
+ build_one_dev_entry(entry->d_name, tmp_irqs, build_irq);
|
||||
+ if (build_irq >= 0) {
|
||||
+ new_irq = get_irq_info(build_irq);
|
||||
+ if (new_irq)
|
||||
+ break;
|
||||
+ }
|
||||
} while (entry != NULL);
|
||||
-
|
||||
closedir(devdir);
|
||||
}
|
||||
+ return new_irq;
|
||||
+}
|
||||
+
|
||||
+int proc_irq_hotplug(char *savedline, int irq, struct irq_info **pinfo)
|
||||
+{
|
||||
+ struct irq_info tmp_info = {0};
|
||||
+
|
||||
+ /* firstly, init irq info by read device info */
|
||||
+ *pinfo = build_dev_irqs(interrupts_db, irq);
|
||||
+ if (*pinfo == NULL) {
|
||||
+ /* secondly, init irq info by parse savedline */
|
||||
+ init_irq_class_and_type(savedline, &tmp_info, irq);
|
||||
+ add_new_irq(NULL, &tmp_info, interrupts_db);
|
||||
+ *pinfo = get_irq_info(irq);
|
||||
+ }
|
||||
+ if (*pinfo == NULL) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ force_rebalance_irq(*pinfo, NULL);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void rebuild_irq_db(void)
|
||||
+{
|
||||
+ GList *tmp_irqs = NULL;
|
||||
+
|
||||
+ free_irq_db();
|
||||
+
|
||||
+ tmp_irqs = collect_full_irq_list();
|
||||
+
|
||||
+ build_dev_irqs(tmp_irqs, -1);
|
||||
|
||||
for_each_irq(tmp_irqs, add_missing_irq, interrupts_db);
|
||||
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index eaa0ce1..9baa955 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -249,7 +249,7 @@ static void dump_object_tree(void)
|
||||
for_each_object(numa_nodes, dump_numa_node_info, NULL);
|
||||
}
|
||||
|
||||
-static void force_rebalance_irq(struct irq_info *info, void *data __attribute__((unused)))
|
||||
+void force_rebalance_irq(struct irq_info *info, void *data __attribute__((unused)))
|
||||
{
|
||||
if (info->level == BALANCE_NONE)
|
||||
return;
|
||||
diff --git a/irqbalance.h b/irqbalance.h
|
||||
index acf0ed5..d8e80a9 100644
|
||||
--- a/irqbalance.h
|
||||
+++ b/irqbalance.h
|
||||
@@ -40,8 +40,11 @@ extern GList* collect_full_irq_list();
|
||||
extern void parse_proc_stat(void);
|
||||
extern void set_interrupt_count(int number, uint64_t count);
|
||||
extern void set_msi_interrupt_numa(int number);
|
||||
+extern void init_irq_class_and_type(char *savedline, struct irq_info *info, int irq);
|
||||
+extern int proc_irq_hotplug(char *line, int irq, struct irq_info **pinfo);
|
||||
|
||||
extern GList *rebalance_irq_list;
|
||||
+extern void force_rebalance_irq(struct irq_info *info, void *data __attribute__((unused)));
|
||||
|
||||
void update_migration_status(void);
|
||||
void dump_workloads(void);
|
||||
@@ -52,7 +55,6 @@ void dump_tree(void);
|
||||
void activate_mappings(void);
|
||||
void clear_cpu_tree(void);
|
||||
void free_cpu_topo(gpointer data);
|
||||
-
|
||||
/*===================NEW BALANCER FUNCTIONS============================*/
|
||||
|
||||
/*
|
||||
diff --git a/procinterrupts.c b/procinterrupts.c
|
||||
index 858b66b..0671be0 100644
|
||||
--- a/procinterrupts.c
|
||||
+++ b/procinterrupts.c
|
||||
@@ -145,16 +145,59 @@ static void guess_arm_irq_hints(char *name, struct irq_info *info)
|
||||
}
|
||||
#endif
|
||||
|
||||
+void init_irq_class_and_type(char *savedline, struct irq_info *info, int irq)
|
||||
+{
|
||||
+ char *irq_name = NULL;
|
||||
+ char *irq_mod = NULL;
|
||||
+ char *savedptr = NULL;
|
||||
+ char *last_token = NULL;
|
||||
+ char *p = NULL;
|
||||
+ int is_xen_dyn = 0;
|
||||
+#ifdef AARCH64
|
||||
+ char *tmp = NULL;
|
||||
+#endif
|
||||
+
|
||||
+ irq_name = strtok_r(savedline, " ", &savedptr);
|
||||
+ if (strstr(irq_name, "xen-dyn") != NULL)
|
||||
+ is_xen_dyn = 1;
|
||||
+ last_token = strtok_r(NULL, " ", &savedptr);
|
||||
+ while ((p = strtok_r(NULL, " ", &savedptr))) {
|
||||
+ irq_name = last_token;
|
||||
+ if (strstr(irq_name, "xen-dyn") != NULL)
|
||||
+ is_xen_dyn = 1;
|
||||
+ last_token = p;
|
||||
+ }
|
||||
+
|
||||
+#ifdef AARCH64
|
||||
+ irq_name = last_token;
|
||||
+ tmp = strchr(irq_name, '\n');
|
||||
+ if (tmp)
|
||||
+ *tmp = 0;
|
||||
+#endif
|
||||
+ irq_mod = last_token;
|
||||
+ info->irq = irq;
|
||||
+
|
||||
+ if (strstr(irq_name, "-event") != NULL && is_xen_dyn == 1) {
|
||||
+ info->type = IRQ_TYPE_VIRT_EVENT;
|
||||
+ info->class = IRQ_VIRT_EVENT;
|
||||
+ } else {
|
||||
+#ifdef AARCH64
|
||||
+ guess_arm_irq_hints(irq_name, info);
|
||||
+#else
|
||||
+ info->type = IRQ_TYPE_LEGACY;
|
||||
+ info->class = IRQ_OTHER;
|
||||
+#endif
|
||||
+ }
|
||||
+ info->numa_node = get_numa_node(0);
|
||||
+ info->name = strdup(irq_mod);
|
||||
+}
|
||||
+
|
||||
GList* collect_full_irq_list()
|
||||
{
|
||||
GList *tmp_list = NULL;
|
||||
FILE *file;
|
||||
char *line = NULL;
|
||||
size_t size = 0;
|
||||
- char *irq_name, *irq_mod, *savedptr, *last_token, *p;
|
||||
-#ifdef AARCH64
|
||||
- char *tmp;
|
||||
-#endif
|
||||
|
||||
file = fopen("/proc/interrupts", "r");
|
||||
if (!file)
|
||||
@@ -169,7 +212,6 @@ GList* collect_full_irq_list()
|
||||
|
||||
while (!feof(file)) {
|
||||
int number;
|
||||
- int is_xen_dyn = 0;
|
||||
struct irq_info *info;
|
||||
char *c;
|
||||
char *savedline = NULL;
|
||||
@@ -191,44 +233,12 @@ GList* collect_full_irq_list()
|
||||
savedline = strdup(line);
|
||||
if (!savedline)
|
||||
break;
|
||||
- irq_name = strtok_r(savedline, " ", &savedptr);
|
||||
- if (strstr(irq_name, "xen-dyn") != NULL)
|
||||
- is_xen_dyn = 1;
|
||||
- last_token = strtok_r(NULL, " ", &savedptr);
|
||||
- while ((p = strtok_r(NULL, " ", &savedptr))) {
|
||||
- irq_name = last_token;
|
||||
- if (strstr(irq_name, "xen-dyn") != NULL)
|
||||
- is_xen_dyn = 1;
|
||||
- last_token = p;
|
||||
- }
|
||||
-
|
||||
-#ifdef AARCH64
|
||||
- /* Of course the formatting for /proc/interrupts is different on different arches */
|
||||
- irq_name = last_token;
|
||||
- tmp = strchr(irq_name, '\n');
|
||||
- if (tmp)
|
||||
- *tmp = 0;
|
||||
-#endif
|
||||
- irq_mod = last_token;
|
||||
-
|
||||
*c = 0;
|
||||
number = strtoul(line, NULL, 10);
|
||||
|
||||
info = calloc(1, sizeof(struct irq_info));
|
||||
if (info) {
|
||||
- info->irq = number;
|
||||
- if (strstr(irq_name, "-event") != NULL && is_xen_dyn == 1) {
|
||||
- info->type = IRQ_TYPE_VIRT_EVENT;
|
||||
- info->class = IRQ_VIRT_EVENT;
|
||||
- } else {
|
||||
-#ifdef AARCH64
|
||||
- guess_arm_irq_hints(irq_name, info);
|
||||
-#else
|
||||
- info->type = IRQ_TYPE_LEGACY;
|
||||
- info->class = IRQ_OTHER;
|
||||
-#endif
|
||||
- }
|
||||
- info->name = strdup(irq_mod);
|
||||
+ init_irq_class_and_type(savedline, info, number);
|
||||
tmp_list = g_list_append(tmp_list, info);
|
||||
}
|
||||
free(savedline);
|
||||
@@ -238,11 +248,13 @@ GList* collect_full_irq_list()
|
||||
return tmp_list;
|
||||
}
|
||||
|
||||
+
|
||||
void parse_proc_interrupts(void)
|
||||
{
|
||||
FILE *file;
|
||||
char *line = NULL;
|
||||
size_t size = 0;
|
||||
+ int ret;
|
||||
|
||||
file = fopen("/proc/interrupts", "r");
|
||||
if (!file)
|
||||
@@ -261,6 +273,7 @@ void parse_proc_interrupts(void)
|
||||
uint64_t count;
|
||||
char *c, *c2;
|
||||
struct irq_info *info;
|
||||
+ char *savedline = NULL;
|
||||
|
||||
if (getline(&line, &size, file)<=0)
|
||||
break;
|
||||
@@ -280,15 +293,24 @@ void parse_proc_interrupts(void)
|
||||
if (!c)
|
||||
continue;
|
||||
|
||||
+ savedline = strdup(line);
|
||||
+ if (!savedline)
|
||||
+ break;
|
||||
*c = 0;
|
||||
c++;
|
||||
number = strtoul(line, NULL, 10);
|
||||
|
||||
info = get_irq_info(number);
|
||||
if (!info) {
|
||||
- need_rescan = 1;
|
||||
- break;
|
||||
+ ret = proc_irq_hotplug(savedline, number, &info);
|
||||
+ if (ret < 0) {
|
||||
+ /* hotplug fail, need to rescan */
|
||||
+ need_rescan = 1;
|
||||
+ free(savedline);
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
+ free(savedline);
|
||||
|
||||
count = 0;
|
||||
cpunr = 0;
|
||||
@@ -316,7 +338,7 @@ void parse_proc_interrupts(void)
|
||||
break;
|
||||
}
|
||||
|
||||
- info->last_irq_count = info->irq_count;
|
||||
+ info->last_irq_count = info->irq_count;
|
||||
info->irq_count = count;
|
||||
|
||||
/* is interrupt MSI based? */
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
Summary: A dynamic adaptive IRQ balancing daemon
|
||||
Name: irqbalance
|
||||
Version: 1.7.0
|
||||
Release: 6
|
||||
Release: 7
|
||||
Epoch: 3
|
||||
License: GPLv2
|
||||
Source0: https://github.com/Irqbalance/irqbalance/archive/irqbalance-%{version}.tar.gz
|
||||
@ -24,6 +24,8 @@ Requires: numactl-libs
|
||||
Patch6000: fix-unsigned-integer-subtraction-sign-overflow.patch
|
||||
Patch6001: backport-activate_mapping-activate-only-online-CPUs.patch
|
||||
Patch6002: backport-log-correctly-for-isolated-and-nohz_full-cpus.patch
|
||||
Patch6003: backport-add-irq-hotplug-feature-for-irqbalance.patch
|
||||
Patch6004: backport-Add-log-for-hotplug-appropriately.patch
|
||||
|
||||
%description
|
||||
Irqbalance is a daemon to help balance the cpu load generated by
|
||||
@ -81,6 +83,12 @@ fi
|
||||
/sbin/chkconfig --del %{name} >/dev/null 2>&1 || :
|
||||
|
||||
%changelog
|
||||
* Thu Jan 5 2023 qinyu <qinyu32@huawei.com> - 3:1.7.0-7
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
- SUG:restart
|
||||
- DESC: add irq hotplug feature for irqbalance
|
||||
|
||||
* Thu Jan 5 2023 qinyu <qinyu32@huawei.com> - 3:1.7.0-6
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user