backport patches
This commit is contained in:
parent
9852dc1539
commit
c65a85a98c
@ -1,39 +0,0 @@
|
||||
From 31c7d128fd6f083c7395b327f824a0c11d5e380f Mon Sep 17 00:00:00 2001
|
||||
From: Yunfeng Ye <yeyunfeng@huawei.com>
|
||||
Date: Sat, 21 Nov 2020 14:27:28 +0800
|
||||
Subject: [PATCH] Add IRQBALANCE_BANNED_CPULIST to env file
|
||||
|
||||
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
|
||||
---
|
||||
misc/irqbalance.env | 15 +++++++++++++++
|
||||
1 file changed, 15 insertions(+)
|
||||
|
||||
diff --git a/misc/irqbalance.env b/misc/irqbalance.env
|
||||
index 23570b2..237e4af 100644
|
||||
--- a/misc/irqbalance.env
|
||||
+++ b/misc/irqbalance.env
|
||||
@@ -22,6 +22,21 @@
|
||||
#IRQBALANCE_BANNED_CPUS=
|
||||
|
||||
#
|
||||
+# IRQBALANCE_BANNED_CPULIST
|
||||
+# The CPUs list which allows you to indicate which CPUs should
|
||||
+# be skipped when reblancing IRQs. CPU numbers in CPUs list will
|
||||
+# not have any IRQs assigned to them on rebalance.
|
||||
+#
|
||||
+# The format of CPUs list is:
|
||||
+# <cpu number>,...,<cpu number>
|
||||
+# or a range:
|
||||
+# <cpu number>-<cpu number>
|
||||
+# or a mixture:
|
||||
+# <cpu number>,...,<cpu number>-<cpu number>
|
||||
+#
|
||||
+#IRQBALANCE_BANNED_CPULIST=
|
||||
+
|
||||
+#
|
||||
# IRQBALANCE_ARGS
|
||||
# Append any args here to the irqbalance daemon as documented in the man
|
||||
# page.
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
115
backport-Add-hot-pull-method-for-irqbalance.patch
Normal file
115
backport-Add-hot-pull-method-for-irqbalance.patch
Normal file
@ -0,0 +1,115 @@
|
||||
From ef9bf64affbca0b030f9128d93f302296d166dac Mon Sep 17 00:00:00 2001
|
||||
From: hejingxian 00273181 <hejingxian@huawei.com>
|
||||
Date: Mon, 4 Jan 2021 12:34:02 +0800
|
||||
Subject: [PATCH] Add hot pull method for irqbalance
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/Irqbalance/irqbalance/commit/ef9bf64affbca0b030f9128d93f302296d166dac
|
||||
---
|
||||
classify.c | 37 +++++++++++++++++++++++++++++++++++++
|
||||
irqbalance.h | 1 +
|
||||
procinterrupts.c | 4 +++-
|
||||
types.h | 1 +
|
||||
4 files changed, 42 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/classify.c b/classify.c
|
||||
index 4b6ffa8..beb2919 100644
|
||||
--- a/classify.c
|
||||
+++ b/classify.c
|
||||
@@ -852,3 +852,39 @@ void sort_irq_list(GList **list)
|
||||
{
|
||||
*list = g_list_sort(*list, sort_irqs);
|
||||
}
|
||||
+
|
||||
+static void remove_no_existing_irq(struct irq_info *info, void *data __attribute__((unused)))
|
||||
+{
|
||||
+ GList *entry = NULL;
|
||||
+
|
||||
+ if (info->existing) {
|
||||
+ /* clear existing flag for next detection */
|
||||
+ info->existing = 0;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ entry = g_list_find_custom(interrupts_db, info, compare_ints);
|
||||
+ if (entry)
|
||||
+ interrupts_db = g_list_delete_link(interrupts_db, entry);
|
||||
+
|
||||
+ entry = g_list_find_custom(rebalance_irq_list, info, compare_ints);
|
||||
+ if (entry)
|
||||
+ rebalance_irq_list = g_list_delete_link(rebalance_irq_list, entry);
|
||||
+
|
||||
+ if(info->assigned_obj) {
|
||||
+ entry = g_list_find_custom(info->assigned_obj->interrupts, info, compare_ints);
|
||||
+ if (entry) {
|
||||
+ info->assigned_obj->interrupts = g_list_delete_link(info->assigned_obj->interrupts, entry);
|
||||
+ }
|
||||
+ }
|
||||
+ log(TO_CONSOLE, LOG_INFO, "IRQ %d is removed from interrupts_db.\n", info->irq);
|
||||
+ free_irq(info, NULL);
|
||||
+}
|
||||
+
|
||||
+void clear_no_existing_irqs(void)
|
||||
+{
|
||||
+ for_each_irq(NULL, remove_no_existing_irq, NULL);
|
||||
+ if (banned_irqs) {
|
||||
+ for_each_irq(banned_irqs, remove_no_existing_irq, NULL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
diff --git a/irqbalance.h b/irqbalance.h
|
||||
index d8e80a9..e7f6b94 100644
|
||||
--- a/irqbalance.h
|
||||
+++ b/irqbalance.h
|
||||
@@ -42,6 +42,7 @@ 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 void clear_no_existing_irqs(void);
|
||||
|
||||
extern GList *rebalance_irq_list;
|
||||
extern void force_rebalance_irq(struct irq_info *info, void *data __attribute__((unused)));
|
||||
diff --git a/procinterrupts.c b/procinterrupts.c
|
||||
index 0671be0..854282f 100644
|
||||
--- a/procinterrupts.c
|
||||
+++ b/procinterrupts.c
|
||||
@@ -248,7 +248,6 @@ GList* collect_full_irq_list()
|
||||
return tmp_list;
|
||||
}
|
||||
|
||||
-
|
||||
void parse_proc_interrupts(void)
|
||||
{
|
||||
FILE *file;
|
||||
@@ -310,6 +309,7 @@ void parse_proc_interrupts(void)
|
||||
break;
|
||||
}
|
||||
}
|
||||
+ info->existing = 1;
|
||||
free(savedline);
|
||||
|
||||
count = 0;
|
||||
@@ -354,6 +354,8 @@ void parse_proc_interrupts(void)
|
||||
*/
|
||||
msi_found_in_sysfs = 1;
|
||||
}
|
||||
+ if (!need_rescan)
|
||||
+ clear_no_existing_irqs();
|
||||
fclose(file);
|
||||
free(line);
|
||||
}
|
||||
diff --git a/types.h b/types.h
|
||||
index a01d649..9693cf4 100644
|
||||
--- a/types.h
|
||||
+++ b/types.h
|
||||
@@ -70,6 +70,7 @@ struct irq_info {
|
||||
uint64_t last_irq_count;
|
||||
uint64_t load;
|
||||
int moved;
|
||||
+ int existing;
|
||||
struct topo_obj *assigned_obj;
|
||||
char *name;
|
||||
};
|
||||
--
|
||||
2.23.0
|
||||
|
||||
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
|
||||
|
||||
39
backport-Also-fetch-node-info-for-non-PCI-devices.patch
Normal file
39
backport-Also-fetch-node-info-for-non-PCI-devices.patch
Normal file
@ -0,0 +1,39 @@
|
||||
From 31dea01f3a47aa6374560638486879e5129f9c94 Mon Sep 17 00:00:00 2001
|
||||
From: Kairui Song <kasong@redhat.com>
|
||||
Date: Thu, 28 Jan 2021 15:24:32 +0800
|
||||
Subject: [PATCH] Also fetch node info for non-PCI devices
|
||||
|
||||
non-PCI devices could also be bind to a certain node. So if failed to
|
||||
fetch the info from sysfs, try to get it from /proc/irq/<irq>/node.
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/Irqbalance/irqbalance/commit/31dea01f3a47aa6374560638486879e5129f9c94
|
||||
---
|
||||
classify.c | 11 ++++++++---
|
||||
1 file changed, 8 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/classify.c b/classify.c
|
||||
index beb2919..105ecd6 100644
|
||||
--- a/classify.c
|
||||
+++ b/classify.c
|
||||
@@ -361,9 +361,14 @@ static struct irq_info *add_one_irq_to_db(const char *devpath, struct irq_info *
|
||||
|
||||
get_numa_node:
|
||||
numa_node = NUMA_NO_NODE;
|
||||
- if (devpath != NULL && numa_avail) {
|
||||
- sprintf(path, "%s/numa_node", devpath);
|
||||
- process_one_line(path, get_int, &numa_node);
|
||||
+ if (numa_avail) {
|
||||
+ if (devpath != NULL) {
|
||||
+ sprintf(path, "%s/numa_node", devpath);
|
||||
+ process_one_line(path, get_int, &numa_node);
|
||||
+ } else {
|
||||
+ sprintf(path, "/proc/irq/%i/node", irq);
|
||||
+ process_one_line(path, get_int, &numa_node);
|
||||
+ }
|
||||
}
|
||||
|
||||
if (pol->numa_node_set == 1)
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
From 518d81cdd8c54c820d16afb73658753b46032676 Mon Sep 17 00:00:00 2001
|
||||
From: SuperSix173 <liuchao173@huawei.com>
|
||||
Date: Tue, 6 Apr 2021 10:26:17 +0800
|
||||
Subject: [PATCH] Hotplug may occur again during sleep, so wait until there is
|
||||
no hotplug
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/Irqbalance/irqbalance/commit/518d81cdd8c54c820d16afb73658753b46032676
|
||||
---
|
||||
irqbalance.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index 458bb07..3f94847 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -285,7 +285,7 @@ gboolean scan(gpointer data __attribute__((unused)))
|
||||
|
||||
|
||||
/* cope with cpu hotplug -- detected during /proc/interrupts parsing */
|
||||
- if (need_rescan || need_rebuild) {
|
||||
+ while (need_rescan || need_rebuild) {
|
||||
int try_times = 0;
|
||||
|
||||
need_rescan = 0;
|
||||
--
|
||||
2.23.0
|
||||
|
||||
56
backport-activate_mapping-activate-only-online-CPUs.patch
Normal file
56
backport-activate_mapping-activate-only-online-CPUs.patch
Normal file
@ -0,0 +1,56 @@
|
||||
From c8757c6d870c4788da4980abaf21cb7369702ee9 Mon Sep 17 00:00:00 2001
|
||||
From: Paride Legovini <paride@debian.org>
|
||||
Date: Tue, 25 Aug 2020 23:18:27 +0200
|
||||
Subject: [PATCH] activate_mapping: activate only online CPUs
|
||||
|
||||
When echoing a mask to /proc/irq/N/smp_affinity make sure to activate
|
||||
only CPUs which are online. Activating a CPU which is not online results
|
||||
in a EOVERFLOW.
|
||||
|
||||
Originally fixed in Debian by Helge Deller <deller@gmx.de>.
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/Irqbalance/irqbalance/commit/c8757c6d870c4788da4980abaf21cb7369702ee9
|
||||
---
|
||||
activate.c | 8 ++++++--
|
||||
1 file changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/activate.c b/activate.c
|
||||
index 065f880..62cfd08 100644
|
||||
--- a/activate.c
|
||||
+++ b/activate.c
|
||||
@@ -49,6 +49,7 @@ static void activate_mapping(struct irq_info *info, void *data __attribute__((un
|
||||
char buf[PATH_MAX];
|
||||
FILE *file;
|
||||
int ret = 0;
|
||||
+ cpumask_t applied_mask;
|
||||
|
||||
/*
|
||||
* only activate mappings for irqs that have moved
|
||||
@@ -59,10 +60,13 @@ static void activate_mapping(struct irq_info *info, void *data __attribute__((un
|
||||
if (!info->assigned_obj)
|
||||
return;
|
||||
|
||||
+ /* activate only online cpus, otherwise writing to procfs returns EOVERFLOW */
|
||||
+ cpus_and(applied_mask, cpu_online_map, info->assigned_obj->mask);
|
||||
+
|
||||
/*
|
||||
* Don't activate anything for which we have an invalid mask
|
||||
*/
|
||||
- if (check_affinity(info, info->assigned_obj->mask))
|
||||
+ if (check_affinity(info, applied_mask))
|
||||
return;
|
||||
|
||||
sprintf(buf, "/proc/irq/%i/smp_affinity", info->irq);
|
||||
@@ -70,7 +74,7 @@ static void activate_mapping(struct irq_info *info, void *data __attribute__((un
|
||||
if (!file)
|
||||
return;
|
||||
|
||||
- cpumask_scnprintf(buf, PATH_MAX, info->assigned_obj->mask);
|
||||
+ cpumask_scnprintf(buf, PATH_MAX, applied_mask);
|
||||
ret = fprintf(file, "%s", buf);
|
||||
if (ret < 0) {
|
||||
log(TO_ALL, LOG_WARNING, "cannot change irq %i's affinity, add it to banned list", info->irq);
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -7,7 +7,8 @@ allows banning of cpus using the taskset cpulist syntax in addition to the
|
||||
bitmap syntax supported via the existing environment variable
|
||||
IRQBALANCE_BANNED_CPUS
|
||||
|
||||
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
|
||||
Conflict:NA
|
||||
Reference:https://github.com/Irqbalance/irqbalance/commit/677b686e223c74e64f5b230bdb4079555a5a62a9
|
||||
---
|
||||
cputree.c | 6 ++++++
|
||||
irqbalance.1 | 6 ++++++
|
||||
@ -48,5 +49,5 @@ index 3005f6b..33ffd26 100644
|
||||
.TP
|
||||
.B SIGHUP
|
||||
--
|
||||
1.8.3.1
|
||||
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
|
||||
|
||||
57
backport-log-correctly-for-isolated-and-nohz_full-cpus.patch
Normal file
57
backport-log-correctly-for-isolated-and-nohz_full-cpus.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From 6fe032945b69d8f382fa3e8de8e4fdce84063199 Mon Sep 17 00:00:00 2001
|
||||
From: Yunfeng Ye <yeyunfeng@huawei.com>
|
||||
Date: Fri, 20 Nov 2020 00:15:58 +0800
|
||||
Subject: [PATCH] log correctly for isolated and nohz_full cpus
|
||||
|
||||
When the banded CPU is configured, and the "isolcpus" or "nohz_full"
|
||||
is configured, the log for isolated and nohz CPUs are not correct.
|
||||
|
||||
So only log relevant infomation when isolcpus and nohz_full has been
|
||||
handled, also put the cpus_clear() closer.
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/Irqbalance/irqbalance/commit/6fe032945b69d8f382fa3e8de8e4fdce84063199
|
||||
---
|
||||
cputree.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/cputree.c b/cputree.c
|
||||
index 80a6d9d..eed20db 100644
|
||||
--- a/cputree.c
|
||||
+++ b/cputree.c
|
||||
@@ -112,9 +112,6 @@ static void setup_banned_cpus(void)
|
||||
cpumask_t isolated_cpus;
|
||||
char *env = NULL;
|
||||
|
||||
- cpus_clear(isolated_cpus);
|
||||
- cpus_clear(nohz_full);
|
||||
-
|
||||
/* A manually specified cpumask overrides auto-detection. */
|
||||
if (cpu_ban_string != NULL && banned_cpumask_from_ui != NULL) {
|
||||
cpulist_parse(banned_cpumask_from_ui,
|
||||
@@ -133,6 +130,9 @@ static void setup_banned_cpus(void)
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ cpus_clear(isolated_cpus);
|
||||
+ cpus_clear(nohz_full);
|
||||
+
|
||||
path = "/sys/devices/system/cpu/isolated";
|
||||
process_one_line(path, get_mask_from_cpulist, &isolated_cpus);
|
||||
|
||||
@@ -141,11 +141,11 @@ static void setup_banned_cpus(void)
|
||||
|
||||
cpus_or(banned_cpus, nohz_full, isolated_cpus);
|
||||
|
||||
-out:
|
||||
cpumask_scnprintf(buffer, 4096, isolated_cpus);
|
||||
log(TO_CONSOLE, LOG_INFO, "Isolated CPUs: %s\n", buffer);
|
||||
cpumask_scnprintf(buffer, 4096, nohz_full);
|
||||
log(TO_CONSOLE, LOG_INFO, "Adaptive-ticks CPUs: %s\n", buffer);
|
||||
+out:
|
||||
cpumask_scnprintf(buffer, 4096, banned_cpus);
|
||||
log(TO_CONSOLE, LOG_INFO, "Banned CPUs: %s\n", buffer);
|
||||
}
|
||||
--
|
||||
2.23.0
|
||||
|
||||
93
feature-aarch64-add-the-regular-to-get-the-correct-i.patch
Normal file
93
feature-aarch64-add-the-regular-to-get-the-correct-i.patch
Normal file
@ -0,0 +1,93 @@
|
||||
From c924f1df705a301a0ffc01fce4c7712756c8b1d2 Mon Sep 17 00:00:00 2001
|
||||
From: Zengruan Ye <yezengruan@huawei.com>
|
||||
Date: Sat, 13 Jul 2019 19:09:09 +0800
|
||||
Subject: [PATCH] feature: aarch64: add the regular to get the correct irq
|
||||
class on hisi board
|
||||
|
||||
First, get the full irq desc name, include that the name split by blank, just like
|
||||
(hisi_sas_v2_hw sata). We use the irq type to mark the begin of the name.
|
||||
|
||||
Second, for hisi bord, we consider to match the IRQ_SCSI class (which the
|
||||
irqbalance service concerned, and the eth device match follow the
|
||||
open community rule) by keywords group hisi & sas or hisi & sata.
|
||||
|
||||
Signed-off-by: wanghaibin <wanghaibin.wang@huawei.com>
|
||||
---
|
||||
procinterrupts.c | 33 ++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 32 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/procinterrupts.c b/procinterrupts.c
|
||||
index 854282f..32c5e53 100644
|
||||
--- a/procinterrupts.c
|
||||
+++ b/procinterrupts.c
|
||||
@@ -108,6 +108,8 @@ static void guess_arm_irq_hints(char *name, struct irq_info *info)
|
||||
/* Note: Last entry is a catchall */
|
||||
static struct irq_match matches[] = {
|
||||
{ "eth.*" ,{NULL} ,NULL, IRQ_TYPE_LEGACY, IRQ_GBETH },
|
||||
+ { "hisi\\w*? *sas" ,{NULL} ,NULL, IRQ_TYPE_LEGACY, IRQ_SCSI},
|
||||
+ { "hisi\\w*? *sata" ,{NULL} ,NULL, IRQ_TYPE_LEGACY, IRQ_SCSI},
|
||||
{ "[A-Z0-9]{4}[0-9a-f]{4}", {NULL} ,check_platform_device, IRQ_TYPE_LEGACY, IRQ_OTHER},
|
||||
{ "PNP[0-9a-f]{4}", {NULL} ,check_platform_device, IRQ_TYPE_LEGACY, IRQ_OTHER},
|
||||
{ ".*", {NULL}, NULL, IRQ_TYPE_LEGACY, IRQ_OTHER},
|
||||
@@ -155,6 +157,8 @@ void init_irq_class_and_type(char *savedline, struct irq_info *info, int irq)
|
||||
int is_xen_dyn = 0;
|
||||
#ifdef AARCH64
|
||||
char *tmp = NULL;
|
||||
+ int irq_fullname_valid = 1;
|
||||
+ char irq_fullname[PATH_MAX] = {0};
|
||||
#endif
|
||||
|
||||
irq_name = strtok_r(savedline, " ", &savedptr);
|
||||
@@ -166,6 +170,16 @@ void init_irq_class_and_type(char *savedline, struct irq_info *info, int irq)
|
||||
if (strstr(irq_name, "xen-dyn") != NULL)
|
||||
is_xen_dyn = 1;
|
||||
last_token = p;
|
||||
+
|
||||
+#ifdef AARCH64
|
||||
+ /*
|
||||
+ * /proc/interrupts format defined, after of interrupt type
|
||||
+ * the reset string is mark the irq desc name.
|
||||
+ */
|
||||
+ if (strncmp(irq_name, "Level", strlen("Level")) == 0 ||
|
||||
+ strncmp(irq_name, "Edge", strlen("Edge")) == 0)
|
||||
+ break;
|
||||
+#endif
|
||||
}
|
||||
|
||||
#ifdef AARCH64
|
||||
@@ -173,6 +187,17 @@ void init_irq_class_and_type(char *savedline, struct irq_info *info, int irq)
|
||||
tmp = strchr(irq_name, '\n');
|
||||
if (tmp)
|
||||
*tmp = 0;
|
||||
+
|
||||
+ if (strlen(irq_name) + strlen(savedptr) + 1 < PATH_MAX) {
|
||||
+ strcat(irq_fullname, irq_name);
|
||||
+ strcat(irq_fullname, " ");
|
||||
+ strcat(irq_fullname, savedptr);
|
||||
+ tmp = strchr(irq_fullname, '\n');
|
||||
+ if (tmp)
|
||||
+ *tmp = 0;
|
||||
+ } else {
|
||||
+ irq_fullname_valid = 0;
|
||||
+ }
|
||||
#endif
|
||||
irq_mod = last_token;
|
||||
info->irq = irq;
|
||||
@@ -182,7 +207,13 @@ void init_irq_class_and_type(char *savedline, struct irq_info *info, int irq)
|
||||
info->class = IRQ_VIRT_EVENT;
|
||||
} else {
|
||||
#ifdef AARCH64
|
||||
- guess_arm_irq_hints(irq_name, info);
|
||||
+ if (irq_fullname_valid) {
|
||||
+ irq_name = irq_fullname;
|
||||
+ guess_arm_irq_hints(irq_name, info);
|
||||
+ } else {
|
||||
+ info->type = IRQ_TYPE_LEGACY;
|
||||
+ info->class = IRQ_OTHER;
|
||||
+ }
|
||||
#else
|
||||
info->type = IRQ_TYPE_LEGACY;
|
||||
info->class = IRQ_OTHER;
|
||||
--
|
||||
2.23.0
|
||||
|
||||
34
feature-add-ability-to-set-hintpolicy-during-runtime.patch
Normal file
34
feature-add-ability-to-set-hintpolicy-during-runtime.patch
Normal file
@ -0,0 +1,34 @@
|
||||
From 7db6af3a25c9742febce616081a723e1c92889d1 Mon Sep 17 00:00:00 2001
|
||||
From: BiaoXiang Ye <yebiaoxiang@huawei.com>
|
||||
Date: Wed, 1 Jul 2020 12:05:33 +0800
|
||||
Subject: [PATCH] feature: add ability to set hintpolicy during runtime
|
||||
|
||||
irqbalance adds default config --hintpolicy=subset, so we need provide the ability to set
|
||||
hintpolicy back to ignore during runtime.
|
||||
---
|
||||
irqbalance.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index 859fd6a..ffbb191 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -538,6 +538,15 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
||||
cpu_ban_string = NULL;
|
||||
}
|
||||
need_rescan = 1;
|
||||
+ } else if (!(strncmp(buff + strlen("settings "), "hintpolicy ",
|
||||
+ strlen("hintpolicy ")))) {
|
||||
+ if (!(strncmp(buff + strlen("settings hintpolicy "), "ignore",
|
||||
+ strlen("ignore")))) {
|
||||
+ hint_enabled = 0;
|
||||
+ } else if (!(strncmp(buff + strlen("settings hintpolicy "),
|
||||
+ "subset", strlen("subset")))) {
|
||||
+ hint_enabled = 1;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
if (!strncmp(buff, "setup", strlen("setup"))) {
|
||||
--
|
||||
2.23.0
|
||||
|
||||
89
feature-add-new-irq-migrate-rule-to-avoid-high-cpu-i.patch
Normal file
89
feature-add-new-irq-migrate-rule-to-avoid-high-cpu-i.patch
Normal file
@ -0,0 +1,89 @@
|
||||
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] feature: 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 | 8 +++++++-
|
||||
irqbalance.h | 1 +
|
||||
irqlist.c | 3 ++-
|
||||
3 files changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index 9449e40..82ac3ea 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -72,6 +72,7 @@ GMainLoop *main_loop;
|
||||
char *cpu_ban_string = NULL;
|
||||
char *banned_cpumask_from_ui = NULL;
|
||||
unsigned long migrate_ratio = 0;
|
||||
+unsigned long load_limit = 0;
|
||||
|
||||
static void sleep_approx(int seconds)
|
||||
{
|
||||
@@ -106,6 +107,7 @@ struct option lopts[] = {
|
||||
{"hintpolicy", 1, NULL, 'h'},
|
||||
{"verifyhint", 1, NULL, 'v'},
|
||||
{"notclearhint", 0, NULL, 'n'},
|
||||
+ {"loadlimit", 1, NULL, 'g'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -115,6 +117,7 @@ static void usage(void)
|
||||
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>] [--migrateval= | -e <n>]\n");
|
||||
log(TO_CONSOLE, LOG_INFO, " [--rulesconfig= | -r <config>] [--hintpolicy | -h <subset>] [--verifyhint= | -v n] [--notclearhint | -n]\n");
|
||||
+ log(TO_CONSOLE, LOG_INFO, " [--loadlimit= | -g <n>]\n");
|
||||
}
|
||||
|
||||
static void version(void)
|
||||
@@ -129,7 +132,7 @@ static void parse_command_line(int argc, char **argv)
|
||||
unsigned long val;
|
||||
|
||||
while ((opt = getopt_long(argc, argv,
|
||||
- "odfjVni:p:s:c:l:m:t:e:r:h:v:",
|
||||
+ "odfjVni:p:s:c:l:m:t:e:r:h:v:g:",
|
||||
lopts, &longind)) != -1) {
|
||||
|
||||
switch(opt) {
|
||||
@@ -223,6 +226,9 @@ static void parse_command_line(int argc, char **argv)
|
||||
case 'n':
|
||||
clear_affinity_hint = 0;
|
||||
break;
|
||||
+ case 'g':
|
||||
+ load_limit = strtoul(optarg, NULL, 10);
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/irqbalance.h b/irqbalance.h
|
||||
index 4a73b83..9ff8f37 100644
|
||||
--- a/irqbalance.h
|
||||
+++ b/irqbalance.h
|
||||
@@ -83,6 +83,7 @@ extern cpumask_t banned_cpus;
|
||||
extern cpumask_t unbanned_cpus;
|
||||
extern long HZ;
|
||||
extern unsigned long migrate_ratio;
|
||||
+extern unsigned long load_limit;
|
||||
|
||||
/*
|
||||
* Numa node access routines
|
||||
diff --git a/irqlist.c b/irqlist.c
|
||||
index 9ab321a..98a4224 100644
|
||||
--- a/irqlist.c
|
||||
+++ b/irqlist.c
|
||||
@@ -97,7 +97,8 @@ static void move_candidate_irqs(struct irq_info *info, void *data)
|
||||
}
|
||||
|
||||
/* If we can migrate an irq without swapping the imbalance do it. */
|
||||
- if ((lb_info->min_load + info->load) - (lb_info->adjustment_load - info->load) < delta_load) {
|
||||
+ if ((lb_info->min_load + info->load) - (lb_info->adjustment_load - info->load) < delta_load &&
|
||||
+ lb_info->adjustment_load > load_limit) {
|
||||
lb_info->adjustment_load -= info->load;
|
||||
lb_info->min_load += info->load;
|
||||
if (lb_info->min_load > lb_info->adjustment_load) {
|
||||
--
|
||||
2.23.0
|
||||
|
||||
387
feature-add-new-user-irq-policy-config-rule.patch
Normal file
387
feature-add-new-user-irq-policy-config-rule.patch
Normal file
@ -0,0 +1,387 @@
|
||||
From 0406d202af914881af1a6caf5247e7ac40564366 Mon Sep 17 00:00:00 2001
|
||||
From: hejingxian <hejingxian@huawei.com>
|
||||
Date: Tue, 17 Sep 2019 23:32:54 +0800
|
||||
Subject: [PATCH] add new user irq policy config rule
|
||||
|
||||
When there is many irqs, the old user irq policy script will cost too much time.
|
||||
Therefore, we introduce a new user irq policy config rule which avoid policy script running
|
||||
for every irq.
|
||||
---
|
||||
Makefile.am | 2 +-
|
||||
classify.c | 19 ++++--
|
||||
irqbalance.c | 15 ++++-
|
||||
irqbalance.h | 1 +
|
||||
placement.c | 3 +-
|
||||
rules_config.c | 174 +++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
rules_config.h | 40 ++++++++++++
|
||||
7 files changed, 244 insertions(+), 10 deletions(-)
|
||||
create mode 100644 rules_config.c
|
||||
create mode 100644 rules_config.h
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 73988b3..3086d67 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -38,7 +38,7 @@ sbin_PROGRAMS += irqbalance-ui
|
||||
endif
|
||||
|
||||
irqbalance_SOURCES = activate.c bitmap.c classify.c cputree.c irqbalance.c \
|
||||
- irqlist.c numa.c placement.c procinterrupts.c
|
||||
+ irqlist.c numa.c placement.c procinterrupts.c rules_config.c
|
||||
irqbalance_LDADD = $(LIBCAP_NG_LIBS) $(GLIB2_LIBS)
|
||||
if IRQBALANCEUI
|
||||
irqbalance_ui_SOURCES = $(UI_DIR)/helpers.c $(UI_DIR)/irqbalance-ui.c \
|
||||
diff --git a/classify.c b/classify.c
|
||||
index 74103bf..254197e 100644
|
||||
--- a/classify.c
|
||||
+++ b/classify.c
|
||||
@@ -625,12 +625,18 @@ static void add_new_irq(char *path, struct irq_info *hint, GList *proc_interrupt
|
||||
return;
|
||||
|
||||
/* Set NULL devpath for the irq has no sysfs entries */
|
||||
- get_irq_user_policy(path, irq, &pol);
|
||||
+ if (user_policy_list == NULL) {
|
||||
+ get_irq_user_policy(path, irq, &pol);
|
||||
+ }
|
||||
if ((pol.ban == 1) || check_for_irq_ban(irq, proc_interrupts)) { /*FIXME*/
|
||||
__add_banned_irq(irq, &banned_irqs);
|
||||
new = get_irq_info(irq);
|
||||
- } else
|
||||
+ } else {
|
||||
new = add_one_irq_to_db(path, hint, &pol);
|
||||
+ if ((new != NULL) && (user_policy_list != NULL)) {
|
||||
+ set_usr_irq_policy(hint->name, new);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
if (!new)
|
||||
log(TO_CONSOLE, LOG_WARNING, "add_new_irq: Failed to add irq %d\n", irq);
|
||||
@@ -781,14 +787,15 @@ 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 */
|
||||
+ /* firstly, init irq info by parse savedline */
|
||||
+ init_irq_class_and_type(savedline, &tmp_info, irq);
|
||||
+ /* secondly, 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);
|
||||
- }
|
||||
+ } else
|
||||
+ set_usr_irq_policy(tmp_info.name, *pinfo);
|
||||
if (*pinfo == NULL) {
|
||||
return -1;
|
||||
}
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index 10e2b13..ecc3eca 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -99,6 +99,7 @@ struct option lopts[] = {
|
||||
{"interval", 1 , NULL, 't'},
|
||||
{"version", 0, NULL, 'V'},
|
||||
{"migrateval", 1, NULL, 'e'},
|
||||
+ {"rulesconfig", 1, NULL, 'r'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -107,6 +108,7 @@ static void usage(void)
|
||||
log(TO_CONSOLE, LOG_INFO, "irqbalance [--oneshot | -o] [--debug | -d] [--foreground | -f] [--journal | -j]\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>] [--migrateval= | -e <n>]\n");
|
||||
+ log(TO_CONSOLE, LOG_INFO, " [--rulesconfig= | -r <config>]\n");
|
||||
}
|
||||
|
||||
static void version(void)
|
||||
@@ -121,7 +123,7 @@ static void parse_command_line(int argc, char **argv)
|
||||
unsigned long val;
|
||||
|
||||
while ((opt = getopt_long(argc, argv,
|
||||
- "odfjVi:p:s:c:l:m:t:e:",
|
||||
+ "odfjVi:p:s:c:l:m:t:e:r:",
|
||||
lopts, &longind)) != -1) {
|
||||
|
||||
switch(opt) {
|
||||
@@ -193,6 +195,9 @@ static void parse_command_line(int argc, char **argv)
|
||||
case 'e':
|
||||
migrate_ratio = strtoul(optarg, NULL, 10);
|
||||
break;
|
||||
+ case 'r':
|
||||
+ rules_config_file = strdup(optarg);
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -661,6 +666,14 @@ int main(int argc, char** argv)
|
||||
}
|
||||
}
|
||||
|
||||
+ if (read_user_policy_config() != 0) {
|
||||
+ log(TO_ALL, LOG_WARNING, "Read user policy config fail.\n");
|
||||
+ }
|
||||
+ if (rules_config_file) {
|
||||
+ free(rules_config_file);
|
||||
+ rules_config_file = NULL;
|
||||
+ }
|
||||
+
|
||||
build_object_tree();
|
||||
if (debug_mode)
|
||||
dump_object_tree();
|
||||
diff --git a/irqbalance.h b/irqbalance.h
|
||||
index 618f254..78d0adc 100644
|
||||
--- a/irqbalance.h
|
||||
+++ b/irqbalance.h
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "types.h"
|
||||
#include "config.h"
|
||||
+#include "rules_config.h"
|
||||
|
||||
#ifdef __aarch64__
|
||||
#define AARCH64
|
||||
diff --git a/placement.c b/placement.c
|
||||
index 17a9f2e..bf27297 100644
|
||||
--- a/placement.c
|
||||
+++ b/placement.c
|
||||
@@ -52,8 +52,7 @@ static void find_best_object(struct topo_obj *d, void *data)
|
||||
* also don't consider any node that doesn't have at least one cpu in
|
||||
* the unbanned list
|
||||
*/
|
||||
- if ((d->obj_type == OBJ_TYPE_NODE) &&
|
||||
- (!cpus_intersects(d->mask, unbanned_cpus)))
|
||||
+ if (!cpus_intersects(d->mask, unbanned_cpus))
|
||||
return;
|
||||
|
||||
if (d->powersave_mode)
|
||||
diff --git a/rules_config.c b/rules_config.c
|
||||
new file mode 100644
|
||||
index 0000000..e32a31e
|
||||
--- /dev/null
|
||||
+++ b/rules_config.c
|
||||
@@ -0,0 +1,174 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2019. Huawei Technologies Co., Ltd. All rights reserved.
|
||||
+ *
|
||||
+ * This program file is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License as published by the
|
||||
+ * Free Software Foundation; version 2 of the License.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
+ * for more details.
|
||||
+ */
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include "irqbalance.h"
|
||||
+
|
||||
+char *rules_config_file = NULL;
|
||||
+USER_IRQ_POLICY *user_policy_list = NULL;
|
||||
+
|
||||
+void add_usr_irq_policy(USER_IRQ_POLICY *policy)
|
||||
+{
|
||||
+ if (policy == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+ policy->next = user_policy_list;
|
||||
+ user_policy_list = policy;
|
||||
+}
|
||||
+
|
||||
+USER_IRQ_POLICY *get_usr_irq_policy(char *name)
|
||||
+{
|
||||
+ USER_IRQ_POLICY *p = user_policy_list;
|
||||
+ if (name == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ while (p != NULL) {
|
||||
+ if (strstr(name, p->irq_type) != NULL) {
|
||||
+ return p;
|
||||
+ }
|
||||
+ p = p->next;
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+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) {
|
||||
+ info->numa_node = get_numa_node(user_policy->numa_node);
|
||||
+ log(TO_ALL, LOG_WARNING, "override irq (%d) numa_node to %d\n",
|
||||
+ info->irq, user_policy->numa_node);
|
||||
+ }
|
||||
+ if (user_policy->balance_level_set) {
|
||||
+ info->level = user_policy->balance_level;
|
||||
+ log(TO_ALL, LOG_WARNING, "override irq (%d) balance_level to %d\n",
|
||||
+ info->irq, info->level);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
+
|
||||
+int read_user_policy_config()
|
||||
+{
|
||||
+ FILE *file;
|
||||
+ char *line = NULL;
|
||||
+ size_t size = 0;
|
||||
+ size_t len;
|
||||
+ char *key;
|
||||
+ char *value;
|
||||
+ char *c;
|
||||
+ int level;
|
||||
+ int node = -1;
|
||||
+ char savedline[CONFIG_LINE_MAX_LEN] = {0};
|
||||
+ USER_IRQ_POLICY *cur_policy = NULL;
|
||||
+ char *levelvals[] = { "none", "package", "cache", "core" };
|
||||
+
|
||||
+ if (rules_config_file == NULL) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ log(TO_ALL, LOG_INFO, "rules_config_file is: %s\n", rules_config_file);
|
||||
+ file = fopen(rules_config_file, "r");
|
||||
+ if (!file)
|
||||
+ return -1;
|
||||
+
|
||||
+ while (!feof(file)) {
|
||||
+ if (getline(&line, &size, file) <= 0)
|
||||
+ break;
|
||||
+ c = line;
|
||||
+ if (*c == '#') {
|
||||
+ continue;
|
||||
+ }
|
||||
+ len = strlen(line);
|
||||
+ if (len > sizeof(savedline)-1) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ strncpy(savedline, line, len);
|
||||
+ savedline[len] = '\0';
|
||||
+ c = savedline;
|
||||
+ while (*c == ' ') {
|
||||
+ c++;
|
||||
+ }
|
||||
+ key = c;
|
||||
+ /* make sure there is no space near '=' */
|
||||
+ c = strchr(savedline, '=');
|
||||
+ if (c != NULL) {
|
||||
+ value = c + 1;
|
||||
+ *c = '\0';
|
||||
+ } else {
|
||||
+ continue;
|
||||
+ }
|
||||
+ c = strchr(value, '\n');
|
||||
+ if (c != NULL) {
|
||||
+ *c = '\0';
|
||||
+ }
|
||||
+ if ((strlen(key) == 0) || (strlen(value) == 0)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ log(TO_ALL, LOG_INFO, "User irq policy config read: key is %s, value is %s\n", key, value);
|
||||
+ if (strcmp(key, "type") == 0) {
|
||||
+ cur_policy = malloc(sizeof(USER_IRQ_POLICY));
|
||||
+ if (cur_policy == NULL) {
|
||||
+ goto out;
|
||||
+ }
|
||||
+ cur_policy->next = NULL;
|
||||
+ cur_policy->numa_node_set = 0;
|
||||
+ cur_policy->balance_level_set = 0;
|
||||
+ if (strlen(value) > CONFIG_TYPE_MAX_LEN - 1) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ strncpy(cur_policy->irq_type, value, strlen(value) + 1);
|
||||
+ add_usr_irq_policy(cur_policy);
|
||||
+ } else if (strcmp(key, "balance_level") == 0) {
|
||||
+ if (cur_policy == NULL) {
|
||||
+ goto out;
|
||||
+ }
|
||||
+ for (level = 0; level < MAX_LEVEL_NUM; level++) {
|
||||
+ if (strcasecmp(value, levelvals[level]) == 0) {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (level >= MAX_LEVEL_NUM) {
|
||||
+ log(TO_ALL, LOG_WARNING, "Bad value for balance_level policy: %s\n", value);
|
||||
+ } else {
|
||||
+ cur_policy->balance_level = level;
|
||||
+ cur_policy->balance_level_set = 1;
|
||||
+ }
|
||||
+ } else if (strcmp(key, "numa_node") == 0) {
|
||||
+ if (cur_policy == NULL) {
|
||||
+ goto out;
|
||||
+ }
|
||||
+ node = strtoul(value, NULL, 10);
|
||||
+ /* check node */
|
||||
+ if (node != -1 && !get_numa_node(node)) {
|
||||
+ log(TO_ALL, LOG_WARNING, "NUMA node %d doesn't exist\n",
|
||||
+ node);
|
||||
+ continue;
|
||||
+ }
|
||||
+ cur_policy->numa_node = node;
|
||||
+ cur_policy->numa_node_set = 1;
|
||||
+ }
|
||||
+ }
|
||||
+out:
|
||||
+ fclose(file);
|
||||
+ if (line) {
|
||||
+ free(line);
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/rules_config.h b/rules_config.h
|
||||
new file mode 100644
|
||||
index 0000000..edcac8a
|
||||
--- /dev/null
|
||||
+++ b/rules_config.h
|
||||
@@ -0,0 +1,40 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2019. Huawei Technologies Co., Ltd. All rights reserved.
|
||||
+ *
|
||||
+ * This program file is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License as published by the
|
||||
+ * Free Software Foundation; version 2 of the License.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
+ * for more details.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _INCLUDE_RULES_CONFIG_H
|
||||
+#define _INCLUDE_RULES_CONFIG_H
|
||||
+
|
||||
+#define CONFIG_TYPE_MAX_LEN 32
|
||||
+#define CONFIG_LINE_MAX_LEN 512
|
||||
+#define MAX_LEVEL_NUM 4
|
||||
+
|
||||
+typedef struct user_irq_policy_config {
|
||||
+ char irq_type[CONFIG_TYPE_MAX_LEN];
|
||||
+ int numa_node;
|
||||
+ int balance_level;
|
||||
+ int numa_node_set;
|
||||
+ int balance_level_set;
|
||||
+ struct user_irq_policy_config *next;
|
||||
+}USER_IRQ_POLICY;
|
||||
+extern USER_IRQ_POLICY *user_policy_list;
|
||||
+extern char *rules_config_file;
|
||||
+
|
||||
+void add_usr_irq_policy(USER_IRQ_POLICY *policy);
|
||||
+
|
||||
+USER_IRQ_POLICY *get_usr_irq_policy(char *name);
|
||||
+
|
||||
+int read_user_policy_config();
|
||||
+
|
||||
+void set_usr_irq_policy(char *name, struct irq_info *info);
|
||||
+
|
||||
+#endif
|
||||
--
|
||||
2.23.0
|
||||
|
||||
105
feature-add-switch-to-clear-affinity-hint.patch
Normal file
105
feature-add-switch-to-clear-affinity-hint.patch
Normal file
@ -0,0 +1,105 @@
|
||||
From e44eed4faef6ee1bd1ae41dd27a8513d37681f7f Mon Sep 17 00:00:00 2001
|
||||
From: liuchao <liuchao173@huawei.com>
|
||||
Date: Tue, 17 Dec 2019 02:54:57 +0000
|
||||
Subject: [PATCH] feature: add switch to clear affinity hint
|
||||
|
||||
All irqs' affinity hints are cleared in update_affinity_hint and forced
|
||||
to rebalance. In some scenarios, it will affect performance.
|
||||
---
|
||||
hint_verify.c | 10 +++++++++-
|
||||
irqbalance.c | 9 +++++++--
|
||||
2 files changed, 16 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/hint_verify.c b/hint_verify.c
|
||||
index 3492902..2f895be 100644
|
||||
--- a/hint_verify.c
|
||||
+++ b/hint_verify.c
|
||||
@@ -18,6 +18,7 @@ extern int keep_going;
|
||||
extern GMainLoop *main_loop;
|
||||
extern gboolean scan();
|
||||
extern int last_interval;
|
||||
+extern int clear_affinity_hint;
|
||||
|
||||
int real_sleep_interval;
|
||||
int sleep_interval_count;
|
||||
@@ -55,7 +56,8 @@ void update_affinity_hint(struct irq_info *info, void *data __attribute__((unuse
|
||||
if (!hint_enabled)
|
||||
return;
|
||||
|
||||
- cpus_clear(info->affinity_hint);
|
||||
+ if (clear_affinity_hint)
|
||||
+ cpus_clear(info->affinity_hint);
|
||||
sprintf(path, "/proc/irq/%d/affinity_hint", info->irq);
|
||||
process_one_line(path, get_mask_from_bitmap, ¤t_affinity_hint);
|
||||
|
||||
@@ -68,6 +70,11 @@ void update_affinity_hint(struct irq_info *info, void *data __attribute__((unuse
|
||||
}
|
||||
}
|
||||
|
||||
+static void check_clear()
|
||||
+{
|
||||
+ process_one_line("/etc/sysconfig/irqbalance_clear", get_int, &clear_affinity_hint);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* This function is the main loop of irqbalance, which include:
|
||||
* 1. scan opration for irq balancing;
|
||||
@@ -92,6 +99,7 @@ gboolean poll_hint_affinity_and_scan(gpointer data __attribute__((unused)))
|
||||
sleep_count++;
|
||||
|
||||
if (need_verify_flag && hint_changed()) {
|
||||
+ check_clear();
|
||||
for_each_irq(NULL, update_affinity_hint, NULL);
|
||||
if (hint_has_changed) {
|
||||
hint_has_changed = FALSE;
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index 5985d8d..9449e40 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -54,6 +54,7 @@ int numa_avail;
|
||||
int journal_logging = 0;
|
||||
int need_rescan;
|
||||
int need_rebuild;
|
||||
+int clear_affinity_hint = 1;
|
||||
unsigned int log_mask = TO_ALL;
|
||||
const char *log_indent;
|
||||
unsigned long power_thresh = ULONG_MAX;
|
||||
@@ -104,6 +105,7 @@ struct option lopts[] = {
|
||||
{"rulesconfig", 1, NULL, 'r'},
|
||||
{"hintpolicy", 1, NULL, 'h'},
|
||||
{"verifyhint", 1, NULL, 'v'},
|
||||
+ {"notclearhint", 0, NULL, 'n'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -112,7 +114,7 @@ static void usage(void)
|
||||
log(TO_CONSOLE, LOG_INFO, "irqbalance [--oneshot | -o] [--debug | -d] [--foreground | -f] [--journal | -j]\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>] [--migrateval= | -e <n>]\n");
|
||||
- log(TO_CONSOLE, LOG_INFO, " [--rulesconfig= | -r <config>] [--hintpolicy | -h <subset>] [--verifyhint= | -v n]\n");
|
||||
+ log(TO_CONSOLE, LOG_INFO, " [--rulesconfig= | -r <config>] [--hintpolicy | -h <subset>] [--verifyhint= | -v n] [--notclearhint | -n]\n");
|
||||
}
|
||||
|
||||
static void version(void)
|
||||
@@ -127,7 +129,7 @@ static void parse_command_line(int argc, char **argv)
|
||||
unsigned long val;
|
||||
|
||||
while ((opt = getopt_long(argc, argv,
|
||||
- "odfjVi:p:s:c:l:m:t:e:r:h:v:",
|
||||
+ "odfjVni:p:s:c:l:m:t:e:r:h:v:",
|
||||
lopts, &longind)) != -1) {
|
||||
|
||||
switch(opt) {
|
||||
@@ -218,6 +220,9 @@ static void parse_command_line(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
+ case 'n':
|
||||
+ clear_affinity_hint = 0;
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
}
|
||||
--
|
||||
2.23.0
|
||||
|
||||
100
feature-add-the-switch-of-printing-log.patch
Normal file
100
feature-add-the-switch-of-printing-log.patch
Normal file
@ -0,0 +1,100 @@
|
||||
From b697a97436dafa13f0ae3febde299bfc20498f9d Mon Sep 17 00:00:00 2001
|
||||
From: liuchao <liuchao173@huawei.com>
|
||||
Date: Wed, 23 Oct 2019 11:42:26 +0000
|
||||
Subject: [PATCH] feature: add the switch of printing log
|
||||
|
||||
add the switch of printing log
|
||||
---
|
||||
cputree.c | 16 ++++++++--------
|
||||
irqbalance.c | 11 ++++++++++-
|
||||
2 files changed, 18 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/cputree.c b/cputree.c
|
||||
index 010e672..48d3d0d 100644
|
||||
--- a/cputree.c
|
||||
+++ b/cputree.c
|
||||
@@ -399,23 +399,23 @@ static void dump_irq(struct irq_info *info, void *data)
|
||||
indent[i] = log_indent[0];
|
||||
|
||||
indent[i] = '\0';
|
||||
- log(TO_CONSOLE, LOG_INFO, "%sInterrupt %i node_num is %d (%s/%lu:%lu) \n", indent,
|
||||
+ log(TO_ALL, LOG_INFO, "%sInterrupt %i node_num is %d (%s/%lu:%lu) \n", indent,
|
||||
info->irq, irq_numa_node(info)->number, classes[info->class], info->load, (info->irq_count - info->last_irq_count));
|
||||
free(indent);
|
||||
}
|
||||
|
||||
static void dump_numa_node_num(struct topo_obj *p, void *data __attribute__((unused)))
|
||||
{
|
||||
- log(TO_CONSOLE, LOG_INFO, "%d ", p->number);
|
||||
+ log(TO_ALL, LOG_INFO, "%d ", p->number);
|
||||
}
|
||||
|
||||
static void dump_balance_obj(struct topo_obj *d, void *data __attribute__((unused)))
|
||||
{
|
||||
struct topo_obj *c = (struct topo_obj *)d;
|
||||
- log(TO_CONSOLE, LOG_INFO, "%s%s%s%sCPU number %i numa_node is ",
|
||||
+ log(TO_ALL, LOG_INFO, "%s%s%s%sCPU number %i numa_node is ",
|
||||
log_indent, log_indent, log_indent, log_indent, c->number);
|
||||
for_each_object(cpu_numa_node(c), dump_numa_node_num, NULL);
|
||||
- log(TO_CONSOLE, LOG_INFO, "(load %lu)\n", (unsigned long)c->load);
|
||||
+ log(TO_ALL, LOG_INFO, "(load %lu)\n", (unsigned long)c->load);
|
||||
if (c->interrupts)
|
||||
for_each_irq(c->interrupts, dump_irq, (void *)18);
|
||||
}
|
||||
@@ -424,10 +424,10 @@ static void dump_cache_domain(struct topo_obj *d, void *data)
|
||||
{
|
||||
char *buffer = data;
|
||||
cpumask_scnprintf(buffer, 4095, d->mask);
|
||||
- log(TO_CONSOLE, LOG_INFO, "%s%sCache domain %i: numa_node is ",
|
||||
+ log(TO_ALL, LOG_INFO, "%s%sCache domain %i: numa_node is ",
|
||||
log_indent, log_indent, d->number);
|
||||
for_each_object(d->numa_nodes, dump_numa_node_num, NULL);
|
||||
- log(TO_CONSOLE, LOG_INFO, "cpu mask is %s (load %lu) \n", buffer,
|
||||
+ log(TO_ALL, LOG_INFO, "cpu mask is %s (load %lu) \n", buffer,
|
||||
(unsigned long)d->load);
|
||||
if (d->children)
|
||||
for_each_object(d->children, dump_balance_obj, NULL);
|
||||
@@ -439,9 +439,9 @@ static void dump_package(struct topo_obj *d, void *data)
|
||||
{
|
||||
char *buffer = data;
|
||||
cpumask_scnprintf(buffer, 4096, d->mask);
|
||||
- log(TO_CONSOLE, LOG_INFO, "Package %i: numa_node ", d->number);
|
||||
+ log(TO_ALL, LOG_INFO, "Package %i: numa_node ", d->number);
|
||||
for_each_object(d->numa_nodes, dump_numa_node_num, NULL);
|
||||
- log(TO_CONSOLE, LOG_INFO, "cpu mask is %s (load %lu)\n",
|
||||
+ log(TO_ALL, LOG_INFO, "cpu mask is %s (load %lu)\n",
|
||||
buffer, (unsigned long)d->load);
|
||||
if (d->children)
|
||||
for_each_object(d->children, dump_cache_domain, buffer);
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index ecc3eca..450a1ff 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -266,6 +266,15 @@ gboolean force_rescan(gpointer data __attribute__((unused)))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+static int check_debug()
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ process_one_line("/etc/sysconfig/irqbalance_debug", get_int, &ret);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
gboolean scan(gpointer data __attribute__((unused)))
|
||||
{
|
||||
log(TO_CONSOLE, LOG_INFO, "\n\n\n-----------------------------------------------------------------------------\n");
|
||||
@@ -310,7 +319,7 @@ gboolean scan(gpointer data __attribute__((unused)))
|
||||
activate_mappings();
|
||||
|
||||
out:
|
||||
- if (debug_mode)
|
||||
+ if (debug_mode || check_debug())
|
||||
dump_tree();
|
||||
if (one_shot_mode)
|
||||
keep_going = 0;
|
||||
--
|
||||
2.23.0
|
||||
|
||||
39
feature-enable-irqbalance-to-link-with-multiple-clie.patch
Normal file
39
feature-enable-irqbalance-to-link-with-multiple-clie.patch
Normal file
@ -0,0 +1,39 @@
|
||||
From 2fdfbc218be09a6335df8dde15498f75fa12bc0a Mon Sep 17 00:00:00 2001
|
||||
From: liuchao <liuchao173@huawei.com>
|
||||
Date: Thu, 6 Feb 2020 06:44:51 +0000
|
||||
Subject: [PATCH] feature: enable irqbalance to link with multiple clients at
|
||||
the same time
|
||||
|
||||
---
|
||||
irqbalance.c | 2 +-
|
||||
irqbalance.h | 1 +
|
||||
2 files changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index 368233f..f0a4164 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -608,7 +608,7 @@ int init_socket()
|
||||
log(TO_ALL, LOG_WARNING, "Unable to set socket options.\n");
|
||||
return 1;
|
||||
}
|
||||
- listen(socket_fd, 1);
|
||||
+ listen(socket_fd, MAX_CLIENT_NUM);
|
||||
g_unix_fd_add(socket_fd, G_IO_IN, sock_handle, NULL);
|
||||
return 0;
|
||||
}
|
||||
diff --git a/irqbalance.h b/irqbalance.h
|
||||
index fba8a1b..8662741 100644
|
||||
--- a/irqbalance.h
|
||||
+++ b/irqbalance.h
|
||||
@@ -174,6 +174,7 @@ extern unsigned int log_mask;
|
||||
|
||||
#define SOCKET_PATH "irqbalance"
|
||||
#define SOCKET_TMPFS "/run/irqbalance"
|
||||
+#define MAX_CLIENT_NUM 32
|
||||
|
||||
extern int process_one_line(char *path, void (*cb)(char *line, void *data), void *data);
|
||||
extern void get_mask_from_bitmap(char *line, void *mask);
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,678 @@
|
||||
From 5390ed72086f1d9ffce2b4ca367daf2cbda4d358 Mon Sep 17 00:00:00 2001
|
||||
From: hejingxian <hejingxian@huawei.com>
|
||||
Date: Tue, 18 Feb 2020 14:49:31 +0800
|
||||
Subject: [PATCH] feature: encapsulate and compile the functions in irqbalance-ui
|
||||
into a shared library
|
||||
|
||||
users can send settings msg to irqbalance or get information from irqbalance
|
||||
by calling external functions in the shared library.
|
||||
|
||||
Signed-off-by: Liu Chao <liuchao173@huawei.com>
|
||||
Signed-off-by: He Jingxian <hejingxian@huawei.com>
|
||||
---
|
||||
irqbalance.c | 4 +-
|
||||
irqbalance.h | 1 +
|
||||
ui/Makefile | 29 ++++
|
||||
ui/client.c | 435 +++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
ui/irqbalance-ui.c | 4 +-
|
||||
ui/irqbalance-ui.h | 1 +
|
||||
ui/irqbalance_client.h | 111 +++++++++++++
|
||||
7 files changed, 581 insertions(+), 4 deletions(-)
|
||||
create mode 100644 ui/Makefile
|
||||
create mode 100644 ui/client.c
|
||||
create mode 100644 ui/irqbalance_client.h
|
||||
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index 1af23c6..7c79087 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -452,12 +452,12 @@ void get_object_stat(struct topo_obj *object, void *data)
|
||||
|
||||
gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attribute__((unused)))
|
||||
{
|
||||
- char buff[500];
|
||||
+ char buff[SOCKET_RECV_BUF_LEN];
|
||||
int sock;
|
||||
int recv_size = 0;
|
||||
int valid_user = 0;
|
||||
|
||||
- struct iovec iov = { buff, 500 };
|
||||
+ struct iovec iov = { buff, SOCKET_RECV_BUF_LEN };
|
||||
struct msghdr msg = { 0 };
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
diff --git a/irqbalance.h b/irqbalance.h
|
||||
index b2e5409..842cead 100644
|
||||
--- a/irqbalance.h
|
||||
+++ b/irqbalance.h
|
||||
@@ -175,6 +175,7 @@ extern unsigned int log_mask;
|
||||
#define SOCKET_PATH "irqbalance"
|
||||
#define SOCKET_TMPFS "/run/irqbalance"
|
||||
#define MAX_CLIENT_NUM 32
|
||||
+#define SOCKET_RECV_BUF_LEN 4096
|
||||
|
||||
extern int process_one_line(char *path, void (*cb)(char *line, void *data), void *data);
|
||||
extern void get_mask_from_bitmap(char *line, void *mask);
|
||||
diff --git a/ui/Makefile b/ui/Makefile
|
||||
new file mode 100644
|
||||
index 0000000..27e0fbf
|
||||
--- /dev/null
|
||||
+++ b/ui/Makefile
|
||||
@@ -0,0 +1,29 @@
|
||||
+#!/bin/make
|
||||
+export SHELL = /bin/bash
|
||||
+DIR = $(shell pwd)
|
||||
+TARGET = libirqbalance_client.so
|
||||
+
|
||||
+RM = rm
|
||||
+CC = gcc
|
||||
+
|
||||
+SRC = $(wildcard $(DIR)/*.c)
|
||||
+OBJ = $(patsubst $(DIR)/%.c,$(DIR)/%.o,$(SRC))
|
||||
+
|
||||
+INC = -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include
|
||||
+CFLAG = -g3 -Wall -fPIC -D_GNU_SOURCE -fstack-protector-strong -D_FORTIFY_SOURCE=2 -O2 -ftrapv
|
||||
+SHARED = -shared
|
||||
+LFLAG = -lglib-2.0 -lncursesw -z now -s
|
||||
+
|
||||
+CFLAG += $(INC)
|
||||
+
|
||||
+all: $(TARGET)
|
||||
+
|
||||
+$(TARGET): $(OBJ)
|
||||
+ $(CC) $(SHARED) $(LFLAG) -o $@ $(OBJ)
|
||||
+
|
||||
+$(DIR)/%.o: $(DIR)/%.c
|
||||
+ $(CC) $(CFLAG) -c $< -o $@
|
||||
+
|
||||
+clean:
|
||||
+ -$(RM) $(DIR)/*.o
|
||||
+ -$(RM) $(TARGET)
|
||||
diff --git a/ui/client.c b/ui/client.c
|
||||
new file mode 100644
|
||||
index 0000000..027404b
|
||||
--- /dev/null
|
||||
+++ b/ui/client.c
|
||||
@@ -0,0 +1,435 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2020. Huawei Technologies Co., Ltd. All rights reserved.
|
||||
+ *
|
||||
+ * This program file is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License as published by the
|
||||
+ * Free Software Foundation; version 2 of the License.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
+ * for more details.
|
||||
+ */
|
||||
+#include <sys/socket.h>
|
||||
+#include <stdio.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+#include "irqbalance-ui.h"
|
||||
+#include "irqbalance_client.h"
|
||||
+
|
||||
+extern int irqbalance_pid;
|
||||
+extern GList *tree;
|
||||
+
|
||||
+void irqbalance_set_pid(int pid)
|
||||
+{
|
||||
+ irqbalance_pid = pid;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * string format:
|
||||
+ * <int> <int> <int> <int> ... or NONE
|
||||
+ */
|
||||
+int irqbalance_set_ban_irqs(const char *irqs)
|
||||
+{
|
||||
+ char *data = NULL;
|
||||
+ const char *tmp;
|
||||
+ int ret = IRQBALANCE_SUCCESS;
|
||||
+ int socket_fd = 0;
|
||||
+ int i;
|
||||
+ struct msghdr *msg = NULL;
|
||||
+ struct iovec iov;
|
||||
+
|
||||
+ if (irqs == NULL || strlen(irqs) == 0) {
|
||||
+ ret = IRQBALANCE_INPUT_ILLEGAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (strncmp(irqs, "NONE", strlen("NONE"))) {
|
||||
+ tmp = irqs;
|
||||
+ for (i = 0; i < strlen(irqs); i++) {
|
||||
+ if (*tmp != ' ' && (*tmp < '0' || *tmp > '9')) {
|
||||
+ ret = IRQBALANCE_INPUT_ILLEGAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ tmp++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ socket_fd = init_connection();
|
||||
+ if (!socket_fd) {
|
||||
+ ret = IRQBALANCE_CONNECT_FAIL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ data = (char *)malloc(strlen(irqs) + strlen(BAN_IRQS) + 1);
|
||||
+ if (!data) {
|
||||
+ ret = IRQBALANCE_MALLOC_FAIL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ msg = create_credentials_msg();
|
||||
+ if (!msg) {
|
||||
+ ret = IRQBALANCE_MALLOC_FAIL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ snprintf(data, strlen(irqs) + strlen(BAN_IRQS) + 1,
|
||||
+ "%s%s", BAN_IRQS, irqs);
|
||||
+ iov.iov_base = (void *) data;
|
||||
+ iov.iov_len = strlen(data) + 1;
|
||||
+ msg->msg_iov = &iov;
|
||||
+ if (sendmsg(socket_fd, msg, 0) == -1)
|
||||
+ ret = IRQBALANCE_SEND_FAIL;
|
||||
+
|
||||
+out:
|
||||
+ if (socket_fd > 0)
|
||||
+ close(socket_fd);
|
||||
+ if (msg)
|
||||
+ free(msg->msg_control);
|
||||
+ free(msg);
|
||||
+ free(data);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+unsigned int char_to_hex(char c)
|
||||
+{
|
||||
+ unsigned int hex;
|
||||
+
|
||||
+ if (c >= '0' && c <= '9') {
|
||||
+ hex = c - '0';
|
||||
+ } else {
|
||||
+ hex = c - 'a' + 10;
|
||||
+ }
|
||||
+ return hex;
|
||||
+}
|
||||
+
|
||||
+char *parse_cpus_to_cpulist(const char *cpus)
|
||||
+{
|
||||
+ int i, ret;
|
||||
+ const char *tmp;
|
||||
+ char *cpulist;
|
||||
+ int cpus_len;
|
||||
+ unsigned int hex;
|
||||
+ int index;
|
||||
+
|
||||
+ if (cpus == NULL
|
||||
+ || strlen(cpus) == 0
|
||||
+ || strlen(cpus) > CPU_MASK_MAX_LEN)
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (strncmp(cpus, "NULL", strlen("NULL"))) {
|
||||
+ tmp = cpus;
|
||||
+ cpus_len = strlen(cpus);
|
||||
+ for (i = 0; i < cpus_len; i++) {
|
||||
+ if ((*tmp < '0' || *tmp > '9')
|
||||
+ && (*tmp < 'a' || *tmp > 'f'))
|
||||
+ return NULL;
|
||||
+ tmp++;
|
||||
+ }
|
||||
+ cpulist = (char *)malloc(CPU_LIST_MAX_LEN);
|
||||
+ if (!cpulist)
|
||||
+ return NULL;
|
||||
+ cpulist[0] = 0;
|
||||
+ for (i = 0; i < cpus_len; i++) {
|
||||
+ hex = char_to_hex(cpus[cpus_len - 1 - i]);
|
||||
+ index = 0;
|
||||
+ while (hex) {
|
||||
+ if (hex & 1) {
|
||||
+ ret = snprintf(cpulist + strlen(cpulist),
|
||||
+ CPU_LIST_MAX_LEN - strlen(cpulist), "%d,", (i << 2) + index);
|
||||
+ if (ret < 0)
|
||||
+ break;
|
||||
+ }
|
||||
+ index++;
|
||||
+ hex = (hex >> 1);
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+ cpulist = strdup(cpus);
|
||||
+ }
|
||||
+ return cpulist;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * string format:
|
||||
+ * 00000001 or NULL
|
||||
+ */
|
||||
+int irqbalance_set_ban_cpus(const char *cpus)
|
||||
+{
|
||||
+ int socket_fd = 0;
|
||||
+ int ret = IRQBALANCE_SUCCESS;
|
||||
+ char *data = NULL;
|
||||
+ char *cpulist = NULL;
|
||||
+ struct msghdr *msg = NULL;
|
||||
+ struct iovec iov;
|
||||
+
|
||||
+ cpulist = parse_cpus_to_cpulist(cpus);
|
||||
+ if(!cpulist) {
|
||||
+ ret = IRQBALANCE_INPUT_ILLEGAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ socket_fd = init_connection();
|
||||
+ if(!socket_fd) {
|
||||
+ ret = IRQBALANCE_CONNECT_FAIL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ data = (char *)malloc(strlen(cpulist) + strlen(BAN_CPUS) + 1);
|
||||
+ if (!data) {
|
||||
+ ret = IRQBALANCE_MALLOC_FAIL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ msg = create_credentials_msg();
|
||||
+ if (!msg) {
|
||||
+ ret = IRQBALANCE_MALLOC_FAIL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ snprintf(data, strlen(cpulist) + strlen(BAN_CPUS) + 1,
|
||||
+ "%s%s", BAN_CPUS, cpulist);
|
||||
+ iov.iov_base = (void *) data;
|
||||
+ iov.iov_len = strlen(data) + 1;
|
||||
+ msg->msg_iov = &iov;
|
||||
+ if (sendmsg(socket_fd, msg, 0) == -1)
|
||||
+ ret = IRQBALANCE_SEND_FAIL;
|
||||
+
|
||||
+out:
|
||||
+ if (socket_fd)
|
||||
+ close(socket_fd);
|
||||
+ if (msg)
|
||||
+ free(msg->msg_control);
|
||||
+ free(msg);
|
||||
+ free(data);
|
||||
+ free(cpulist);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int irqbalance_set_sleep_interval(int sleep)
|
||||
+{
|
||||
+ char data[DATA_BUF_MAX_LEN];
|
||||
+ int ret = IRQBALANCE_SUCCESS;
|
||||
+ int socket_fd = 0;
|
||||
+ struct msghdr *msg = NULL;
|
||||
+ struct iovec iov;
|
||||
+
|
||||
+ if (sleep < 1) {
|
||||
+ ret = IRQBALANCE_INPUT_ILLEGAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ socket_fd = init_connection();
|
||||
+ if(!socket_fd) {
|
||||
+ ret = IRQBALANCE_CONNECT_FAIL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ msg = create_credentials_msg();
|
||||
+ if (!msg) {
|
||||
+ ret = IRQBALANCE_MALLOC_FAIL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ snprintf(data, DATA_BUF_MAX_LEN, "%s %d", SET_SLEEP, sleep);
|
||||
+ iov.iov_base = (void *) data;
|
||||
+ iov.iov_len = strlen(data) + 1;
|
||||
+ msg->msg_iov = &iov;
|
||||
+ if (sendmsg(socket_fd, msg, 0) == -1)
|
||||
+ ret = IRQBALANCE_SEND_FAIL;
|
||||
+
|
||||
+out:
|
||||
+ if (socket_fd)
|
||||
+ close(socket_fd);
|
||||
+ if (msg)
|
||||
+ free(msg->msg_control);
|
||||
+ free(msg);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+void free_banned_irq_list(irqbalance_banned_irq_list_t *list_head)
|
||||
+{
|
||||
+ irqbalance_banned_irq_list_t *banned_irq = list_head;
|
||||
+ irqbalance_banned_irq_list_t *next_banned_irq;
|
||||
+
|
||||
+ while (banned_irq) {
|
||||
+ next_banned_irq = banned_irq->next;
|
||||
+ free(banned_irq);
|
||||
+ banned_irq = next_banned_irq;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* get user setup info, including sleep setting, banned irqs and banned cpus info */
|
||||
+irqbalance_setup_t *irqbalance_get_setup_info()
|
||||
+{
|
||||
+ char *token, *ptr, *setup_info;
|
||||
+ char *copy = NULL;
|
||||
+ char *scan;
|
||||
+ int i, sleep, setup_size;
|
||||
+ int ban_irq_num = 0;
|
||||
+ int ban_irq_size = sizeof(irqbalance_banned_irq_t);
|
||||
+ irqbalance_setup_t *setup_data = NULL;
|
||||
+ irqbalance_banned_irq_list_t *banned_irq = NULL;
|
||||
+ irqbalance_banned_irq_list_t *list_head = NULL;
|
||||
+
|
||||
+ setup_info = get_data(SETUP);
|
||||
+ if (setup_info == NULL || strlen(setup_info) == 0)
|
||||
+ return NULL;
|
||||
+ copy = strdup(setup_info);
|
||||
+ if (!copy)
|
||||
+ goto out;
|
||||
+
|
||||
+ token = strtok_r(copy, " ", &ptr);
|
||||
+ if (!token)
|
||||
+ goto out;
|
||||
+ if(strncmp(token, "SLEEP", strlen("SLEEP")))
|
||||
+ goto out;
|
||||
+ scan = strtok_r(NULL, " ", &ptr);
|
||||
+ if (!scan)
|
||||
+ goto out;
|
||||
+ sleep = strtol(scan, NULL, 10);
|
||||
+ token = strtok_r(NULL, " ", &ptr);
|
||||
+ while(token && !strncmp(token, "IRQ", strlen("IRQ"))) {
|
||||
+ banned_irq = (irqbalance_banned_irq_list_t *)malloc(sizeof(irqbalance_banned_irq_list_t));
|
||||
+ if (!banned_irq)
|
||||
+ goto out;
|
||||
+ scan = strtok_r(NULL, " ", &ptr);
|
||||
+ if (!scan)
|
||||
+ goto out;
|
||||
+ banned_irq->irq = strtol(scan, NULL, 10);
|
||||
+ token = strtok_r(NULL, " ", &ptr);
|
||||
+ if (!token || strncmp(token, "LOAD", strlen("LOAD")))
|
||||
+ goto out;
|
||||
+ scan = strtok_r(NULL, " ", &ptr);
|
||||
+ if (!scan)
|
||||
+ goto out;
|
||||
+ banned_irq->load = strtol(scan, NULL, 10);
|
||||
+ token = strtok_r(NULL, " ", &ptr);
|
||||
+ if (!token || strncmp(token, "DIFF", strlen("DIFF")))
|
||||
+ goto out;
|
||||
+ scan = strtok_r(NULL, " ", &ptr);
|
||||
+ if (!scan)
|
||||
+ goto out;
|
||||
+ banned_irq->diff = strtol(scan, NULL, 10);
|
||||
+ token = strtok_r(ptr, " ", &ptr);
|
||||
+ if (!token || strncmp(token, "CLASS", strlen("CLASS")))
|
||||
+ goto out;
|
||||
+ scan = strtok_r(NULL, " ", &ptr);
|
||||
+ if (!scan)
|
||||
+ goto out;
|
||||
+ banned_irq->class = strtol(scan, NULL, 10);
|
||||
+ banned_irq->next = list_head;
|
||||
+ list_head = banned_irq;
|
||||
+ ban_irq_num++;
|
||||
+ token = strtok_r(NULL, " ", &ptr);
|
||||
+ banned_irq = NULL;
|
||||
+ }
|
||||
+ if (ban_irq_num > 1)
|
||||
+ setup_size = sizeof(irqbalance_setup_t) + (ban_irq_num - 1) * ban_irq_size;
|
||||
+ else
|
||||
+ setup_size = sizeof(irqbalance_setup_t);
|
||||
+ setup_data = (irqbalance_setup_t *)malloc(setup_size);
|
||||
+ if (!setup_data)
|
||||
+ goto out;
|
||||
+ memset(setup_data->banned_cpus, 0, NR_CPUS + 1);
|
||||
+ setup_data->sleep = sleep;
|
||||
+ setup_data->ban_irq_num = ban_irq_num;
|
||||
+ banned_irq = list_head;
|
||||
+ for (i = ban_irq_num; i > 0; i--) {
|
||||
+ memcpy(&(setup_data->banned_irqs[i - 1]), banned_irq, ban_irq_size);
|
||||
+ banned_irq = banned_irq->next;
|
||||
+ }
|
||||
+ if(strncmp(token, "BANNED", strlen("BANNED")))
|
||||
+ goto out;
|
||||
+ token = strtok_r(NULL, " ", &ptr);
|
||||
+ if (strlen(token) > NR_CPUS)
|
||||
+ goto out;
|
||||
+ strcpy(setup_data->banned_cpus, token);
|
||||
+out:
|
||||
+ free(setup_info);
|
||||
+ free(copy);
|
||||
+ free_banned_irq_list(list_head);
|
||||
+ return setup_data;
|
||||
+}
|
||||
+
|
||||
+/* the type of the GList pointer data is irqbalance_cpu_node_t*/
|
||||
+GList *irqbalance_get_stats_info()
|
||||
+{
|
||||
+ char *stats_data;
|
||||
+
|
||||
+ stats_data = get_data(STATS);
|
||||
+ if (stats_data == NULL)
|
||||
+ return NULL;
|
||||
+ parse_into_tree(stats_data);
|
||||
+ free(stats_data);
|
||||
+ return tree;
|
||||
+}
|
||||
+
|
||||
+/* get banned cpus mask */
|
||||
+char *irqbalance_get_banned_cpus()
|
||||
+{
|
||||
+ char *setup_info;
|
||||
+ char *copy;
|
||||
+ char *bancpu_str;
|
||||
+
|
||||
+ setup_info = get_data(SETUP);
|
||||
+ if (setup_info == NULL)
|
||||
+ return NULL;
|
||||
+ bancpu_str = strstr(setup_info, "BANNED");
|
||||
+ if (bancpu_str == NULL) {
|
||||
+ free(setup_info);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ copy = strdup(bancpu_str + strlen("BANNED") + 1);
|
||||
+ free(setup_info);
|
||||
+ return copy;
|
||||
+}
|
||||
+
|
||||
+/* get banned irqs string */
|
||||
+char *irqbalance_get_banned_irqs()
|
||||
+{
|
||||
+ char *setup_info;
|
||||
+ char *copy;
|
||||
+ char *start_ptr, *end_ptr;
|
||||
+ char *ret_str, *temp, *last_temp;;
|
||||
+
|
||||
+ setup_info = get_data(SETUP);
|
||||
+ if (setup_info == NULL)
|
||||
+ return NULL;
|
||||
+ start_ptr = strstr(setup_info, "IRQ");
|
||||
+ if (start_ptr == NULL) {
|
||||
+ free(setup_info);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ copy = strdup(start_ptr);
|
||||
+ free(setup_info);
|
||||
+ if (copy == NULL)
|
||||
+ return NULL;
|
||||
+ end_ptr = strstr(copy, "BANNED");
|
||||
+ if (end_ptr)
|
||||
+ *end_ptr = '\0';
|
||||
+
|
||||
+ ret_str = (char*)malloc(strlen(copy) + 1);
|
||||
+ if (ret_str == NULL) {
|
||||
+ free(copy);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ memset(ret_str, 0, strlen(copy) + 1);
|
||||
+ temp = copy + strlen("IRQ") + 1;
|
||||
+ last_temp = temp;
|
||||
+ while (*temp) {
|
||||
+ temp = strstr(last_temp, " ");
|
||||
+ if (temp)
|
||||
+ *temp = '\0';
|
||||
+ else
|
||||
+ break;
|
||||
+ strcat(ret_str, last_temp);
|
||||
+ strcat(ret_str, " ");
|
||||
+ last_temp = strstr(temp + 1, "IRQ");
|
||||
+ if (last_temp == NULL)
|
||||
+ break;
|
||||
+ last_temp = last_temp + strlen("IRQ") + 1;
|
||||
+ temp = last_temp;
|
||||
+ }
|
||||
+ free(copy);
|
||||
+ if (strlen(ret_str) == 0) {
|
||||
+ free(ret_str);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ return ret_str;
|
||||
+}
|
||||
+
|
||||
diff --git a/ui/irqbalance-ui.c b/ui/irqbalance-ui.c
|
||||
index 943f008..f0deaf8 100644
|
||||
--- a/ui/irqbalance-ui.c
|
||||
+++ b/ui/irqbalance-ui.c
|
||||
@@ -120,8 +120,8 @@ char * get_data(char *string)
|
||||
* With a select, ioctl to determine size, and malloc based
|
||||
* on that
|
||||
*/
|
||||
- char *data = malloc(8192);
|
||||
- int len = recv(socket_fd, data, 8192, 0);
|
||||
+ char *data = malloc(RECV_BUF_SIZE);
|
||||
+ int len = recv(socket_fd, data, RECV_BUF_SIZE, 0);
|
||||
close(socket_fd);
|
||||
data[len] = '\0';
|
||||
free(msg->msg_control);
|
||||
diff --git a/ui/irqbalance-ui.h b/ui/irqbalance-ui.h
|
||||
index b32d58a..503c0c5 100644
|
||||
--- a/ui/irqbalance-ui.h
|
||||
+++ b/ui/irqbalance-ui.h
|
||||
@@ -26,6 +26,7 @@
|
||||
#define IRQ_10GBETH 6
|
||||
#define IRQ_VIRT_EVENT 7
|
||||
|
||||
+#define RECV_BUF_SIZE (4096 * 8)
|
||||
|
||||
/* Typedefs */
|
||||
|
||||
diff --git a/ui/irqbalance_client.h b/ui/irqbalance_client.h
|
||||
new file mode 100644
|
||||
index 0000000..8f18b79
|
||||
--- /dev/null
|
||||
+++ b/ui/irqbalance_client.h
|
||||
@@ -0,0 +1,111 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2020. Huawei Technologies Co., Ltd. All rights reserved.
|
||||
+ *
|
||||
+ * This program file is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License as published by the
|
||||
+ * Free Software Foundation; version 2 of the License.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
+ * for more details.
|
||||
+ */
|
||||
+#include <glib.h>
|
||||
+#include <glib-unix.h>
|
||||
+
|
||||
+#ifndef IRQBALANCE_CLIENT_H
|
||||
+#define IRQBALANCE_CLIENT_H
|
||||
+
|
||||
+/* ERRORNO */
|
||||
+#define IRQBALANCE_SUCCESS 0
|
||||
+#define IRQBALANCE_INPUT_ILLEGAL 1
|
||||
+#define IRQBALANCE_CONNECT_FAIL 2
|
||||
+#define IRQBALANCE_SEND_FAIL 3
|
||||
+#define IRQBALANCE_MALLOC_FAIL 4
|
||||
+
|
||||
+#define BAN_CPUS "settings cpus "
|
||||
+#define DATA_BUF_MAX_LEN 128
|
||||
+#define NR_CPUS 1024
|
||||
+#define CPU_LIST_MAX_LEN 4096
|
||||
+#define CPU_MASK_MAX_LEN 256
|
||||
+
|
||||
+typedef enum irqbalance_node_type {
|
||||
+ IRQ_OBJ_TYPE_CPU,
|
||||
+ IRQ_OBJ_TYPE_CACHE,
|
||||
+ IRQ_OBJ_TYPE_PACKAGE,
|
||||
+ IRQ_OBJ_TYPE_NODE
|
||||
+} irqbalance_node_type_e;
|
||||
+
|
||||
+typedef struct irqbalance_irq {
|
||||
+ int vector;
|
||||
+ unsigned long load;
|
||||
+ unsigned long diff;
|
||||
+ char is_banned;
|
||||
+ GList *assigned_to;
|
||||
+ int class;
|
||||
+} irqbalance_irq_t;
|
||||
+
|
||||
+typedef struct irqbalance_cpu_node {
|
||||
+ irqbalance_node_type_e type;
|
||||
+ int number;
|
||||
+ unsigned long load;
|
||||
+ int is_powersave;
|
||||
+ struct irqbalance_cpu_node *parent;
|
||||
+ GList *children;
|
||||
+ GList *irqs;
|
||||
+ GList *cpu_list;
|
||||
+ char *cpu_mask;
|
||||
+} irqbalance_cpu_node_t;
|
||||
+
|
||||
+typedef struct irqbalance_banned_irq_list {
|
||||
+ int irq;
|
||||
+ int class;
|
||||
+ unsigned long load;
|
||||
+ unsigned long diff;
|
||||
+ struct irqbalance_banned_irq_list *next;
|
||||
+} irqbalance_banned_irq_list_t;
|
||||
+
|
||||
+typedef struct irqbalance_banned_irq_info {
|
||||
+ int irq;
|
||||
+ int class;
|
||||
+ unsigned long load;
|
||||
+ unsigned long diff;
|
||||
+} irqbalance_banned_irq_t;
|
||||
+
|
||||
+typedef struct irqbalance_setup_data {
|
||||
+ int sleep;
|
||||
+ char banned_cpus[NR_CPUS + 1];
|
||||
+ int ban_irq_num;
|
||||
+ irqbalance_banned_irq_t banned_irqs[1];
|
||||
+} irqbalance_setup_t;
|
||||
+
|
||||
+/*
|
||||
+ * set_ban_irqs string format:
|
||||
+ * <int> <int> <int> <int> ... or NONE
|
||||
+ * */
|
||||
+int irqbalance_set_ban_irqs(const char *irqs);
|
||||
+
|
||||
+/*
|
||||
+ * set_ban_cpus string format:
|
||||
+ * 00000001 or NULL
|
||||
+ * */
|
||||
+int irqbalance_set_ban_cpus(const char *cpus);
|
||||
+
|
||||
+/* set sleep interval of irqbalance main loop */
|
||||
+int irqbalance_set_sleep_interval(int sleep);
|
||||
+
|
||||
+/* get user setup info, including sleep setting, banned irqs and banned cpus info */
|
||||
+irqbalance_setup_t *irqbalance_get_setup_info();
|
||||
+
|
||||
+/* get irqbalance stats tree */
|
||||
+GList *irqbalance_get_stats_info();
|
||||
+
|
||||
+/* get banned cpus mask */
|
||||
+char *irqbalance_get_banned_cpus();
|
||||
+
|
||||
+/* get banned irqs string */
|
||||
+char *irqbalance_get_banned_irqs();
|
||||
+
|
||||
+/* set the pid of irqbalance server */
|
||||
+void irqbalance_set_pid(int pid);
|
||||
+#endif
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
468
feature-introduce-verifyhint-to-detect-hint-variatio.patch
Normal file
468
feature-introduce-verifyhint-to-detect-hint-variatio.patch
Normal file
@ -0,0 +1,468 @@
|
||||
From e5b83ac140634830b8f8d9ca8d40a1d9d16d2d5b Mon Sep 17 00:00:00 2001
|
||||
From: hejingxian <hejingxian@huawei.com>
|
||||
Date: Tue, 12 Nov 2019 15:29:16 +0800
|
||||
Subject: [PATCH] feature: introduce affinity hint verify to detect user hint variation
|
||||
|
||||
In order to make the user affinity hint becomes effective quickly,
|
||||
introduce the periodically affinity hint verify.
|
||||
---
|
||||
Makefile.am | 2 +-
|
||||
activate.c | 14 ++++--
|
||||
classify.c | 5 ++-
|
||||
cpumask.h | 7 +++
|
||||
hint_verify.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
hint_verify.h | 21 ++++++++
|
||||
irqbalance.c | 43 ++++++++++-----
|
||||
irqbalance.h | 5 ++
|
||||
placement.c | 14 ++++++
|
||||
types.h | 1 +
|
||||
10 files changed, 228 insertions(+), 20 deletions(-)
|
||||
create mode 100644 hint_verify.c
|
||||
create mode 100644 hint_verify.h
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 3086d67..aacb399 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -38,7 +38,7 @@ sbin_PROGRAMS += irqbalance-ui
|
||||
endif
|
||||
|
||||
irqbalance_SOURCES = activate.c bitmap.c classify.c cputree.c irqbalance.c \
|
||||
- irqlist.c numa.c placement.c procinterrupts.c rules_config.c
|
||||
+ irqlist.c numa.c placement.c procinterrupts.c rules_config.c hint_verify.c
|
||||
irqbalance_LDADD = $(LIBCAP_NG_LIBS) $(GLIB2_LIBS)
|
||||
if IRQBALANCEUI
|
||||
irqbalance_ui_SOURCES = $(UI_DIR)/helpers.c $(UI_DIR)/irqbalance-ui.c \
|
||||
diff --git a/activate.c b/activate.c
|
||||
index 93fde58..c5859bf 100644
|
||||
--- a/activate.c
|
||||
+++ b/activate.c
|
||||
@@ -78,11 +78,6 @@ static void activate_mapping(struct irq_info *info, void *data __attribute__((un
|
||||
int ret = 0;
|
||||
cpumask_t applied_mask;
|
||||
|
||||
- /*
|
||||
- * only activate mappings for irqs that have moved
|
||||
- */
|
||||
- if (!info->moved)
|
||||
- return;
|
||||
|
||||
if (!info->assigned_obj)
|
||||
return;
|
||||
@@ -90,6 +85,15 @@ static void activate_mapping(struct irq_info *info, void *data __attribute__((un
|
||||
/* activate only online cpus, otherwise writing to procfs returns EOVERFLOW */
|
||||
cpus_and(applied_mask, cpu_online_map, info->assigned_obj->mask);
|
||||
|
||||
+ if (hint_enabled) {
|
||||
+ if (!cpus_empty(info->affinity_hint)) {
|
||||
+ cpus_and(applied_mask, applied_mask, info->affinity_hint);
|
||||
+ if (!cpus_intersects(applied_mask, unbanned_cpus)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* Don't activate anything for which we have an invalid mask
|
||||
*/
|
||||
diff --git a/classify.c b/classify.c
|
||||
index 254197e..e9987ee 100644
|
||||
--- a/classify.c
|
||||
+++ b/classify.c
|
||||
@@ -263,7 +263,7 @@ static int get_irq_class(const char *devpath)
|
||||
return irq_class;
|
||||
}
|
||||
|
||||
-static gint compare_ints(gconstpointer a, gconstpointer b)
|
||||
+gint compare_ints(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
const struct irq_info *ai = a;
|
||||
const struct irq_info *bi = b;
|
||||
@@ -397,6 +397,9 @@ get_numa_node:
|
||||
process_one_line(path, get_mask_from_bitmap, &new->cpumask);
|
||||
}
|
||||
|
||||
+ sprintf(path, "/proc/irq/%d/affinity_hint", irq);
|
||||
+ process_one_line(path, get_mask_from_bitmap, &new->affinity_hint);
|
||||
+
|
||||
log(TO_CONSOLE, LOG_INFO, "Adding IRQ %d to database\n", irq);
|
||||
return new;
|
||||
}
|
||||
diff --git a/cpumask.h b/cpumask.h
|
||||
index 5bebbeb..bc5f006 100644
|
||||
--- a/cpumask.h
|
||||
+++ b/cpumask.h
|
||||
@@ -30,6 +30,7 @@
|
||||
* void cpus_xor(dst, src1, src2) dst = src1 ^ src2
|
||||
* void cpus_andnot(dst, src1, src2) dst = src1 & ~src2
|
||||
* void cpus_complement(dst, src) dst = ~src
|
||||
+ * void cpumask_copy(dst, src) dst = src
|
||||
*
|
||||
* int cpus_equal(mask1, mask2) Does mask1 == mask2?
|
||||
* int cpus_intersects(mask1, mask2) Do mask1 and mask2 intersect?
|
||||
@@ -142,6 +143,12 @@ static inline void __cpus_complement(cpumask_t *dstp,
|
||||
bitmap_complement(dstp->bits, srcp->bits, nbits);
|
||||
}
|
||||
|
||||
+#define cpumask_copy(dst, src) __cpumask_copy(&(dst), &(src), NR_CPUS)
|
||||
+static inline void __cpumask_copy(cpumask_t *dstp, const cpumask_t *srcp, int nbits)
|
||||
+{
|
||||
+ bitmap_copy(dstp->bits, srcp->bits, nbits);
|
||||
+}
|
||||
+
|
||||
#define cpus_equal(src1, src2) __cpus_equal(&(src1), &(src2), NR_CPUS)
|
||||
static inline int __cpus_equal(const cpumask_t *src1p,
|
||||
const cpumask_t *src2p, int nbits)
|
||||
diff --git a/hint_verify.c b/hint_verify.c
|
||||
new file mode 100644
|
||||
index 0000000..3492902
|
||||
--- /dev/null
|
||||
+++ b/hint_verify.c
|
||||
@@ -0,0 +1,136 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2019. Huawei Technologies Co., Ltd. All rights reserved.
|
||||
+ *
|
||||
+ * This program file is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License as published by the
|
||||
+ * Free Software Foundation; version 2 of the License.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
+ * for more details.
|
||||
+ */
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include "irqbalance.h"
|
||||
+
|
||||
+extern int keep_going;
|
||||
+extern GMainLoop *main_loop;
|
||||
+extern gboolean scan();
|
||||
+extern int last_interval;
|
||||
+
|
||||
+int real_sleep_interval;
|
||||
+int sleep_interval_count;
|
||||
+int poll_hint_interval_count;
|
||||
+int sleep_count = 0;
|
||||
+gboolean hint_has_changed = FALSE;
|
||||
+
|
||||
+int hint_changed(void)
|
||||
+{
|
||||
+ FILE *file;
|
||||
+ char *line = NULL;
|
||||
+ size_t size = 0;
|
||||
+ gboolean changed = FALSE;
|
||||
+
|
||||
+ file = fopen("/proc/irq/affinity_hint_notify", "r+");
|
||||
+ if (!file)
|
||||
+ return changed;
|
||||
+
|
||||
+ if (getline(&line, &size, file) > 0 && *line != '0') {
|
||||
+ fprintf(file, "Done");
|
||||
+ changed = TRUE;
|
||||
+ }
|
||||
+
|
||||
+ fclose(file);
|
||||
+ if (line)
|
||||
+ free(line);
|
||||
+ return changed;
|
||||
+}
|
||||
+
|
||||
+void update_affinity_hint(struct irq_info *info, void *data __attribute__((unused)))
|
||||
+{
|
||||
+ cpumask_t current_affinity_hint;
|
||||
+ char path[PATH_MAX];
|
||||
+
|
||||
+ if (!hint_enabled)
|
||||
+ return;
|
||||
+
|
||||
+ cpus_clear(info->affinity_hint);
|
||||
+ sprintf(path, "/proc/irq/%d/affinity_hint", info->irq);
|
||||
+ process_one_line(path, get_mask_from_bitmap, ¤t_affinity_hint);
|
||||
+
|
||||
+ if (!cpus_equal(current_affinity_hint, info->affinity_hint)) {
|
||||
+ cpumask_copy(info->affinity_hint, current_affinity_hint);
|
||||
+ force_rebalance_irq(info, data);
|
||||
+ hint_has_changed = TRUE;
|
||||
+ cpumask_scnprintf(path, PATH_MAX, current_affinity_hint);
|
||||
+ log(TO_ALL, LOG_INFO, "IRQ(%d): affinity hint modified %s\n", info->irq, path);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This function is the main loop of irqbalance, which include:
|
||||
+ * 1. scan opration for irq balancing;
|
||||
+ * 2. poll irq affinity hint changes for quickly applying them.
|
||||
+ */
|
||||
+gboolean poll_hint_affinity_and_scan(gpointer data __attribute__((unused)))
|
||||
+{
|
||||
+ gboolean need_verify_flag = FALSE;
|
||||
+ gboolean need_scan_flag = FALSE;
|
||||
+
|
||||
+ if (!sleep_interval_count)
|
||||
+ sleep_interval_count = 1;
|
||||
+ if (!poll_hint_interval_count)
|
||||
+ poll_hint_interval_count = 1;
|
||||
+
|
||||
+ if (sleep_count % sleep_interval_count == 0) {
|
||||
+ need_scan_flag = TRUE;
|
||||
+ }
|
||||
+ if (sleep_count % poll_hint_interval_count == 0) {
|
||||
+ need_verify_flag = TRUE;
|
||||
+ }
|
||||
+ sleep_count++;
|
||||
+
|
||||
+ if (need_verify_flag && hint_changed()) {
|
||||
+ for_each_irq(NULL, update_affinity_hint, NULL);
|
||||
+ if (hint_has_changed) {
|
||||
+ hint_has_changed = FALSE;
|
||||
+ sleep_count = 1;
|
||||
+ need_scan_flag = TRUE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (need_scan_flag) {
|
||||
+ if (!scan()) {
|
||||
+ g_main_loop_quit(main_loop);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ update_interval_and_count();
|
||||
+ if (last_interval != real_sleep_interval) {
|
||||
+ last_interval = real_sleep_interval;
|
||||
+ g_timeout_add_seconds(real_sleep_interval, poll_hint_affinity_and_scan, NULL);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (keep_going) {
|
||||
+ return TRUE;
|
||||
+ } else {
|
||||
+ g_main_loop_quit(main_loop);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void update_interval_and_count()
|
||||
+{
|
||||
+ real_sleep_interval =
|
||||
+ sleep_interval > poll_hint_interval ? poll_hint_interval : sleep_interval;
|
||||
+ if (!real_sleep_interval) {
|
||||
+ sleep_interval_count = 1;
|
||||
+ poll_hint_interval_count = 1;
|
||||
+ return;
|
||||
+ }
|
||||
+ sleep_interval_count = sleep_interval / real_sleep_interval;
|
||||
+ poll_hint_interval_count = poll_hint_interval / real_sleep_interval;
|
||||
+}
|
||||
diff --git a/hint_verify.h b/hint_verify.h
|
||||
new file mode 100644
|
||||
index 0000000..7391b32
|
||||
--- /dev/null
|
||||
+++ b/hint_verify.h
|
||||
@@ -0,0 +1,21 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2019. Huawei Technologies Co., Ltd. All rights reserved.
|
||||
+ *
|
||||
+ * This program file is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License as published by the
|
||||
+ * Free Software Foundation; version 2 of the License.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
+ * for more details.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _INCLUDE_HINT_VERIFY_H
|
||||
+#define _INCLUDE_HINT_VERIFY_H
|
||||
+
|
||||
+extern int real_sleep_interval;
|
||||
+extern gboolean poll_hint_affinity_and_scan();
|
||||
+extern void update_interval_and_count();
|
||||
+
|
||||
+#endif
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index 450a1ff..5985d8d 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -64,6 +64,8 @@ char *polscript = NULL;
|
||||
long HZ;
|
||||
int sleep_interval = SLEEP_INTERVAL;
|
||||
int last_interval;
|
||||
+int hint_enabled = 0;
|
||||
+int poll_hint_interval = SLEEP_INTERVAL / 5;
|
||||
GMainLoop *main_loop;
|
||||
|
||||
char *cpu_ban_string = NULL;
|
||||
@@ -100,6 +102,8 @@ struct option lopts[] = {
|
||||
{"version", 0, NULL, 'V'},
|
||||
{"migrateval", 1, NULL, 'e'},
|
||||
{"rulesconfig", 1, NULL, 'r'},
|
||||
+ {"hintpolicy", 1, NULL, 'h'},
|
||||
+ {"verifyhint", 1, NULL, 'v'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -108,7 +112,7 @@ static void usage(void)
|
||||
log(TO_CONSOLE, LOG_INFO, "irqbalance [--oneshot | -o] [--debug | -d] [--foreground | -f] [--journal | -j]\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>] [--migrateval= | -e <n>]\n");
|
||||
- log(TO_CONSOLE, LOG_INFO, " [--rulesconfig= | -r <config>]\n");
|
||||
+ log(TO_CONSOLE, LOG_INFO, " [--rulesconfig= | -r <config>] [--hintpolicy | -h <subset>] [--verifyhint= | -v n]\n");
|
||||
}
|
||||
|
||||
static void version(void)
|
||||
@@ -123,7 +127,7 @@ static void parse_command_line(int argc, char **argv)
|
||||
unsigned long val;
|
||||
|
||||
while ((opt = getopt_long(argc, argv,
|
||||
- "odfjVi:p:s:c:l:m:t:e:r:",
|
||||
+ "odfjVi:p:s:c:l:m:t:e:r:h:v:",
|
||||
lopts, &longind)) != -1) {
|
||||
|
||||
switch(opt) {
|
||||
@@ -198,6 +202,22 @@ static void parse_command_line(int argc, char **argv)
|
||||
case 'r':
|
||||
rules_config_file = strdup(optarg);
|
||||
break;
|
||||
+ case 'h':
|
||||
+ if (!strncmp(optarg, "subset", strlen(optarg)))
|
||||
+ hint_enabled = 1;
|
||||
+ else {
|
||||
+ usage();
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ break;
|
||||
+ case 'v':
|
||||
+ poll_hint_interval = strtol(optarg, NULL, 10);
|
||||
+ if (poll_hint_interval < 1) {
|
||||
+ usage();
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -261,6 +283,10 @@ void force_rebalance_irq(struct irq_info *info, void *data __attribute__((unused)))
|
||||
if (info->level == BALANCE_NONE)
|
||||
return;
|
||||
|
||||
+ /* Prevent inserting a duplicate entry to avoid list chaos */
|
||||
+ if (g_list_find_custom(rebalance_irq_list, info, compare_ints))
|
||||
+ return;
|
||||
+
|
||||
if (info->assigned_obj == NULL)
|
||||
rebalance_irq_list = g_list_append(rebalance_irq_list, info);
|
||||
else
|
||||
@@ -275,7 +299,7 @@ static int check_debug()
|
||||
return ret;
|
||||
}
|
||||
|
||||
-gboolean scan(gpointer data __attribute__((unused)))
|
||||
+gboolean scan()
|
||||
{
|
||||
log(TO_CONSOLE, LOG_INFO, "\n\n\n-----------------------------------------------------------------------------\n");
|
||||
clear_work_stats();
|
||||
@@ -325,17 +349,9 @@ out:
|
||||
keep_going = 0;
|
||||
cycle_count++;
|
||||
|
||||
- /* sleep_interval may be changed by socket */
|
||||
- if (last_interval != sleep_interval) {
|
||||
- last_interval = sleep_interval;
|
||||
- g_timeout_add_seconds(sleep_interval, scan, NULL);
|
||||
- return FALSE;
|
||||
- }
|
||||
-
|
||||
if (keep_going) {
|
||||
return TRUE;
|
||||
} else {
|
||||
- g_main_loop_quit(main_loop);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -720,9 +736,10 @@ int main(int argc, char** argv)
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
+ update_interval_and_count();
|
||||
main_loop = g_main_loop_new(NULL, FALSE);
|
||||
- last_interval = sleep_interval;
|
||||
- g_timeout_add_seconds(sleep_interval, scan, NULL);
|
||||
+ last_interval = real_sleep_interval;
|
||||
+ g_timeout_add_seconds(real_sleep_interval, poll_hint_affinity_and_scan, NULL);
|
||||
g_main_loop_run(main_loop);
|
||||
|
||||
g_main_loop_quit(main_loop);
|
||||
diff --git a/irqbalance.h b/irqbalance.h
|
||||
index 78d0adc..4a73b83 100644
|
||||
--- a/irqbalance.h
|
||||
+++ b/irqbalance.h
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "types.h"
|
||||
#include "config.h"
|
||||
#include "rules_config.h"
|
||||
+#include "hint_verify.h"
|
||||
|
||||
#ifdef __aarch64__
|
||||
#define AARCH64
|
||||
@@ -114,6 +115,10 @@ extern void add_banned_irq(int irq);
|
||||
extern void add_cl_banned_module(char *modname);
|
||||
extern void add_banned_irq(int irq);
|
||||
extern void remove_one_irq_from_db(int irq);
|
||||
+extern void force_rebalance_irq(struct irq_info *info, void *data __attribute__((unused)));
|
||||
+extern gint compare_ints(gconstpointer a, gconstpointer b);
|
||||
+extern int hint_enabled, poll_hint_interval;
|
||||
+extern int sleep_interval;
|
||||
#define irq_numa_node(irq) ((irq)->numa_node)
|
||||
|
||||
|
||||
diff --git a/placement.c b/placement.c
|
||||
index bf27297..db79b8b 100644
|
||||
--- a/placement.c
|
||||
+++ b/placement.c
|
||||
@@ -41,6 +41,7 @@ static void find_best_object(struct topo_obj *d, void *data)
|
||||
{
|
||||
struct obj_placement *best = (struct obj_placement *)data;
|
||||
uint64_t newload;
|
||||
+ cpumask_t subset;
|
||||
|
||||
/*
|
||||
* Don't consider the unspecified numa node here
|
||||
@@ -58,6 +59,19 @@ static void find_best_object(struct topo_obj *d, void *data)
|
||||
if (d->powersave_mode)
|
||||
return;
|
||||
|
||||
+ /*
|
||||
+ * If the hint feature is enabled, then we only want
|
||||
+ * to consider objects that are within the irqs hint, but
|
||||
+ * only if that irq in fact has published a hint
|
||||
+ */
|
||||
+ if (hint_enabled) {
|
||||
+ if (!cpus_empty(best->info->affinity_hint)) {
|
||||
+ cpus_and(subset, best->info->affinity_hint, d->mask);
|
||||
+ if (cpus_empty(subset))
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
newload = d->load;
|
||||
if (newload < best->best_cost) {
|
||||
best->best = d;
|
||||
diff --git a/types.h b/types.h
|
||||
index fa91561..3a04318 100644
|
||||
--- a/types.h
|
||||
+++ b/types.h
|
||||
@@ -67,6 +67,7 @@ struct irq_info {
|
||||
int flags;
|
||||
struct topo_obj *numa_node;
|
||||
cpumask_t cpumask;
|
||||
+ cpumask_t affinity_hint;
|
||||
uint64_t irq_count;
|
||||
uint64_t last_irq_count;
|
||||
uint64_t load;
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -21,6 +21,10 @@ if [ -n "$IRQBALANCE_BANNED_CPUS" ]; then
|
||||
export IRQBALANCE_BANNED_CPUS
|
||||
fi
|
||||
|
||||
if [ -n "$IRQBALANCE_BANNED_CPULIST" ]; then
|
||||
export IRQBALANCE_BANNED_CPULIST
|
||||
fi
|
||||
|
||||
if [ "$IRQBALANCE_ONESHOT" != "auto" ]; then
|
||||
export IRQBALANCE_ONESHOT
|
||||
fi
|
||||
|
||||
2
irqbalance.rules
Normal file
2
irqbalance.rules
Normal file
@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
echo > /dev/null
|
||||
@ -1,16 +1,17 @@
|
||||
Summary: A dynamic adaptive IRQ balancing daemon
|
||||
Name: irqbalance
|
||||
Version: 1.7.0
|
||||
Release: 4
|
||||
Release: 5
|
||||
Epoch: 3
|
||||
License: GPLv2
|
||||
Source0: https://github.com/Irqbalance/irqbalance/archive/v%{version}.tar.gz#/irqbalance-%{version}.tar.gz
|
||||
Source1: irqbalance.service
|
||||
Source2: irqbalance.sysconfig
|
||||
Source3: irq_balancer
|
||||
Source3: irqbalance.rules
|
||||
Source4: irq_balancer
|
||||
Url: https://github.com/irqbalance/irqbalance
|
||||
|
||||
BuildRequires: gdb autoconf automake libtool libcap-ng systemd
|
||||
BuildRequires: autoconf automake libtool libcap-ng systemd
|
||||
BuildRequires: glib2-devel pkgconf libcap-ng-devel ncurses-devel
|
||||
|
||||
Requires: ncurses-libs
|
||||
@ -22,8 +23,25 @@ Requires: numactl-libs
|
||||
|
||||
%define _hardened_build 1
|
||||
|
||||
Patch6000: add-env-variable-to-ban-cpus-using-cpulist-syntax.patch
|
||||
Patch6001: Add-IRQBALANCE_BANNED_CPULIST-to-env-file.patch
|
||||
|
||||
Patch6000: backport-add-env-variable-to-ban-cpus-using-cpulist-syntax.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
|
||||
Patch6005: backport-Add-hot-pull-method-for-irqbalance.patch
|
||||
Patch6006: backport-Also-fetch-node-info-for-non-PCI-devices.patch
|
||||
Patch6007: backport-Hotplug-may-occur-again-during-sleep-so-wait-until-t.patch
|
||||
|
||||
Patch9000: feature-aarch64-add-the-regular-to-get-the-correct-i.patch
|
||||
Patch9001: feature-add-new-user-irq-policy-config-rule.patch
|
||||
Patch9002: feature-add-the-switch-of-printing-log.patch
|
||||
Patch9003: feature-introduce-verifyhint-to-detect-hint-variatio.patch
|
||||
Patch9004: feature-add-switch-to-clear-affinity-hint.patch
|
||||
Patch9005: feature-add-new-irq-migrate-rule-to-avoid-high-cpu-i.patch
|
||||
Patch9006: feature-enable-irqbalance-to-link-with-multiple-clie.patch
|
||||
Patch9007: feature-add-ability-to-set-hintpolicy-during-runtime.patch
|
||||
Patch9008: feature-encapsulate-and-compile-the-functions-in-irqbalance-ui.patch
|
||||
|
||||
%description
|
||||
Irqbalance is a daemon to help balance the cpu load generated by
|
||||
@ -33,6 +51,20 @@ single unique cpu, so that load is spread as much as possible over
|
||||
an entire processor set, while minimizing cache miss rates for irq
|
||||
handlers.
|
||||
|
||||
%package devel
|
||||
Summary: The development files of irqbalance client
|
||||
Requires: glib2-devel ncurses-devel irqbalance-libs
|
||||
|
||||
%description devel
|
||||
Development files for irqbalance client.
|
||||
|
||||
%package libs
|
||||
Summary: The shared librariy of irqbalance client
|
||||
Requires: glib2 ncurses-libs
|
||||
|
||||
%description libs
|
||||
Shared librariy for irqbalance client.
|
||||
|
||||
%package_help
|
||||
|
||||
%prep
|
||||
@ -42,6 +74,10 @@ handlers.
|
||||
./autogen.sh
|
||||
%configure
|
||||
CFLAGS="%{optflags}" %make_build CFLAGS+='-fstack-protector-strong '
|
||||
cd ui
|
||||
rm -rf *.o
|
||||
make
|
||||
cd -
|
||||
|
||||
%install
|
||||
install -D -p -m 0755 %{name} %{buildroot}%{_sbindir}/%{name}
|
||||
@ -49,6 +85,9 @@ install -D -p -m 0644 %{SOURCE1} %{buildroot}/%{_unitdir}/%{name}.service
|
||||
install -D -p -m 0644 %{SOURCE2} %{buildroot}%{_sysconfdir}/sysconfig/%{name}
|
||||
install -D -p -m 0755 %{SOURCE3} %{buildroot}%{_sbindir}/irq_balancer
|
||||
|
||||
install -D -p -m 0755 ui/irqbalance_client.h %{buildroot}/%{_includedir}/irqbalance_client.h
|
||||
install -D -p -m 0755 ui/libirqbalance_client.so %{buildroot}/%{_libdir}/libirqbalance_client.so
|
||||
|
||||
install -d %{buildroot}%{_mandir}/man1/
|
||||
install -p -m 0644 ./%{name}.1 %{buildroot}%{_mandir}/man1/
|
||||
|
||||
@ -62,6 +101,12 @@ make check
|
||||
%config(noreplace) %{_sysconfdir}/sysconfig/%{name}
|
||||
%{_sbindir}/irq_balancer
|
||||
|
||||
%files devel
|
||||
%{_includedir}/irqbalance_client.h
|
||||
|
||||
%files libs
|
||||
%{_libdir}/libirqbalance_client.so
|
||||
|
||||
%files help
|
||||
%{_mandir}/man1/*
|
||||
|
||||
@ -81,6 +126,12 @@ fi
|
||||
/sbin/chkconfig --del %{name} >/dev/null 2>&1 || :
|
||||
|
||||
%changelog
|
||||
* Fri Apr 9 2021 Liu Chao <liuchao173@huawei.com> - 3:1.7.0-5
|
||||
- Type:enhanced
|
||||
- ID:NA
|
||||
- SUG:restart
|
||||
- DESC:backport patches
|
||||
|
||||
* Tue May 2 2021 Liu Chao <liuchao173@huawei.com> - 3:1.7.0-4
|
||||
- Type:enhanced
|
||||
- ID:NA
|
||||
|
||||
@ -21,6 +21,20 @@
|
||||
#
|
||||
#IRQBALANCE_BANNED_CPUS=
|
||||
|
||||
# IRQBALANCE_BANNED_CPULIST
|
||||
# The CPUs list which allows you to indicate which CPUs should
|
||||
# be skipped when reblancing IRQs. CPU numbers in CPUs list will
|
||||
# not have any IRQs assigned to them on rebalance.
|
||||
#
|
||||
# The format of CPUs list is:
|
||||
# <cpu number>,...,<cpu number>
|
||||
# or a range:
|
||||
# <cpu number>-<cpu number>
|
||||
# or a mixture:
|
||||
# <cpu number>,...,<cpu number>-<cpu number>
|
||||
#
|
||||
#IRQBALANCE_BANNED_CPULIST=
|
||||
|
||||
#
|
||||
# IRQBALANCE_BANNED_INTERRUPTS
|
||||
# Interrupts that don't get banlanced as list (separation character
|
||||
@ -35,4 +49,4 @@
|
||||
# Append any args here to the irqbalance daemon as documented in the man
|
||||
# page.
|
||||
#
|
||||
#IRQBALANCE_ARGS=
|
||||
IRQBALANCE_ARGS="--hintpolicy=subset"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user