remove feature patches

This commit is contained in:
SuperSix173 2021-11-11 11:36:29 +08:00
parent 12449eb036
commit 1122bf0dd7
12 changed files with 7 additions and 2169 deletions

View File

@ -1,52 +0,0 @@
From a9f0290a6754a475eb95818dd38dc401370da071 Mon Sep 17 00:00:00 2001
From: liuchao173 <55137861+liuchao173@users.noreply.github.com>
Date: Mon, 23 Aug 2021 19:40:41 +0800
Subject: [PATCH] fix opendir fails in check_platform_device
When irq name does not contain spaces, savedptr is an empty string and irq_fullname will have a extra space at the end like "
LNRO0005:00 ".
So opendir in check_platform_device will fail, and irqbalance prints log:
"No directory /sys/devices/platform/LNRO0005:00 /: No such file or directory"
---
procinterrupts.c | 25 +++++++++++--------------
1 file changed, 11 insertions(+), 14 deletions(-)
diff --git a/procinterrupts.c b/procinterrupts.c
index 32c5e53..2bd201b 100644
--- a/procinterrupts.c
+++ b/procinterrupts.c
@@ -183,20 +183,17 @@ void init_irq_class_and_type(char *savedline, struct irq_info *info, int irq)
}
#ifdef AARCH64
- irq_name = last_token;
- 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;
+ if (strlen(savedptr) > 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;
--
1.8.3.1

View File

@ -1,81 +0,0 @@
From 6f0ea91bfa9ee3016abf694e6fb9f46e7c847cc1 Mon Sep 17 00:00:00 2001
From: SuperSix173 <liuchao173@huawei.com>
Date: Mon, 1 Nov 2021 11:40:39 +0800
Subject: [PATCH] bugfix: set hint->name in add_new_irq to avoid segmentation
fault
hint->name is uninitialized in add_new_irq, so segmentation fault occurs
when calling strstr in get_usr_irq_policy
Signed-off-by: SuperSix173 <liuchao173@huawei.com>
---
classify.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/classify.c b/classify.c
index c5a2a35..560e932 100644
--- a/classify.c
+++ b/classify.c
@@ -607,6 +607,7 @@ static void add_new_irq(char *path, struct irq_info *hint, GList *proc_interrupt
struct irq_info *new;
struct user_irq_policy pol;
int irq = hint->irq;
+ GList *entry;
new = get_irq_info(irq);
if (new)
@@ -620,6 +621,11 @@ static void add_new_irq(char *path, struct irq_info *hint, GList *proc_interrupt
__add_banned_irq(irq, &banned_irqs);
new = get_irq_info(irq);
} else {
+ if (!hint->name) {
+ entry = g_list_find_custom(proc_interrupts, hint, compare_ints);
+ if (entry)
+ hint->name = ((struct irq_info *)entry->data)->name;
+ }
new = add_one_irq_to_db(path, hint, &pol);
if ((new != NULL) && (user_policy_list != NULL)) {
set_usr_irq_policy(hint->name, new);
@@ -660,6 +666,7 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs, int build_
if (irqnum && ((build_irq < 0) || (irqnum == build_irq))) {
hint.irq = irqnum;
hint.type = IRQ_TYPE_MSIX;
+ hint.name = NULL;
add_new_irq(devpath, &hint, tmp_irqs);
if (build_irq >= 0) {
log(TO_CONSOLE, LOG_INFO, "Hotplug dev irq: %d finished.\n", irqnum);
@@ -688,6 +695,7 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs, int build_
if ((build_irq < 0) || (irqnum == build_irq)) {
hint.irq = irqnum;
hint.type = IRQ_TYPE_LEGACY;
+ hint.name = NULL;
add_new_irq(devpath, &hint, tmp_irqs);
if (build_irq >= 0)
log(TO_CONSOLE, LOG_INFO, "Hotplug dev irq: %d finished.\n", irqnum);
@@ -764,11 +772,13 @@ static struct irq_info * build_dev_irqs(GList *tmp_irqs, int build_irq)
int proc_irq_hotplug(char *savedline, int irq, struct irq_info **pinfo)
{
struct irq_info tmp_info = {0};
+ GList *tmp_list = NULL;
/* firstly, init irq info by parse savedline */
init_irq_class_and_type(savedline, &tmp_info, irq);
+ tmp_list = g_list_append(tmp_list, &tmp_info);
/* secondly, init irq info by read device info */
- *pinfo = build_dev_irqs(interrupts_db, irq);
+ *pinfo = build_dev_irqs(tmp_list, irq);
if (*pinfo == NULL) {
add_new_irq(NULL, &tmp_info, interrupts_db);
*pinfo = get_irq_info(irq);
@@ -779,6 +789,8 @@ int proc_irq_hotplug(char *savedline, int irq, struct irq_info **pinfo)
}
force_rebalance_irq(*pinfo, NULL);
+ free(tmp_info.name);
+ g_list_free(tmp_list);
return 0;
}
--
1.8.3.1

View File

@ -1,93 +0,0 @@
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

View File

@ -1,34 +0,0 @@
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

View File

@ -1,92 +0,0 @@
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 | 6 ++++-
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,11 @@ 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) < delta_load + (lb_info->adjustment_load - info->load)) {
+ if ((lb_info->adjustment_load - info->load) > (lb_info->min_load + info->load)) {
+ lb_info->adjustment_load -= info->load;
+ lb_info->min_load += info->load;
+ } else if (delta_load && load_limit && (lb_info->adjustment_load > load_limit) &&
+ (lb_info->min_load + info->load) < (lb_info->adjustment_load - info->load) + delta_load) {
lb_info->adjustment_load -= info->load;
lb_info->min_load += info->load;
if (lb_info->min_load > lb_info->adjustment_load) {
--
2.23.0

View File

@ -1,387 +0,0 @@
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

View File

@ -1,105 +0,0 @@
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, &current_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

View File

@ -1,100 +0,0 @@
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/%" PRIu64 ":%" PRIu64 ") \n", indent,
+ log(TO_ALL, LOG_INFO, "%sInterrupt %i node_num is %d (%s/%" PRIu64 ":%" PRIu64 ") \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

View File

@ -1,39 +0,0 @@
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

View File

@ -1,678 +0,0 @@
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

View File

@ -1,468 +0,0 @@
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, &current_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

View File

@ -1,7 +1,7 @@
Summary: A dynamic adaptive IRQ balancing daemon
Name: irqbalance
Version: 1.8.0
Release: 4
Release: 5
Epoch: 3
License: GPLv2
Source0: https://github.com/Irqbalance/irqbalance/archive/v%{version}.tar.gz#/irqbalance-%{version}.tar.gz
@ -25,18 +25,6 @@ Requires: numactl-libs
Patch6000: bugfix-fix-unsigned-integer-subtraction-sign-overflow.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
Patch9009: bugfix-fix-opendir-fails-in-check_platform_device.patch
Patch9010: bugfix-set-hint-name-in-add_new_irq-to-avoid-segment.patch
%description
Irqbalance is a daemon to help balance the cpu load generated by
interrupts across all of a systems cpus. Irqbalance identifies the
@ -45,20 +33,6 @@ 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
@ -68,10 +42,6 @@ Shared librariy for irqbalance client.
./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}
@ -80,9 +50,6 @@ install -D -p -m 0644 %{SOURCE2} %{buildroot}%{_sysconfdir}/sysconfig/%{name}
install -D -p -m 0755 %{SOURCE3} %{buildroot}%{_sysconfdir}/sysconfig/%{name}.rules
install -D -p -m 0755 %{SOURCE4} %{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/
@ -97,12 +64,6 @@ make check
%{_sysconfdir}/sysconfig/%{name}.rules
%{_sbindir}/irq_balancer
%files devel
%{_includedir}/irqbalance_client.h
%files libs
%{_libdir}/libirqbalance_client.so
%files help
%{_mandir}/man1/*
@ -122,6 +83,12 @@ fi
/sbin/chkconfig --del %{name} >/dev/null 2>&1 || :
%changelog
*Thu Nov 11 2021 Liu Chao <liuchao173@huawei.com> - 3:1.8.0-5
- Type:bugfix
- ID:NA
- SUG:restart
- DESC:remove feature patches
* Mon Nov 1 2021 Liu Chao <liuchao173@huawei.com> - 3:1.8.0-4
- Type:bugfix
- ID:NA