!15 Rebase to v1.7.0
Merge pull request !15 from SuperSix173/openEuler-20.03-LTS
This commit is contained in:
commit
e2b4a3d61e
@ -1,29 +0,0 @@
|
||||
From 7dafc4d5c8d8229f107c90d97f33a4094eb89c6e Mon Sep 17 00:00:00 2001
|
||||
From: liuchao173 <liuchao173@huawei.com>
|
||||
Date: Thu, 7 Nov 2019 09:12:42 +0000
|
||||
Subject: [PATCH 1/8] backport: Checking return value of strdup() in
|
||||
collect_full_irq_list()
|
||||
|
||||
strdup() may return NULL if memory allocation fail, checking the return
|
||||
value before reference.
|
||||
|
||||
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
|
||||
---
|
||||
procinterrupts.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/procinterrupts.c b/procinterrupts.c
|
||||
index 2c8118a..87fae2f 100644
|
||||
--- a/procinterrupts.c
|
||||
+++ b/procinterrupts.c
|
||||
@@ -188,6 +188,8 @@ GList* collect_full_irq_list()
|
||||
continue;
|
||||
|
||||
savedline = strdup(line);
|
||||
+ if (!savedline)
|
||||
+ break;
|
||||
irq_name = strtok_r(savedline, " ", &savedptr);
|
||||
if (strstr(irq_name, "xen-dyn") != NULL)
|
||||
is_xen_dyn = 1;
|
||||
--
|
||||
2.19.1
|
||||
@ -1,65 +0,0 @@
|
||||
From f2623176c2997e7803d485084fa5150556caddcf Mon Sep 17 00:00:00 2001
|
||||
From: Kairui Song <kasong@redhat.com>
|
||||
Date: Mon, 5 Nov 2018 17:18:49 +0800
|
||||
Subject: [PATCH 102/112] Don't leak socket fd on connection error
|
||||
|
||||
Signed-off-by: Kairui Song <kasong@redhat.com>
|
||||
---
|
||||
irqbalance.c | 7 ++++---
|
||||
ui/irqbalance-ui.c | 1 +
|
||||
2 files changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index 0946603..364ca72 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -376,7 +376,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
||||
}
|
||||
if ((recv_size = recvmsg(sock, &msg, 0)) < 0) {
|
||||
log(TO_ALL, LOG_WARNING, "Error while receiving data.\n");
|
||||
- goto out;
|
||||
+ goto out_close;
|
||||
}
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
if ((cmsg->cmsg_level == SOL_SOCKET) &&
|
||||
@@ -388,7 +388,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
||||
}
|
||||
if (!valid_user) {
|
||||
log(TO_ALL, LOG_INFO, "Permission denied for user to connect to socket.\n");
|
||||
- goto out;
|
||||
+ goto out_close;
|
||||
}
|
||||
|
||||
if (!strncmp(buff, "stats", strlen("stats"))) {
|
||||
@@ -421,7 +421,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
||||
need_rescan = 1;
|
||||
if (!strncmp(irq_string, "NONE", strlen("NONE"))) {
|
||||
free(irq_string);
|
||||
- goto out;
|
||||
+ goto out_close;
|
||||
}
|
||||
int irq = strtoul(irq_string, &end, 10);
|
||||
do {
|
||||
@@ -457,6 +457,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
||||
free(setup);
|
||||
}
|
||||
|
||||
+out_close:
|
||||
close(sock);
|
||||
}
|
||||
|
||||
diff --git a/ui/irqbalance-ui.c b/ui/irqbalance-ui.c
|
||||
index 5a76ddf..005eea4 100644
|
||||
--- a/ui/irqbalance-ui.c
|
||||
+++ b/ui/irqbalance-ui.c
|
||||
@@ -66,6 +66,7 @@ int init_connection()
|
||||
memset(&addr, 0, sizeof(struct sockaddr_un));
|
||||
addr.sun_family = AF_UNIX;
|
||||
if (connect(socket_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
+ close(socket_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,73 +0,0 @@
|
||||
From 721460664afad79e2d96bbcb173eda68eed9743b Mon Sep 17 00:00:00 2001
|
||||
From: Gerd Rausch <gerd.rausch@oracle.com>
|
||||
Date: Thu, 18 Oct 2018 11:21:40 -0700
|
||||
Subject: [PATCH 100/112] Fix ambiguous parsing of *node* entries in /sys.
|
||||
|
||||
The code used to use strstr(..., "node") while iterating over
|
||||
sysfs directories such as /sys/devices/system/cpu/cpu*.
|
||||
It then made an assumption that the entry would start with "node",
|
||||
which is not necessarily the case (e.g. the "firmware_node" entry).
|
||||
|
||||
The code happened to work for as long as the node[0-9]* entry
|
||||
would be processed before the "firmware_node" entry shows up.
|
||||
|
||||
A change to the linux kernel "end_name_hash" function resulted
|
||||
in a different hash, and ultimately in a different order
|
||||
by which entries were returned by readdir(3).
|
||||
|
||||
This led to the exposure of this bug.
|
||||
|
||||
Signed-off-by: Gerd Rausch <gerd.rausch@oracle.com>
|
||||
---
|
||||
cputree.c | 11 ++++++++---
|
||||
numa.c | 5 ++++-
|
||||
2 files changed, 12 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/cputree.c b/cputree.c
|
||||
index c88143f..f08ce84 100644
|
||||
--- a/cputree.c
|
||||
+++ b/cputree.c
|
||||
@@ -368,9 +368,14 @@ static void do_one_cpu(char *path)
|
||||
entry = readdir(dir);
|
||||
if (!entry)
|
||||
break;
|
||||
- if (strstr(entry->d_name, "node")) {
|
||||
- nodeid = strtoul(&entry->d_name[4], NULL, 10);
|
||||
- break;
|
||||
+ if (strncmp(entry->d_name, "node", 4) == 0) {
|
||||
+ char *end;
|
||||
+ int num;
|
||||
+ num = strtol(entry->d_name + 4, &end, 10);
|
||||
+ if (!*end && num >= 0) {
|
||||
+ nodeid = num;
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
} while (entry);
|
||||
closedir(dir);
|
||||
diff --git a/numa.c b/numa.c
|
||||
index cd67ec8..f0b1a98 100644
|
||||
--- a/numa.c
|
||||
+++ b/numa.c
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
+#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
@@ -115,7 +116,9 @@ void build_numa_node_list(void)
|
||||
entry = readdir(dir);
|
||||
if (!entry)
|
||||
break;
|
||||
- if ((entry->d_type == DT_DIR) && (strstr(entry->d_name, "node"))) {
|
||||
+ if ((entry->d_type == DT_DIR) &&
|
||||
+ (strncmp(entry->d_name, "node", 4) == 0) &&
|
||||
+ isdigit(entry->d_name[4])) {
|
||||
add_one_node(entry->d_name);
|
||||
}
|
||||
} while (entry);
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,34 +0,0 @@
|
||||
From 702cab67df2bafd9735a753387eae7febd74263b Mon Sep 17 00:00:00 2001
|
||||
From: Kairui Song <kasong@redhat.com>
|
||||
Date: Sun, 2 Sep 2018 23:40:45 +0800
|
||||
Subject: [PATCH 095/112] Fix an possible overflow error
|
||||
|
||||
Got:
|
||||
"specified bound 2048 exceeds the size 19 of the destination"
|
||||
when -O2 is used, and a "*** buffer overflow detected ***" error output
|
||||
with no backtrace.
|
||||
|
||||
With -O0, it's gone, guess it's some gcc optimization problem, and the
|
||||
size there is wrong anyway, this patch could fix it.
|
||||
---
|
||||
irqbalance.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index 81bf8d8..0946603 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -444,8 +444,8 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
||||
}
|
||||
if (!strncmp(buff, "setup", strlen("setup"))) {
|
||||
char banned[512];
|
||||
- char *setup = calloc(strlen("SLEEP ") + 11 +1, 1);
|
||||
- snprintf(setup, 2048, "SLEEP %d ", sleep_interval);
|
||||
+ char *setup = calloc(strlen("SLEEP ") + 11 + 1, 1);
|
||||
+ snprintf(setup, strlen("SLEEP ") + 11 + 1, "SLEEP %d ", sleep_interval);
|
||||
if(g_list_length(cl_banned_irqs) > 0) {
|
||||
for_each_irq(cl_banned_irqs, get_irq_data, setup);
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,57 +0,0 @@
|
||||
From ce806df0081cf09344197285e32bd2113d86f554 Mon Sep 17 00:00:00 2001
|
||||
From: Kairui Song <kasong@redhat.com>
|
||||
Date: Mon, 3 Sep 2018 00:30:14 +0800
|
||||
Subject: [PATCH 23/58] Fix irqbalance ui failing to connect to irqbalance
|
||||
daemon
|
||||
|
||||
irqbalance ui is faling due to the changes in commit 19c25dd.
|
||||
This patch align irqbalance-ui's socket connecting routine with
|
||||
irqbalance.c
|
||||
---
|
||||
ui/irqbalance-ui.c | 16 +++++++++++-----
|
||||
ui/irqbalance-ui.h | 1 +
|
||||
2 files changed, 12 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/ui/irqbalance-ui.c b/ui/irqbalance-ui.c
|
||||
index 47dd5dc..5a76ddf 100644
|
||||
--- a/ui/irqbalance-ui.c
|
||||
+++ b/ui/irqbalance-ui.c
|
||||
@@ -57,12 +57,18 @@ int init_connection()
|
||||
}
|
||||
addr.sun_family = AF_UNIX;
|
||||
char socket_name[64];
|
||||
- snprintf(socket_name, 64, "%s%d.sock", SOCKET_PATH, irqbalance_pid);
|
||||
- strncpy(addr.sun_path, socket_name, strlen(addr.sun_path));
|
||||
|
||||
- if(connect(socket_fd, (struct sockaddr *)&addr,
|
||||
- sizeof(sa_family_t) + strlen(socket_name) + 1) < 0) {
|
||||
- return 0;
|
||||
+ snprintf(socket_name, 64, "%s/%s%d.sock", SOCKET_TMPFS, SOCKET_PATH, irqbalance_pid);
|
||||
+ strncpy(addr.sun_path, socket_name, strlen(socket_name));
|
||||
+
|
||||
+ if(connect(socket_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
+ /* Try connect to abstract */
|
||||
+ memset(&addr, 0, sizeof(struct sockaddr_un));
|
||||
+ addr.sun_family = AF_UNIX;
|
||||
+ if (connect(socket_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
}
|
||||
|
||||
return socket_fd;
|
||||
diff --git a/ui/irqbalance-ui.h b/ui/irqbalance-ui.h
|
||||
index f97fcb1..b32d58a 100644
|
||||
--- a/ui/irqbalance-ui.h
|
||||
+++ b/ui/irqbalance-ui.h
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <glib-unix.h>
|
||||
|
||||
#define SOCKET_PATH "irqbalance"
|
||||
+#define SOCKET_TMPFS "/var/run"
|
||||
|
||||
#define STATS "stats"
|
||||
#define SET_SLEEP "settings sleep "
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,253 +0,0 @@
|
||||
From 85d37098a551034061d4b77be275d664e109c3fb Mon Sep 17 00:00:00 2001
|
||||
From: Kairui Song <kasong@redhat.com>
|
||||
Date: Thu, 30 Aug 2018 17:45:53 +0800
|
||||
Subject: [PATCH 094/112] Fix several memleak problems found by covscan
|
||||
|
||||
Some memleak issues is found by static analysis tools, and can confirm
|
||||
irqbalance is leaking memory slowly when there are incomming connection
|
||||
to socket.
|
||||
|
||||
This patch could solve the memleak problem.
|
||||
---
|
||||
irqbalance.c | 16 ++++++++++++----
|
||||
ui/irqbalance-ui.c | 31 +++++++++++++++++++++++++++----
|
||||
ui/ui.c | 2 ++
|
||||
3 files changed, 41 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index bce9d56..81bf8d8 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -372,11 +372,11 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
||||
sock = accept(fd, NULL, NULL);
|
||||
if (sock < 0) {
|
||||
log(TO_ALL, LOG_WARNING, "Connection couldn't be accepted.\n");
|
||||
- return TRUE;
|
||||
+ goto out;
|
||||
}
|
||||
if ((recv_size = recvmsg(sock, &msg, 0)) < 0) {
|
||||
log(TO_ALL, LOG_WARNING, "Error while receiving data.\n");
|
||||
- return TRUE;
|
||||
+ goto out;
|
||||
}
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
if ((cmsg->cmsg_level == SOL_SOCKET) &&
|
||||
@@ -388,7 +388,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
||||
}
|
||||
if (!valid_user) {
|
||||
log(TO_ALL, LOG_INFO, "Permission denied for user to connect to socket.\n");
|
||||
- return TRUE;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
if (!strncmp(buff, "stats", strlen("stats"))) {
|
||||
@@ -408,6 +408,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
||||
if (new_iterval >= 1) {
|
||||
sleep_interval = new_iterval;
|
||||
}
|
||||
+ free(sleep_string);
|
||||
} else if (!(strncmp(buff + strlen("settings "), "ban irqs ",
|
||||
strlen("ban irqs ")))) {
|
||||
char *end;
|
||||
@@ -419,12 +420,14 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
||||
cl_banned_irqs = NULL;
|
||||
need_rescan = 1;
|
||||
if (!strncmp(irq_string, "NONE", strlen("NONE"))) {
|
||||
- return TRUE;
|
||||
+ free(irq_string);
|
||||
+ goto out;
|
||||
}
|
||||
int irq = strtoul(irq_string, &end, 10);
|
||||
do {
|
||||
add_cl_banned_irq(irq);
|
||||
} while((irq = strtoul(end, &end, 10)));
|
||||
+ free(irq_string);
|
||||
} else if (!(strncmp(buff + strlen("settings "), "cpus ",
|
||||
strlen("cpus")))) {
|
||||
char *cpu_ban_string = malloc(
|
||||
@@ -436,6 +439,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
||||
banned_cpumask_from_ui = NULL;
|
||||
}
|
||||
need_rescan = 1;
|
||||
+ free(cpu_ban_string);
|
||||
}
|
||||
}
|
||||
if (!strncmp(buff, "setup", strlen("setup"))) {
|
||||
@@ -450,10 +454,14 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
||||
snprintf(setup + strlen(setup), strlen(banned) + 7 + 1,
|
||||
"BANNED %s", banned);
|
||||
send(sock, setup, strlen(setup), 0);
|
||||
+ free(setup);
|
||||
}
|
||||
|
||||
close(sock);
|
||||
}
|
||||
+
|
||||
+out:
|
||||
+ free(msg.msg_control);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
diff --git a/ui/irqbalance-ui.c b/ui/irqbalance-ui.c
|
||||
index d4deee0..47dd5dc 100644
|
||||
--- a/ui/irqbalance-ui.c
|
||||
+++ b/ui/irqbalance-ui.c
|
||||
@@ -41,6 +41,7 @@ struct msghdr * create_credentials_msg()
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred));
|
||||
memcpy(CMSG_DATA(cmsg), credentials, sizeof(struct ucred));
|
||||
|
||||
+ free(credentials);
|
||||
return msg;
|
||||
}
|
||||
|
||||
@@ -87,6 +88,8 @@ void send_settings(char *data)
|
||||
sendmsg(socket_fd, msg, 0);
|
||||
|
||||
close(socket_fd);
|
||||
+ free(msg->msg_control);
|
||||
+ free(msg);
|
||||
}
|
||||
|
||||
char * get_data(char *string)
|
||||
@@ -115,6 +118,8 @@ char * get_data(char *string)
|
||||
int len = recv(socket_fd, data, 8192, 0);
|
||||
close(socket_fd);
|
||||
data[len] = '\0';
|
||||
+ free(msg->msg_control);
|
||||
+ free(msg);
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -123,6 +128,7 @@ void parse_setup(char *setup_data)
|
||||
char *token, *ptr;
|
||||
int i,j;
|
||||
char *copy;
|
||||
+ irq_t *new_irq = NULL;
|
||||
if((setup_data == NULL) || (strlen(setup_data) == 0)) return;
|
||||
copy = strdup(setup_data);
|
||||
if (!copy)
|
||||
@@ -136,7 +142,7 @@ void parse_setup(char *setup_data)
|
||||
token = strtok_r(NULL, " ", &ptr);
|
||||
/* Parse banned IRQ data */
|
||||
while(!strncmp(token, "IRQ", strlen("IRQ"))) {
|
||||
- irq_t *new_irq = malloc(sizeof(irq_t));
|
||||
+ new_irq = malloc(sizeof(irq_t));
|
||||
new_irq->vector = strtol(strtok_r(NULL, " ", &ptr), NULL, 10);
|
||||
token = strtok_r(NULL, " ", &ptr);
|
||||
if(strncmp(token, "LOAD", strlen("LOAD"))) goto out;
|
||||
@@ -151,6 +157,7 @@ void parse_setup(char *setup_data)
|
||||
new_irq->assigned_to = NULL;
|
||||
setup.banned_irqs = g_list_append(setup.banned_irqs, new_irq);
|
||||
token = strtok_r(NULL, " ", &ptr);
|
||||
+ new_irq = NULL;
|
||||
}
|
||||
|
||||
if(strncmp(token, "BANNED", strlen("BANNED"))) goto out;
|
||||
@@ -165,6 +172,7 @@ void parse_setup(char *setup_data)
|
||||
banned_cpu);
|
||||
}
|
||||
}
|
||||
+ free(map);
|
||||
|
||||
}
|
||||
free(copy);
|
||||
@@ -173,6 +181,9 @@ void parse_setup(char *setup_data)
|
||||
out: {
|
||||
/* Invalid data presented */
|
||||
printf("Invalid data sent. Unexpected token: %s", token);
|
||||
+ if (new_irq) {
|
||||
+ free(new_irq);
|
||||
+ }
|
||||
free(copy);
|
||||
g_list_free(tree);
|
||||
exit(1);
|
||||
@@ -240,7 +251,9 @@ void parse_into_tree(char *data)
|
||||
cpu_node_t *parent = NULL;
|
||||
char *copy;
|
||||
tree = NULL;
|
||||
-
|
||||
+ irq_t *new_irq = NULL;
|
||||
+ cpu_node_t *new = NULL;
|
||||
+
|
||||
if (!data || strlen(data) == 0)
|
||||
return;
|
||||
|
||||
@@ -255,7 +268,7 @@ void parse_into_tree(char *data)
|
||||
free(copy);
|
||||
goto out;
|
||||
}
|
||||
- cpu_node_t *new = malloc(sizeof(cpu_node_t));
|
||||
+ new = malloc(sizeof(cpu_node_t));
|
||||
new->irqs = NULL;
|
||||
new->children = NULL;
|
||||
new->cpu_list = NULL;
|
||||
@@ -279,7 +292,7 @@ void parse_into_tree(char *data)
|
||||
|
||||
/* Parse assigned IRQ data */
|
||||
while((token != NULL) && (!strncmp(token, "IRQ", strlen("IRQ")))) {
|
||||
- irq_t *new_irq = malloc(sizeof(irq_t));
|
||||
+ new_irq = malloc(sizeof(irq_t));
|
||||
new_irq->vector = strtol(strtok_r(NULL, " ", &ptr), NULL, 10);
|
||||
token = strtok_r(NULL, " ", &ptr);
|
||||
if(strncmp(token, "LOAD", strlen("LOAD"))) goto out;
|
||||
@@ -293,6 +306,7 @@ void parse_into_tree(char *data)
|
||||
new_irq->is_banned = 0;
|
||||
new->irqs = g_list_append(new->irqs, new_irq);
|
||||
token = strtok_r(NULL, " ", &ptr);
|
||||
+ new_irq = NULL;
|
||||
}
|
||||
|
||||
if((token == NULL) || (strncmp(token, "IRQ", strlen("IRQ")))) {
|
||||
@@ -306,6 +320,8 @@ void parse_into_tree(char *data)
|
||||
parent = new;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ new = NULL;
|
||||
}
|
||||
free(copy);
|
||||
for_each_node(tree, assign_cpu_lists, NULL);
|
||||
@@ -315,6 +331,12 @@ void parse_into_tree(char *data)
|
||||
out: {
|
||||
/* Invalid data presented */
|
||||
printf("Invalid data sent. Unexpected token: %s\n", token);
|
||||
+ if (new_irq) {
|
||||
+ free(new_irq);
|
||||
+ }
|
||||
+ if (new) {
|
||||
+ free(new);
|
||||
+ }
|
||||
g_list_free(tree);
|
||||
exit(1);
|
||||
}
|
||||
@@ -330,6 +352,7 @@ gboolean rescan_tree(gpointer data __attribute__((unused)))
|
||||
display_tree();
|
||||
}
|
||||
free(setup_data);
|
||||
+ free(irqbalance_data);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
diff --git a/ui/ui.c b/ui/ui.c
|
||||
index 4054f0e..06ec472 100644
|
||||
--- a/ui/ui.c
|
||||
+++ b/ui/ui.c
|
||||
@@ -71,6 +71,7 @@ char * check_control_in_sleep_input(int max_len, int column_offest, int line_off
|
||||
attrset(COLOR_PAIR(6));
|
||||
break;
|
||||
case 27:
|
||||
+ free(input_to);
|
||||
return NULL;
|
||||
default:
|
||||
input_to[iteration] = new;
|
||||
@@ -115,6 +116,7 @@ int get_valid_sleep_input(int column_offest)
|
||||
input);
|
||||
refresh();
|
||||
}
|
||||
+ free(input);
|
||||
}
|
||||
|
||||
attrset(COLOR_PAIR(1));
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,58 +0,0 @@
|
||||
From d6abbe898baa111207e1e9316dde75c38d555325 Mon Sep 17 00:00:00 2001
|
||||
From: Neil Horman <nhorman@tuxdriver.com>
|
||||
Date: Mon, 9 Jul 2018 10:12:41 -0400
|
||||
Subject: [PATCH 091/112] Fix some string copy limitations
|
||||
|
||||
Latest gcc caught some errors in our string copying routines. Fix those
|
||||
up
|
||||
|
||||
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
|
||||
---
|
||||
irqbalance.c | 3 +--
|
||||
procinterrupts.c | 2 +-
|
||||
ui/irqbalance-ui.c | 2 +-
|
||||
3 files changed, 3 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index 66e56f8..2614719 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -468,8 +468,7 @@ int init_socket(char *socket_name)
|
||||
}
|
||||
|
||||
addr.sun_family = AF_UNIX;
|
||||
- addr.sun_path[0] = '\0';
|
||||
- strncpy(addr.sun_path + 1, socket_name, strlen(socket_name));
|
||||
+ strncpy(addr.sun_path, socket_name, strlen(addr.sun_path));
|
||||
if (bind(socket_fd, (struct sockaddr *)&addr,
|
||||
sizeof(sa_family_t) + strlen(socket_name) + 1) < 0) {
|
||||
log(TO_ALL, LOG_WARNING, "Daemon couldn't be bound to the socket.\n");
|
||||
diff --git a/procinterrupts.c b/procinterrupts.c
|
||||
index 4ef8751..7283998 100644
|
||||
--- a/procinterrupts.c
|
||||
+++ b/procinterrupts.c
|
||||
@@ -274,7 +274,7 @@ void parse_proc_interrupts(void)
|
||||
if (!c)
|
||||
continue;
|
||||
|
||||
- strncpy(savedline, line, sizeof(savedline));
|
||||
+ strncpy(savedline, line, sizeof(savedline)-1);
|
||||
|
||||
*c = 0;
|
||||
c++;
|
||||
diff --git a/ui/irqbalance-ui.c b/ui/irqbalance-ui.c
|
||||
index 3fc46af..d4deee0 100644
|
||||
--- a/ui/irqbalance-ui.c
|
||||
+++ b/ui/irqbalance-ui.c
|
||||
@@ -57,7 +57,7 @@ int init_connection()
|
||||
addr.sun_family = AF_UNIX;
|
||||
char socket_name[64];
|
||||
snprintf(socket_name, 64, "%s%d.sock", SOCKET_PATH, irqbalance_pid);
|
||||
- strncpy(addr.sun_path + 1, socket_name, strlen(socket_name));
|
||||
+ strncpy(addr.sun_path, socket_name, strlen(addr.sun_path));
|
||||
|
||||
if(connect(socket_fd, (struct sockaddr *)&addr,
|
||||
sizeof(sa_family_t) + strlen(socket_name) + 1) < 0) {
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,54 +0,0 @@
|
||||
From 8adbe9aacb93c5a160f3ecfc00adc10a64d27c14 Mon Sep 17 00:00:00 2001
|
||||
From: Sekhar Nori <nsekhar@ti.com>
|
||||
Date: Tue, 19 Feb 2019 08:29:58 +0000
|
||||
Subject: [PATCH 108/112] Fix string truncation issues detected by GCC 8
|
||||
|
||||
This fixes string truncation warning generated by GCC of the form:
|
||||
|
||||
irqbalance.c:485:2: warning: 'strncpy' output truncated before terminating nul copying as many bytes from a string as its length [-Wstringop-truncation]
|
||||
strncpy(addr.sun_path, socket_name, strlen(socket_name));
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Using source size in strncpy so fix that by using destination size.
|
||||
For the instance of this issue in irqbalance-ui.c, fix the issue by
|
||||
eliminating the unneeded temporary buffer.
|
||||
|
||||
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
|
||||
---
|
||||
irqbalance.c | 2 +-
|
||||
ui/irqbalance-ui.c | 5 ++---
|
||||
2 files changed, 3 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index 60d8a5e..c1a0e15 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -482,7 +482,7 @@ int init_socket()
|
||||
*/
|
||||
addr.sun_family = AF_UNIX;
|
||||
snprintf(socket_name, 64, "%s/%s%d.sock", SOCKET_TMPFS, SOCKET_PATH, getpid());
|
||||
- strncpy(addr.sun_path, socket_name, strlen(socket_name));
|
||||
+ strncpy(addr.sun_path, socket_name, sizeof(addr.sun_path));
|
||||
if (bind(socket_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
log(TO_ALL, LOG_WARNING, "Daemon couldn't be bound to the file-based socket.\n");
|
||||
|
||||
diff --git a/ui/irqbalance-ui.c b/ui/irqbalance-ui.c
|
||||
index 005eea4..1119665 100644
|
||||
--- a/ui/irqbalance-ui.c
|
||||
+++ b/ui/irqbalance-ui.c
|
||||
@@ -56,10 +56,9 @@ int init_connection()
|
||||
return 0;
|
||||
}
|
||||
addr.sun_family = AF_UNIX;
|
||||
- char socket_name[64];
|
||||
|
||||
- snprintf(socket_name, 64, "%s/%s%d.sock", SOCKET_TMPFS, SOCKET_PATH, irqbalance_pid);
|
||||
- strncpy(addr.sun_path, socket_name, strlen(socket_name));
|
||||
+ snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s%d.sock", SOCKET_TMPFS,
|
||||
+ SOCKET_PATH, irqbalance_pid);
|
||||
|
||||
if(connect(socket_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
/* Try connect to abstract */
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,52 +0,0 @@
|
||||
From 0906c9dcf1754bb2f32f9247608cc937650d2a0e Mon Sep 17 00:00:00 2001
|
||||
From: Neil Horman <nhorman@tuxdriver.com>
|
||||
Date: Fri, 4 May 2018 06:15:51 -0400
|
||||
Subject: [PATCH] arm: Add a catchall guessing mechanism
|
||||
|
||||
Instead of spamming the logs to indicate we are guessing at an irq type,
|
||||
and then not finding one, add a catchall regex to match on everything
|
||||
last to assign the type and class as legacy/other, and report that
|
||||
|
||||
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
|
||||
---
|
||||
procinterrupts.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/procinterrupts.c b/procinterrupts.c
|
||||
index eb84a1c..1aa4413 100644
|
||||
--- a/procinterrupts.c
|
||||
+++ b/procinterrupts.c
|
||||
@@ -105,10 +105,12 @@ static void guess_arm_irq_hints(char *name, struct irq_info *info)
|
||||
{
|
||||
int i, rc;
|
||||
static int compiled = 0;
|
||||
+ /* Note: Last entry is a catchall */
|
||||
static struct irq_match matches[] = {
|
||||
{ "eth.*" ,{NULL} ,NULL, IRQ_TYPE_LEGACY, IRQ_GBETH },
|
||||
{ "[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},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
@@ -134,8 +136,7 @@ static void guess_arm_irq_hints(char *name, struct irq_info *info)
|
||||
info->class = matches[i].class;
|
||||
if (matches[i].refine_match)
|
||||
matches[i].refine_match(name, info);
|
||||
-
|
||||
- log(TO_ALL, LOG_DEBUG, "IRQ %s(%d) is class %d\n", name, info->irq,info->class);
|
||||
+ log(TO_ALL, LOG_DEBUG, "IRQ %s(%d) guessed as class %d\n", name, info->irq,info->class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,7 +215,6 @@ GList* collect_full_irq_list()
|
||||
info->class = IRQ_VIRT_EVENT;
|
||||
} else {
|
||||
#ifdef AARCH64
|
||||
- log(TO_ALL, LOG_DEBUG, "GUESSING AARCH64 CLASS FOR %s\n", irq_name);
|
||||
guess_arm_irq_hints(irq_name, info);
|
||||
#else
|
||||
info->type = IRQ_TYPE_LEGACY;
|
||||
--
|
||||
2.21.0.windows.1
|
||||
|
||||
@ -1,61 +0,0 @@
|
||||
From 07032f71ea956ca195c9b2386d09d24b07b7133f Mon Sep 17 00:00:00 2001
|
||||
From: hejingxian <hejingxian@huawei.com>
|
||||
Date: Tue, 12 Nov 2019 10:59:20 +0800
|
||||
Subject: [PATCH] Prevent inserting a duplicate entry to avoid list chaos
|
||||
|
||||
Introduced by bugfix-force-irq-into-rebalance-list-when-irq-removed-and-reinserted.patch
|
||||
and feature-introduce-verifyhint-to-detect-hint-variation.patch, irq may want be inserted to
|
||||
rebalance list more then once, and we need to prevent this. we developped a solution in
|
||||
bugfix-fix-two-same-irq-insert-to-list.patch, but we are likely to call irq_in_rebalance_list.
|
||||
|
||||
this patch remove the code in bugfix-fix-two-same-irq-insert-to-list.patch and add protection
|
||||
in force_rebalance_irq instead.
|
||||
---
|
||||
classify.c | 2 +-
|
||||
irqbalance.c | 4 ++++
|
||||
irqbalance.h | 1 +
|
||||
3 files changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/classify.c b/classify.c
|
||||
index f041054..5aed9e5 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;
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index 395669c..faa8e6a 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -251,6 +251,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
|
||||
diff --git a/irqbalance.h b/irqbalance.h
|
||||
index c07a4fc..1befb46 100644
|
||||
--- a/irqbalance.h
|
||||
+++ b/irqbalance.h
|
||||
@@ -113,6 +113,7 @@ extern void migrate_irq(GList **from, GList **to, struct irq_info *info);
|
||||
extern void free_cl_opts(void);
|
||||
extern void add_cl_banned_module(char *modname);
|
||||
#define irq_numa_node(irq) ((irq)->numa_node)
|
||||
+extern gint compare_ints(gconstpointer a, gconstpointer b);
|
||||
|
||||
extern struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list);
|
||||
extern void find_irq_dev_path(int irq, char *dirname, int length);
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,29 +0,0 @@
|
||||
From 73c26ac2d6e856c5a9ffd1c48ed7c1abc85de3df Mon Sep 17 00:00:00 2001
|
||||
From: liuchao <liuchao173@huawei.com>
|
||||
Date: Sat, 12 Oct 2019 03:34:44 +0000
|
||||
Subject: [PATCH] irqbalance: change irq ban check path to devpath
|
||||
|
||||
keep the parameters 'path' of check_for_irq_ban function consistent with line 699.
|
||||
In check_for_irq_ban,
|
||||
sprintf(cmd, "%s %s %d > /dev/null",banscript, path, irq);
|
||||
the banscript is unique, so the path should keep consistent.
|
||||
---
|
||||
classify.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/classify.c b/classify.c
|
||||
index 7c97d47..3681c48 100644
|
||||
--- a/classify.c
|
||||
+++ b/classify.c
|
||||
@@ -719,7 +719,7 @@ struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list)
|
||||
if (user_policy_list == NULL) {
|
||||
get_irq_user_policy(devpath, irqnum, &pol);
|
||||
}
|
||||
- if ((pol.ban == 1) || (check_for_irq_ban(path, irqnum, tmp_list))) {
|
||||
+ if ((pol.ban == 1) || (check_for_irq_ban(devpath, irqnum, tmp_list))) {
|
||||
add_banned_irq(irqnum, &banned_irqs, 0);
|
||||
goto done;
|
||||
}
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,29 +0,0 @@
|
||||
From 0d6ed42e5d195f6a00d2f000ce8da11e89cb3010 Mon Sep 17 00:00:00 2001
|
||||
From: caihongda <caihongda@huawei.com>
|
||||
Date: Fri, 1 Nov 2019 10:06:03 +0800
|
||||
Subject: [PATCH] irqbalance: bufix in banned irq delete
|
||||
|
||||
reason: The banned irq will not be added int interrupts_db, so
|
||||
we need to additionaly delete it if it is no_existing.
|
||||
To test this in llt, we add a stub for function
|
||||
is_banned_irq.
|
||||
|
||||
Signed-off-by: caihongda <caihongda@huawei.com>
|
||||
|
||||
diff --git a/classify.c b/classify.c
|
||||
index 9f72ae8..585f2dc 100644
|
||||
--- a/classify.c
|
||||
+++ b/classify.c
|
||||
@@ -853,6 +860,9 @@ static void remove_no_existing_irq(struct irq_info *info, void *data __attribute
|
||||
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);
|
||||
+ }
|
||||
}
|
||||
|
||||
void free_irq_db(void)
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,50 +0,0 @@
|
||||
From 0c8ecab9e6f5fae5860e7fbc795e988c112edede Mon Sep 17 00:00:00 2001
|
||||
From: xiashuang <xiashuang1@huawei.com>
|
||||
Date: Thu, 25 Jul 2019 22:38:32 -0400
|
||||
Subject: [PATCH] fix fgets will get a redundant new line
|
||||
|
||||
this patch fix a bug introduced by bugfix-force-irq-into-rebalance-list-when-irq-removed-and-reinserted.patch.
|
||||
the previous patch use fgets to get a directory name from buffer. but fgets will get a redundant newline,
|
||||
so the directory name are always invalid, this patch just remove the '\n'.
|
||||
---
|
||||
classify.c | 8 ++++++--
|
||||
1 file changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/classify.c b/classify.c
|
||||
index e61c39b..440576f 100644
|
||||
--- a/classify.c
|
||||
+++ b/classify.c
|
||||
@@ -747,6 +747,7 @@ void find_irq_dev_path(int irq, char *dirname, int length)
|
||||
char path[PATH_MAX];
|
||||
char buffer[128];
|
||||
char *brc = NULL;
|
||||
+ size_t dirlen;
|
||||
|
||||
memset(dirname, 0, length);
|
||||
/* Return defaults if irq is 0 */
|
||||
@@ -762,8 +763,10 @@ void find_irq_dev_path(int irq, char *dirname, int length)
|
||||
}
|
||||
|
||||
brc = fgets(buffer, 128, output);
|
||||
- if (brc) {
|
||||
+ /* fgets will get a redundant \n */
|
||||
+ if (brc && (dirlen = strcspn(brc, "\n")) > 0) {
|
||||
log(TO_CONSOLE, LOG_INFO, "msi_irqs IRQ %d dirname is %s\n", irq, brc);
|
||||
+ brc[dirlen] = '\0';
|
||||
strncpy(dirname, brc, length);
|
||||
pclose(output);
|
||||
return;
|
||||
@@ -779,8 +782,9 @@ void find_irq_dev_path(int irq, char *dirname, int length)
|
||||
}
|
||||
|
||||
brc = fgets(buffer, 128, output);
|
||||
- if (brc) {
|
||||
+ if (brc && (dirlen = strcspn(brc, "\n")) > 0) {
|
||||
log(TO_CONSOLE, LOG_INFO, "IRQ %d dirname is %s\n", irq, brc);
|
||||
+ brc[dirlen] = '\0';
|
||||
strncpy(dirname, brc, length);
|
||||
pclose(output);
|
||||
return;
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
From 2c040ddc5869635598e4fbf5c63217f60fdef5f1 Mon Sep 17 00:00:00 2001
|
||||
From: xiashuang <xiashuang1@huawei.com>
|
||||
Date: Sun, 17 Mar 2019 18:59:09 -0400
|
||||
Subject: [PATCH 2/4] bugfix fix a hole that flees hotplug event
|
||||
|
||||
from 1.0.9, original infoformation is missing
|
||||
---
|
||||
irqbalance.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index 6412447..2f699b8 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -284,9 +284,9 @@ gboolean scan(gpointer data)
|
||||
for_each_irq(NULL, force_rebalance_irq, NULL);
|
||||
parse_proc_interrupts();
|
||||
parse_proc_stat();
|
||||
- sleep_approx(sleep_interval);
|
||||
- clear_work_stats();
|
||||
- parse_proc_interrupts();
|
||||
+
|
||||
+ /* Still need to check hotplugged or not next round */
|
||||
+ return TRUE;
|
||||
}
|
||||
|
||||
parse_proc_stat();
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,34 +0,0 @@
|
||||
From f3c1502c83f5ae09202a707669c924fc2bd0cca4 Mon Sep 17 00:00:00 2001
|
||||
From: liuchao173 <liuchao173@huawei.com>
|
||||
Date: Mon, 18 Nov 2019 13:57:11 +0000
|
||||
Subject: [PATCH] irqblance: fix memory leak of strdup
|
||||
|
||||
fix memory leak of strdup in collect_full_irq_list(), when continue
|
||||
in if branch, the savedline isn't freed
|
||||
---
|
||||
procinterrupts.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/procinterrupts.c b/procinterrupts.c
|
||||
index e36fcac..bde31f4 100644
|
||||
--- a/procinterrupts.c
|
||||
+++ b/procinterrupts.c
|
||||
@@ -321,6 +321,7 @@ GList* collect_full_irq_list()
|
||||
if (ban_pci_assigned_irq && is_pci_assigned_irq(c)) {
|
||||
log(TO_ALL, LOG_INFO, "Banned PCI-assigned irq %d.\n", number);
|
||||
add_vm_banned_irq(number);
|
||||
+ free(savedline);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -338,6 +339,7 @@ GList* collect_full_irq_list()
|
||||
* For these irqs, we can add these to banned irq list.
|
||||
*/
|
||||
add_banned_list_irq(number);
|
||||
+ free(savedline);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,161 +0,0 @@
|
||||
From feeb95206e1f178e2bbf0393483861f364bd7d5b Mon Sep 17 00:00:00 2001
|
||||
From: liuchao173 <liuchao173@huawei.com>
|
||||
Date: Wed, 23 Oct 2019 11:38:17 +0000
|
||||
Subject: [PATCH] irqbalance: fix new irqs in hotplug keep stay on one numa node
|
||||
|
||||
when the number of cpus is huge, hotplug occurs and new irqs will stay on one numa node
|
||||
---
|
||||
classify.c | 25 +++++++++++++++++++++++++
|
||||
procinterrupts.c | 24 +++++++++++++++++++++---
|
||||
rules_config.c | 4 ++++
|
||||
3 files changed, 50 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/classify.c b/classify.c
|
||||
index 3681c48..54f27f0 100644
|
||||
--- a/classify.c
|
||||
+++ b/classify.c
|
||||
@@ -38,6 +38,7 @@ static GList *banned_irqs = NULL;
|
||||
GList *cl_banned_irqs = NULL;
|
||||
static GList *cl_banned_modules = NULL;
|
||||
static GList *vm_banned_irqs = NULL;
|
||||
+extern int need_add_single;
|
||||
|
||||
#define SYSFS_DIR "/sys"
|
||||
#define SYSPCI_DIR "/sys/bus/pci/devices"
|
||||
@@ -646,6 +647,21 @@ static int check_for_irq_ban(char *path __attribute__((unused)), int irq, GList
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int is_proc_irq_info_exist(int irq, GList *tmp_list)
|
||||
+{
|
||||
+ GList *entry;
|
||||
+ struct irq_info find;
|
||||
+
|
||||
+ if (!tmp_list) {
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ find.irq = irq;
|
||||
+ entry = g_list_find_custom(tmp_list, &find, compare_ints);
|
||||
+
|
||||
+ return entry ? 1 : 0;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Figures out which interrupt(s) relate to the device we"re looking at in dirname
|
||||
*/
|
||||
@@ -686,6 +702,12 @@ struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list)
|
||||
add_banned_irq(irqnum, &banned_irqs, 0);
|
||||
continue;
|
||||
}
|
||||
+ if (!is_proc_irq_info_exist(irqnum, tmp_list)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (need_add_single && need_add_single != irqnum) {
|
||||
+ continue;
|
||||
+ }
|
||||
hint.irq = irqnum;
|
||||
hint.type = IRQ_TYPE_MSIX;
|
||||
new = add_one_irq_to_db(devpath, &hint, &pol);
|
||||
@@ -723,6 +745,9 @@ struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list)
|
||||
add_banned_irq(irqnum, &banned_irqs, 0);
|
||||
goto done;
|
||||
}
|
||||
+ if (!is_proc_irq_info_exist(irqnum, tmp_list)) {
|
||||
+ goto done;
|
||||
+ }
|
||||
|
||||
hint.irq = irqnum;
|
||||
hint.type = IRQ_TYPE_LEGACY;
|
||||
diff --git a/procinterrupts.c b/procinterrupts.c
|
||||
index c32c1b2..f0dd608 100644
|
||||
--- a/procinterrupts.c
|
||||
+++ b/procinterrupts.c
|
||||
@@ -43,6 +43,7 @@
|
||||
static int proc_int_has_msi = 0;
|
||||
static int msi_found_in_sysfs = 0;
|
||||
extern int ban_pci_assigned_irq;
|
||||
+int need_add_single = 0;
|
||||
|
||||
#ifdef AARCH64
|
||||
struct irq_match {
|
||||
@@ -361,9 +362,10 @@ void parse_proc_interrupts(void)
|
||||
uint64_t count;
|
||||
char *c, *c2;
|
||||
struct irq_info *info;
|
||||
- struct irq_info tmp_info;
|
||||
- char savedline[1024];
|
||||
+ struct irq_info tmp_info = {0};
|
||||
+ char *savedline = NULL;
|
||||
char dirname[PATH_MAX] = {'\0'};
|
||||
+ struct irq_info *lookup;
|
||||
|
||||
if (getline(&line, &size, file)<=0)
|
||||
break;
|
||||
@@ -383,7 +385,9 @@ void parse_proc_interrupts(void)
|
||||
if (!c)
|
||||
continue;
|
||||
|
||||
- strncpy(savedline, line, sizeof(savedline)-1);
|
||||
+ savedline = strdup(line);
|
||||
+ if (!savedline)
|
||||
+ continue;
|
||||
|
||||
*c = 0;
|
||||
c++;
|
||||
@@ -391,23 +395,36 @@ void parse_proc_interrupts(void)
|
||||
|
||||
info = get_irq_info(number);
|
||||
if (!info) {
|
||||
+ init_irq_class_and_type(savedline, &tmp_info, number);
|
||||
find_irq_dev_path(number, dirname, PATH_MAX);
|
||||
if (strlen(dirname) > 0) {
|
||||
+ need_add_single = number;
|
||||
info = build_one_dev_entry(dirname, NULL);
|
||||
+ need_add_single = 0;
|
||||
+ lookup = get_irq_info(number);
|
||||
+ if (lookup != NULL) {
|
||||
+ lookup->existing = 1;
|
||||
+ set_usr_irq_policy(tmp_info.name, lookup);
|
||||
+ }
|
||||
log(TO_CONSOLE, LOG_INFO, "new IRQ %d added into database, dirname %s\n", number, dirname);
|
||||
} else {
|
||||
- init_irq_class_and_type(savedline, &tmp_info, number);
|
||||
info = add_new_irq(number, &tmp_info, NULL);
|
||||
}
|
||||
+ if (tmp_info.name) {
|
||||
+ free(tmp_info.name);
|
||||
+ tmp_info.name = NULL;
|
||||
+ }
|
||||
|
||||
if (info) {
|
||||
force_rebalance_irq(info, NULL);
|
||||
log(TO_CONSOLE, LOG_INFO, "new IRQ %d added into rebalance list\n", number);
|
||||
} else {
|
||||
need_rescan = 1;
|
||||
+ free(savedline);
|
||||
break;
|
||||
}
|
||||
}
|
||||
+ free(savedline);
|
||||
info->existing = 1;
|
||||
|
||||
if (ban_pci_assigned_irq) {
|
||||
diff --git a/rules_config.c b/rules_config.c
|
||||
index 767e9e1..9313fc6 100644
|
||||
--- a/rules_config.c
|
||||
+++ b/rules_config.c
|
||||
@@ -43,6 +43,10 @@ void set_usr_irq_policy(char *name, struct irq_info *info)
|
||||
{
|
||||
USER_IRQ_POLICY *user_policy;
|
||||
|
||||
+ if (user_policy_list == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
user_policy = get_usr_irq_policy(name);
|
||||
if (user_policy != NULL) {
|
||||
if (user_policy->numa_node_set) {
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
From d4fc2426a38728b912ec1acf3a3a990636e48b1d Mon Sep 17 00:00:00 2001
|
||||
From: liuchao173 <liuchao173@huawei.com>
|
||||
Date: Fri, 1 Nov 2019 02:42:19 +0000
|
||||
Subject: [PATCH] irqbalance: fix new msi irq hasnot been added to rebalance list
|
||||
|
||||
fix new msi irq hasnot been added to rebalance_irq_list
|
||||
---
|
||||
procinterrupts.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/procinterrupts.c b/procinterrupts.c
|
||||
index 64b462a..33e72ea 100644
|
||||
--- a/procinterrupts.c
|
||||
+++ b/procinterrupts.c
|
||||
@@ -405,6 +405,7 @@ void parse_proc_interrupts(void)
|
||||
if (lookup != NULL) {
|
||||
lookup->existing = 1;
|
||||
set_usr_irq_policy(tmp_info.name, lookup);
|
||||
+ info = lookup;
|
||||
}
|
||||
log(TO_CONSOLE, LOG_INFO, "new IRQ %d added into database, dirname %s\n", number, dirname);
|
||||
} else {
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,79 +0,0 @@
|
||||
From f04d6488c12e215e2302b44c77bf66fce4950aef Mon Sep 17 00:00:00 2001
|
||||
From: liuchao <liuchao173@huawei.com>
|
||||
Date: Thu, 5 Dec 2019 15:28:14 +0800
|
||||
Subject: [PATCH] fix sleep interval when sleep_interval is changed by
|
||||
socket
|
||||
|
||||
currently, in scan, irqbalance compare sleep_interval's address to decide if sleep_interval is changed, accutually this judgement is always false now.
|
||||
|
||||
Signed-off-by: liuchao <liuchao173@huawei.com>
|
||||
---
|
||||
hint_verify.c | 10 ++++++----
|
||||
irqbalance.c | 5 +++--
|
||||
2 files changed, 9 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/hint_verify.c b/hint_verify.c
|
||||
index b3175ae..0718078 100644
|
||||
--- a/hint_verify.c
|
||||
+++ b/hint_verify.c
|
||||
@@ -15,6 +15,7 @@
|
||||
extern int keep_going;
|
||||
extern GMainLoop *main_loop;
|
||||
extern gboolean scan();
|
||||
+extern int last_interval;
|
||||
|
||||
int real_sleep_interval;
|
||||
int sleep_interval_count;
|
||||
diff --git a/hint_verify.c b/hint_verify.c
|
||||
index b3175ae..4258557 100644
|
||||
--- a/hint_verify.c
|
||||
+++ b/hint_verify.c
|
||||
@@ -84,7 +84,7 @@ void update_affinity_hint(struct irq_info *info, void *data __attribute__((unuse
|
||||
* 1. scan opration for irq balancing;
|
||||
* 2. poll irq affinity hint changes for quickly applying them.
|
||||
*/
|
||||
-gboolean poll_hint_affinity_and_scan(gpointer data)
|
||||
+gboolean poll_hint_affinity_and_scan(gpointer data __attribute__((unused)))
|
||||
{
|
||||
gboolean need_verify_flag = FALSE;
|
||||
gboolean need_scan_flag = FALSE;
|
||||
@@ -118,9 +118,10 @@ gboolean poll_hint_affinity_and_scan(gpointer data)
|
||||
}
|
||||
}
|
||||
|
||||
- if (data != &real_sleep_interval) {
|
||||
- data = &real_sleep_interval;
|
||||
- g_timeout_add_seconds(real_sleep_interval, poll_hint_affinity_and_scan, data);
|
||||
+ 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;
|
||||
}
|
||||
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index 3fc00db..05eaa29 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -67,6 +67,7 @@ long HZ;
|
||||
int sleep_interval = SLEEP_INTERVAL;
|
||||
int hint_enabled = 0;
|
||||
int poll_hint_interval = SLEEP_INTERVAL / 5;
|
||||
+int last_interval;
|
||||
GMainLoop *main_loop;
|
||||
|
||||
char *banned_cpumask_from_ui = NULL;
|
||||
@@ -641,8 +642,8 @@ int main(int argc, char** argv)
|
||||
log(TO_ALL, LOG_INFO, "irqbalance start scan.\n");
|
||||
update_interval_and_count();
|
||||
main_loop = g_main_loop_new(NULL, FALSE);
|
||||
- int *last_interval = &real_sleep_interval;
|
||||
- g_timeout_add_seconds(real_sleep_interval, poll_hint_affinity_and_scan, last_interval);
|
||||
+ 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);
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,64 +0,0 @@
|
||||
From f4d052d7b210612a7ffbdd7c3cfbce213c9a0e21 Mon Sep 17 00:00:00 2001
|
||||
From: liuchao173 <liuchao173@huawei.com>
|
||||
Date: Fri, 8 Nov 2019 08:47:43 +0000
|
||||
Subject: [PATCH] irqbalance: fix strcat may cause buffer overrun
|
||||
|
||||
when the sum length of irq_name and saveptr is more than PATH_MAX, strcat will cause buffer overrun
|
||||
---
|
||||
procinterrupts.c | 26 ++++++++++++++++++--------
|
||||
1 file changed, 18 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/procinterrupts.c b/procinterrupts.c
|
||||
index 373d8b5..0b24b56 100644
|
||||
--- a/procinterrupts.c
|
||||
+++ b/procinterrupts.c
|
||||
@@ -205,6 +205,7 @@ static void init_irq_class_and_type(char *savedline, struct irq_info *info, int
|
||||
int is_xen_dyn = 0;
|
||||
#ifdef AARCH64
|
||||
char *tmp = NULL;
|
||||
+ char irq_fullname_valid = 1;
|
||||
char irq_fullname[PATH_MAX] = {0};
|
||||
#endif
|
||||
|
||||
@@ -236,12 +237,16 @@ static void init_irq_class_and_type(char *savedline, struct irq_info *info, int
|
||||
if (tmp)
|
||||
*tmp = 0;
|
||||
|
||||
- strcat(irq_fullname, irq_name);
|
||||
- strcat(irq_fullname, " ");
|
||||
- strcat(irq_fullname, savedptr);
|
||||
- tmp = strchr(irq_fullname, '\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;
|
||||
@@ -251,8 +256,13 @@ static void init_irq_class_and_type(char *savedline, struct irq_info *info, int
|
||||
info->class = IRQ_VIRT_EVENT;
|
||||
} else {
|
||||
#ifdef AARCH64
|
||||
- irq_name = irq_fullname;
|
||||
- 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.19.1
|
||||
|
||||
@ -1,471 +0,0 @@
|
||||
From 1ca314651ddc31cd52ef67893fdd7aac43ea5201 Mon Sep 17 00:00:00 2001
|
||||
From: zhengshaoyu <zhengshaoyu@huawei.com>
|
||||
Date: Thu, 22 Jun 2017 04:39:00 +0000
|
||||
Subject: [PATCH] irqbalance: bugfix popen and pclose
|
||||
|
||||
[Changelog]: bugfix popen and pclose
|
||||
[Author]:zhengshaoyu
|
||||
|
||||
Date: Sun, 17 Mar 2019 20:07:28 -0400
|
||||
|
||||
---
|
||||
classify.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++-------
|
||||
irqbalance.c | 2 +-
|
||||
irqbalance.h | 5 +++
|
||||
procinterrupts.c | 112 +++++++++++++++++++++++++++++++------------------
|
||||
types.h | 1 +
|
||||
5 files changed, 190 insertions(+), 56 deletions(-)
|
||||
|
||||
diff --git a/classify.c b/classify.c
|
||||
index 9868633..30a8d2a 100644
|
||||
--- a/classify.c
|
||||
+++ b/classify.c
|
||||
@@ -66,6 +66,8 @@ struct pci_info {
|
||||
#define PCI_SUB_DEVICE_EMC_0568 0x0568
|
||||
#define PCI_SUB_DEVICE_EMC_dd00 0xdd00
|
||||
|
||||
+extern void force_rebalance_irq(struct irq_info *info, void *data __attribute__((unused)));
|
||||
+
|
||||
/*
|
||||
* Apply software workarounds for some special devices
|
||||
*
|
||||
@@ -562,11 +564,13 @@ static int check_for_irq_ban(char *path __attribute__((unused)), int irq, GList
|
||||
/*
|
||||
* Check to see if we banned module which the irq belongs to.
|
||||
*/
|
||||
- entry = g_list_find_custom(proc_interrupts, &find, compare_ints);
|
||||
- if (entry) {
|
||||
- res = entry->data;
|
||||
- if (check_for_module_ban(res->name))
|
||||
- return 1;
|
||||
+ if (proc_interrupts) {
|
||||
+ entry = g_list_find_custom(proc_interrupts, &find, compare_ints);
|
||||
+ if (entry) {
|
||||
+ res = entry->data;
|
||||
+ if (check_for_module_ban(res->name))
|
||||
+ return 1;
|
||||
+ }
|
||||
}
|
||||
|
||||
#ifdef INCLUDE_BANSCRIPT
|
||||
@@ -605,13 +609,14 @@ static int check_for_irq_ban(char *path __attribute__((unused)), int irq, GList
|
||||
/*
|
||||
* 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)
|
||||
+struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list)
|
||||
{
|
||||
struct dirent *entry;
|
||||
DIR *msidir;
|
||||
FILE *fd;
|
||||
int irqnum;
|
||||
- struct irq_info *new, hint;
|
||||
+ struct irq_info *new = NULL;
|
||||
+ struct irq_info hint;
|
||||
char path[PATH_MAX];
|
||||
char devpath[PATH_MAX];
|
||||
struct user_irq_policy pol;
|
||||
@@ -635,7 +640,7 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
|
||||
if (new)
|
||||
continue;
|
||||
get_irq_user_policy(devpath, irqnum, &pol);
|
||||
- if ((pol.ban == 1) || (check_for_irq_ban(devpath, irqnum, tmp_irqs))) {
|
||||
+ if ((pol.ban == 1) || (check_for_irq_ban(devpath, irqnum, tmp_list))) {
|
||||
add_banned_irq(irqnum, &banned_irqs);
|
||||
continue;
|
||||
}
|
||||
@@ -647,13 +652,13 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
|
||||
}
|
||||
} while (entry != NULL);
|
||||
closedir(msidir);
|
||||
- return;
|
||||
+ return new;
|
||||
}
|
||||
|
||||
sprintf(path, "%s/%s/irq", SYSPCI_DIR, dirname);
|
||||
fd = fopen(path, "r");
|
||||
if (!fd)
|
||||
- return;
|
||||
+ return new;
|
||||
if (fscanf(fd, "%d", &irqnum) < 0)
|
||||
goto done;
|
||||
|
||||
@@ -670,7 +675,7 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
|
||||
if (new)
|
||||
goto done;
|
||||
get_irq_user_policy(devpath, irqnum, &pol);
|
||||
- if ((pol.ban == 1) || (check_for_irq_ban(path, irqnum, tmp_irqs))) {
|
||||
+ if ((pol.ban == 1) || (check_for_irq_ban(path, irqnum, tmp_list))) {
|
||||
add_banned_irq(irqnum, &banned_irqs);
|
||||
goto done;
|
||||
}
|
||||
@@ -684,7 +689,56 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
|
||||
|
||||
done:
|
||||
fclose(fd);
|
||||
- return;
|
||||
+ return new;
|
||||
+}
|
||||
+
|
||||
+void find_irq_dev_path(int irq, char *dirname, int length)
|
||||
+{
|
||||
+ char cmd[PATH_MAX + 128];
|
||||
+ FILE *output = NULL;
|
||||
+ char path[PATH_MAX];
|
||||
+ char buffer[128];
|
||||
+ char *brc = NULL;
|
||||
+
|
||||
+ memset(dirname, 0, length);
|
||||
+ /* Return defaults if irq is 0 */
|
||||
+ if (!irq)
|
||||
+ return;
|
||||
+
|
||||
+ sprintf(path, "%s/*/msi_irqs", SYSPCI_DIR);
|
||||
+ sprintf(cmd, "exec find %s -type f -name %d | awk -F '/' '{print $6}' ", path, irq);
|
||||
+ output = popen(cmd, "r");
|
||||
+ if (!output) {
|
||||
+ log(TO_CONSOLE, LOG_WARNING, "Unable to execute IRQ %d path %s\n", irq, path);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ brc = fgets(buffer, 128, output);
|
||||
+ if (brc) {
|
||||
+ log(TO_CONSOLE, LOG_INFO, "msi_irqs IRQ %d dirname is %s\n", irq, brc);
|
||||
+ strncpy(dirname, brc, length);
|
||||
+ pclose(output);
|
||||
+ return;
|
||||
+ }
|
||||
+ pclose(output);
|
||||
+
|
||||
+ sprintf(path, "%s/*/irq", SYSPCI_DIR);
|
||||
+ sprintf(cmd, "exec grep -w %d %s | awk -F '/' '{print $6}' ", irq, path);
|
||||
+ output = popen(cmd, "r");
|
||||
+ if (!output) {
|
||||
+ log(TO_CONSOLE, LOG_WARNING, "Unable to execute IRQ %d path %s\n", irq, path);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ brc = fgets(buffer, 128, output);
|
||||
+ if (brc) {
|
||||
+ log(TO_CONSOLE, LOG_INFO, "IRQ %d dirname is %s\n", irq, brc);
|
||||
+ strncpy(dirname, brc, length);
|
||||
+ pclose(output);
|
||||
+ return;
|
||||
+ }
|
||||
+ pclose(output);
|
||||
+
|
||||
}
|
||||
|
||||
static void free_irq(struct irq_info *info, void *data __attribute__((unused)))
|
||||
@@ -692,6 +750,42 @@ static void free_irq(struct irq_info *info, void *data __attribute__((unused)))
|
||||
free(info);
|
||||
}
|
||||
|
||||
+static void remove_no_existing_irq(struct irq_info *info, void *data __attribute__((unused)))
|
||||
+{
|
||||
+ GList *entry = NULL;
|
||||
+
|
||||
+ if (info->existing) {
|
||||
+ 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(banned_irqs, info, compare_ints);
|
||||
+ if (entry)
|
||||
+ banned_irqs = g_list_delete_link(banned_irqs, 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);
|
||||
+}
|
||||
+
|
||||
void free_irq_db(void)
|
||||
{
|
||||
for_each_irq(NULL, free_irq, NULL);
|
||||
@@ -711,14 +805,14 @@ void free_cl_opts(void)
|
||||
g_list_free(banned_irqs);
|
||||
}
|
||||
|
||||
-static void add_new_irq(int irq, struct irq_info *hint, GList *proc_interrupts)
|
||||
+struct irq_info *add_new_irq(int irq, struct irq_info *hint, GList *proc_interrupts)
|
||||
{
|
||||
- struct irq_info *new;
|
||||
+ struct irq_info *new = NULL;
|
||||
struct user_irq_policy pol;
|
||||
|
||||
new = get_irq_info(irq);
|
||||
if (new)
|
||||
- return;
|
||||
+ return new;
|
||||
|
||||
/* Set NULL devpath for the irq has no sysfs entries */
|
||||
get_irq_user_policy(NULL, irq, &pol);
|
||||
@@ -730,6 +824,8 @@ static void add_new_irq(int irq, struct irq_info *hint, GList *proc_interrupts)
|
||||
|
||||
if (!new)
|
||||
log(TO_CONSOLE, LOG_WARNING, "add_new_irq: Failed to add irq %d\n", irq);
|
||||
+
|
||||
+ return new;
|
||||
}
|
||||
|
||||
static void add_missing_irq(struct irq_info *info, void *attr)
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index 2f699b8..e375a1a 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -238,7 +238,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 8d5b329..73737ed 100644
|
||||
--- a/irqbalance.h
|
||||
+++ b/irqbalance.h
|
||||
@@ -107,6 +107,10 @@ extern void free_cl_opts(void);
|
||||
extern void add_cl_banned_module(char *modname);
|
||||
#define irq_numa_node(irq) ((irq)->numa_node)
|
||||
|
||||
+extern struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list);
|
||||
+extern void find_irq_dev_path(int irq, char *dirname, int length);
|
||||
+extern struct irq_info *add_new_irq(int irq, struct irq_info *hint, GList *proc_interrupts);
|
||||
+extern void clear_no_existing_irqs(void);
|
||||
|
||||
/*
|
||||
* Generic object functions
|
||||
diff --git a/procinterrupts.c b/procinterrupts.c
|
||||
index eb84a1c..d384860 100644
|
||||
--- a/procinterrupts.c
|
||||
+++ b/procinterrupts.c
|
||||
@@ -142,6 +142,52 @@ static void guess_arm_irq_hints(char *name, struct irq_info *info)
|
||||
|
||||
}
|
||||
#endif
|
||||
+static 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
|
||||
+ /* 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;
|
||||
+ 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->name = strdupa(irq_mod);
|
||||
+}
|
||||
+
|
||||
|
||||
GList* collect_full_irq_list()
|
||||
{
|
||||
@@ -149,10 +187,6 @@ GList* collect_full_irq_list()
|
||||
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)
|
||||
@@ -168,7 +206,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;
|
||||
@@ -188,45 +222,13 @@ 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;
|
||||
c++;
|
||||
number = strtoul(line, NULL, 10);
|
||||
|
||||
info = calloc(sizeof(struct irq_info), 1);
|
||||
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);
|
||||
@@ -230,6 +235,14 @@ GList* collect_full_irq_list()
|
||||
return tmp_list;
|
||||
}
|
||||
|
||||
+/* parsing /proc/interrrupts to detect whether removed and reinserted IRQ
|
||||
+* device happened or not. If yes, then IRQs have to be rescanning again;
|
||||
+* However, in order to keep no impact on online running IRQs performance stable,
|
||||
+* removed and reinserted IRQ added back into rebalance_irq_list,
|
||||
+* for irq load re-calculation instead of trigger rescanning all IRQs.
|
||||
+* specially, when a new IRQ is detected, it has to be checked what devpath is,
|
||||
+* then it is added into database accordingly.
|
||||
+*/
|
||||
void parse_proc_interrupts(void)
|
||||
{
|
||||
FILE *file;
|
||||
@@ -253,7 +266,9 @@ void parse_proc_interrupts(void)
|
||||
uint64_t count;
|
||||
char *c, *c2;
|
||||
struct irq_info *info;
|
||||
+ struct irq_info tmp_info;
|
||||
char savedline[1024];
|
||||
+ char dirname[PATH_MAX] = {'\0'};
|
||||
|
||||
if (getline(&line, &size, file)==0)
|
||||
break;
|
||||
@@ -281,9 +296,24 @@ void parse_proc_interrupts(void)
|
||||
|
||||
info = get_irq_info(number);
|
||||
if (!info) {
|
||||
- need_rescan = 1;
|
||||
- break;
|
||||
+ find_irq_dev_path(number, dirname, PATH_MAX);
|
||||
+ if (strlen(dirname) > 0) {
|
||||
+ info = build_one_dev_entry(dirname, NULL);
|
||||
+ log(TO_CONSOLE, LOG_INFO, "new IRQ %d added into database, dirname %s\n", number, dirname);
|
||||
+ } else {
|
||||
+ init_irq_class_and_type(savedline, &tmp_info, number);
|
||||
+ info = add_new_irq(number, &tmp_info, NULL);
|
||||
+ }
|
||||
+
|
||||
+ if (info) {
|
||||
+ force_rebalance_irq(info, NULL);
|
||||
+ log(TO_CONSOLE, LOG_INFO, "new IRQ %d added into rebalance list\n", number);
|
||||
+ } else {
|
||||
+ need_rescan = 1;
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
+ info->existing = 1;
|
||||
|
||||
count = 0;
|
||||
cpunr = 0;
|
||||
@@ -307,17 +337,19 @@ void parse_proc_interrupts(void)
|
||||
* cause an overflow and IRQ won't be rebalanced again
|
||||
*/
|
||||
if (count < info->irq_count) {
|
||||
- need_rescan = 1;
|
||||
- break;
|
||||
+ log(TO_CONSOLE, LOG_INFO, "Removed and reinserted IRQ %d added into rebalance list\n", number);
|
||||
+ force_rebalance_irq(info, NULL);
|
||||
}
|
||||
|
||||
- info->last_irq_count = info->irq_count;
|
||||
+ info->last_irq_count = info->irq_count;
|
||||
info->irq_count = count;
|
||||
|
||||
/* is interrupt MSI based? */
|
||||
if ((info->type == IRQ_TYPE_MSI) || (info->type == IRQ_TYPE_MSIX))
|
||||
msi_found_in_sysfs = 1;
|
||||
- }
|
||||
+ }
|
||||
+ clear_no_existing_irqs();
|
||||
+
|
||||
if ((proc_int_has_msi) && (!msi_found_in_sysfs) && (!need_rescan)) {
|
||||
log(TO_ALL, LOG_WARNING, "WARNING: MSI interrupts found in /proc/interrupts\n");
|
||||
log(TO_ALL, LOG_WARNING, "But none found in sysfs, you need to update your kernel\n");
|
||||
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;
|
||||
};
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
From a8ad43cc682e268c9f35633a15636222b6933649 Mon Sep 17 00:00:00 2001
|
||||
From:Xia Shuang <xiashuang1@huawei.com>
|
||||
Date: Thu, 29 Aug 2019 14:31:25 +0800
|
||||
Subject: [PATCH] fix guess_arm_irq_hints
|
||||
|
||||
in aarch64, irqbalance will guess
|
||||
irq's class and type according to irq's name, but it did't work properly now,
|
||||
a irq's name will be matched twice and class will always be IRQ_OTHER. such
|
||||
as a nic interrupt, the debug log will be:
|
||||
IRQ eth3-tx0 (109) guessed as class 5
|
||||
IRQ eth3-tx0 (109) guessed as class 0
|
||||
irq's class should be IRQ_GBETH but is IRQ_GBETH.
|
||||
---
|
||||
procinterrupts.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/procinterrupts.c b/procinterrupts.c
|
||||
index 2088c58..3898b10 100644
|
||||
--- a/procinterrupts.c
|
||||
+++ b/procinterrupts.c
|
||||
@@ -137,6 +137,7 @@ static void guess_arm_irq_hints(char *name, struct irq_info *info)
|
||||
if (matches[i].refine_match)
|
||||
matches[i].refine_match(name, info);
|
||||
log(TO_ALL, LOG_DEBUG, "IRQ %s(%d) guessed as class %d\n", name, info->irq,info->class);
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.21.0.windows.1
|
||||
@ -1,125 +0,0 @@
|
||||
From 948425c293615a9f4a30e9049d6ca4380c7b6c83 Mon Sep 17 00:00:00 2001
|
||||
From: hejingxian <hejingxian@huawei.com>
|
||||
Date: Wed, 13 Nov 2019 13:13:28 +0800
|
||||
Subject: [PATCH] bugfix: irqbalance: fix wrong pid value in pid file
|
||||
|
||||
If irqbalance is killed by SIGKILL or SIGTERM,
|
||||
after restarting irqbalance, the pid in pid file is
|
||||
wrong, that's because the way we forbid starting
|
||||
multiple irqbalance instances is wrong.
|
||||
|
||||
Here we use fcntl to lock pid file to forbid another instance
|
||||
been launched.
|
||||
|
||||
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
||||
---
|
||||
irqbalance.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------
|
||||
1 file changed, 75 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index 18cd7de..467e968 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -560,6 +560,78 @@ int init_socket()
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int create_lock_pidfile(const char *lockfile)
|
||||
+{
|
||||
+ struct flock lock = { 0 };
|
||||
+ char pid_s[16] = { 0 };
|
||||
+ int lf = 0;
|
||||
+ int err = -1;
|
||||
+
|
||||
+ lf = open(lockfile, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
|
||||
+ if (lf == -1) {
|
||||
+ err = -errno;
|
||||
+ log(TO_ALL, LOG_WARNING, "irqbalance (%u): Can't create lock file.\n",
|
||||
+ getpid());
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+retry_fcntl:
|
||||
+ lock.l_type = F_WRLCK;
|
||||
+ lock.l_start = 0;
|
||||
+ lock.l_whence = SEEK_SET;
|
||||
+ lock.l_len = 0;
|
||||
+ if (fcntl (lf, F_SETLK, &lock) == -1) {
|
||||
+ err = -errno;
|
||||
+ switch (errno) {
|
||||
+ case EINTR:
|
||||
+ goto retry_fcntl;
|
||||
+ case EAGAIN:
|
||||
+ case EACCES:
|
||||
+ log(TO_ALL, LOG_WARNING, "irqbalance (%u): Another instance is"
|
||||
+ " already running, errno:%d.\n", getpid(), errno);
|
||||
+ goto error_close;
|
||||
+ default:
|
||||
+ log(TO_ALL, LOG_WARNING, "irqbalance (%u): Can't aquire lock."
|
||||
+ " errno %d.\n", getpid(), errno);
|
||||
+ goto error_close;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (ftruncate(lf, 0) == -1) {
|
||||
+ err = -errno;
|
||||
+ log(TO_ALL, LOG_WARNING, "irqbalance (%u): Can't truncate lock file."
|
||||
+ " errno: %d.\n", getpid(), errno);
|
||||
+ goto error_close_unlink;
|
||||
+ }
|
||||
+ if (snprintf(pid_s, sizeof(pid_s), "%u\n", getpid()) < 0) {
|
||||
+ log(TO_ALL, LOG_WARNING, "irqbalance (%u): Can't printf pid string.\n", getpid());
|
||||
+ err = -1;
|
||||
+ goto error_close_unlink;
|
||||
+ }
|
||||
+
|
||||
+retry_write:
|
||||
+ if ((size_t)write(lf, pid_s, strlen (pid_s)) != strlen (pid_s)) {
|
||||
+ err = -errno;
|
||||
+ if (errno == EINTR) {
|
||||
+ goto retry_write;
|
||||
+ } else {
|
||||
+ log(TO_ALL, LOG_WARNING, "irqbalance (%u): Can't write pid to lock"
|
||||
+ " file. errno %d\n", getpid(), errno);
|
||||
+ goto error_close_unlink;
|
||||
+ }
|
||||
+ }
|
||||
+ close(lf);
|
||||
+ return 0;
|
||||
+
|
||||
+error_close_unlink:
|
||||
+ (void) unlink(lockfile);
|
||||
+
|
||||
+error_close:
|
||||
+ close(lf);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
sigset_t sigset, old_sigset;
|
||||
@@ -652,17 +724,12 @@ int main(int argc, char** argv)
|
||||
}
|
||||
|
||||
if (!foreground_mode) {
|
||||
- int pidfd = -1;
|
||||
if (daemon(0,0))
|
||||
exit(EXIT_FAILURE);
|
||||
/* Write pidfile */
|
||||
- if (pidfile && (pidfd = open(pidfile,
|
||||
- O_WRONLY | O_CREAT | O_EXCL | O_TRUNC,
|
||||
- S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) >= 0) {
|
||||
- char str[16];
|
||||
- snprintf(str, sizeof(str), "%u\n", getpid());
|
||||
- write(pidfd, str, strlen(str));
|
||||
- close(pidfd);
|
||||
+ if (pidfile && create_lock_pidfile(pidfile) < 0) {
|
||||
+ ret = EXIT_FAILURE;
|
||||
+ goto out;
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,118 +0,0 @@
|
||||
From 74970054568728d11dbbb160e0c5cacdfeb07ff3 Mon Sep 17 00:00:00 2001
|
||||
From: liuchao <liuchao173@huawei.com>
|
||||
Date: Fri, 11 Oct 2019 07:49:55 +0000
|
||||
Subject: [PATCH] irqbalance: make the return value of getline() handled correct
|
||||
|
||||
getline() will return -1 when fail, so make the return value handle correct.
|
||||
|
||||
---
|
||||
activate.c | 2 +-
|
||||
cputree.c | 6 +++---
|
||||
procinterrupts.c | 12 ++++++------
|
||||
3 files changed, 10 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/activate.c b/activate.c
|
||||
index ad60fde..87336f4 100644
|
||||
--- a/activate.c
|
||||
+++ b/activate.c
|
||||
@@ -47,7 +47,7 @@ static int check_affinity(struct irq_info *info, cpumask_t applied_mask)
|
||||
file = fopen(buf, "r");
|
||||
if (!file)
|
||||
return 1;
|
||||
- if (getline(&line, &size, file)==0) {
|
||||
+ if (getline(&line, &size, file)<=0) {
|
||||
free(line);
|
||||
fclose(file);
|
||||
return 1;
|
||||
diff --git a/cputree.c b/cputree.c
|
||||
index 0dbb5c8..51ef357 100644
|
||||
--- a/cputree.c
|
||||
+++ b/cputree.c
|
||||
@@ -324,7 +324,7 @@ static void do_one_cpu(char *path)
|
||||
if (file) {
|
||||
char *line = NULL;
|
||||
size_t size = 0;
|
||||
- if (getline(&line, &size, file))
|
||||
+ if (getline(&line, &size, file) > 0)
|
||||
cpumask_parse_user(line, strlen(line), package_mask);
|
||||
fclose(file);
|
||||
free(line);
|
||||
@@ -336,7 +336,7 @@ static void do_one_cpu(char *path)
|
||||
if (file) {
|
||||
char *line = NULL;
|
||||
size_t size = 0;
|
||||
- if (getline(&line, &size, file))
|
||||
+ if (getline(&line, &size, file) > 0)
|
||||
packageid = strtoul(line, NULL, 10);
|
||||
fclose(file);
|
||||
free(line);
|
||||
@@ -369,7 +369,7 @@ static void do_one_cpu(char *path)
|
||||
if (file) {
|
||||
char *line = NULL;
|
||||
size_t size = 0;
|
||||
- if (getline(&line, &size, file))
|
||||
+ if (getline(&line, &size, file) > 0)
|
||||
cpumask_parse_user(line, strlen(line), cache_mask);
|
||||
fclose(file);
|
||||
free(line);
|
||||
diff --git a/procinterrupts.c b/procinterrupts.c
|
||||
index 18b3ceb..c32c1b2 100644
|
||||
--- a/procinterrupts.c
|
||||
+++ b/procinterrupts.c
|
||||
@@ -262,7 +262,7 @@ GList* collect_full_irq_list()
|
||||
return NULL;
|
||||
|
||||
/* first line is the header we don't need; nuke it */
|
||||
- if (getline(&line, &size, file)==0) {
|
||||
+ if (getline(&line, &size, file)<=0) {
|
||||
free(line);
|
||||
fclose(file);
|
||||
return NULL;
|
||||
@@ -274,7 +274,7 @@ GList* collect_full_irq_list()
|
||||
char *c;
|
||||
char *savedline = NULL;
|
||||
|
||||
- if (getline(&line, &size, file)==0)
|
||||
+ if (getline(&line, &size, file)<=0)
|
||||
break;
|
||||
|
||||
/* lines with letters in front are special, like NMI count. Ignore */
|
||||
@@ -349,7 +349,7 @@ void parse_proc_interrupts(void)
|
||||
return;
|
||||
|
||||
/* first line is the header we don't need; nuke it */
|
||||
- if (getline(&line, &size, file)==0) {
|
||||
+ if (getline(&line, &size, file)<=0) {
|
||||
free(line);
|
||||
fclose(file);
|
||||
return;
|
||||
@@ -365,7 +365,7 @@ void parse_proc_interrupts(void)
|
||||
char savedline[1024];
|
||||
char dirname[PATH_MAX] = {'\0'};
|
||||
|
||||
- if (getline(&line, &size, file)==0)
|
||||
+ if (getline(&line, &size, file)<=0)
|
||||
break;
|
||||
|
||||
if (!proc_int_has_msi)
|
||||
@@ -579,7 +579,7 @@ void parse_proc_stat(void)
|
||||
}
|
||||
|
||||
/* first line is the header we don't need; nuke it */
|
||||
- if (getline(&line, &size, file)==0) {
|
||||
+ if (getline(&line, &size, file)<=0) {
|
||||
free(line);
|
||||
log(TO_ALL, LOG_WARNING, "WARNING read /proc/stat. balancing is broken\n");
|
||||
fclose(file);
|
||||
@@ -588,7 +588,7 @@ void parse_proc_stat(void)
|
||||
|
||||
cpucount = 0;
|
||||
while (!feof(file)) {
|
||||
- if (getline(&line, &size, file)==0)
|
||||
+ if (getline(&line, &size, file)<=0)
|
||||
break;
|
||||
|
||||
if (!strstr(line, "cpu"))
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,27 +0,0 @@
|
||||
From cea147fc56b018266ac3235b82cdaf7d0ba74628 Mon Sep 17 00:00:00 2001
|
||||
From: hejingxian <hejingxian@huawei.com>
|
||||
Date: Fri, 10 Jan 2020 15:36:57 +0800
|
||||
Subject: [PATCH] prevent version cmd need an argument
|
||||
|
||||
In order to prevent the version cmd need an argument,
|
||||
the option 'V' can't be followed by ':'.
|
||||
---
|
||||
irqbalance.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index 15fb0fe..f182b3c 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -133,7 +133,7 @@ static void parse_command_line(int argc, char **argv)
|
||||
unsigned long val;
|
||||
|
||||
while ((opt = getopt_long(argc, argv,
|
||||
- "odfji:p:s:c:b:l:m:t:V:h:v:r:ne:g:",
|
||||
+ "odfjVni:p:s:c:b:l:m:t:h:v:r:e:g:",
|
||||
lopts, &longind)) != -1) {
|
||||
|
||||
switch(opt) {
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,151 +0,0 @@
|
||||
From 21b69dd5d3212026881825901442a51eeecd3dad Mon Sep 17 00:00:00 2001
|
||||
From: Yun Wu <wuyun.wu@huawei.com>
|
||||
Date: Tue, 25 Aug 2015 19:47:58 +0800
|
||||
Subject: [PATCH] use policy prior to the default values
|
||||
|
||||
Currently user-defined policies against non-PCI devices' interrupts
|
||||
are not working properly.
|
||||
|
||||
For example, when trying to set "balance_level=core" for a non-PCI
|
||||
device interrupt which is classified as "other", will result in
|
||||
the level of "package" because overrided in add_new_irq().
|
||||
|
||||
This patch fixes this by restricting irq info initializations in
|
||||
add_one_irq_to_db(), which requires a change on its parameters.
|
||||
|
||||
Signed-off-by: Yun Wu <wuyun.wu@huawei.com>
|
||||
---
|
||||
classify.c | 49 +++++++++++++++++++++----------------------------
|
||||
1 file changed, 21 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/classify.c b/classify.c
|
||||
index df8a89b..9868633 100644
|
||||
--- a/classify.c
|
||||
+++ b/classify.c
|
||||
@@ -342,10 +342,10 @@ void add_cl_banned_module(char *modname)
|
||||
* related device. NULL devpath means no sysfs entries for
|
||||
* this irq.
|
||||
*/
|
||||
-static struct irq_info *add_one_irq_to_db(const char *devpath, int irq, struct user_irq_policy *pol)
|
||||
+static struct irq_info *add_one_irq_to_db(const char *devpath, struct irq_info *hint, struct user_irq_policy *pol)
|
||||
{
|
||||
- int irq_class = IRQ_OTHER;
|
||||
- struct irq_info *new, find;
|
||||
+ int irq = hint->irq;
|
||||
+ struct irq_info *new;
|
||||
int numa_node;
|
||||
char path[PATH_MAX];
|
||||
FILE *fd;
|
||||
@@ -357,8 +357,7 @@ static struct irq_info *add_one_irq_to_db(const char *devpath, int irq, struct u
|
||||
/*
|
||||
* First check to make sure this isn't a duplicate entry
|
||||
*/
|
||||
- find.irq = irq;
|
||||
- entry = g_list_find_custom(interrupts_db, &find, compare_ints);
|
||||
+ entry = g_list_find_custom(interrupts_db, hint, compare_ints);
|
||||
if (entry) {
|
||||
log(TO_CONSOLE, LOG_INFO, "DROPPING DUPLICATE ENTRY FOR IRQ %d on path %s\n", irq, devpath);
|
||||
return NULL;
|
||||
@@ -374,23 +373,24 @@ static struct irq_info *add_one_irq_to_db(const char *devpath, int irq, struct u
|
||||
return NULL;
|
||||
|
||||
new->irq = irq;
|
||||
- new->class = IRQ_OTHER;
|
||||
+ new->type = hint->type;
|
||||
+ new->class = hint->class;
|
||||
|
||||
interrupts_db = g_list_append(interrupts_db, new);
|
||||
|
||||
/* Some special irqs have NULL devpath */
|
||||
if (devpath != NULL) {
|
||||
/* Map PCI class code to irq class */
|
||||
- irq_class = get_irq_class(devpath);
|
||||
+ int irq_class = get_irq_class(devpath);
|
||||
if (irq_class < 0)
|
||||
goto get_numa_node;
|
||||
+ new->class = irq_class;
|
||||
}
|
||||
|
||||
- new->class = irq_class;
|
||||
if (pol->level >= 0)
|
||||
new->level = pol->level;
|
||||
else
|
||||
- new->level = map_class_to_level[irq_class];
|
||||
+ new->level = map_class_to_level[new->class];
|
||||
|
||||
get_numa_node:
|
||||
numa_node = -1;
|
||||
@@ -611,13 +611,16 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
|
||||
DIR *msidir;
|
||||
FILE *fd;
|
||||
int irqnum;
|
||||
- struct irq_info *new;
|
||||
+ struct irq_info *new, hint;
|
||||
char path[PATH_MAX];
|
||||
char devpath[PATH_MAX];
|
||||
struct user_irq_policy pol;
|
||||
|
||||
sprintf(path, "%s/%s/msi_irqs", SYSPCI_DIR, dirname);
|
||||
sprintf(devpath, "%s/%s", SYSPCI_DIR, dirname);
|
||||
+
|
||||
+ /* Needs to be further classified */
|
||||
+ hint.class = IRQ_OTHER;
|
||||
|
||||
msidir = opendir(path);
|
||||
|
||||
@@ -636,10 +639,11 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
|
||||
add_banned_irq(irqnum, &banned_irqs);
|
||||
continue;
|
||||
}
|
||||
- new = add_one_irq_to_db(devpath, irqnum, &pol);
|
||||
+ hint.irq = irqnum;
|
||||
+ hint.type = IRQ_TYPE_MSIX;
|
||||
+ new = add_one_irq_to_db(devpath, &hint, &pol);
|
||||
if (!new)
|
||||
continue;
|
||||
- new->type = IRQ_TYPE_MSIX;
|
||||
}
|
||||
} while (entry != NULL);
|
||||
closedir(msidir);
|
||||
@@ -671,10 +675,11 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
|
||||
goto done;
|
||||
}
|
||||
|
||||
- new = add_one_irq_to_db(devpath, irqnum, &pol);
|
||||
+ hint.irq = irqnum;
|
||||
+ hint.type = IRQ_TYPE_LEGACY;
|
||||
+ new = add_one_irq_to_db(devpath, &hint, &pol);
|
||||
if (!new)
|
||||
goto done;
|
||||
- new->type = IRQ_TYPE_LEGACY;
|
||||
}
|
||||
|
||||
done:
|
||||
@@ -721,22 +726,10 @@ static void add_new_irq(int irq, struct irq_info *hint, GList *proc_interrupts)
|
||||
add_banned_irq(irq, &banned_irqs);
|
||||
new = get_irq_info(irq);
|
||||
} else
|
||||
- new = add_one_irq_to_db(NULL, irq, &pol);
|
||||
+ new = add_one_irq_to_db(NULL, hint, &pol);
|
||||
|
||||
- if (!new) {
|
||||
+ if (!new)
|
||||
log(TO_CONSOLE, LOG_WARNING, "add_new_irq: Failed to add irq %d\n", irq);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- /*
|
||||
- * Override some of the new irq defaults here
|
||||
- */
|
||||
- if (hint) {
|
||||
- new->type = hint->type;
|
||||
- new->class = hint->class;
|
||||
- }
|
||||
-
|
||||
- new->level = map_class_to_level[new->class];
|
||||
}
|
||||
|
||||
static void add_missing_irq(struct irq_info *info, void *attr)
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,28 +0,0 @@
|
||||
From ff28f445a0808677c983d85a3b8331e4c090d70d Mon Sep 17 00:00:00 2001
|
||||
From: Neil Horman <nhorman@tuxdriver.com>
|
||||
Date: Tue, 29 May 2018 10:27:37 -0400
|
||||
Subject: [PATCH 084/112] classify: remove unused label
|
||||
|
||||
A recent refactoring in commit a4fbf90c2395ffa13176e8b002b7ef89a0ffc667
|
||||
left us with an unused label 'free' in rebuild_irq_db, just remove it
|
||||
|
||||
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
|
||||
---
|
||||
classify.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/classify.c b/classify.c
|
||||
index 3394823..3136fc3 100644
|
||||
--- a/classify.c
|
||||
+++ b/classify.c
|
||||
@@ -777,7 +777,6 @@ void rebuild_irq_db(void)
|
||||
|
||||
for_each_irq(tmp_irqs, add_missing_irq, interrupts_db);
|
||||
|
||||
-free:
|
||||
g_list_free_full(tmp_irqs, free);
|
||||
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,106 +0,0 @@
|
||||
From 22a40e9d0dd59ee58ff06d2b6360007e046d608f Mon Sep 17 00:00:00 2001
|
||||
From: liuchao173 <liuchao173@huawei.com>
|
||||
Date: Thu, 7 Nov 2019 09:33:47 +0000
|
||||
Subject: [PATCH 6/8] irqbalance: correct to use realloc() function
|
||||
|
||||
The man doc about realloc() say:
|
||||
"
|
||||
If realloc() fails the original block is left untouched; it is not
|
||||
freed or move
|
||||
"
|
||||
|
||||
So make the handling of realloc() function correctly.
|
||||
|
||||
In addition, there is another problem about parameter using in
|
||||
sock_handle(), it should be use the address of @setup instead of @setup.
|
||||
|
||||
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
|
||||
---
|
||||
irqbalance.c | 33 +++++++++++++++++++++++----------
|
||||
1 file changed, 23 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index c9378d0..cace4d8 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -321,14 +321,18 @@ gboolean scan(gpointer data)
|
||||
void get_irq_data(struct irq_info *irq, void *data)
|
||||
{
|
||||
char **irqdata = (char **)data;
|
||||
+ char *newptr = NULL;
|
||||
+
|
||||
if (!*irqdata)
|
||||
- *irqdata = calloc(24 + 1 + 11 + 20 + 20 + 11, 1);
|
||||
+ newptr = calloc(24 + 1 + 11 + 20 + 20 + 11, 1);
|
||||
else
|
||||
- *irqdata = realloc(*irqdata, strlen(*irqdata) + 24 + 1 + 11 + 20 + 20 + 11);
|
||||
+ newptr = realloc(*irqdata, strlen(*irqdata) + 24 + 1 + 11 + 20 + 20 + 11);
|
||||
|
||||
- if (!*irqdata)
|
||||
+ if (!newptr)
|
||||
return;
|
||||
|
||||
+ *irqdata = newptr;
|
||||
+
|
||||
sprintf(*irqdata + strlen(*irqdata),
|
||||
"IRQ %d LOAD %lu DIFF %lu CLASS %d ", irq->irq, irq->load,
|
||||
(irq->irq_count - irq->last_irq_count), irq->class);
|
||||
@@ -338,6 +342,7 @@ void get_object_stat(struct topo_obj *object, void *data)
|
||||
{
|
||||
char **stats = (char **)data;
|
||||
char *irq_data = NULL;
|
||||
+ char *newptr = NULL;
|
||||
size_t irqdlen;
|
||||
|
||||
if (g_list_length(object->interrupts) > 0) {
|
||||
@@ -355,13 +360,17 @@ void get_object_stat(struct topo_obj *object, void *data)
|
||||
* This should be adjusted if the string in the sprintf is changed
|
||||
*/
|
||||
if (!*stats) {
|
||||
- *stats = calloc(irqdlen + 31 + 11 + 20 + 11 + 1, 1);
|
||||
+ newptr = calloc(irqdlen + 31 + 11 + 20 + 11 + 1, 1);
|
||||
} else {
|
||||
- *stats = realloc(*stats, strlen(*stats) + irqdlen + 31 + 11 + 20 + 11 + 1);
|
||||
+ newptr = realloc(*stats, strlen(*stats) + irqdlen + 31 + 11 + 20 + 11 + 1);
|
||||
}
|
||||
|
||||
- if (!*stats)
|
||||
+ if (!newptr) {
|
||||
+ free(irq_data);
|
||||
return;
|
||||
+ }
|
||||
+
|
||||
+ *stats = newptr;
|
||||
|
||||
sprintf(*stats + strlen(*stats), "TYPE %d NUMBER %d LOAD %lu SAVE_MODE %d %s",
|
||||
object->obj_type, object->number, object->load,
|
||||
@@ -475,19 +484,23 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
||||
if (!strncmp(buff, "setup", strlen("setup"))) {
|
||||
char banned[512];
|
||||
char *setup = calloc(strlen("SLEEP ") + 11 + 1, 1);
|
||||
+ char *newptr = NULL;
|
||||
if (!setup)
|
||||
goto out_close;
|
||||
snprintf(setup, strlen("SLEEP ") + 11 + 1, "SLEEP %d ", sleep_interval);
|
||||
if(g_list_length(cl_banned_irqs) > 0) {
|
||||
- for_each_irq(cl_banned_irqs, get_irq_data, setup);
|
||||
+ for_each_irq(cl_banned_irqs, get_irq_data, &setup);
|
||||
}
|
||||
cpumask_scnprintf(banned, 512, banned_cpus);
|
||||
- setup = realloc(setup, strlen(setup) + strlen(banned) + 7 + 1);
|
||||
- if (!setup)
|
||||
- goto out_close;
|
||||
+ newptr = realloc(setup, strlen(setup) + strlen(banned) + 7 + 1);
|
||||
+ if (!newptr)
|
||||
+ goto out_free_setup;
|
||||
+
|
||||
+ setup = newptr;
|
||||
snprintf(setup + strlen(setup), strlen(banned) + 7 + 1,
|
||||
"BANNED %s", banned);
|
||||
send(sock, setup, strlen(setup), 0);
|
||||
+out_free_setup:
|
||||
free(setup);
|
||||
}
|
||||
|
||||
--
|
||||
2.19.1
|
||||
@ -1,91 +0,0 @@
|
||||
From 0605850acfce6f2ae23759618604f02f946026c2 Mon Sep 17 00:00:00 2001
|
||||
From: Neil Horman <nhorman@tuxdriver.com>
|
||||
Date: Tue, 29 May 2018 10:26:00 -0400
|
||||
Subject: [PATCH 129/152] cputree: adjust snprintf sizes to avoid gcc warnings
|
||||
|
||||
Gcc detects potential overruns in our use of PATH_MAX arrays when
|
||||
parsing cpu topology. This commit corrects those issues by ensuing that
|
||||
the print size is no longer than the array size in all cases
|
||||
|
||||
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
|
||||
---
|
||||
cputree.c | 21 ++++++++++++++-------
|
||||
1 file changed, 14 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/cputree.c b/cputree.c
|
||||
index d09af43..c88143f 100644
|
||||
--- a/cputree.c
|
||||
+++ b/cputree.c
|
||||
@@ -241,7 +241,8 @@ static struct topo_obj* add_cpu_to_cache_domain(struct topo_obj *cpu,
|
||||
|
||||
return cache;
|
||||
}
|
||||
-
|
||||
+
|
||||
+#define ADJ_SIZE(r,s) PATH_MAX-strlen(r)-strlen(#s)
|
||||
static void do_one_cpu(char *path)
|
||||
{
|
||||
struct topo_obj *cpu;
|
||||
@@ -256,7 +257,7 @@ static void do_one_cpu(char *path)
|
||||
unsigned int max_cache_index, cache_index, cache_stat;
|
||||
|
||||
/* skip offline cpus */
|
||||
- snprintf(new_path, PATH_MAX, "%s/online", path);
|
||||
+ snprintf(new_path, ADJ_SIZE(path,"/online"), "%s/online", path);
|
||||
file = fopen(new_path, "r");
|
||||
if (file) {
|
||||
char *line = NULL;
|
||||
@@ -299,7 +300,8 @@ static void do_one_cpu(char *path)
|
||||
|
||||
|
||||
/* try to read the package mask; if it doesn't exist assume solitary */
|
||||
- snprintf(new_path, PATH_MAX, "%s/topology/core_siblings", path);
|
||||
+ snprintf(new_path, ADJ_SIZE(path, "/topology/core_siblings"),
|
||||
+ "%s/topology/core_siblings", path);
|
||||
file = fopen(new_path, "r");
|
||||
cpu_set(cpu->number, package_mask);
|
||||
if (file) {
|
||||
@@ -311,7 +313,8 @@ static void do_one_cpu(char *path)
|
||||
free(line);
|
||||
}
|
||||
/* try to read the package id */
|
||||
- snprintf(new_path, PATH_MAX, "%s/topology/physical_package_id", path);
|
||||
+ snprintf(new_path, ADJ_SIZE(path, "/topology/physical_package_id"),
|
||||
+ "%s/topology/physical_package_id", path);
|
||||
file = fopen(new_path, "r");
|
||||
if (file) {
|
||||
char *line = NULL;
|
||||
@@ -329,7 +332,9 @@ static void do_one_cpu(char *path)
|
||||
cache_index = 1;
|
||||
do {
|
||||
struct stat sb;
|
||||
- snprintf(new_path, PATH_MAX, "%s/cache/index%d/shared_cpu_map", path, cache_index);
|
||||
+ /* Extra 10 subtraction is for the max character length of %d */
|
||||
+ snprintf(new_path, ADJ_SIZE(path, "/cache/index%d/shared_cpu_map") - 10,
|
||||
+ "%s/cache/index%d/shared_cpu_map", path, cache_index);
|
||||
cache_stat = stat(new_path, &sb);
|
||||
if (!cache_stat) {
|
||||
max_cache_index = cache_index;
|
||||
@@ -340,7 +345,9 @@ static void do_one_cpu(char *path)
|
||||
} while(!cache_stat);
|
||||
|
||||
if (max_cache_index > 0) {
|
||||
- snprintf(new_path, PATH_MAX, "%s/cache/index%d/shared_cpu_map", path, max_cache_index);
|
||||
+ /* Extra 10 subtraction is for the max character length of %d */
|
||||
+ snprintf(new_path, ADJ_SIZE(path, "/cache/index%d/shared_cpu_map") - 10,
|
||||
+ "%s/cache/index%d/shared_cpu_map", path, max_cache_index);
|
||||
file = fopen(new_path, "r");
|
||||
if (file) {
|
||||
char *line = NULL;
|
||||
@@ -505,7 +512,7 @@ void parse_cpu_tree(void)
|
||||
sscanf(entry->d_name, "cpu%d%c", &num, &pad) == 1 &&
|
||||
!strchr(entry->d_name, ' ')) {
|
||||
char new_path[PATH_MAX];
|
||||
- sprintf(new_path, "/sys/devices/system/cpu/%s", entry->d_name);
|
||||
+ snprintf(new_path, PATH_MAX, "/sys/devices/system/cpu/%s", entry->d_name);
|
||||
do_one_cpu(new_path);
|
||||
}
|
||||
} while (entry);
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,121 +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] 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 | 14 ++++++++++++--
|
||||
irqbalance.h | 3 ++-
|
||||
irqlist.c | 15 ++++++++++++++-
|
||||
3 files changed, 28 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index 1ca401e..15fb0fe 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -69,6 +69,8 @@ int sleep_interval = SLEEP_INTERVAL;
|
||||
int last_interval;
|
||||
int hint_enabled = 0;
|
||||
int poll_hint_interval = SLEEP_INTERVAL / 5;
|
||||
+unsigned long migrate_val = 0;
|
||||
+unsigned long load_limit = 0;
|
||||
GMainLoop *main_loop;
|
||||
|
||||
char *cpu_ban_string = NULL;
|
||||
@@ -106,6 +108,8 @@ struct option lopts[] = {
|
||||
{"verifyhint", 1, NULL, 'v'},
|
||||
{"rulesconfig", 1, NULL, 'r'},
|
||||
{"notclearhint", 0, NULL, 'n'},
|
||||
+ {"migrateval", 1, NULL, 'e'},
|
||||
+ {"loadlimit", 1, NULL, 'g'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -114,7 +118,7 @@ static void usage(void)
|
||||
log(TO_CONSOLE, LOG_INFO, "irqbalance [--oneshot | -o] [--debug | -d] [--foreground | -f] [--journal | -j] [--hintpolicy | -h <subset>]\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>] [--verifyhint= | -v n]\n");
|
||||
- log(TO_CONSOLE, LOG_INFO, " [--rulesconfig= | -r <config>] [--notclearhint | -n]\n");
|
||||
+ log(TO_CONSOLE, LOG_INFO, " [--rulesconfig= | -r <config>] [--notclearhint | -n] [--migrateval= | -e <n>] [--loadlimit= | -g <n>]\n");
|
||||
}
|
||||
|
||||
static void version(void)
|
||||
@@ -129,7 +133,7 @@ static void parse_command_line(int argc, char **argv)
|
||||
unsigned long val;
|
||||
|
||||
while ((opt = getopt_long(argc, argv,
|
||||
- "odfji:p:s:c:b:l:m:t:V:h:v:r:n",
|
||||
+ "odfji:p:s:c:b:l:m:t:V:h:v:r:ne:g:",
|
||||
lopts, &longind)) != -1) {
|
||||
|
||||
switch(opt) {
|
||||
@@ -231,6 +235,12 @@ static void parse_command_line(int argc, char **argv)
|
||||
case 'n':
|
||||
clear_affinity_hint = 0;
|
||||
break;
|
||||
+ case 'e':
|
||||
+ migrate_val = strtoul(optarg, NULL, 10);
|
||||
+ break;
|
||||
+ case 'g':
|
||||
+ load_limit = strtoul(optarg, NULL, 10);
|
||||
+ break;
|
||||
|
||||
}
|
||||
}
|
||||
diff --git a/irqbalance.h b/irqbalance.h
|
||||
index 72e141b..d4f6e7a 100644
|
||||
--- a/irqbalance.h
|
||||
+++ b/irqbalance.h
|
||||
@@ -124,7 +124,8 @@ extern struct irq_info *add_new_irq(int irq, struct irq_info *hint, GList *proc_
|
||||
extern void clear_no_existing_irqs(void);
|
||||
extern int hint_enabled, poll_hint_interval;
|
||||
extern int sleep_interval;
|
||||
-
|
||||
+extern unsigned long migrate_val;
|
||||
+extern unsigned long load_limit;
|
||||
/*
|
||||
* Generic object functions
|
||||
*/
|
||||
diff --git a/irqlist.c b/irqlist.c
|
||||
index 95ccc7a..3c38b18 100644
|
||||
--- a/irqlist.c
|
||||
+++ b/irqlist.c
|
||||
@@ -76,6 +76,7 @@ static void compute_deviations(struct topo_obj *obj, void *data)
|
||||
static void move_candidate_irqs(struct irq_info *info, void *data)
|
||||
{
|
||||
struct load_balance_info *lb_info = data;
|
||||
+ unsigned long delta_load = 0;
|
||||
|
||||
/* Don't rebalance irqs that don't want it */
|
||||
if (info->level == BALANCE_NONE)
|
||||
@@ -91,12 +92,24 @@ static void move_candidate_irqs(struct irq_info *info, void *data)
|
||||
if (info->load <= 1)
|
||||
return;
|
||||
|
||||
+ if (migrate_val > 0) {
|
||||
+ delta_load = (lb_info->adjustment_load - lb_info->min_load) / migrate_val;
|
||||
+ }
|
||||
+
|
||||
/* If we can migrate an irq without swapping the imbalance do it. */
|
||||
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
|
||||
+ } 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) {
|
||||
+ lb_info->min_load = lb_info->adjustment_load;
|
||||
+ }
|
||||
+ } else {
|
||||
return;
|
||||
+ }
|
||||
|
||||
log(TO_CONSOLE, LOG_INFO, "Selecting irq %d for rebalancing\n", info->irq);
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,488 +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 | 32 +++++++--
|
||||
irqbalance.c | 38 +++++----
|
||||
irqbalance.h | 2 +-
|
||||
misc/irqbalance.service | 2 +-
|
||||
placement.c | 3 +-
|
||||
procinterrupts.c | 3 +-
|
||||
rules_config.c | 172 ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
rules_config.h | 40 +++++++++++
|
||||
9 files changed, 271 insertions(+), 23 deletions(-)
|
||||
create mode 100644 rules_config.c
|
||||
create mode 100644 rules_config.h
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 62ac482..9276bfb 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 65aeae2..7c97d47 100644
|
||||
--- a/classify.c
|
||||
+++ b/classify.c
|
||||
@@ -663,7 +663,7 @@ struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list)
|
||||
|
||||
sprintf(path, "%s/%s/msi_irqs", SYSPCI_DIR, dirname);
|
||||
sprintf(devpath, "%s/%s", SYSPCI_DIR, dirname);
|
||||
-
|
||||
+ memset(&pol, -1, sizeof(struct user_irq_policy));
|
||||
/* Needs to be further classified */
|
||||
hint.class = IRQ_OTHER;
|
||||
|
||||
@@ -679,7 +679,9 @@ struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list)
|
||||
new = get_irq_info(irqnum);
|
||||
if (new)
|
||||
continue;
|
||||
- get_irq_user_policy(devpath, irqnum, &pol);
|
||||
+ if (user_policy_list == NULL) {
|
||||
+ get_irq_user_policy(devpath, irqnum, &pol);
|
||||
+ }
|
||||
if ((pol.ban == 1) || (check_for_irq_ban(devpath, irqnum, tmp_list))) {
|
||||
add_banned_irq(irqnum, &banned_irqs, 0);
|
||||
continue;
|
||||
@@ -714,7 +716,9 @@ struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list)
|
||||
new = get_irq_info(irqnum);
|
||||
if (new)
|
||||
goto done;
|
||||
- get_irq_user_policy(devpath, irqnum, &pol);
|
||||
+ if (user_policy_list == NULL) {
|
||||
+ get_irq_user_policy(devpath, irqnum, &pol);
|
||||
+ }
|
||||
if ((pol.ban == 1) || (check_for_irq_ban(path, irqnum, tmp_list))) {
|
||||
add_banned_irq(irqnum, &banned_irqs, 0);
|
||||
goto done;
|
||||
@@ -855,18 +859,24 @@ struct irq_info *add_new_irq(int irq, struct irq_info *hint, GList *proc_interru
|
||||
struct irq_info *new = NULL;
|
||||
struct user_irq_policy pol;
|
||||
|
||||
+ memset(&pol, -1, sizeof(struct user_irq_policy));
|
||||
new = get_irq_info(irq);
|
||||
if (new)
|
||||
return new;
|
||||
|
||||
/* Set NULL devpath for the irq has no sysfs entries */
|
||||
- get_irq_user_policy(NULL, irq, &pol);
|
||||
+ if (user_policy_list == NULL) {
|
||||
+ get_irq_user_policy(NULL, irq, &pol);
|
||||
+ }
|
||||
if ((pol.ban == 1) || check_for_irq_ban(NULL, irq, proc_interrupts)) { /*FIXME*/
|
||||
add_banned_irq(irq, &banned_irqs, 0);
|
||||
new = get_irq_info(irq);
|
||||
- } else
|
||||
+ } else {
|
||||
new = add_one_irq_to_db(NULL, 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);
|
||||
|
||||
@@ -880,6 +890,16 @@ static void add_missing_irq(struct irq_info *info, void *attr)
|
||||
|
||||
if (!lookup)
|
||||
add_new_irq(info->irq, info, proc_interrupts);
|
||||
+ else {
|
||||
+ if (user_policy_list != NULL) {
|
||||
+ set_usr_irq_policy(info->name, lookup);
|
||||
+ }
|
||||
+ }
|
||||
+ if (info->name) {
|
||||
+ free(info->name);
|
||||
+ info->name = NULL;
|
||||
+ }
|
||||
+
|
||||
}
|
||||
|
||||
static void free_tmp_irqs(gpointer data)
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index 21d578a..d41753c 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -99,6 +99,7 @@ struct option lopts[] = {
|
||||
{"banmod", 1 , NULL, 'm'},
|
||||
{"interval", 1 , NULL, 't'},
|
||||
{"version", 0, NULL, 'V'},
|
||||
+ {"rulesconfig", 1, NULL, 'r'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -106,7 +107,7 @@ static void usage(void)
|
||||
{
|
||||
log(TO_CONSOLE, LOG_INFO, "irqbalance [--oneshot | -o] [--debug | -d] [--foreground | -f] [--journal | -j] [--hintpolicy= | -h [exact|subset|ignore]]\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>]\n");
|
||||
+ log(TO_CONSOLE, LOG_INFO, " [--pid= | -s <file>] [--deepestcache= | -c <n>] [--interval= | -t <n>] [--rulesconfig= | -r <config>]\n");
|
||||
}
|
||||
|
||||
static void version(void)
|
||||
@@ -121,7 +122,7 @@ static void parse_command_line(int argc, char **argv)
|
||||
unsigned long val;
|
||||
|
||||
while ((opt = getopt_long(argc, argv,
|
||||
- "odfji:p:s:c:b:l:m:t:V",
|
||||
+ "odfji:p:s:c:b:l:m:t:V:r",
|
||||
lopts, &longind)) != -1) {
|
||||
|
||||
switch(opt) {
|
||||
@@ -201,6 +202,9 @@ static void parse_command_line(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
+ case 'r':
|
||||
+ rules_config_file = strdup(optarg);
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -539,6 +543,25 @@ int main(int argc, char** argv)
|
||||
log(TO_ALL, LOG_WARNING, "Unable to determin HZ defaulting to 100\n");
|
||||
HZ = 100;
|
||||
}
|
||||
+ if (!foreground_mode) {
|
||||
+ if (daemon(0,0)) {
|
||||
+ ret = EXIT_FAILURE;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ /* Write pidfile */
|
||||
+ if (pidfile && create_lock_pidfile(pidfile) < 0) {
|
||||
+ ret = EXIT_FAILURE;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ 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)
|
||||
@@ -554,16 +573,6 @@ int main(int argc, char** argv)
|
||||
goto out;
|
||||
}
|
||||
|
||||
- if (!foreground_mode) {
|
||||
- if (daemon(0,0))
|
||||
- exit(EXIT_FAILURE);
|
||||
- /* Write pidfile */
|
||||
- if (pidfile && create_lock_pidfile(pidfile) < 0) {
|
||||
- ret = EXIT_FAILURE;
|
||||
- goto out;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
g_unix_signal_add(SIGINT, handler, NULL);
|
||||
g_unix_signal_add(SIGTERM, handler, NULL);
|
||||
g_unix_signal_add(SIGUSR1, handler, NULL);
|
||||
@@ -589,6 +598,7 @@ int main(int argc, char** argv)
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
+ log(TO_ALL, LOG_INFO, "irqbalance start scan.\n");
|
||||
main_loop = g_main_loop_new(NULL, FALSE);
|
||||
last_interval = sleep_interval;
|
||||
g_timeout_add_seconds(sleep_interval, scan, NULL);
|
||||
diff --git a/irqbalance.h b/irqbalance.h
|
||||
index 120bc9b..42f95cb 100644
|
||||
--- a/irqbalance.h
|
||||
+++ b/irqbalance.h
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
#include "types.h"
|
||||
#include "config.h"
|
||||
-
|
||||
+#include "rules_config.h"
|
||||
#ifdef __aarch64__
|
||||
#define AARCH64
|
||||
#endif
|
||||
diff --git a/misc/irqbalance.service b/misc/irqbalance.service
|
||||
index ce0022c..2c002b2 100644
|
||||
--- a/misc/irqbalance.service
|
||||
+++ b/misc/irqbalance.service
|
||||
@@ -5,7 +5,7 @@ After=syslog.target
|
||||
|
||||
[Service]
|
||||
OOMScoreAdjust=-500
|
||||
-Type=simple
|
||||
+Type=forking
|
||||
PIDFile=/var/run/irqbalance.pid
|
||||
EnvironmentFile=/etc/sysconfig/irqbalance
|
||||
ExecStart=/usr/sbin/irq_balancer
|
||||
diff --git a/placement.c b/placement.c
|
||||
index 19462bb..d887c60 100644
|
||||
--- a/placement.c
|
||||
+++ b/placement.c
|
||||
@@ -53,8 +53,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/procinterrupts.c b/procinterrupts.c
|
||||
index 60b2545..18b3ceb 100644
|
||||
--- a/procinterrupts.c
|
||||
+++ b/procinterrupts.c
|
||||
@@ -245,7 +245,8 @@ static void init_irq_class_and_type(char *savedline, struct irq_info *info, int
|
||||
info->class = IRQ_OTHER;
|
||||
#endif
|
||||
}
|
||||
- info->name = strdupa(irq_mod);
|
||||
+
|
||||
+ info->name = strdup(irq_mod);
|
||||
}
|
||||
|
||||
|
||||
diff --git a/rules_config.c b/rules_config.c
|
||||
new file mode 100644
|
||||
index 0000000..1270ac7
|
||||
--- /dev/null
|
||||
+++ b/rules_config.c
|
||||
@@ -0,0 +1,172 @@
|
||||
+/*
|
||||
+ * 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;
|
||||
+
|
||||
+ 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 (!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..b8f9dc5
|
||||
--- /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
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
@ -1,123 +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] 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 | 26 +++++++++++++++++++++++++-
|
||||
irqbalance.c | 10 ++++++++--
|
||||
2 files changed, 33 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/hint_verify.c b/hint_verify.c
|
||||
index 0718078..11ef868 100644
|
||||
--- a/hint_verify.c
|
||||
+++ b/hint_verify.c
|
||||
@@ -16,6 +16,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;
|
||||
@@ -57,7 +58,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);
|
||||
file = fopen(path, "r");
|
||||
if (!file)
|
||||
@@ -80,6 +82,27 @@ void update_affinity_hint(struct irq_info *info, void *data __attribute__((unuse
|
||||
free(line);
|
||||
}
|
||||
|
||||
+static void check_clear()
|
||||
+{
|
||||
+ char *line = NULL;
|
||||
+ size_t size = 0;
|
||||
+ FILE *file;
|
||||
+
|
||||
+ file = fopen("/etc/sysconfig/irqbalance_clear", "r");
|
||||
+ if (!file)
|
||||
+ return;
|
||||
+ if (getline(&line, &size, file) <= 0)
|
||||
+ goto out;
|
||||
+ if (line != NULL && strstr(line, "0") != NULL)
|
||||
+ clear_affinity_hint = 0;
|
||||
+ else
|
||||
+ clear_affinity_hint = 1;
|
||||
+
|
||||
+out:
|
||||
+ fclose(file);
|
||||
+ free(line);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* This function is the main loop of irqbalance, which include:
|
||||
* 1. scan opration for irq balancing;
|
||||
@@ -104,6 +127,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 05eaa29..77076fa 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -55,6 +55,7 @@ int foreground_mode;
|
||||
int numa_avail;
|
||||
int journal_logging = 0;
|
||||
int need_rescan;
|
||||
+int clear_affinity_hint = 1;
|
||||
unsigned int log_mask = TO_ALL;
|
||||
const char *log_indent;
|
||||
unsigned long power_thresh = ULONG_MAX;
|
||||
@@ -104,14 +105,16 @@ struct option lopts[] = {
|
||||
{"version", 0, NULL, 'V'},
|
||||
{"verifyhint", 1, NULL, 'v'},
|
||||
{"rulesconfig", 1, NULL, 'r'},
|
||||
+ {"notclearhint", 0, NULL, 'n'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
log(TO_CONSOLE, LOG_INFO, "irqbalance [--oneshot | -o] [--debug | -d] [--foreground | -f] [--journal | -j] [--hintpolicy | -h <subset>]\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>] [--verifyhint= | -v n] [--rulesconfig= | -r <config>]\n");
|
||||
+ log(TO_CONSOLE, LOG_INFO, " [--pid= | -s <file>] [--deepestcache= | -c <n>] [--interval= | -t <n>] [--verifyhint= | -v n]\n");
|
||||
+ log(TO_CONSOLE, LOG_INFO, " [--rulesconfig= | -r <config>] [--notclearhint | -n]\n");
|
||||
}
|
||||
|
||||
static void version(void)
|
||||
@@ -126,7 +128,7 @@ static void parse_command_line(int argc, char **argv)
|
||||
unsigned long val;
|
||||
|
||||
while ((opt = getopt_long(argc, argv,
|
||||
- "odfji:p:s:c:b:l:m:t:V:h:v:r:",
|
||||
+ "odfji:p:s:c:b:l:m:t:V:h:v:r:n",
|
||||
lopts, &longind)) != -1) {
|
||||
|
||||
switch(opt) {
|
||||
@@ -225,6 +227,10 @@ static void parse_command_line(int argc, char **argv)
|
||||
case 'r':
|
||||
rules_config_file = strdup(optarg);
|
||||
break;
|
||||
+ case 'n':
|
||||
+ clear_affinity_hint = 0;
|
||||
+ break;
|
||||
+
|
||||
}
|
||||
}
|
||||
}
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,114 +0,0 @@
|
||||
From b697a97436dafa13f0ae3febde299bfc20498f9d Mon Sep 17 00:00:00 2001
|
||||
From: liuchao173 <liuchao173@huawei.com>
|
||||
Date: Wed, 23 Oct 2019 11:42:26 +0000
|
||||
Subject: [PATCH] irqbalance: add the switch of printing log
|
||||
|
||||
add the switch of printing log
|
||||
---
|
||||
cputree.c | 16 ++++++++--------
|
||||
irqbalance.c | 25 +++++++++++++++++++++++++-
|
||||
2 files changed, 32 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/cputree.c b/cputree.c
|
||||
index 99f14d2..1465103 100644
|
||||
--- a/cputree.c
|
||||
+++ b/cputree.c
|
||||
@@ -432,23 +432,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);
|
||||
}
|
||||
@@ -457,10 +457,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);
|
||||
@@ -472,9 +472,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 d41753c..7d8d15c 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -273,6 +273,29 @@ gboolean force_rescan(gpointer data __attribute__((unused)))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+static int check_debug()
|
||||
+{
|
||||
+ char *line = NULL;
|
||||
+ size_t size = 0;
|
||||
+ FILE *file;
|
||||
+
|
||||
+ file = fopen("/etc/sysconfig/irqbalance_debug", "r");
|
||||
+ if (!file)
|
||||
+ return 0;
|
||||
+ if (getline(&line, &size, file) <= 0) {
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (line != NULL && strstr(line, "1") != NULL) {
|
||||
+ fclose(file);
|
||||
+ free(line);
|
||||
+ return 1;
|
||||
+ }
|
||||
+out:
|
||||
+ fclose(file);
|
||||
+ free(line);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
gboolean scan(gpointer data __attribute__((unused)))
|
||||
{
|
||||
log(TO_CONSOLE, LOG_INFO, "\n\n\n-----------------------------------------------------------------------------\n");
|
||||
@@ -305,7 +328,7 @@ gboolean scan(gpointer data)
|
||||
calculate_placement();
|
||||
activate_mappings();
|
||||
|
||||
- if (debug_mode)
|
||||
+ if (debug_mode || check_debug())
|
||||
dump_tree();
|
||||
if (one_shot_mode)
|
||||
keep_going = 0;
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,43 +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
|
||||
|
||||
Type:bugfix/CVE/requirement/cleancode/testcode
|
||||
CVE:
|
||||
DTS/AR:
|
||||
reason:
|
||||
---
|
||||
irqbalance.c | 2 +-
|
||||
irqbalance.h | 2 ++
|
||||
2 files changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index 1af23c6..dc8307d 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -622,7 +622,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 61b39dd..2d59d31 100644
|
||||
--- a/irqbalance.h
|
||||
+++ b/irqbalance.h
|
||||
@@ -177,5 +177,7 @@ extern unsigned int log_mask;
|
||||
#define SOCKET_PATH "irqbalance"
|
||||
#define SOCKET_TMPFS "/var/run"
|
||||
#define SOCKET_RECV_BUF_LEN 4096
|
||||
+#define MAX_CLIENT_NUM 32
|
||||
+
|
||||
#endif /* __INCLUDE_GUARD_IRQBALANCE_H_ */
|
||||
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -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] 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 | 2 +-
|
||||
ui/Makefile | 30 ++++
|
||||
ui/client.c | 434 +++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
ui/irqbalance-ui.c | 4 +-
|
||||
ui/irqbalance-ui.h | 1 +
|
||||
ui/irqbalance_client.h | 111 +++++++++++++
|
||||
7 files changed, 581 insertions(+), 5 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,6 @@ extern unsigned int log_mask;
|
||||
|
||||
#define SOCKET_PATH "irqbalance"
|
||||
#define SOCKET_TMPFS "/var/run"
|
||||
-
|
||||
+#define SOCKET_RECV_BUF_LEN 4096
|
||||
#endif /* __INCLUDE_GUARD_IRQBALANCE_H_ */
|
||||
|
||||
diff --git a/ui/Makefile b/ui/Makefile
|
||||
new file mode 100644
|
||||
index 0000000..27e0fbf
|
||||
--- /dev/null
|
||||
+++ b/ui/Makefile
|
||||
@@ -0,0 +1,30 @@
|
||||
+#!/bin/make
|
||||
+export SHELL = /bin/bash
|
||||
+DIR = $(shell pwd)
|
||||
+TARGET = libirqbalance_client.so
|
||||
+
|
||||
+RM = rm
|
||||
+LINK = ld
|
||||
+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
|
||||
+SHARED = -shared
|
||||
+LFLAG = -lglib-2.0 -lncursesw
|
||||
+
|
||||
+CFLAG += $(INC)
|
||||
+
|
||||
+all: $(TARGET)
|
||||
+
|
||||
+$(TARGET): $(OBJ)
|
||||
+ $(LINK) $(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,434 @@
|
||||
+/*
|
||||
+ * 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);
|
||||
+ 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
|
||||
|
||||
@ -1,511 +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 | 24 +++++------
|
||||
classify.c | 18 ++++++--
|
||||
cpumask.h | 7 +++
|
||||
hint_verify.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
hint_verify.h | 21 +++++++++
|
||||
irqbalance.c | 40 +++++++++++------
|
||||
irqbalance.h | 4 ++
|
||||
placement.c | 14 ++++++
|
||||
types.h | 1 +
|
||||
10 files changed, 252 insertions(+), 30 deletions(-)
|
||||
create mode 100644 hint_verify.c
|
||||
create mode 100644 hint_verify.h
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 9276bfb..5fac265 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 d9e1fc3..87336f4 100644
|
||||
--- a/activate.c
|
||||
+++ b/activate.c
|
||||
@@ -88,26 +88,26 @@ static void activate_mapping(struct irq_info *info, void *data __attribute__((un
|
||||
char buf[PATH_MAX];
|
||||
FILE *file;
|
||||
cpumask_t applied_mask;
|
||||
- int valid_mask = 0;
|
||||
|
||||
- /*
|
||||
- * only activate mappings for irqs that have moved
|
||||
- */
|
||||
- if (!info->moved)
|
||||
+ if (!info->assigned_obj)
|
||||
return;
|
||||
|
||||
- if (info->assigned_obj) {
|
||||
- applied_mask = info->assigned_obj->mask;
|
||||
- valid_mask = 1;
|
||||
+ applied_mask = 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)) {
|
||||
+ log(TO_ALL, LOG_WARNING, "irq %d affinity_hint subset empty\n", info->irq);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't activate anything for which we have an invalid mask
|
||||
*/
|
||||
- if (!valid_mask || check_affinity(info, applied_mask))
|
||||
- return;
|
||||
-
|
||||
- if (!info->assigned_obj)
|
||||
+ if (check_affinity(info, applied_mask))
|
||||
return;
|
||||
|
||||
sprintf(buf, "/proc/irq/%i/smp_affinity", info->irq);
|
||||
diff --git a/classify.c b/classify.c
|
||||
index 5aed9e5..75677f4 100644
|
||||
--- a/classify.c
|
||||
+++ b/classify.c
|
||||
@@ -71,8 +71,6 @@ struct pci_info {
|
||||
#define PCI_SUB_DEVICE_EMC_0568 0x0568
|
||||
#define PCI_SUB_DEVICE_EMC_dd00 0xdd00
|
||||
|
||||
-extern void force_rebalance_irq(struct irq_info *info, void *data __attribute__((unused)));
|
||||
-
|
||||
/*
|
||||
* Apply software workarounds for some special devices
|
||||
*
|
||||
@@ -448,7 +446,7 @@ get_numa_node:
|
||||
fd = fopen(path, "r");
|
||||
if (!fd) {
|
||||
cpus_setall(new->cpumask);
|
||||
- goto out;
|
||||
+ goto assign_affinity_hint;
|
||||
}
|
||||
lcpu_mask = NULL;
|
||||
ret = getline(&lcpu_mask, &blen, fd);
|
||||
@@ -460,6 +458,20 @@ get_numa_node:
|
||||
}
|
||||
free(lcpu_mask);
|
||||
|
||||
+assign_affinity_hint:
|
||||
+ cpus_clear(new->affinity_hint);
|
||||
+ sprintf(path, "/proc/irq/%d/affinity_hint", irq);
|
||||
+ fd = fopen(path, "r");
|
||||
+ if (!fd)
|
||||
+ goto out;
|
||||
+ lcpu_mask = NULL;
|
||||
+ ret = getline(&lcpu_mask, &blen, fd);
|
||||
+ fclose(fd);
|
||||
+ if (ret <= 0)
|
||||
+ goto out;
|
||||
+ cpumask_parse_user(lcpu_mask, ret, new->affinity_hint);
|
||||
+ free(lcpu_mask);
|
||||
+
|
||||
out:
|
||||
log(TO_CONSOLE, LOG_INFO, "Adding IRQ %d to database\n", irq);
|
||||
return new;
|
||||
diff --git a/cpumask.h b/cpumask.h
|
||||
index 0774a88..8dd3703 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?
|
||||
@@ -150,6 +151,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..7a904b0
|
||||
--- /dev/null
|
||||
+++ b/hint_verify.c
|
||||
@@ -0,0 +1,151 @@
|
||||
+/*
|
||||
+ * 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)))
|
||||
+{
|
||||
+ FILE *file = NULL;
|
||||
+ cpumask_t current_affinity_hint;
|
||||
+ char path[PATH_MAX];
|
||||
+ char *line = NULL;
|
||||
+ size_t size = 0;
|
||||
+ ssize_t len;
|
||||
+
|
||||
+ if (!hint_enabled)
|
||||
+ return;
|
||||
+
|
||||
+ cpus_clear(info->affinity_hint);
|
||||
+ sprintf(path, "/proc/irq/%d/affinity_hint", info->irq);
|
||||
+ file = fopen(path, "r");
|
||||
+ if (!file)
|
||||
+ return;
|
||||
+
|
||||
+ len = getline(&line, &size, file);
|
||||
+ fclose(file);
|
||||
+
|
||||
+ if (len > 0) {
|
||||
+ cpumask_parse_user(line, len, 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;
|
||||
+ log(TO_ALL, LOG_INFO, "IRQ(%d): affinity hint modified %s\n", info->irq, line);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (line)
|
||||
+ free(line);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * 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..a309461
|
||||
--- /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 faa8e6a..4a7eb39 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -65,6 +65,8 @@ char *banscript = 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;
|
||||
@@ -99,15 +101,16 @@ struct option lopts[] = {
|
||||
{"banmod", 1 , NULL, 'm'},
|
||||
{"interval", 1 , NULL, 't'},
|
||||
{"version", 0, NULL, 'V'},
|
||||
+ {"verifyhint", 1, NULL, 'v'},
|
||||
{"rulesconfig", 1, NULL, 'r'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
- log(TO_CONSOLE, LOG_INFO, "irqbalance [--oneshot | -o] [--debug | -d] [--foreground | -f] [--journal | -j] [--hintpolicy= | -h [exact|subset|ignore]]\n");
|
||||
+ log(TO_CONSOLE, LOG_INFO, "irqbalance [--oneshot | -o] [--debug | -d] [--foreground | -f] [--journal | -j] [--hintpolicy | -h <subset>]\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>] [--rulesconfig= | -r <config>]\n");
|
||||
+ log(TO_CONSOLE, LOG_INFO, " [--pid= | -s <file>] [--deepestcache= | -c <n>] [--interval= | -t <n>] [--verifyhint= | -v n] [--rulesconfig= | -r <config>]\n");
|
||||
}
|
||||
|
||||
static void version(void)
|
||||
@@ -122,7 +125,7 @@ static void parse_command_line(int argc, char **argv)
|
||||
unsigned long val;
|
||||
|
||||
while ((opt = getopt_long(argc, argv,
|
||||
- "odfji:p:s:c:b:l:m:t:V:r",
|
||||
+ "odfji:p:s:c:b:l:m:t:V:h:v:r:",
|
||||
lopts, &longind)) != -1) {
|
||||
|
||||
switch(opt) {
|
||||
@@ -202,6 +205,22 @@ static void parse_command_line(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
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;
|
||||
case 'r':
|
||||
rules_config_file = strdup(optarg);
|
||||
break;
|
||||
@@ -300,7 +319,7 @@ out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
-gboolean scan(gpointer data __attribute__((unused)))
|
||||
+gboolean scan()
|
||||
{
|
||||
log(TO_CONSOLE, LOG_INFO, "\n\n\n-----------------------------------------------------------------------------\n");
|
||||
clear_work_stats();
|
||||
@@ -338,17 +357,9 @@ gboolean scan(gpointer data)
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -626,9 +638,10 @@ int main(int argc, char** argv)
|
||||
goto out;
|
||||
}
|
||||
log(TO_ALL, LOG_INFO, "irqbalance start scan.\n");
|
||||
+ 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 1befb46..72e141b 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
|
||||
#endif
|
||||
@@ -113,6 +114,7 @@ extern void migrate_irq(GList **from, GList **to, struct irq_info *info);
|
||||
extern void free_cl_opts(void);
|
||||
extern void add_cl_banned_module(char *modname);
|
||||
#define irq_numa_node(irq) ((irq)->numa_node)
|
||||
+extern void force_rebalance_irq(struct irq_info *info, void *data __attribute__((unused)));
|
||||
extern gint compare_ints(gconstpointer a, gconstpointer b);
|
||||
|
||||
extern struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list);
|
||||
@@ -120,6 +122,8 @@ extern struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list
|
||||
extern void find_irq_dev_path(int irq, char *dirname, int length);
|
||||
extern struct irq_info *add_new_irq(int irq, struct irq_info *hint, GList *proc_interrupts);
|
||||
extern void clear_no_existing_irqs(void);
|
||||
+extern int hint_enabled, poll_hint_interval;
|
||||
+extern int sleep_interval;
|
||||
|
||||
/*
|
||||
* Generic object functions
|
||||
diff --git a/placement.c b/placement.c
|
||||
index 48ac68b..d887c60 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 e1f3dc6..c0950ee 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;
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
@ -1,552 +0,0 @@
|
||||
From 8e84d5ba4aad02509165cb1926091baa3630e418 Mon Sep 17 00:00:00 2001
|
||||
From: hejingxian <hejingxian@huawei.com>
|
||||
Date: Fri, 14 Feb 2020 16:42:01 +0800
|
||||
Subject: [PATCH] feature: add ability for unblock socket communication
|
||||
|
||||
This will be used with user interface and also can be used as API for users
|
||||
to create their own scripts on top of. The socket communication can be used
|
||||
for receiving data about IRQs-to-CPUs assignments and setup, as well as
|
||||
setting some options during runtime.
|
||||
|
||||
Socket address: /var/run/uvp_irqbalance.socket
|
||||
|
||||
Data to send to socket:
|
||||
settings sleep <int>: set new sleep interval value
|
||||
settings cpus <cpumask> <cpumask> ... : ban listed CPUs from
|
||||
IRQ handling (old values are forgotten, not added to)
|
||||
settings ban irqs <irq1> <irq2> ... : ban listed IRQs from balancing (old
|
||||
values are forgotten, not added to)
|
||||
|
||||
Signed-off-by: Xu Yandong <xuyandong2@huawei.com>
|
||||
Signed-off-by: He Jingxian <hejingxian@huawei.com>
|
||||
---
|
||||
Makefile.am | 4 +-
|
||||
classify.c | 2 +-
|
||||
cputree.c | 20 ++--
|
||||
irqbalance.c | 33 +++++--
|
||||
irqbalance.h | 1 +
|
||||
sockapi.c | 297 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
sockapi.h | 19 ++++
|
||||
7 files changed, 359 insertions(+), 17 deletions(-)
|
||||
create mode 100644 sockapi.c
|
||||
create mode 100644 sockapi.h
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 46e7173..c7be22d 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -30,7 +30,7 @@ UI_DIR = ui
|
||||
AM_CFLAGS = $(LIBCAP_NG_CFLAGS) $(GLIB2_CFLAGS)
|
||||
AM_CPPFLAGS = -I${top_srcdir} -W -Wall -Wshadow -Wformat -Wundef -D_GNU_SOURCE
|
||||
noinst_HEADERS = bitmap.h constants.h cpumask.h irqbalance.h non-atomic.h \
|
||||
- types.h $(UI_DIR)/helpers.h $(UI_DIR)/irqbalance-ui.h $(UI_DIR)/ui.h
|
||||
+ types.h sockapi.h $(UI_DIR)/helpers.h $(UI_DIR)/irqbalance-ui.h $(UI_DIR)/ui.h
|
||||
sbin_PROGRAMS = irqbalance
|
||||
|
||||
if IRQBALANCEUI
|
||||
@@ -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 hint_verify.c
|
||||
+ irqlist.c numa.c placement.c procinterrupts.c rules_config.c hint_verify.c sockapi.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 91ff022..b0bb3b4 100644
|
||||
--- a/classify.c
|
||||
+++ b/classify.c
|
||||
@@ -37,7 +37,7 @@ static GList *interrupts_db = NULL;
|
||||
static GList *banned_irqs = NULL;
|
||||
GList *cl_banned_irqs = NULL;
|
||||
static GList *cl_banned_modules = NULL;
|
||||
-static GList *vm_banned_irqs = NULL;
|
||||
+GList *vm_banned_irqs = NULL;
|
||||
extern int need_add_single;
|
||||
|
||||
#define SYSFS_DIR "/sys"
|
||||
diff --git a/cputree.c b/cputree.c
|
||||
index 741c7c8..5a96e30 100644
|
||||
--- a/cputree.c
|
||||
+++ b/cputree.c
|
||||
@@ -40,6 +40,8 @@
|
||||
|
||||
extern char *banned_cpumask_from_ui;
|
||||
extern char *cpu_ban_string;
|
||||
+extern int use_unblock_socket;
|
||||
+extern int is_set_banned_cpumask_from_ui;
|
||||
|
||||
GList *cpus;
|
||||
GList *cache_domains;
|
||||
@@ -78,12 +80,18 @@ static void setup_banned_cpus(void)
|
||||
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,
|
||||
- strlen(banned_cpumask_from_ui), banned_cpus);
|
||||
- goto out;
|
||||
- }
|
||||
- if (getenv("IRQBALANCE_BANNED_CPUS")) {
|
||||
+ if (!use_unblock_socket && cpu_ban_string != NULL && banned_cpumask_from_ui != NULL) {
|
||||
+ cpulist_parse(banned_cpumask_from_ui,
|
||||
+ strlen(banned_cpumask_from_ui), banned_cpus);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (use_unblock_socket && is_set_banned_cpumask_from_ui) {
|
||||
+ cpumask_parse_user(banned_cpumask_from_ui,
|
||||
+ strlen(banned_cpumask_from_ui), banned_cpus);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (getenv("IRQBALANCE_BANNED_CPUS")) {
|
||||
cpumask_parse_user(getenv("IRQBALANCE_BANNED_CPUS"), strlen(getenv("IRQBALANCE_BANNED_CPUS")), banned_cpus);
|
||||
goto out;
|
||||
}
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index dc8307d..1774eda 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -42,6 +42,7 @@
|
||||
#include <cap-ng.h>
|
||||
#endif
|
||||
#include "irqbalance.h"
|
||||
+#include "sockapi.h"
|
||||
|
||||
volatile int keep_going = 1;
|
||||
volatile int ban_pci_assigned_irq = 1;
|
||||
@@ -73,6 +74,7 @@ GMainLoop *main_loop;
|
||||
|
||||
char *cpu_ban_string = NULL;
|
||||
char *banned_cpumask_from_ui = NULL;
|
||||
+int use_unblock_socket = 1;
|
||||
|
||||
static void sleep_approx(int seconds)
|
||||
{
|
||||
@@ -109,6 +111,7 @@ struct option lopts[] = {
|
||||
{"notclearhint", 0, NULL, 'n'},
|
||||
{"migrateval", 1, NULL, 'e'},
|
||||
{"loadlimit", 1, NULL, 'g'},
|
||||
+ {"blocksocket", 0, NULL, 'k'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -116,8 +119,8 @@ static void usage(void)
|
||||
{
|
||||
log(TO_CONSOLE, LOG_INFO, "irqbalance [--oneshot | -o] [--debug | -d] [--foreground | -f] [--journal | -j] [--hintpolicy | -h <subset>]\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>] [--verifyhint= | -v n]\n");
|
||||
- log(TO_CONSOLE, LOG_INFO, " [--rulesconfig= | -r <config>] [--notclearhint | -n] [--migrateval= | -e <n>] [--loadlimit= | -g <n>]\n");
|
||||
+ log(TO_CONSOLE, LOG_INFO, " [--pid= | -s <file>] [--deepestcache= | -c <n>] [--interval= | -t <n>] [--verifyhint= | -v n] [--blocksocket | -k]\n");
|
||||
+ log(TO_CONSOLE, LOG_INFO, " [--rulesconfig= | -r <config>] [--notclearhint | -n] [--migrateval= | -e <n>] [--loadlimit= | -g <n>]\n");
|
||||
}
|
||||
|
||||
static void version(void)
|
||||
@@ -132,7 +135,7 @@ static void parse_command_line(int argc, char **argv)
|
||||
unsigned long val;
|
||||
|
||||
while ((opt = getopt_long(argc, argv,
|
||||
- "odfjVni:p:s:c:b:l:m:t:h:v:r:e:g:",
|
||||
+ "odfjVni:p:s:c:b:l:m:t:h:v:r:e:g:k",
|
||||
lopts, &longind)) != -1) {
|
||||
|
||||
switch(opt) {
|
||||
@@ -240,7 +243,9 @@ static void parse_command_line(int argc, char **argv)
|
||||
case 'g':
|
||||
load_limit = strtoul(optarg, NULL, 10);
|
||||
break;
|
||||
-
|
||||
+ case 'k':
|
||||
+ use_unblock_socket = 0;
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -562,9 +567,12 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
||||
if (!setup)
|
||||
goto out_close;
|
||||
snprintf(setup, strlen("SLEEP ") + 11 + 1, "SLEEP %d ", sleep_interval);
|
||||
- if(g_list_length(cl_banned_irqs) > 0) {
|
||||
+ if (g_list_length(cl_banned_irqs) > 0) {
|
||||
for_each_irq(cl_banned_irqs, get_irq_data, &setup);
|
||||
}
|
||||
+ if (g_list_length(vm_banned_irqs) > 0) {
|
||||
+ for_each_irq(vm_banned_irqs, get_irq_data, &setup);
|
||||
+ }
|
||||
cpumask_scnprintf(banned, 512, banned_cpus);
|
||||
newptr = realloc(setup, strlen(setup) + strlen(banned) + 7 + 1);
|
||||
if (!newptr)
|
||||
@@ -827,10 +835,18 @@ int main(int argc, char** argv)
|
||||
parse_proc_interrupts();
|
||||
parse_proc_stat();
|
||||
|
||||
- if (init_socket()) {
|
||||
- ret = EXIT_FAILURE;
|
||||
- goto out;
|
||||
+ if (use_unblock_socket) {
|
||||
+ if (init_unblock_socket()) {
|
||||
+ ret = EXIT_FAILURE;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (init_socket()) {
|
||||
+ ret = EXIT_FAILURE;
|
||||
+ goto out;
|
||||
+ }
|
||||
}
|
||||
+
|
||||
log(TO_ALL, LOG_INFO, "irqbalance start scan.\n");
|
||||
update_interval_and_count();
|
||||
main_loop = g_main_loop_new(NULL, FALSE);
|
||||
@@ -852,6 +868,7 @@ out:
|
||||
close(socket_fd);
|
||||
if (socket_name[0])
|
||||
unlink(socket_name);
|
||||
+ free(banned_cpumask_from_ui);
|
||||
|
||||
return ret;
|
||||
}
|
||||
diff --git a/irqbalance.h b/irqbalance.h
|
||||
index fc42a9b..7473ee7 100644
|
||||
--- a/irqbalance.h
|
||||
+++ b/irqbalance.h
|
||||
@@ -65,6 +65,7 @@ extern GList *cache_domains;
|
||||
extern GList *cpus;
|
||||
extern int numa_avail;
|
||||
extern GList *cl_banned_irqs;
|
||||
+extern GList *vm_banned_irqs;
|
||||
|
||||
extern int debug_mode;
|
||||
extern int journal_logging;
|
||||
diff --git a/sockapi.c b/sockapi.c
|
||||
new file mode 100644
|
||||
index 0000000..9891978
|
||||
--- /dev/null
|
||||
+++ b/sockapi.c
|
||||
@@ -0,0 +1,297 @@
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <unistd.h>
|
||||
+#include <string.h>
|
||||
+#include <ctype.h>
|
||||
+#include <errno.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <sys/time.h>
|
||||
+#include <sys/types.h>
|
||||
+#include <sys/socket.h>
|
||||
+#include <sys/un.h>
|
||||
+#include <sys/epoll.h>
|
||||
+#include <pthread.h>
|
||||
+
|
||||
+#include "sockapi.h"
|
||||
+#include "irqbalance.h"
|
||||
+
|
||||
+volatile int is_set_banned_cpumask_from_ui = 0;
|
||||
+
|
||||
+extern char *banned_cpumask_from_ui;
|
||||
+extern int socket_fd;
|
||||
+extern char socket_name[64];
|
||||
+extern int sleep_interval;
|
||||
+extern GList *cl_banned_irqs;
|
||||
+extern GList *vm_banned_irqs;
|
||||
+extern cpumask_t banned_cpus;
|
||||
+extern int keep_going;
|
||||
+int cur_fd_count = 0;
|
||||
+
|
||||
+static void fill_banned_cpus(char *cpustr, int length)
|
||||
+{
|
||||
+ (void)snprintf(cpustr, length, "CPU:");
|
||||
+ cpumask_scnprintf(cpustr + strlen(cpustr), length - strlen(cpustr), banned_cpus);
|
||||
+}
|
||||
+
|
||||
+static void fill_banned_irqs(char *irqstr, int length)
|
||||
+{
|
||||
+ GList *entry = NULL;
|
||||
+ GList *next = NULL;
|
||||
+ struct irq_info *info = NULL;
|
||||
+
|
||||
+ (void)snprintf(irqstr, length, "IRQ:");
|
||||
+ entry = g_list_first(cl_banned_irqs);
|
||||
+ if (!entry)
|
||||
+ (void)snprintf(irqstr + strlen(irqstr), length - strlen(irqstr), "None ");
|
||||
+ while (entry) {
|
||||
+ next = g_list_next(entry);
|
||||
+ info = entry->data;
|
||||
+ (void)snprintf(irqstr + strlen(irqstr), length - strlen(irqstr),
|
||||
+ "%d,", info->irq);
|
||||
+ entry = next;
|
||||
+ }
|
||||
+
|
||||
+ (void)snprintf(irqstr + strlen(irqstr) - 1, length - strlen(irqstr), " PCI:");
|
||||
+
|
||||
+ entry = g_list_first(vm_banned_irqs);
|
||||
+ if (!entry)
|
||||
+ (void)snprintf(irqstr + strlen(irqstr), length - strlen(irqstr), "None");
|
||||
+ while (entry) {
|
||||
+ next = g_list_next(entry);
|
||||
+ info = entry->data;
|
||||
+ (void)snprintf(irqstr + strlen(irqstr), length - strlen(irqstr),
|
||||
+ "%d,", info->irq);
|
||||
+ entry = next;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int send_msg(int fd, char* buf, int len)
|
||||
+{
|
||||
+ int ret = -1;
|
||||
+
|
||||
+ do {
|
||||
+ ret = send(fd, buf, len, 0);
|
||||
+ } while ((ret <= 0) && (errno == EINTR));
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int setnonblocking(int fd)
|
||||
+{
|
||||
+ if (fcntl(fd, F_SETFL,
|
||||
+ (int)((unsigned int)fcntl(socket_fd, F_GETFL, 0) | O_NONBLOCK)) < 0) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void prase_banned_irq_string(char *irq_string)
|
||||
+{
|
||||
+ char *end = NULL;
|
||||
+ char *last = irq_string;
|
||||
+ int irq;
|
||||
+
|
||||
+ g_list_free_full(cl_banned_irqs, free);
|
||||
+ cl_banned_irqs = NULL;
|
||||
+
|
||||
+ log(TO_ALL, LOG_INFO, "Ban irqs(%s) online.\n", irq_string);
|
||||
+ if (!strncmp(irq_string, "NONE", strlen("NONE"))) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ irq = strtoul(irq_string, &end, 10);
|
||||
+ while (last != end) {
|
||||
+ add_cl_banned_irq(irq);
|
||||
+ log(TO_ALL, LOG_INFO, "add banned irq %d from api.\n", irq);
|
||||
+ last = end;
|
||||
+ irq = strtoul(end, &end, 10);
|
||||
+ };
|
||||
+}
|
||||
+
|
||||
+static void prase_banned_cpu_string(char *cpu_ban_string)
|
||||
+{
|
||||
+ if (strlen(cpu_ban_string) < 1)
|
||||
+ return;
|
||||
+ if (!is_set_banned_cpumask_from_ui)
|
||||
+ is_set_banned_cpumask_from_ui = 1;
|
||||
+
|
||||
+ strcpy(banned_cpumask_from_ui, cpu_ban_string);
|
||||
+ log(TO_ALL, LOG_INFO, "Ban cpus(%s) online.\n", cpu_ban_string);
|
||||
+ if (!strncmp(banned_cpumask_from_ui, "NONE", strlen("NONE"))) {
|
||||
+ memset((void*)banned_cpumask_from_ui, 0, NR_CPUS + 1);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+gboolean recv_msg_handle(gint client_fd,
|
||||
+ GIOCondition condition,
|
||||
+ gpointer user_data __attribute__((unused)))
|
||||
+{
|
||||
+ char buff[FILE_LINE_MAX_NUM];
|
||||
+ struct cmsghdr *cmsg;
|
||||
+ int recv_size = 0;
|
||||
+ int valid_user = 0;
|
||||
+ struct iovec iov = { buff, FILE_LINE_MAX_NUM - 1 };
|
||||
+ struct msghdr msg = { 0 };
|
||||
+ int new_iterval = 0;
|
||||
+
|
||||
+ if (condition == G_IO_IN) {
|
||||
+ msg.msg_iov = &iov;
|
||||
+ msg.msg_iovlen = 1;
|
||||
+ msg.msg_control = malloc(CMSG_SPACE(sizeof(struct ucred)));
|
||||
+ if (!msg.msg_control) {
|
||||
+ goto out_close;
|
||||
+ }
|
||||
+ msg.msg_controllen = CMSG_SPACE(sizeof(struct ucred));
|
||||
+ if ((recv_size = recvmsg(client_fd, &msg, 0)) < 0) {
|
||||
+ log(TO_ALL, LOG_WARNING, "Error while receiving data:%d %s\n", recv_size, strerror(errno));
|
||||
+ goto out_close;
|
||||
+ }
|
||||
+ cmsg = CMSG_FIRSTHDR(&msg);
|
||||
+ if ((cmsg->cmsg_level == SOL_SOCKET) &&
|
||||
+ (cmsg->cmsg_type == SCM_CREDENTIALS)) {
|
||||
+ struct ucred *credentials = (struct ucred *) CMSG_DATA(cmsg);
|
||||
+ if (!credentials->uid) {
|
||||
+ valid_user = 1;
|
||||
+ }
|
||||
+ }
|
||||
+ if (!valid_user) {
|
||||
+ log(TO_ALL, LOG_INFO, "Permission denied for user to connect to socket.\n");
|
||||
+ goto out_close;
|
||||
+ }
|
||||
+ if (!strncmp(buff, "settings ", strlen("settings "))) {
|
||||
+ if (!(strncmp(buff + strlen("settings "), "sleep ",
|
||||
+ strlen("sleep ")))) {
|
||||
+ new_iterval = strtoul(buff + strlen("settings sleep "), NULL, 10);
|
||||
+ if (new_iterval >= 1) {
|
||||
+ sleep_interval = new_iterval;
|
||||
+ }
|
||||
+ } else if (!(strncmp(buff + strlen("settings "), "ban irqs \"",
|
||||
+ strlen("ban irqs \"")))
|
||||
+ && buff[recv_size - 1] == '\"') {
|
||||
+ buff[recv_size - 1] = '\0';
|
||||
+ prase_banned_irq_string(buff + strlen("settings ban irqs \""));
|
||||
+ need_rescan = 1;
|
||||
+ } else if (!(strncmp(buff + strlen("settings "), "cpus ",
|
||||
+ strlen("cpus")))) {
|
||||
+ if (recv_size > (int)(NR_CPUS + strlen("settings cpus "))) {
|
||||
+ log(TO_ALL, LOG_WARNING, "Setting cpus more than limit: %d.\n",
|
||||
+ NR_CPUS);
|
||||
+ goto out_close;
|
||||
+ }
|
||||
+ buff[recv_size] = '\0';
|
||||
+ prase_banned_cpu_string(buff + strlen("settings cpus "));
|
||||
+ need_rescan = 1;
|
||||
+ }
|
||||
+ } else if (!strncmp(buff, "stats ", strlen("stats "))) {
|
||||
+ if (!(strncmp(buff + strlen("stats "), "cpu", strlen("cpu")))) {
|
||||
+ fill_banned_cpus(buff, FILE_LINE_MAX_NUM - 1);
|
||||
+ send_msg(client_fd, buff, strlen(buff));
|
||||
+ } else if (!(strncmp(buff + strlen("stats "), "irq", strlen("irq")))) {
|
||||
+ fill_banned_irqs(buff, FILE_LINE_MAX_NUM - 1);
|
||||
+ send_msg(client_fd, buff, strlen(buff));
|
||||
+ }
|
||||
+ }
|
||||
+out_close:
|
||||
+ close(client_fd);
|
||||
+ free(msg.msg_control);
|
||||
+ cur_fd_count--;
|
||||
+ }
|
||||
+ return FALSE;
|
||||
+}
|
||||
+
|
||||
+gboolean accept_handle(gint fd,
|
||||
+ GIOCondition condition,
|
||||
+ gpointer user_data __attribute__((unused)))
|
||||
+{
|
||||
+ int client_fd;
|
||||
+
|
||||
+ if (condition != G_IO_IN) {
|
||||
+ return TRUE;
|
||||
+ }
|
||||
+ client_fd = accept(fd, NULL, NULL);
|
||||
+ if (client_fd < 0) {
|
||||
+ log(TO_ALL, LOG_WARNING, "Connection couldn't be accepted.\n");
|
||||
+ return TRUE;
|
||||
+ }
|
||||
+ if (cur_fd_count >= MAX_EVENTS) {
|
||||
+ log(TO_ALL, LOG_WARNING, "Daemon support no more than %d connection\n",
|
||||
+ MAX_EVENTS);
|
||||
+ close(client_fd);
|
||||
+ return TRUE;
|
||||
+ }
|
||||
+ if (setnonblocking(client_fd) < 0) {
|
||||
+ log(TO_ALL, LOG_WARNING, "Daemon set connection nonblocking failed: %s.\n",
|
||||
+ strerror(errno));
|
||||
+ close(client_fd);
|
||||
+ return TRUE;
|
||||
+ }
|
||||
+ cur_fd_count++;
|
||||
+ g_unix_fd_add(client_fd, G_IO_IN, recv_msg_handle, NULL);
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+int init_unblock_socket()
|
||||
+{
|
||||
+ struct sockaddr_un addr;
|
||||
+ int optval = 1;
|
||||
+
|
||||
+ (void)unlink(socket_name);
|
||||
+
|
||||
+ socket_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
|
||||
+ if (socket_fd < 0) {
|
||||
+ log(TO_ALL, LOG_WARNING, "Socket couldn't be created.\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * First try to create a file-based socket in tmpfs. If that doesn't
|
||||
+ * succeed, fall back to an abstract socket (non file-based).
|
||||
+ */
|
||||
+ memset(&addr, 0, sizeof(struct sockaddr_un));
|
||||
+ addr.sun_family = AF_UNIX;
|
||||
+ snprintf(socket_name, 64, "%s/%s%d.sock", SOCKET_TMPFS, SOCKET_PATH, getpid());
|
||||
+ strncpy(addr.sun_path, socket_name, sizeof(addr.sun_path));
|
||||
+ if (bind(socket_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
+ log(TO_ALL, LOG_WARNING, "Daemon couldn't be bound to the file-based socket.\n");
|
||||
+ /* Try binding to abstract */
|
||||
+ memset(&addr, 0, sizeof(struct sockaddr_un));
|
||||
+ addr.sun_family = AF_UNIX;
|
||||
+ if (bind(socket_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
+ log(TO_ALL, LOG_WARNING, "Daemon couldn't be bound to the abstract socket.\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (chmod(socket_name, SOCK_RWX_MODE) != 0) {
|
||||
+ /* when use abstract socket, chmod may fail. No need return here. */
|
||||
+ log(TO_ALL, LOG_WARNING, "socket name : %s, chmod failed\n", socket_name);
|
||||
+ }
|
||||
+
|
||||
+ if (setsockopt(socket_fd, SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval)) < 0) {
|
||||
+ log(TO_ALL, LOG_WARNING, "Unable to set socket options: %s.\n", strerror(errno));
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ if (listen(socket_fd, MAX_CLIENT) != 0) {
|
||||
+ log(TO_ALL, LOG_WARNING, "Daemon couldn't be listening to the socket: %s.\n",
|
||||
+ strerror(errno));
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ if (setnonblocking(socket_fd) < 0) {
|
||||
+ log(TO_ALL, LOG_WARNING, "Daemon set connection(listen) nonblocking failed: %s.\n",
|
||||
+ strerror(errno));
|
||||
+ return 1;
|
||||
+ }
|
||||
+ banned_cpumask_from_ui = (char*)malloc(NR_CPUS + 1);
|
||||
+ if (!banned_cpumask_from_ui) {
|
||||
+ log(TO_ALL, LOG_WARNING, "Daemon faild to malloc banned_cpumask_from_ui space.\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ memset((void*)banned_cpumask_from_ui, 0, NR_CPUS + 1);
|
||||
+
|
||||
+ g_unix_fd_add(socket_fd, G_IO_IN, accept_handle, NULL);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/sockapi.h b/sockapi.h
|
||||
new file mode 100644
|
||||
index 0000000..3875234
|
||||
--- /dev/null
|
||||
+++ b/sockapi.h
|
||||
@@ -0,0 +1,19 @@
|
||||
+#ifndef UVP_IRQBALANCE_SOCKAPI_H_
|
||||
+#define UVP_IRQBALANCE_SOCKAPI_H_
|
||||
+
|
||||
+#include <sys/stat.h>
|
||||
+
|
||||
+/* set socket file mode to 660 */
|
||||
+#define SOCK_RWX_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)
|
||||
+
|
||||
+#define SLEEP_TIME (100 * 1000) /* 100ms */
|
||||
+
|
||||
+#define MAX_CLIENT 512
|
||||
+
|
||||
+#define MAX_EVENTS 1024
|
||||
+
|
||||
+#define FILE_LINE_MAX_NUM (4096*6)
|
||||
+
|
||||
+int init_unblock_socket();
|
||||
+
|
||||
+#endif
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,83 +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 1/6] feature: irqbalance: 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 | 23 ++++++++++++++++++++++-
|
||||
1 file changed, 22 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/procinterrupts.c b/procinterrupts.c
|
||||
index fc4641a..99bcf50 100644
|
||||
--- a/procinterrupts.c
|
||||
+++ b/procinterrupts.c
|
||||
@@ -107,7 +107,9 @@ static void guess_arm_irq_hints(char *name, struct irq_info *info)
|
||||
static int compiled = 0;
|
||||
/* Note: Last entry is a catchall */
|
||||
static struct irq_match matches[] = {
|
||||
- { "eth.*" ,{NULL} ,NULL, IRQ_TYPE_LEGACY, IRQ_GBETH },
|
||||
+ { "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},
|
||||
@@ -152,6 +154,7 @@ static void init_irq_class_and_type(char *savedline, struct irq_info *info, int
|
||||
int is_xen_dyn = 0;
|
||||
#ifdef AARCH64
|
||||
char *tmp = NULL;
|
||||
+ char irq_fullname[PATH_MAX] = {0};
|
||||
#endif
|
||||
|
||||
irq_name = strtok_r(savedline, " ", &savedptr);
|
||||
@@ -163,6 +166,16 @@ static void init_irq_class_and_type(char *savedline, struct irq_info *info, int
|
||||
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
|
||||
@@ -171,6 +184,13 @@ static void init_irq_class_and_type(char *savedline, struct irq_info *info, int
|
||||
tmp = strchr(irq_name, '\n');
|
||||
if (tmp)
|
||||
*tmp = 0;
|
||||
+
|
||||
+ strcat(irq_fullname, irq_name);
|
||||
+ strcat(irq_fullname, " ");
|
||||
+ strcat(irq_fullname, savedptr);
|
||||
+ tmp = strchr(irq_fullname, '\n');
|
||||
+ if (tmp)
|
||||
+ *tmp = 0;
|
||||
#endif
|
||||
irq_mod = last_token;
|
||||
info->irq = irq;
|
||||
@@ -180,6 +200,7 @@ static void init_irq_class_and_type(char *savedline, struct irq_info *info, int
|
||||
info->class = IRQ_VIRT_EVENT;
|
||||
} else {
|
||||
#ifdef AARCH64
|
||||
+ irq_name = irq_fullname;
|
||||
guess_arm_irq_hints(irq_name, info);
|
||||
#else
|
||||
info->type = IRQ_TYPE_LEGACY;
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,131 +0,0 @@
|
||||
From 0ddf835e21b4d33aba9d30755cc5674d1ee5a979 Mon Sep 17 00:00:00 2001
|
||||
From: Zengruan Ye <yezengruan@huawei.com>
|
||||
Date: Sat, 13 Jul 2019 19:12:29 +0800
|
||||
Subject: [PATCH 2/6] feature: irqbalance: arm64: Add irq aff change check
|
||||
|
||||
For aarch64, the PPIs format in /proc/interrputs can be parsed
|
||||
and add to interrupt db, and next, the number of interrupts
|
||||
is counted and used to calculate the load. Finally these interrupts
|
||||
maybe scheduled between the NUMA domains.
|
||||
|
||||
Acctually, the PPIs cannot change aff, and it should not be added
|
||||
to interrupt db. This patch fix it.
|
||||
|
||||
Add a check before add a interrupt to db, just only reads the irq's
|
||||
aff, and write it back to avoid any impact on the system,
|
||||
According to the result of writing to fitler the irq.
|
||||
|
||||
Signed-off-by: wanghaibin <wanghaibin.wang@huawei.com>
|
||||
---
|
||||
classify.c | 7 +++++++
|
||||
irqbalance.h | 3 +++
|
||||
procinterrupts.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 64 insertions(+)
|
||||
|
||||
diff --git a/classify.c b/classify.c
|
||||
index 3a25d62..65cb4e5 100644
|
||||
--- a/classify.c
|
||||
+++ b/classify.c
|
||||
@@ -299,6 +299,13 @@ static void add_banned_irq(int irq, GList **list, int extra_flag)
|
||||
return;
|
||||
}
|
||||
|
||||
+#ifdef AARCH64
|
||||
+void add_banned_list_irq(int irq)
|
||||
+{
|
||||
+ add_banned_irq(irq, &banned_irqs);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
void add_cl_banned_irq(int irq)
|
||||
{
|
||||
add_banned_irq(irq, &cl_banned_irqs);
|
||||
diff --git a/irqbalance.h b/irqbalance.h
|
||||
index 821de0e..c00430f 100644
|
||||
--- a/irqbalance.h
|
||||
+++ b/irqbalance.h
|
||||
@@ -100,6 +100,9 @@ extern int get_cpu_count(void);
|
||||
extern void rebuild_irq_db(void);
|
||||
extern void free_irq_db(void);
|
||||
extern void add_cl_banned_irq(int irq);
|
||||
+#ifdef AARCH64
|
||||
+extern void add_banned_list_irq(int irq);
|
||||
+#endif
|
||||
extern void for_each_irq(GList *list, void (*cb)(struct irq_info *info, void *data), void *data);
|
||||
extern struct irq_info *get_irq_info(int irq);
|
||||
extern void migrate_irq(GList **from, GList **to, struct irq_info *info);
|
||||
diff --git a/procinterrupts.c b/procinterrupts.c
|
||||
index 9e38e49..1f04a82 100644
|
||||
--- a/procinterrupts.c
|
||||
+++ b/procinterrupts.c
|
||||
@@ -142,6 +142,42 @@ static void guess_arm_irq_hints(char *name, struct irq_info *info)
|
||||
|
||||
|
||||
}
|
||||
+
|
||||
+/*
|
||||
+ * This check is only invoked at service startup, and avoid any impact on the system,
|
||||
+ * The scheme just only reads the irq's aff, and write it back. According to the result
|
||||
+ * of writing to fitler the irq.
|
||||
+ * Return 0 means the irq can change aff. Other return values, on the contrary.
|
||||
+ */
|
||||
+static int is_arm_irq_aff_cannot_change(int irq)
|
||||
+{
|
||||
+ char buf[PATH_MAX] = { 0 };
|
||||
+ FILE *file = NULL;
|
||||
+ char *line = NULL;
|
||||
+ size_t size = 0;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ snprintf(buf, PATH_MAX - 1, "/proc/irq/%i/smp_affinity", irq);
|
||||
+ file = fopen(buf, "r+");
|
||||
+ if (!file)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (getline(&line, &size, file) <= 0) {
|
||||
+ ret = -1;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ line[strlen(line) - 1] = '\0';
|
||||
+
|
||||
+ fprintf(file, "%s", line);
|
||||
+ ret = fflush(file);
|
||||
+
|
||||
+out:
|
||||
+ free(line);
|
||||
+ fclose(file);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
#endif
|
||||
static void init_irq_class_and_type(char *savedline, struct irq_info *info, int irq) {
|
||||
char *irq_name = NULL;
|
||||
@@ -233,6 +269,24 @@ GList* collect_full_irq_list()
|
||||
c++;
|
||||
number = strtoul(line, NULL, 10);
|
||||
|
||||
+#ifdef AARCH64
|
||||
+ if (is_arm_irq_aff_cannot_change(number)) {
|
||||
+ /*
|
||||
+ * This means that the irq affinity cannot be changed, just like:
|
||||
+ * (1) the irq with IRQF_PERCPU flag, per cpu irq (in arm64, like PPI)
|
||||
+ * (2) the irq with IRQD_NO_BALANCING flag, some driver request irq can
|
||||
+ * set the flag according to themselves require. for example in arm64,
|
||||
+ * for the passthrough doorbell irq (GICV4), in future.
|
||||
+ * (3) the irq with IRQD_AFFINITY_MANAGED flag, some drivers can set
|
||||
+ * specially irq affinity, and prohibit user to modify it.
|
||||
+ *
|
||||
+ * For these irqs, we can add these to banned irq list.
|
||||
+ */
|
||||
+ add_banned_list_irq(number);
|
||||
+ continue;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
info = calloc(sizeof(struct irq_info), 1);
|
||||
if (info) {
|
||||
init_irq_class_and_type(savedline, info, number);
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,345 +0,0 @@
|
||||
From fd447c6f129769fcb685d8a2e22c75a922efe342 Mon Sep 17 00:00:00 2001
|
||||
From: Zengruan Ye <yezengruan@huawei.com>
|
||||
Date: Mon, 15 Jul 2019 21:35:29 +0800
|
||||
Subject: [PATCH 3/6] feature: irqbalance: auto banned pci-assigned irq
|
||||
|
||||
checkout VM pci-assigned pci device irq, and banned it
|
||||
|
||||
Signed-off-by: Xu Yandong <xuyandong2@huawei.com>
|
||||
---
|
||||
activate.c | 38 ++++++++++++++++++++++++++++++++++++-
|
||||
classify.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++-------
|
||||
irqbalance.c | 11 +++++++++++
|
||||
irqbalance.h | 2 ++
|
||||
procinterrupts.c | 23 ++++++++++++++++++++++
|
||||
types.h | 1 +
|
||||
6 files changed, 125 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/activate.c b/activate.c
|
||||
index 1c4b867..ad60fde 100644
|
||||
--- a/activate.c
|
||||
+++ b/activate.c
|
||||
@@ -29,9 +29,12 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
+#include <dirent.h>
|
||||
|
||||
#include "irqbalance.h"
|
||||
|
||||
+extern int ban_pci_assigned_irq;
|
||||
+
|
||||
static int check_affinity(struct irq_info *info, cpumask_t applied_mask)
|
||||
{
|
||||
cpumask_t current_mask;
|
||||
@@ -56,6 +59,30 @@ static int check_affinity(struct irq_info *info, cpumask_t applied_mask)
|
||||
return cpus_equal(applied_mask, current_mask);
|
||||
}
|
||||
|
||||
+static int is_still_pci_assigned_irq(int irq)
|
||||
+{
|
||||
+ DIR *dir = NULL;
|
||||
+ struct dirent *ptr = NULL;
|
||||
+ char irq_path[PATH_MAX] = { 0 };
|
||||
+
|
||||
+ snprintf(irq_path, PATH_MAX - 1, "/proc/irq/%i/", irq);
|
||||
+ if ((dir = opendir(irq_path)) == NULL) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ while ((ptr = readdir(dir)) != NULL) {
|
||||
+ if(strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) {
|
||||
+ continue;
|
||||
+ } else if (is_pci_assigned_irq(ptr->d_name)) {
|
||||
+ closedir(dir);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ closedir(dir);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static void activate_mapping(struct irq_info *info, void *data __attribute__((unused)))
|
||||
{
|
||||
char buf[PATH_MAX];
|
||||
@@ -89,7 +116,16 @@ static void activate_mapping(struct irq_info *info, void *data __attribute__((un
|
||||
return;
|
||||
|
||||
cpumask_scnprintf(buf, PATH_MAX, applied_mask);
|
||||
- fprintf(file, "%s", buf);
|
||||
+ if (ban_pci_assigned_irq) {
|
||||
+ if (!is_still_pci_assigned_irq(info->irq)) {
|
||||
+ fprintf(file, "%s", buf);
|
||||
+ } else {
|
||||
+ log(TO_CONSOLE, LOG_INFO, "IRQ %d is turned into a PCI-assigned irq number.\n", info->irq);
|
||||
+ need_rescan = 1;
|
||||
+ }
|
||||
+ } else {
|
||||
+ fprintf(file, "%s", buf);
|
||||
+ }
|
||||
fclose(file);
|
||||
info->moved = 0; /*migration is done*/
|
||||
}
|
||||
diff --git a/classify.c b/classify.c
|
||||
index 37bfb29..52fd74a 100644
|
||||
--- a/classify.c
|
||||
+++ b/classify.c
|
||||
@@ -37,6 +37,7 @@ static GList *interrupts_db = NULL;
|
||||
static GList *banned_irqs = NULL;
|
||||
GList *cl_banned_irqs = NULL;
|
||||
static GList *cl_banned_modules = NULL;
|
||||
+static GList *vm_banned_irqs = NULL;
|
||||
|
||||
#define SYSFS_DIR "/sys"
|
||||
#define SYSPCI_DIR "/sys/bus/pci/devices"
|
||||
@@ -264,7 +265,7 @@ static gint compare_ints(gconstpointer a, gconstpointer b)
|
||||
return ai->irq - bi->irq;
|
||||
}
|
||||
|
||||
-static void add_banned_irq(int irq, GList **list)
|
||||
+static void add_banned_irq(int irq, GList **list, int extra_flag)
|
||||
{
|
||||
struct irq_info find, *new;
|
||||
GList *entry;
|
||||
@@ -282,6 +283,7 @@ static void add_banned_irq(int irq, GList **list)
|
||||
|
||||
new->irq = irq;
|
||||
new->flags |= IRQ_FLAG_BANNED;
|
||||
+ new->flags |= extra_flag;
|
||||
|
||||
*list = g_list_append(*list, new);
|
||||
log(TO_CONSOLE, LOG_INFO, "IRQ %d was BANNED.\n", irq);
|
||||
@@ -291,13 +293,18 @@ static void add_banned_irq(int irq, GList **list)
|
||||
#ifdef AARCH64
|
||||
void add_banned_list_irq(int irq)
|
||||
{
|
||||
- add_banned_irq(irq, &banned_irqs);
|
||||
+ add_banned_irq(irq, &banned_irqs, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
void add_cl_banned_irq(int irq)
|
||||
{
|
||||
- add_banned_irq(irq, &cl_banned_irqs);
|
||||
+ add_banned_irq(irq, &cl_banned_irqs, 0);
|
||||
+}
|
||||
+
|
||||
+void add_vm_banned_irq(int irq)
|
||||
+{
|
||||
+ add_banned_irq(irq, &vm_banned_irqs, IRQ_FLAG_VM_BANNED);
|
||||
}
|
||||
|
||||
static int is_banned_irq(int irq)
|
||||
@@ -307,7 +314,10 @@ static int is_banned_irq(int irq)
|
||||
|
||||
find.irq = irq;
|
||||
|
||||
- entry = g_list_find_custom(banned_irqs, &find, compare_ints);
|
||||
+ entry = g_list_find_custom(vm_banned_irqs, &find, compare_ints);
|
||||
+ if (!entry)
|
||||
+ entry = g_list_find_custom(banned_irqs, &find, compare_ints);
|
||||
+
|
||||
return entry ? 1:0;
|
||||
}
|
||||
|
||||
@@ -660,7 +670,7 @@ struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list)
|
||||
continue;
|
||||
get_irq_user_policy(devpath, irqnum, &pol);
|
||||
if ((pol.ban == 1) || (check_for_irq_ban(devpath, irqnum, tmp_list))) {
|
||||
- add_banned_irq(irqnum, &banned_irqs);
|
||||
+ add_banned_irq(irqnum, &banned_irqs, 0);
|
||||
continue;
|
||||
}
|
||||
hint.irq = irqnum;
|
||||
@@ -695,7 +705,7 @@ struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list)
|
||||
goto done;
|
||||
get_irq_user_policy(devpath, irqnum, &pol);
|
||||
if ((pol.ban == 1) || (check_for_irq_ban(path, irqnum, tmp_list))) {
|
||||
- add_banned_irq(irqnum, &banned_irqs);
|
||||
+ add_banned_irq(irqnum, &banned_irqs, 0);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -811,6 +821,9 @@ void free_irq_db(void)
|
||||
banned_irqs = NULL;
|
||||
g_list_free(rebalance_irq_list);
|
||||
rebalance_irq_list = NULL;
|
||||
+ for_each_irq(vm_banned_irqs, free_irq, NULL);
|
||||
+ g_list_free(vm_banned_irqs);
|
||||
+ vm_banned_irqs = NULL;
|
||||
}
|
||||
|
||||
void free_cl_opts(void)
|
||||
@@ -832,7 +845,7 @@ struct irq_info *add_new_irq(int irq, struct irq_info *hint, GList *proc_interru
|
||||
/* Set NULL devpath for the irq has no sysfs entries */
|
||||
get_irq_user_policy(NULL, irq, &pol);
|
||||
if ((pol.ban == 1) || check_for_irq_ban(NULL, irq, proc_interrupts)) { /*FIXME*/
|
||||
- add_banned_irq(irq, &banned_irqs);
|
||||
+ add_banned_irq(irq, &banned_irqs, 0);
|
||||
new = get_irq_info(irq);
|
||||
} else
|
||||
new = add_one_irq_to_db(NULL, hint, &pol);
|
||||
@@ -906,6 +919,9 @@ struct irq_info *get_irq_info(int irq)
|
||||
entry = g_list_find_custom(interrupts_db, &find, compare_ints);
|
||||
|
||||
if (!entry)
|
||||
+ entry = g_list_find_custom(vm_banned_irqs, &find, compare_ints);
|
||||
+
|
||||
+ if (!entry)
|
||||
entry = g_list_find_custom(banned_irqs, &find, compare_ints);
|
||||
|
||||
return entry ? entry->data : NULL;
|
||||
@@ -954,3 +970,31 @@ void sort_irq_list(GList **list)
|
||||
{
|
||||
*list = g_list_sort(*list, sort_irqs);
|
||||
}
|
||||
+
|
||||
+/*
|
||||
+ * assigned pci device's irq in /proc/interrupts
|
||||
+ * has keyword "vfio" or "kvm"
|
||||
+ * and BDF notation "xxxx:xx:xx.x"
|
||||
+ */
|
||||
+int is_pci_assigned_irq(const char *line)
|
||||
+{
|
||||
+ const char *pos = NULL;
|
||||
+
|
||||
+ pos = strstr(line, "vfio");
|
||||
+ if (!pos) {
|
||||
+ pos = strstr(line, "kvm");
|
||||
+ }
|
||||
+
|
||||
+ if (!pos)
|
||||
+ return 0;
|
||||
+
|
||||
+ while (*pos) {
|
||||
+ if (*pos >= '0' && *pos <= '9') {
|
||||
+ if (*(pos + 4) == ':' && *(pos + 7) == ':' && *(pos + 10) == '.')
|
||||
+ return 1;
|
||||
+ }
|
||||
+ pos++;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index 4787cb2..40ec65c 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "irqbalance.h"
|
||||
|
||||
volatile int keep_going = 1;
|
||||
+volatile int ban_pci_assigned_irq = 1;
|
||||
int socket_fd;
|
||||
char socket_name[64];
|
||||
int one_shot_mode;
|
||||
@@ -375,6 +376,12 @@ gboolean scan()
|
||||
}
|
||||
}
|
||||
|
||||
+static void parse_ban_pci_assigned_irq(char *status)
|
||||
+{
|
||||
+ if (status && (0 == strcmp(status,"disabled")))
|
||||
+ ban_pci_assigned_irq = 0;
|
||||
+}
|
||||
+
|
||||
void get_irq_data(struct irq_info *irq, void *data)
|
||||
{
|
||||
char **irqdata = (char **)data;
|
||||
@@ -619,6 +626,10 @@ int main(int argc, char** argv)
|
||||
foreground_mode=1;
|
||||
}
|
||||
|
||||
+ if (getenv("IRQBALANCE_AUTO_BAN_PCI_ASSIGNED_IRQS")) {
|
||||
+ parse_ban_pci_assigned_irq(getenv("IRQBALANCE_AUTO_BAN_PCI_ASSIGNED_IRQS"));
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* If we are't in debug mode, don't dump anything to the console
|
||||
* note that everything goes to the console before we check this
|
||||
diff --git a/irqbalance.h b/irqbalance.h
|
||||
index 5016cc8..339e2a3 100644
|
||||
--- a/irqbalance.h
|
||||
+++ b/irqbalance.h
|
||||
@@ -103,8 +103,10 @@ extern void add_cl_banned_irq(int irq);
|
||||
#ifdef AARCH64
|
||||
extern void add_banned_list_irq(int irq);
|
||||
#endif
|
||||
+extern void add_vm_banned_irq(int irq);
|
||||
extern void for_each_irq(GList *list, void (*cb)(struct irq_info *info, void *data), void *data);
|
||||
extern struct irq_info *get_irq_info(int irq);
|
||||
+extern int is_pci_assigned_irq(const char *line);
|
||||
extern void migrate_irq(GList **from, GList **to, struct irq_info *info);
|
||||
extern void free_cl_opts(void);
|
||||
extern void add_cl_banned_module(char *modname);
|
||||
diff --git a/procinterrupts.c b/procinterrupts.c
|
||||
index 6cfa661..522b9a1 100644
|
||||
--- a/procinterrupts.c
|
||||
+++ b/procinterrupts.c
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
static int proc_int_has_msi = 0;
|
||||
static int msi_found_in_sysfs = 0;
|
||||
+extern int ban_pci_assigned_irq;
|
||||
|
||||
#ifdef AARCH64
|
||||
struct irq_match {
|
||||
@@ -290,6 +291,12 @@ GList* collect_full_irq_list()
|
||||
c++;
|
||||
number = strtoul(line, NULL, 10);
|
||||
|
||||
+ if (ban_pci_assigned_irq && is_pci_assigned_irq(c)) {
|
||||
+ log(TO_ALL, LOG_INFO, "Banned PCI-assigned irq %d.\n", number);
|
||||
+ add_vm_banned_irq(number);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
#ifdef AARCH64
|
||||
if (is_arm_irq_aff_cannot_change(number)) {
|
||||
/*
|
||||
@@ -333,6 +340,7 @@ void parse_proc_interrupts(void)
|
||||
FILE *file;
|
||||
char *line = NULL;
|
||||
size_t size = 0;
|
||||
+ int vfio_flag = 0;
|
||||
|
||||
file = fopen("/proc/interrupts", "r");
|
||||
if (!file)
|
||||
@@ -400,6 +408,21 @@ void parse_proc_interrupts(void)
|
||||
}
|
||||
info->existing = 1;
|
||||
|
||||
+ if (ban_pci_assigned_irq) {
|
||||
+ vfio_flag = is_pci_assigned_irq(c);
|
||||
+ if (vfio_flag && (info->flags & IRQ_FLAG_VM_BANNED) == 0) {
|
||||
+ log(TO_ALL, LOG_INFO, "IRQ %d has been reused as a pci assigned interrupt number", number);
|
||||
+ need_rescan = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (!vfio_flag && (info->flags & IRQ_FLAG_VM_BANNED) != 0) {
|
||||
+ log(TO_ALL, LOG_INFO, "IRQ %d has been reused as a general interrupt number", number);
|
||||
+ need_rescan = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
count = 0;
|
||||
cpunr = 0;
|
||||
|
||||
diff --git a/types.h b/types.h
|
||||
index 62cc2bb..c0950ee 100644
|
||||
--- a/types.h
|
||||
+++ b/types.h
|
||||
@@ -35,6 +35,7 @@
|
||||
* IRQ Internal tracking flags
|
||||
*/
|
||||
#define IRQ_FLAG_BANNED 1
|
||||
+#define IRQ_FLAG_VM_BANNED 2
|
||||
|
||||
enum obj_type_e {
|
||||
OBJ_TYPE_CPU,
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
From aeb65d281ba122ba7539d551984bd37115d48811 Mon Sep 17 00:00:00 2001
|
||||
From: hejingxian <hejingxian@huawei.com>
|
||||
Date: Tue, 10 Sep 2019 22:48:24 +0800
|
||||
Subject: [PATCH] supplement irqbalance service config
|
||||
|
||||
Add irqbalance service config: OOMScoreAdjust, Type, PIDFile, StartLimitInterval, StartLimitBurst, and so on.
|
||||
Modify ExecStart script to improve banirq args config.
|
||||
---
|
||||
irqbalance.service | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/misc/irqbalance.service b/misc/irqbalance.service
|
||||
index 8a5b1f4..ce0022c 100644
|
||||
--- a/misc/irqbalance.service
|
||||
+++ b/misc/irqbalance.service
|
||||
@@ -1,10 +1,16 @@
|
||||
[Unit]
|
||||
Description=irqbalance daemon
|
||||
ConditionVirtualization=!container
|
||||
+After=syslog.target
|
||||
|
||||
[Service]
|
||||
+OOMScoreAdjust=-500
|
||||
+Type=simple
|
||||
+PIDFile=/var/run/irqbalance.pid
|
||||
EnvironmentFile=/etc/sysconfig/irqbalance
|
||||
-ExecStart=/usr/sbin/irqbalance --foreground $IRQBALANCE_ARGS
|
||||
+ExecStart=/usr/sbin/irq_balancer
|
||||
+StartLimitInterval=10
|
||||
+StartLimitBurst=10000
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,105 +0,0 @@
|
||||
From 9f7b1a93150c6bb1f54a7bf5ce36b344f10cdf4a Mon Sep 17 00:00:00 2001
|
||||
From: Neil Horman <nhorman@tuxdriver.com>
|
||||
Date: Wed, 20 Feb 2019 12:03:16 -0500
|
||||
Subject: [PATCH 110/112] fix balancing when numa information isn't available
|
||||
|
||||
Discovered a bug in which, when numa isn't available we failed to assign
|
||||
the unspecified node to the device tree, leading us to not balance any
|
||||
interrupts. Make sure it gets added so irq get parsed down through the
|
||||
tree to the proper topology node
|
||||
|
||||
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
|
||||
---
|
||||
cputree.c | 22 +++++++++++++++++++---
|
||||
placement.c | 9 +++++----
|
||||
2 files changed, 24 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/cputree.c b/cputree.c
|
||||
index f08ce84..5551784 100644
|
||||
--- a/cputree.c
|
||||
+++ b/cputree.c
|
||||
@@ -126,9 +126,10 @@ static void add_numa_node_to_topo_obj(struct topo_obj *obj, int nodeid)
|
||||
GList *entry;
|
||||
struct topo_obj *node;
|
||||
struct topo_obj *cand_node;
|
||||
+ struct topo_obj *package;
|
||||
|
||||
node = get_numa_node(nodeid);
|
||||
- if (!node || node->number == -1)
|
||||
+ if (!node || (numa_avail && (node->number == -1)))
|
||||
return;
|
||||
|
||||
entry = g_list_first(obj->numa_nodes);
|
||||
@@ -141,6 +142,21 @@ static void add_numa_node_to_topo_obj(struct topo_obj *obj, int nodeid)
|
||||
|
||||
if (!entry)
|
||||
obj->numa_nodes = g_list_append(obj->numa_nodes, node);
|
||||
+
|
||||
+ if (!numa_avail && obj->obj_type == OBJ_TYPE_PACKAGE) {
|
||||
+ entry = g_list_first(node->children);
|
||||
+ while (entry) {
|
||||
+ package = entry->data;
|
||||
+ if (package == obj)
|
||||
+ break;
|
||||
+ entry = g_list_next(entry);
|
||||
+ }
|
||||
+
|
||||
+ if (!entry) {
|
||||
+ node->children = g_list_append(node->children, obj);
|
||||
+ obj->parent = node;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
static struct topo_obj* add_cache_domain_to_package(struct topo_obj *cache,
|
||||
@@ -189,7 +205,7 @@ static struct topo_obj* add_cache_domain_to_package(struct topo_obj *cache,
|
||||
cache->parent = package;
|
||||
}
|
||||
|
||||
- if (nodeid > -1)
|
||||
+ if (!numa_avail || (nodeid > -1))
|
||||
add_numa_node_to_topo_obj(package, nodeid);
|
||||
|
||||
return package;
|
||||
@@ -236,7 +252,7 @@ static struct topo_obj* add_cpu_to_cache_domain(struct topo_obj *cpu,
|
||||
cpu->parent = (struct topo_obj *)cache;
|
||||
}
|
||||
|
||||
- if (nodeid > -1)
|
||||
+ if (!numa_avail || (nodeid > -1))
|
||||
add_numa_node_to_topo_obj(cache, nodeid);
|
||||
|
||||
return cache;
|
||||
diff --git a/placement.c b/placement.c
|
||||
index 5a82111..efa8c57 100644
|
||||
--- a/placement.c
|
||||
+++ b/placement.c
|
||||
@@ -130,7 +130,7 @@ static void place_irq_in_node(struct irq_info *info, void *data __attribute__((u
|
||||
if ((info->level == BALANCE_NONE) && cpus_empty(banned_cpus))
|
||||
return;
|
||||
|
||||
- if (irq_numa_node(info)->number != -1) {
|
||||
+ if (irq_numa_node(info)->number != -1 || !numa_avail) {
|
||||
/*
|
||||
* Need to make sure this node is elligible for migration
|
||||
* given the banned cpu list
|
||||
@@ -138,12 +138,13 @@ static void place_irq_in_node(struct irq_info *info, void *data __attribute__((u
|
||||
if (!cpus_intersects(irq_numa_node(info)->mask, unbanned_cpus))
|
||||
goto find_placement;
|
||||
/*
|
||||
- * This irq belongs to a device with a preferred numa node
|
||||
- * put it on that node
|
||||
- */
|
||||
+ * This irq belongs to a device with a preferred numa node
|
||||
+ * put it on that node
|
||||
+ */
|
||||
migrate_irq(&rebalance_irq_list, &irq_numa_node(info)->interrupts, info);
|
||||
info->assigned_obj = irq_numa_node(info);
|
||||
irq_numa_node(info)->load += info->load + 1;
|
||||
+
|
||||
return;
|
||||
}
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,96 +0,0 @@
|
||||
From 6c350eb9af2e36c40f4c1f2122e4b5b270c011b2 Mon Sep 17 00:00:00 2001
|
||||
From: Weiping Zhang <zhangweiping@didiglobal.com>
|
||||
Date: Fri, 8 Nov 2019 23:43:55 +0800
|
||||
Subject: [PATCH 5/5] fix invalid pointer dereference banned_cpumask_from_ui
|
||||
|
||||
The memory of cpu_ban_string was release in sock_handle function,
|
||||
so the banned_cpumask_from_ui will dereference an invalid memory.
|
||||
|
||||
Fix this issue by delay release memory.
|
||||
|
||||
Reproduce:
|
||||
echo "settings cpus 0-3" | nc -U `find /var/run/irqbalance/ -name *sock`
|
||||
|
||||
Signed-off-by: Weiping Zhang <zhangweiping@didiglobal.com>
|
||||
---
|
||||
cputree.c | 7 ++++++-
|
||||
irqbalance.c | 21 ++++++++++++++++++---
|
||||
2 files changed, 24 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/cputree.c b/cputree.c
|
||||
index 305f617..4c5fdf5 100644
|
||||
--- a/cputree.c
|
||||
+++ b/cputree.c
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "irqbalance.h"
|
||||
|
||||
extern char *banned_cpumask_from_ui;
|
||||
+extern char *cpu_ban_string;
|
||||
|
||||
GList *cpus;
|
||||
GList *cache_domains;
|
||||
@@ -104,9 +105,13 @@ static void setup_banned_cpus(void)
|
||||
cpus_clear(nohz_full);
|
||||
|
||||
/* A manually specified cpumask overrides auto-detection. */
|
||||
- if (banned_cpumask_from_ui != NULL) {
|
||||
+ if (cpu_ban_string != NULL && banned_cpumask_from_ui != NULL) {
|
||||
cpulist_parse(banned_cpumask_from_ui,
|
||||
strlen(banned_cpumask_from_ui), banned_cpus);
|
||||
+ /* release it safety, it was allocated in sock_handle */
|
||||
+ free(cpu_ban_string);
|
||||
+ cpu_ban_string = NULL;
|
||||
+ banned_cpumask_from_ui = NULL;
|
||||
goto out;
|
||||
}
|
||||
if (getenv("IRQBALANCE_BANNED_CPUS")) {
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index c9379ad..7630e38 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -65,6 +65,7 @@ int sleep_interval = SLEEP_INTERVAL;
|
||||
int last_interval;
|
||||
GMainLoop *main_loop;
|
||||
|
||||
+char *cpu_ban_string = NULL;
|
||||
char *banned_cpumask_from_ui = NULL;
|
||||
|
||||
static void sleep_approx(int seconds)
|
||||
@@ -469,7 +470,14 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
||||
free(irq_string);
|
||||
} else if (!(strncmp(buff + strlen("settings "), "cpus ",
|
||||
strlen("cpus")))) {
|
||||
- char *cpu_ban_string = malloc(
|
||||
+ /*
|
||||
+ * if cpu_ban_string has not been consumed,
|
||||
+ * just ignore this request.
|
||||
+ */
|
||||
+ if (cpu_ban_string != NULL)
|
||||
+ goto out_close;
|
||||
+
|
||||
+ cpu_ban_string = malloc(
|
||||
sizeof(char) * (recv_size - strlen("settings cpus ")));
|
||||
if (!cpu_ban_string)
|
||||
goto out_close;
|
||||
@@ -479,9 +487,16 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
||||
banned_cpumask_from_ui = strtok(cpu_ban_string, " ");
|
||||
if (!strncmp(banned_cpumask_from_ui, "NULL", strlen("NULL"))) {
|
||||
banned_cpumask_from_ui = NULL;
|
||||
+ free(cpu_ban_string);
|
||||
+ cpu_ban_string = NULL;;
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * don't free cpu_ban_string at here, it will be
|
||||
+ * released after we have store it to @banned_cpus
|
||||
+ * in setup_banned_cpus function.
|
||||
+ */
|
||||
+ need_rescan = 1;
|
||||
}
|
||||
- need_rescan = 1;
|
||||
- free(cpu_ban_string);
|
||||
}
|
||||
}
|
||||
if (!strncmp(buff, "setup", strlen("setup"))) {
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,27 +0,0 @@
|
||||
From d85897487c5f523ebc9ba8a56de911592703fed3 Mon Sep 17 00:00:00 2001
|
||||
From: liuchao173 <liuchao173@huawei.com>
|
||||
Date: Thu, 7 Nov 2019 09:27:55 +0000
|
||||
Subject: [PATCH 5/8] backport: fix resource leak for not invoking closedir()
|
||||
after opendir()
|
||||
|
||||
fix resource leak for not invoking closedir() after opendir()
|
||||
|
||||
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
|
||||
---
|
||||
ui/irqbalance-ui.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/ui/irqbalance-ui.c b/ui/irqbalance-ui.c
|
||||
index 47dd5dc..4dfbd46 100644
|
||||
--- a/ui/irqbalance-ui.c
|
||||
+++ b/ui/irqbalance-ui.c
|
||||
@@ -418,6 +418,7 @@ int main(int argc, char **argv)
|
||||
fclose(f);
|
||||
}
|
||||
} while((entry) && (irqbalance_pid == -1));
|
||||
+ closedir(dir);
|
||||
}
|
||||
if(irqbalance_pid == -1) {
|
||||
printf("Unable to determine irqbalance PID\n");
|
||||
--
|
||||
2.19.1
|
||||
@ -1,70 +0,0 @@
|
||||
From 4bddf961e18f59b27301b73895c0ae3a6cde9b7b Mon Sep 17 00:00:00 2001
|
||||
From: liuchao173 <liuchao173@huawei.com>
|
||||
Date: Thu, 7 Nov 2019 09:38:21 +0000
|
||||
Subject: [PATCH 8/8] backport: fix resource leak on the error paths in main()
|
||||
|
||||
Currently, both checking for core count < 2 and init_socket() fail, just
|
||||
return directly, so lead to resource leak.
|
||||
|
||||
Make it correct to free resource when on these situation.
|
||||
|
||||
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
|
||||
---
|
||||
irqbalance.c | 12 ++++++++----
|
||||
1 file changed, 8 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index cace4d8..5e5ef9b 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -556,6 +556,7 @@ int init_socket()
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
sigset_t sigset, old_sigset;
|
||||
+ int ret = EXIT_SUCCESS;
|
||||
|
||||
sigemptyset(&sigset);
|
||||
sigaddset(&sigset,SIGINT);
|
||||
@@ -636,7 +637,7 @@ int main(int argc, char** argv)
|
||||
"single cpu. Shutting down\n";
|
||||
|
||||
log(TO_ALL, LOG_WARNING, "%s", msg);
|
||||
- exit(EXIT_SUCCESS);
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
if (!foreground_mode) {
|
||||
@@ -673,7 +674,8 @@ int main(int argc, char** argv)
|
||||
parse_proc_stat();
|
||||
|
||||
if (init_socket()) {
|
||||
- return EXIT_FAILURE;
|
||||
+ ret = EXIT_FAILURE;
|
||||
+ goto out;
|
||||
}
|
||||
main_loop = g_main_loop_new(NULL, FALSE);
|
||||
last_interval = sleep_interval;
|
||||
@@ -682,6 +684,7 @@ int main(int argc, char** argv)
|
||||
|
||||
g_main_loop_quit(main_loop);
|
||||
|
||||
+out:
|
||||
free_object_tree();
|
||||
free_cl_opts();
|
||||
|
||||
@@ -689,9 +692,10 @@ int main(int argc, char** argv)
|
||||
if (!foreground_mode && pidfile)
|
||||
unlink(pidfile);
|
||||
/* Remove socket */
|
||||
- close(socket_fd);
|
||||
+ if (socket_fd > 0)
|
||||
+ close(socket_fd);
|
||||
if (socket_name[0])
|
||||
unlink(socket_name);
|
||||
|
||||
- return EXIT_SUCCESS;
|
||||
+ return ret;
|
||||
}
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,62 +0,0 @@
|
||||
From 97730f051e042e67da5728a3b59528c9d0fb72d2 Mon Sep 17 00:00:00 2001
|
||||
From: Pyxisha <xiashuang1@huawei.com>
|
||||
Date: Mon, 15 Jul 2019 20:47:07 +0800
|
||||
Subject: [PATCH 45/50] fix sleep interval when sleep_interval is changed by
|
||||
socket
|
||||
|
||||
currently, in scan, irqbalance compare sleep_interval's address to decide if sleep_interval is changed, accutually this judgement is always false now.
|
||||
|
||||
sign_off_by: Shuang Xia <xiashuang1@huawei.com>
|
||||
---
|
||||
irqbalance.c | 14 ++++++++------
|
||||
1 file changed, 8 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index c1a0e15..d424326 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -61,6 +61,7 @@ char *pidfile = NULL;
|
||||
char *polscript = NULL;
|
||||
long HZ;
|
||||
int sleep_interval = SLEEP_INTERVAL;
|
||||
+int last_interval;
|
||||
GMainLoop *main_loop;
|
||||
|
||||
char *banned_cpumask_from_ui = NULL;
|
||||
@@ -251,7 +252,7 @@ gboolean force_rescan(gpointer data __attribute__((unused)))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
-gboolean scan(gpointer data)
|
||||
+gboolean scan(gpointer data __attribute__((unused)))
|
||||
{
|
||||
log(TO_CONSOLE, LOG_INFO, "\n\n\n-----------------------------------------------------------------------------\n");
|
||||
clear_work_stats();
|
||||
@@ -289,9 +290,10 @@ gboolean scan(gpointer data)
|
||||
keep_going = 0;
|
||||
cycle_count++;
|
||||
|
||||
- if (data != &sleep_interval) {
|
||||
- data = &sleep_interval;
|
||||
- g_timeout_add_seconds(sleep_interval, scan, data);
|
||||
+ /* 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;
|
||||
}
|
||||
|
||||
@@ -623,8 +625,8 @@ int main(int argc, char** argv)
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
main_loop = g_main_loop_new(NULL, FALSE);
|
||||
- int *last_interval = &sleep_interval;
|
||||
- g_timeout_add_seconds(sleep_interval, scan, last_interval);
|
||||
+ last_interval = sleep_interval;
|
||||
+ g_timeout_add_seconds(sleep_interval, scan, NULL);
|
||||
g_main_loop_run(main_loop);
|
||||
|
||||
g_main_loop_quit(main_loop);
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,66 +0,0 @@
|
||||
From 559980c2e1dea1082949c17d52794c43c35f40ce Mon Sep 17 00:00:00 2001
|
||||
From: liuchao173 <liuchao173@huawei.com>
|
||||
Date: Thu, 7 Nov 2019 09:35:42 +0000
|
||||
Subject: [PATCH 7/8] backport: fix the problem of banmod that memory is freed
|
||||
before using
|
||||
|
||||
Currently strdupa() is used to allocate memory for irq_info's name in
|
||||
collect_full_irq_list(), we know that it allocate memory from stack,
|
||||
when the invoking function return, the memory will be freed. so if the
|
||||
irq_info's name is invalid, it will lead to check_for_module_ban() no
|
||||
correct.
|
||||
|
||||
check_for_irq_ban
|
||||
check_for_module_ban(res->name) // res->name is not valid
|
||||
|
||||
Use strdup() instead of strdupa(), and free the memory of irq_info's
|
||||
name before freeing the irq_info.
|
||||
|
||||
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
|
||||
---
|
||||
classify.c | 9 ++++++++-
|
||||
procinterrupts.c | 2 +-
|
||||
2 files changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/classify.c b/classify.c
|
||||
index 3136fc3..ed3f3ba 100644
|
||||
--- a/classify.c
|
||||
+++ b/classify.c
|
||||
@@ -748,6 +748,13 @@ static void add_missing_irq(struct irq_info *info, void *attr)
|
||||
add_new_irq(info->irq, info, proc_interrupts);
|
||||
}
|
||||
|
||||
+static void free_tmp_irqs(gpointer data)
|
||||
+{
|
||||
+ struct irq_info *info = data;
|
||||
+
|
||||
+ free(info->name);
|
||||
+ free(info);
|
||||
+}
|
||||
|
||||
void rebuild_irq_db(void)
|
||||
{
|
||||
@@ -777,7 +784,7 @@ void rebuild_irq_db(void)
|
||||
|
||||
for_each_irq(tmp_irqs, add_missing_irq, interrupts_db);
|
||||
|
||||
- g_list_free_full(tmp_irqs, free);
|
||||
+ g_list_free_full(tmp_irqs, free_tmp_irqs);
|
||||
|
||||
}
|
||||
|
||||
diff --git a/procinterrupts.c b/procinterrupts.c
|
||||
index 87fae2f..11fe1bc 100644
|
||||
--- a/procinterrupts.c
|
||||
+++ b/procinterrupts.c
|
||||
@@ -228,7 +228,7 @@ GList* collect_full_irq_list()
|
||||
info->class = IRQ_OTHER;
|
||||
#endif
|
||||
}
|
||||
- info->name = strdupa(irq_mod);
|
||||
+ info->name = strdup(irq_mod);
|
||||
tmp_list = g_list_append(tmp_list, info);
|
||||
}
|
||||
free(savedline);
|
||||
--
|
||||
2.19.1
|
||||
@ -1,66 +0,0 @@
|
||||
From 0fab11043aef5b835ed5564dc15476cdbfb54d5b Mon Sep 17 00:00:00 2001
|
||||
From: SuperSix173 <liuchao173@huawei.com>
|
||||
Date: Thu, 6 Feb 2020 11:43:48 +0800
|
||||
Subject: [PATCH] free cpu_ban_string when the next request come
|
||||
|
||||
---
|
||||
cputree.c | 4 ----
|
||||
irqbalance.c | 19 +++++--------------
|
||||
2 files changed, 5 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/cputree.c b/cputree.c
|
||||
index 9aa4794..bef1f40 100644
|
||||
--- a/cputree.c
|
||||
+++ b/cputree.c
|
||||
@@ -118,10 +118,6 @@ static void setup_banned_cpus(void)
|
||||
if (cpu_ban_string != NULL && banned_cpumask_from_ui != NULL) {
|
||||
cpulist_parse(banned_cpumask_from_ui,
|
||||
strlen(banned_cpumask_from_ui), banned_cpus);
|
||||
- /* release it safety, it was allocated in sock_handle */
|
||||
- free(cpu_ban_string);
|
||||
- cpu_ban_string = NULL;
|
||||
- banned_cpumask_from_ui = NULL;
|
||||
goto out;
|
||||
}
|
||||
if (getenv("IRQBALANCE_BANNED_CPUS")) {
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index e76d27b..9f65c88 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -471,12 +471,9 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
||||
free(irq_string);
|
||||
} else if (!(strncmp(buff + strlen("settings "), "cpus ",
|
||||
strlen("cpus")))) {
|
||||
- /*
|
||||
- * if cpu_ban_string has not been consumed,
|
||||
- * just ignore this request.
|
||||
- */
|
||||
- if (cpu_ban_string != NULL)
|
||||
- goto out_close;
|
||||
+ banned_cpumask_from_ui = NULL;
|
||||
+ free(cpu_ban_string);
|
||||
+ cpu_ban_string = NULL;
|
||||
|
||||
cpu_ban_string = malloc(
|
||||
sizeof(char) * (recv_size - strlen("settings cpus ")));
|
||||
@@ -489,15 +486,9 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
||||
if (!strncmp(banned_cpumask_from_ui, "NULL", strlen("NULL"))) {
|
||||
banned_cpumask_from_ui = NULL;
|
||||
free(cpu_ban_string);
|
||||
- cpu_ban_string = NULL;;
|
||||
- } else {
|
||||
- /*
|
||||
- * don't free cpu_ban_string at here, it will be
|
||||
- * released after we have store it to @banned_cpus
|
||||
- * in setup_banned_cpus function.
|
||||
- */
|
||||
- need_rescan = 1;
|
||||
+ cpu_ban_string = NULL;
|
||||
}
|
||||
+ need_rescan = 1;
|
||||
}
|
||||
}
|
||||
if (!strncmp(buff, "setup", strlen("setup"))) {
|
||||
--
|
||||
2.21.0.windows.1
|
||||
|
||||
@ -1,35 +0,0 @@
|
||||
From 0f7965c9cc3963c4dbfa7b61820ff973ef5da539 Mon Sep 17 00:00:00 2001
|
||||
From: liuchao173 <liuchao173@huawei.com>
|
||||
Date: Thu, 7 Nov 2019 09:22:15 +0000
|
||||
Subject: [PATCH 3/8] backport: free the memory when getline() fail in
|
||||
add_one_node()
|
||||
|
||||
when getline() fail, the memory still need to be freed.
|
||||
|
||||
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
|
||||
---
|
||||
numa.c | 7 +++----
|
||||
1 file changed, 3 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/numa.c b/numa.c
|
||||
index f0b1a98..542e1f4 100644
|
||||
--- a/numa.c
|
||||
+++ b/numa.c
|
||||
@@ -74,12 +74,11 @@ static void add_one_node(const char *nodename)
|
||||
cpus_clear(new->mask);
|
||||
} else {
|
||||
ret = getline(&cpustr, &blen, f);
|
||||
- if (ret <= 0) {
|
||||
+ if (ret <= 0)
|
||||
cpus_clear(new->mask);
|
||||
- } else {
|
||||
+ else
|
||||
cpumask_parse_user(cpustr, ret, new->mask);
|
||||
- free(cpustr);
|
||||
- }
|
||||
+ free(cpustr);
|
||||
}
|
||||
fclose(f);
|
||||
new->obj_type = OBJ_TYPE_NODE;
|
||||
--
|
||||
2.19.1
|
||||
@ -1,106 +0,0 @@
|
||||
From 9fd716f6627c0bb3b63cef94780e20101d9616c3 Mon Sep 17 00:00:00 2001
|
||||
From: liuchao173 <liuchao173@huawei.com>
|
||||
Date: Thu, 7 Nov 2019 09:19:33 +0000
|
||||
Subject: [PATCH 2/8] backport:
|
||||
getline-clean-up-freeing-of-lines-from-getline.patch
|
||||
|
||||
It was noted that several calls to getline failed to free the resultant line,
|
||||
which the man page for getline says to do even if the call fails. Clean that up
|
||||
here
|
||||
|
||||
And while we're at it, merge some of the free calls so they're common to a
|
||||
function where they can be, and not strewn all over the place
|
||||
|
||||
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
|
||||
---
|
||||
cputree.c | 29 +++++++++++++++++------------
|
||||
1 file changed, 17 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/cputree.c b/cputree.c
|
||||
index 5551784..91919ec 100644
|
||||
--- a/cputree.c
|
||||
+++ b/cputree.c
|
||||
@@ -91,10 +91,10 @@ static void setup_banned_cpus(void)
|
||||
if (getline(&line, &size, file) > 0) {
|
||||
if (strlen(line) && line[0] != '\n')
|
||||
cpulist_parse(line, strlen(line), isolated_cpus);
|
||||
- free(line);
|
||||
- line = NULL;
|
||||
- size = 0;
|
||||
}
|
||||
+ free(line);
|
||||
+ line = NULL;
|
||||
+ size = 0;
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
@@ -103,10 +103,10 @@ static void setup_banned_cpus(void)
|
||||
if (getline(&line, &size, file) > 0) {
|
||||
if (strlen(line) && line[0] != '\n')
|
||||
cpulist_parse(line, strlen(line), nohz_full);
|
||||
- free(line);
|
||||
- line = NULL;
|
||||
- size = 0;
|
||||
}
|
||||
+ free(line);
|
||||
+ line = NULL;
|
||||
+ size = 0;
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
@@ -271,6 +271,7 @@ static void do_one_cpu(char *path)
|
||||
int nodeid;
|
||||
int packageid = 0;
|
||||
unsigned int max_cache_index, cache_index, cache_stat;
|
||||
+ int ret = 1;
|
||||
|
||||
/* skip offline cpus */
|
||||
snprintf(new_path, ADJ_SIZE(path,"/online"), "%s/online", path);
|
||||
@@ -278,14 +279,12 @@ static void do_one_cpu(char *path)
|
||||
if (file) {
|
||||
char *line = NULL;
|
||||
size_t size = 0;
|
||||
- if (getline(&line, &size, file)==0)
|
||||
- return;
|
||||
+ if (getline(&line, &size, file)>0)
|
||||
+ ret = (line && line[0]=='0') ? 1 : 0;
|
||||
fclose(file);
|
||||
- if (line && line[0]=='0') {
|
||||
- free(line);
|
||||
- return;
|
||||
- }
|
||||
free(line);
|
||||
+ if (ret)
|
||||
+ return;
|
||||
}
|
||||
|
||||
cpu = calloc(sizeof(struct topo_obj), 1);
|
||||
@@ -327,6 +326,8 @@ static void do_one_cpu(char *path)
|
||||
cpumask_parse_user(line, strlen(line), package_mask);
|
||||
fclose(file);
|
||||
free(line);
|
||||
+ line = NULL;
|
||||
+ size = 0;
|
||||
}
|
||||
/* try to read the package id */
|
||||
snprintf(new_path, ADJ_SIZE(path, "/topology/physical_package_id"),
|
||||
@@ -339,6 +340,8 @@ static void do_one_cpu(char *path)
|
||||
packageid = strtoul(line, NULL, 10);
|
||||
fclose(file);
|
||||
free(line);
|
||||
+ line = NULL;
|
||||
+ size = 0;
|
||||
}
|
||||
|
||||
/* try to read the cache mask; if it doesn't exist assume solitary */
|
||||
@@ -372,6 +375,8 @@ static void do_one_cpu(char *path)
|
||||
cpumask_parse_user(line, strlen(line), cache_mask);
|
||||
fclose(file);
|
||||
free(line);
|
||||
+ line = NULL;
|
||||
+ size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.19.1
|
||||
@ -1,86 +0,0 @@
|
||||
From a4fbf90c2395ffa13176e8b002b7ef89a0ffc667 Mon Sep 17 00:00:00 2001
|
||||
From: Neil Horman <nhorman@tuxdriver.com>
|
||||
Date: Mon, 28 May 2018 08:33:08 -0400
|
||||
Subject: [PATCH 079/112] irq_db: don't fail entirely if we don't have a pci
|
||||
bus
|
||||
|
||||
aarch64 expects to have several interrupts that aren't associated to
|
||||
devices on a pci bus. However, rebuild_irq_db skips all interrupts if
|
||||
/sys/bus/pci/devices doesn't exist. Fix this by still calling
|
||||
add_missing_irq on all collected interrupts regardless of the pci bus
|
||||
directory.
|
||||
|
||||
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
|
||||
---
|
||||
classify.c | 29 ++++++++++++++---------------
|
||||
1 file changed, 14 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/classify.c b/classify.c
|
||||
index d3688fe..a977dc9 100644
|
||||
--- a/classify.c
|
||||
+++ b/classify.c
|
||||
@@ -39,7 +39,7 @@ GList *cl_banned_irqs = NULL;
|
||||
static GList *cl_banned_modules = NULL;
|
||||
|
||||
#define SYSFS_DIR "/sys"
|
||||
-#define SYSDEV_DIR "/sys/bus/pci/devices"
|
||||
+#define SYSPCI_DIR "/sys/bus/pci/devices"
|
||||
|
||||
#define PCI_MAX_CLASS 0x14
|
||||
#define PCI_MAX_SERIAL_SUBCLASS 0x81
|
||||
@@ -616,8 +616,8 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
|
||||
char devpath[PATH_MAX];
|
||||
struct user_irq_policy pol;
|
||||
|
||||
- sprintf(path, "%s/%s/msi_irqs", SYSDEV_DIR, dirname);
|
||||
- sprintf(devpath, "%s/%s", SYSDEV_DIR, dirname);
|
||||
+ sprintf(path, "%s/%s/msi_irqs", SYSPCI_DIR, dirname);
|
||||
+ sprintf(devpath, "%s/%s", SYSPCI_DIR, dirname);
|
||||
|
||||
msidir = opendir(path);
|
||||
|
||||
@@ -646,7 +646,7 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
|
||||
return;
|
||||
}
|
||||
|
||||
- sprintf(path, "%s/%s/irq", SYSDEV_DIR, dirname);
|
||||
+ sprintf(path, "%s/%s/irq", SYSPCI_DIR, dirname);
|
||||
fd = fopen(path, "r");
|
||||
if (!fd)
|
||||
return;
|
||||
@@ -764,22 +764,21 @@ void rebuild_irq_db(void)
|
||||
|
||||
tmp_irqs = collect_full_irq_list();
|
||||
|
||||
- devdir = opendir(SYSDEV_DIR);
|
||||
- if (!devdir)
|
||||
- goto free;
|
||||
+ devdir = opendir(SYSPCI_DIR);
|
||||
|
||||
- do {
|
||||
- entry = readdir(devdir);
|
||||
-
|
||||
- if (!entry)
|
||||
- break;
|
||||
+ if (devdir) {
|
||||
+ do {
|
||||
+ entry = readdir(devdir);
|
||||
|
||||
- build_one_dev_entry(entry->d_name, tmp_irqs);
|
||||
+ if (!entry)
|
||||
+ break;
|
||||
|
||||
- } while (entry != NULL);
|
||||
+ build_one_dev_entry(entry->d_name, tmp_irqs);
|
||||
|
||||
- closedir(devdir);
|
||||
+ } while (entry != NULL);
|
||||
|
||||
+ closedir(devdir);
|
||||
+ }
|
||||
|
||||
for_each_irq(tmp_irqs, add_missing_irq, interrupts_db);
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
diff -up ./misc/irqbalance.service.path ./misc/irqbalance.service
|
||||
--- ./misc/irqbalance.service.path 2017-11-14 13:09:56.011146473 -0500
|
||||
+++ ./misc/irqbalance.service 2017-11-14 13:10:13.480075654 -0500
|
||||
@@ -4,7 +4,7 @@ After=syslog.target
|
||||
ConditionVirtualization=!container
|
||||
|
||||
[Service]
|
||||
-EnvironmentFile=/path/to/irqbalance.env
|
||||
+EnvironmentFile=/etc/sysconfig/irqbalance
|
||||
ExecStart=/usr/sbin/irqbalance --foreground $IRQBALANCE_ARGS
|
||||
|
||||
[Install]
|
||||
Binary file not shown.
BIN
irqbalance-1.7.0.tar.gz
Normal file
BIN
irqbalance-1.7.0.tar.gz
Normal file
Binary file not shown.
@ -1,105 +0,0 @@
|
||||
From 19c25ddc5a13cf0b993cdb0edac0eee80143be34 Mon Sep 17 00:00:00 2001
|
||||
From: PJ Waskiewicz <peter.waskiewicz.jr@intel.com>
|
||||
Date: Thu, 9 Aug 2018 10:56:03 -0700
|
||||
Subject: [PATCH 093/112] irqbalance: Add support for file-based socket for IPC
|
||||
|
||||
This patch adds support for a file-based socket in tmpfs. It
|
||||
also fixes an inadvertent bug that caused the socket in use to
|
||||
be an abstract socket, which wasn't the intent.
|
||||
|
||||
This addresses Issue #72.
|
||||
|
||||
Signed-off-by: PJ Waskiewicz <pjwaskiewicz@gmail.com>
|
||||
---
|
||||
irqbalance.c | 32 ++++++++++++++++++++++----------
|
||||
irqbalance.h | 1 +
|
||||
2 files changed, 23 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index 2614719..bce9d56 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -45,6 +45,7 @@
|
||||
|
||||
volatile int keep_going = 1;
|
||||
int socket_fd;
|
||||
+char socket_name[64];
|
||||
int one_shot_mode;
|
||||
int debug_mode;
|
||||
int foreground_mode;
|
||||
@@ -456,7 +457,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
-int init_socket(char *socket_name)
|
||||
+int init_socket()
|
||||
{
|
||||
struct sockaddr_un addr;
|
||||
memset(&addr, 0, sizeof(struct sockaddr_un));
|
||||
@@ -467,13 +468,25 @@ int init_socket(char *socket_name)
|
||||
return 1;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * First try to create a file-based socket in tmpfs. If that doesn't
|
||||
+ * succeed, fall back to an abstract socket (non file-based).
|
||||
+ */
|
||||
addr.sun_family = AF_UNIX;
|
||||
- strncpy(addr.sun_path, socket_name, strlen(addr.sun_path));
|
||||
- if (bind(socket_fd, (struct sockaddr *)&addr,
|
||||
- sizeof(sa_family_t) + strlen(socket_name) + 1) < 0) {
|
||||
- log(TO_ALL, LOG_WARNING, "Daemon couldn't be bound to the socket.\n");
|
||||
- return 1;
|
||||
+ snprintf(socket_name, 64, "%s/%s%d.sock", SOCKET_TMPFS, SOCKET_PATH, getpid());
|
||||
+ strncpy(addr.sun_path, socket_name, strlen(socket_name));
|
||||
+ if (bind(socket_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
+ log(TO_ALL, LOG_WARNING, "Daemon couldn't be bound to the file-based socket.\n");
|
||||
+
|
||||
+ /* Try binding to abstract */
|
||||
+ memset(&addr, 0, sizeof(struct sockaddr_un));
|
||||
+ addr.sun_family = AF_UNIX;
|
||||
+ if (bind(socket_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
+ log(TO_ALL, LOG_WARNING, "Daemon couldn't be bound to the abstract socket, bailing out.\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
}
|
||||
+
|
||||
int optval = 1;
|
||||
if (setsockopt(socket_fd, SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval)) < 0) {
|
||||
log(TO_ALL, LOG_WARNING, "Unable to set socket options.\n");
|
||||
@@ -598,10 +611,7 @@ int main(int argc, char** argv)
|
||||
parse_proc_interrupts();
|
||||
parse_proc_stat();
|
||||
|
||||
- char socket_name[64];
|
||||
- snprintf(socket_name, 64, "%s%d.sock", SOCKET_PATH, getpid());
|
||||
-
|
||||
- if (init_socket(socket_name)) {
|
||||
+ if (init_socket()) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
main_loop = g_main_loop_new(NULL, FALSE);
|
||||
@@ -619,6 +629,8 @@ int main(int argc, char** argv)
|
||||
unlink(pidfile);
|
||||
/* Remove socket */
|
||||
close(socket_fd);
|
||||
+ if (socket_name[0])
|
||||
+ unlink(socket_name);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
diff --git a/irqbalance.h b/irqbalance.h
|
||||
index b7a26fc..c4717d3 100644
|
||||
--- a/irqbalance.h
|
||||
+++ b/irqbalance.h
|
||||
@@ -158,6 +158,7 @@ extern unsigned int log_mask;
|
||||
#endif /* HAVE_LIBSYSTEMD */
|
||||
|
||||
#define SOCKET_PATH "irqbalance"
|
||||
+#define SOCKET_TMPFS "/var/run"
|
||||
|
||||
#endif /* __INCLUDE_GUARD_IRQBALANCE_H_ */
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
#!/bin/bash
|
||||
echo > /dev/null
|
||||
19
irqbalance.service
Normal file
19
irqbalance.service
Normal file
@ -0,0 +1,19 @@
|
||||
[Unit]
|
||||
Description=irqbalance daemon
|
||||
Documentation=man:irqbalance(1)
|
||||
Documentation=https://github.com/Irqbalance/irqbalance
|
||||
ConditionVirtualization=!container
|
||||
After=syslog.target
|
||||
|
||||
[Service]
|
||||
OOMScoreAdjust=-500
|
||||
Type=forking
|
||||
PIDFile=/var/run/irqbalance.pid
|
||||
EnvironmentFile=/etc/sysconfig/irqbalance
|
||||
ExecStart=/usr/sbin/irq_balancer
|
||||
StartLimitInterval=10
|
||||
StartLimitBurst=10000
|
||||
RuntimeDirectory=irqbalance/
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
121
irqbalance.spec
121
irqbalance.spec
@ -1,14 +1,12 @@
|
||||
Summary: A dynamic adaptive IRQ balancing daemon
|
||||
Name: irqbalance
|
||||
Version: 1.4.0
|
||||
Release: 18
|
||||
Version: 1.7.0
|
||||
Release: 1
|
||||
Epoch: 3
|
||||
|
||||
License: GPLv2
|
||||
Source0: https://github.com/Irqbalance/irqbalance/archive/irqbalance-%{version}.tar.gz
|
||||
Source1: irqbalance.sysconfig
|
||||
Source2: irqbalance.rules
|
||||
Source3: irq_balancer
|
||||
Source1: irqbalance.service
|
||||
Source2: irq_balancer
|
||||
Url: https://github.com/irqbalance/irqbalance
|
||||
|
||||
BuildRequires: gdb autoconf automake libtool libcap-ng systemd
|
||||
@ -23,63 +21,6 @@ Requires: numactl-libs
|
||||
|
||||
%define _hardened_build 1
|
||||
|
||||
Patch0: add-a-catchall-guessing-mechanis.patch
|
||||
Patch1: irq_db-don-t-fail-entirely-if-we-don-t-have-a-pci-bu.patch
|
||||
Patch2: cputree-adjust-snprintf-sizes-to-avoid-gcc-warnings.patch
|
||||
Patch3: classify-remove-unused-label.patch
|
||||
Patch4: parse_proc_interrupts-ensure-that-buffer-is-long-eno.patch
|
||||
Patch5: Fix-some-string-copy-limitations.patch
|
||||
Patch6: irqbalance-Add-support-for-file-based-socket-for-IPC.patch
|
||||
Patch7: Fix-several-memleak-problems-found-by-covscan.patch
|
||||
Patch8: Fix-an-possible-overflow-error.patch
|
||||
Patch9: Fix-irqbalance-ui-failing-to-connect-to-irqbalance-d.patch
|
||||
Patch10:procinterrupts-check-xen-dyn-event-more-flexible.patch
|
||||
Patch11:Fix-ambiguous-parsing-of-node-entries-in-sys.patch
|
||||
Patch12:Don-t-leak-socket-fd-on-connection-error.patch
|
||||
Patch13:Fix-string-truncation-issues-detected-by-GCC-8.patch
|
||||
Patch14:fix-balancing-when-numa-information-isn-t-available.patch
|
||||
|
||||
Patch6000: Checking-return-value-of-strdup-in-collect_full_irq_.patch
|
||||
Patch6001: getline-clean-up-freeing-of-lines-from-getline.patch
|
||||
Patch6002: free-the-memory-when-getline-fail-in-add_one_node.patch
|
||||
Patch6003: prevent-NULL-pointer-dereference-when-memory-allocat.patch
|
||||
Patch6004: fix-resource-leak-for-not-invoking-closedir-after-op.patch
|
||||
Patch6005: correct-to-use-realloc-function.patch
|
||||
Patch6006: fix-the-problem-of-banmod-that-memory-is-freed-befor.patch
|
||||
Patch6007: fix-sleep-interval-when-sleep_interval-is-changed-by.patch
|
||||
Patch6008: fix-resource-leak-on-the-error-paths-in-main.patch
|
||||
Patch6009: fix-invalid-pointer-dereference-banned_cpumask_from_.patch
|
||||
Patch6010: free-cpu_ban_string-when-the-next-request-come.patch
|
||||
|
||||
Patch9000: irqbalance-1.0.4-env-file-path.patch
|
||||
Patch9001: bugfix-fix-a-hole-that-flees-hotplug-event.patch
|
||||
Patch9002: bugfix-use-policy-prior-to-the-default-values.patch
|
||||
Patch9003: bugfix-force-irq-into-rebalance-list-when-irq-removed-and-reinserted.patch
|
||||
Patch9004: feature-irqbalance-aarch64-add-the-regular-to-get-th.patch
|
||||
Patch9005: feature-irqbalance-arm64-Add-irq-aff-change-check.patch
|
||||
Patch9006: feature-irqbalance-auto-banned-pci-assigned-irq.patch
|
||||
Patch9007: bugfix-irqbalance-fix-wrong-pid-value-in-pid-file.patch
|
||||
Patch9008: feature-supplement-irqbalance-service-config.patch
|
||||
Patch9009: bugfix-fgets-will-get-a-redundant-new-line.patch
|
||||
Patch9010: bugfix-Prevent-inserting-a-duplicate-entry-to-avoid-list-ch.patch
|
||||
Patch9011: bugfix-guess_arm_irq_hints.patch
|
||||
Patch9012: feature-add-new-user-irq-policy-config-rule.patch
|
||||
Patch9013: bugfix-make-the-return-value-of-getline-handled-correct.patch
|
||||
Patch9014: bugfix-change-irq-ban-check-path-to-devpath.patch
|
||||
Patch9015: bugfix-fix-new-irqs-in-hotplug-keep-stay-on-one-numa.patch
|
||||
Patch9016: feature-add-the-switch-of-printing-log.patch
|
||||
Patch9017: bugfix-fix-new-msi-irq-hasnot-been-added-to-rebalance-list.patch
|
||||
Patch9018: bugfix-delete-no-existing-banned-irq.patch
|
||||
Patch9019: bugfix-fix-strcat-may-cause-buffer-overrun.patch
|
||||
Patch9020: feature-introduce-verifyhint-to-detect-hint-variation.patch
|
||||
Patch9021: bugfix-fix-memory-leak-of-strdup-in-collect_full_irq_list.patch
|
||||
Patch9022: feature-add-switch-to-clear-affinity-hint.patch
|
||||
Patch9023: feature-add-new-irq-migrate-rule-to-avoid-high-cpu-irq-load.patch
|
||||
Patch9024: bugfix-prevent-version-cmd-need-an-argument.patch
|
||||
Patch9025: feature-encapsulate-and-compile-the-functions-in-irqbalance-ui.patch
|
||||
Patch9026: feature-enable-irqbalance-to-link-with-multiple-clie.patch
|
||||
Patch9027: feature-irqbalance-Add-ability-for-socket-communicat.patch
|
||||
|
||||
%description
|
||||
Irqbalance is a daemon to help balance the cpu load generated by
|
||||
interrupts across all of a systems cpus. Irqbalance identifies the
|
||||
@ -88,20 +29,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 irqbalanace client
|
||||
|
||||
%package_help
|
||||
|
||||
%prep
|
||||
@ -110,20 +37,13 @@ Shared librariy for irqbalanace client
|
||||
%build
|
||||
./autogen.sh
|
||||
%configure
|
||||
CFLAGS="%{optflags}" %make_build CFLAGS+='-fstack-protector-strong -fPIC'
|
||||
cd ui
|
||||
make
|
||||
cd -
|
||||
CFLAGS="%{optflags}" %make_build CFLAGS+='-fstack-protector-strong '
|
||||
|
||||
%install
|
||||
install -D -p -m 0755 %{name} %{buildroot}%{_sbindir}/%{name}
|
||||
install -D -p -m 0644 ./misc/%{name}.service %{buildroot}/%{_unitdir}/%{name}.service
|
||||
install -D -p -m 0644 %{SOURCE1} %{buildroot}%{_sysconfdir}/sysconfig/%{name}
|
||||
install -D -p -m 0755 %{SOURCE2} %{buildroot}%{_sysconfdir}/sysconfig/%{name}.rules
|
||||
install -D -p -m 0755 %{SOURCE3} %{buildroot}%{_sbindir}/irq_balancer
|
||||
|
||||
install -D -p -m 0640 ui/irqbalance_client.h %{buildroot}%{_includedir}/irqbalance_client.h
|
||||
install -D -p -m 0640 ui/libirqbalance_client.so %{buildroot}%{_libdir}/libirqbalance_client.so
|
||||
install -D -p -m 0644 %{SOURCE1} %{buildroot}/%{_unitdir}/%{name}.service
|
||||
install -D -p -m 0644 ./misc/irqbalance.env %{buildroot}%{_sysconfdir}/sysconfig/%{name}
|
||||
install -D -p -m 0755 %{SOURCE2} %{buildroot}%{_sbindir}/irq_balancer
|
||||
|
||||
install -d %{buildroot}%{_mandir}/man1/
|
||||
install -p -m 0644 ./%{name}.1 %{buildroot}%{_mandir}/man1/
|
||||
@ -136,15 +56,8 @@ make check
|
||||
%{_sbindir}/%{name}
|
||||
%{_unitdir}/%{name}.service
|
||||
%config(noreplace) %{_sysconfdir}/sysconfig/%{name}
|
||||
%{_sysconfdir}/sysconfig/%{name}.rules
|
||||
%{_sbindir}/irq_balancer
|
||||
|
||||
%files devel
|
||||
%{_includedir}/irqbalance_client.h
|
||||
|
||||
%files libs
|
||||
%{_libdir}/libirqbalance_client.so
|
||||
|
||||
%files help
|
||||
%{_mandir}/man1/*
|
||||
|
||||
@ -164,6 +77,24 @@ fi
|
||||
/sbin/chkconfig --del %{name} >/dev/null 2>&1 || :
|
||||
|
||||
%changelog
|
||||
* Fri Aug 14 2020 Liu Chao <liuchao173@huawei.com> - 3:1.7.0-1
|
||||
- Type:enhanced
|
||||
- ID:NA
|
||||
- SUG:restart
|
||||
- DESC:rebase to v1.7.0
|
||||
|
||||
* Fri Jul 3 2020 Liu Chao <liuchao173@huawei.com> - 3:1.6.0-1
|
||||
- Type:enhanced
|
||||
- ID:NA
|
||||
- SUG:restart
|
||||
- DESC:rebase to v1.6.0
|
||||
|
||||
* Tue Mar 24 2020 Liu chao <liuchao173@huawei.com> - 3:1.4.0-19
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
- SUG:restart
|
||||
- DESC:refactor patches
|
||||
|
||||
* Tue Mar 24 2020 Shuaishuai Song <songshuaishuai2@huawei.com> - 3:1.4.0-18
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
|
||||
@ -1,39 +0,0 @@
|
||||
# irqbalance is a daemon process that distributes interrupts across
|
||||
# CPUS on SMP systems. The default is to rebalance once every 10
|
||||
# seconds. This is the environment file that is specified to systemd via the
|
||||
# EnvironmentFile key in the service unit file (or via whatever method the init
|
||||
# system you're using has.
|
||||
#
|
||||
# ONESHOT=yes
|
||||
# after starting, wait for a minute, then look at the interrupt
|
||||
# load and balance it once; after balancing exit and do not change
|
||||
# it again.
|
||||
#IRQBALANCE_ONESHOT=
|
||||
|
||||
#
|
||||
# IRQBALANCE_BANNED_CPUS
|
||||
# 64 bit bitmask which allows you to indicate which cpu's should
|
||||
# be skipped when reblancing irqs. Cpu numbers which have their
|
||||
# corresponding bits set to one in this mask will not have any
|
||||
# irq's assigned to them on rebalance
|
||||
#
|
||||
IRQBALANCE_BANNED_CPUS=
|
||||
|
||||
## Type: string
|
||||
## Default: ""
|
||||
## ServiceRestart: Iirq_balancer
|
||||
#
|
||||
# Interrupt that don't get balanced as list (separation character doesn't
|
||||
# matter). For example broken chipsets don't allow the timer interrupt
|
||||
# to be set to another CPU than the first, and with this option that
|
||||
# policy can be applied.
|
||||
#
|
||||
IRQBALANCE_BANNED_INTERRUPTS=""
|
||||
|
||||
#
|
||||
# IRQBALANCE_ARGS
|
||||
# append any args here to the irqbalance daemon as documented in the man page
|
||||
#
|
||||
IRQBALANCE_ARGS=
|
||||
|
||||
|
||||
4
irqbalance.yaml
Normal file
4
irqbalance.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
version_control: github
|
||||
src_repo: Irqbalance/irqbalance
|
||||
tag_prefix: "^v"
|
||||
seperator: "."
|
||||
@ -1,49 +0,0 @@
|
||||
From 8ab70a85bbda79d47c8cc8e1c2767e1cb307f536 Mon Sep 17 00:00:00 2001
|
||||
From: Neil Horman <nhorman@tuxdriver.com>
|
||||
Date: Tue, 29 May 2018 11:07:32 -0400
|
||||
Subject: [PATCH 085/112] parse_proc_interrupts: ensure that buffer is long
|
||||
enough for a string
|
||||
|
||||
Instead of using strcpy to a save each line in /proc/interrupts, use
|
||||
strdup and free to ensure that the buffer will hold the string
|
||||
consistently, avoiding the gcc error that using a fixed size stack
|
||||
variable triggers
|
||||
|
||||
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
|
||||
---
|
||||
procinterrupts.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/procinterrupts.c b/procinterrupts.c
|
||||
index 1aa4413..4ef8751 100644
|
||||
--- a/procinterrupts.c
|
||||
+++ b/procinterrupts.c
|
||||
@@ -170,7 +170,7 @@ GList* collect_full_irq_list()
|
||||
int number;
|
||||
struct irq_info *info;
|
||||
char *c;
|
||||
- char savedline[1024];
|
||||
+ char *savedline = NULL;
|
||||
|
||||
if (getline(&line, &size, file)==0)
|
||||
break;
|
||||
@@ -186,7 +186,7 @@ GList* collect_full_irq_list()
|
||||
if (!c)
|
||||
continue;
|
||||
|
||||
- strncpy(savedline, line, sizeof(savedline));
|
||||
+ savedline = strdup(line);
|
||||
irq_name = strtok_r(savedline, " ", &savedptr);
|
||||
last_token = strtok_r(NULL, " ", &savedptr);
|
||||
while ((p = strtok_r(NULL, " ", &savedptr))) {
|
||||
@@ -224,6 +224,7 @@ GList* collect_full_irq_list()
|
||||
info->name = strdupa(irq_mod);
|
||||
tmp_list = g_list_append(tmp_list, info);
|
||||
}
|
||||
+ free(savedline);
|
||||
}
|
||||
fclose(file);
|
||||
free(line);
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,109 +0,0 @@
|
||||
From f37fe357b21ffd7ab210b088c36300d9562406cb Mon Sep 17 00:00:00 2001
|
||||
From: liuchao173 <liuchao173@huawei.com>
|
||||
Date: Thu, 7 Nov 2019 09:26:30 +0000
|
||||
Subject: [PATCH 4/8] backport: prevent NULL pointer dereference when memory
|
||||
allocation failure
|
||||
|
||||
There are several places where memory allocation does not check return
|
||||
values, adding null pointer checks.
|
||||
|
||||
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
|
||||
---
|
||||
cputree.c | 2 ++
|
||||
irqbalance.c | 20 ++++++++++++++++++++
|
||||
2 files changed, 22 insertions(+)
|
||||
|
||||
diff --git a/cputree.c b/cputree.c
|
||||
index 91919ec..9cd2db8 100644
|
||||
--- a/cputree.c
|
||||
+++ b/cputree.c
|
||||
@@ -432,6 +432,8 @@ static void dump_irq(struct irq_info *info, void *data)
|
||||
int i;
|
||||
char * indent = malloc (sizeof(char) * (spaces + 1));
|
||||
|
||||
+ if (!indent)
|
||||
+ return;
|
||||
for ( i = 0; i < spaces; i++ )
|
||||
indent[i] = log_indent[0];
|
||||
|
||||
diff --git a/irqbalance.c b/irqbalance.c
|
||||
index 93e4909..c9378d0 100644
|
||||
--- a/irqbalance.c
|
||||
+++ b/irqbalance.c
|
||||
@@ -326,6 +326,9 @@ void get_irq_data(struct irq_info *irq, void *data)
|
||||
else
|
||||
*irqdata = realloc(*irqdata, strlen(*irqdata) + 24 + 1 + 11 + 20 + 20 + 11);
|
||||
|
||||
+ if (!*irqdata)
|
||||
+ return;
|
||||
+
|
||||
sprintf(*irqdata + strlen(*irqdata),
|
||||
"IRQ %d LOAD %lu DIFF %lu CLASS %d ", irq->irq, irq->load,
|
||||
(irq->irq_count - irq->last_irq_count), irq->class);
|
||||
@@ -357,6 +360,9 @@ void get_object_stat(struct topo_obj *object, void *data)
|
||||
*stats = realloc(*stats, strlen(*stats) + irqdlen + 31 + 11 + 20 + 11 + 1);
|
||||
}
|
||||
|
||||
+ if (!*stats)
|
||||
+ return;
|
||||
+
|
||||
sprintf(*stats + strlen(*stats), "TYPE %d NUMBER %d LOAD %lu SAVE_MODE %d %s",
|
||||
object->obj_type, object->number, object->load,
|
||||
object->powersave_mode, irq_data ? irq_data : "");
|
||||
@@ -393,6 +399,10 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
||||
goto out_close;
|
||||
}
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
+ if (!cmsg) {
|
||||
+ log(TO_ALL, LOG_WARNING, "Connection no memory.\n");
|
||||
+ goto out_close;
|
||||
+ }
|
||||
if ((cmsg->cmsg_level == SOL_SOCKET) &&
|
||||
(cmsg->cmsg_type == SCM_CREDENTIALS)) {
|
||||
struct ucred *credentials = (struct ucred *) CMSG_DATA(cmsg);
|
||||
@@ -416,6 +426,8 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
||||
strlen("sleep ")))) {
|
||||
char *sleep_string = malloc(
|
||||
sizeof(char) * (recv_size - strlen("settings sleep ")));
|
||||
+ if (!sleep_string)
|
||||
+ goto out_close;
|
||||
strncpy(sleep_string, buff + strlen("settings sleep "),
|
||||
recv_size - strlen("settings sleep "));
|
||||
int new_iterval = strtoul(sleep_string, NULL, 10);
|
||||
@@ -428,6 +440,8 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
||||
char *end;
|
||||
char *irq_string = malloc(
|
||||
sizeof(char) * (recv_size - strlen("settings ban irqs ")));
|
||||
+ if (!irq_string)
|
||||
+ goto out_close;
|
||||
strncpy(irq_string, buff + strlen("settings ban irqs "),
|
||||
recv_size - strlen("settings ban irqs "));
|
||||
g_list_free_full(cl_banned_irqs, free);
|
||||
@@ -446,6 +460,8 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
||||
strlen("cpus")))) {
|
||||
char *cpu_ban_string = malloc(
|
||||
sizeof(char) * (recv_size - strlen("settings cpus ")));
|
||||
+ if (!cpu_ban_string)
|
||||
+ goto out_close;
|
||||
strncpy(cpu_ban_string, buff + strlen("settings cpus "),
|
||||
recv_size - strlen("settings cpus "));
|
||||
banned_cpumask_from_ui = strtok(cpu_ban_string, " ");
|
||||
@@ -459,12 +475,16 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
|
||||
if (!strncmp(buff, "setup", strlen("setup"))) {
|
||||
char banned[512];
|
||||
char *setup = calloc(strlen("SLEEP ") + 11 + 1, 1);
|
||||
+ if (!setup)
|
||||
+ goto out_close;
|
||||
snprintf(setup, strlen("SLEEP ") + 11 + 1, "SLEEP %d ", sleep_interval);
|
||||
if(g_list_length(cl_banned_irqs) > 0) {
|
||||
for_each_irq(cl_banned_irqs, get_irq_data, setup);
|
||||
}
|
||||
cpumask_scnprintf(banned, 512, banned_cpus);
|
||||
setup = realloc(setup, strlen(setup) + strlen(banned) + 7 + 1);
|
||||
+ if (!setup)
|
||||
+ goto out_close;
|
||||
snprintf(setup + strlen(setup), strlen(banned) + 7 + 1,
|
||||
"BANNED %s", banned);
|
||||
send(sock, setup, strlen(setup), 0);
|
||||
--
|
||||
2.19.1
|
||||
@ -1,72 +0,0 @@
|
||||
From 0ba1d8a59e209cef20955b8437989e730cd19cb3 Mon Sep 17 00:00:00 2001
|
||||
From: Xiao Liang <xiliang@redhat.com>
|
||||
Date: Thu, 18 Oct 2018 21:50:33 +0800
|
||||
Subject: [PATCH 099/112] procinterrupts: check xen-dyn-event more flexible
|
||||
|
||||
In current /proc/interrupts, the 'xen-dyn-event' was split to 'xen-dyn -event'.
|
||||
It causes interrupts not balanced inside xen guest.
|
||||
|
||||
Below result is without this patch:
|
||||
70: 29 0 0 0 xen-dyn -event vif0-q0-tx
|
||||
71: 120 0 0 0 xen-dyn -event vif0-q0-rx
|
||||
72: 586350 0 0 0 xen-dyn -event vif0-q1-tx
|
||||
73: 44 0 0 0 xen-dyn -event vif0-q1-rx
|
||||
74: 19 0 0 0 xen-dyn -event vif0-q2-tx
|
||||
75: 179 0 0 0 xen-dyn -event vif0-q2-rx
|
||||
76: 67 0 0 0 xen-dyn -event vif0-q3-tx
|
||||
77: 299637 0 0 0 xen-dyn -event vif0-q3-rx
|
||||
|
||||
Below result is with this patch:
|
||||
[root@dhcp-3-194 ~]# grep vif0 /proc/interrupts
|
||||
70: 30 0 0 0 xen-dyn -event vif0-q0-tx
|
||||
71: 305 0 11 0 xen-dyn -event vif0-q0-rx
|
||||
72: 586354 0 27 0 xen-dyn -event vif0-q1-tx
|
||||
73: 49 7 5 0 xen-dyn -event vif0-q1-rx
|
||||
74: 27 0 0 509373 xen-dyn -event vif0-q2-tx
|
||||
75: 420 0 5 0 xen-dyn -event vif0-q2-rx
|
||||
76: 179 0 38 0 xen-dyn -event vif0-q3-tx
|
||||
77: 299803 281433 0 0 xen-dyn -event vif0-q3-rx
|
||||
|
||||
Signed-off-by: Xiao Liang <xiliang@redhat.com>
|
||||
---
|
||||
procinterrupts.c | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/procinterrupts.c b/procinterrupts.c
|
||||
index 7283998..2c8118a 100644
|
||||
--- a/procinterrupts.c
|
||||
+++ b/procinterrupts.c
|
||||
@@ -168,6 +168,7 @@ GList* collect_full_irq_list()
|
||||
|
||||
while (!feof(file)) {
|
||||
int number;
|
||||
+ int is_xen_dyn = 0;
|
||||
struct irq_info *info;
|
||||
char *c;
|
||||
char *savedline = NULL;
|
||||
@@ -188,9 +189,13 @@ GList* collect_full_irq_list()
|
||||
|
||||
savedline = strdup(line);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -210,7 +215,7 @@ GList* collect_full_irq_list()
|
||||
info = calloc(sizeof(struct irq_info), 1);
|
||||
if (info) {
|
||||
info->irq = number;
|
||||
- if (strstr(irq_name, "xen-dyn-event") != NULL) {
|
||||
+ if (strstr(irq_name, "-event") != NULL && is_xen_dyn == 1) {
|
||||
info->type = IRQ_TYPE_VIRT_EVENT;
|
||||
info->class = IRQ_VIRT_EVENT;
|
||||
} else {
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user