Package init
This commit is contained in:
commit
aa0afbee66
53
Don-t-leak-socket-fd-on-connection-error.patch
Normal file
53
Don-t-leak-socket-fd-on-connection-error.patch
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
73
Fix-ambiguous-parsing-of-node-entries-in-sys.patch
Normal file
73
Fix-ambiguous-parsing-of-node-entries-in-sys.patch
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
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
|
||||||
|
|
||||||
34
Fix-an-possible-overflow-error.patch
Normal file
34
Fix-an-possible-overflow-error.patch
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
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
|
||||||
|
|
||||||
253
Fix-several-memleak-problems-found-by-covscan.patch
Normal file
253
Fix-several-memleak-problems-found-by-covscan.patch
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
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
|
||||||
|
|
||||||
58
Fix-some-string-copy-limitations.patch
Normal file
58
Fix-some-string-copy-limitations.patch
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
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
|
||||||
|
|
||||||
37
Fix-string-truncation-issues-detected-by-GCC-8.patch
Normal file
37
Fix-string-truncation-issues-detected-by-GCC-8.patch
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
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");
|
||||||
|
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
52
add-a-catchall-guessing-mechanis.patch
Normal file
52
add-a-catchall-guessing-mechanis.patch
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
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
|
||||||
|
|
||||||
50
bugfix-fgets-will-get-a-redundant-new-line.patch
Normal file
50
bugfix-fgets-will-get-a-redundant-new-line.patch
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
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
|
||||||
|
|
||||||
30
bugfix-fix-a-hole-that-flees-hotplug-event.patch
Normal file
30
bugfix-fix-a-hole-that-flees-hotplug-event.patch
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
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] huawei 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
|
||||||
|
|
||||||
81
bugfix-fix-two-same-irq-insert-to-list.patch
Normal file
81
bugfix-fix-two-same-irq-insert-to-list.patch
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
From 384cdfa4ef28415c3df50d1759951a20c6f0661f Mon Sep 17 00:00:00 2001
|
||||||
|
From: caomeng <caomeng5@huawei.com>
|
||||||
|
Date: Thu, 4 Jul 2019 03:47:20 +0800
|
||||||
|
Subject: [PATCH] bugfix-fix-two-same-irq-insert-to-list
|
||||||
|
|
||||||
|
When the function force_rebalance_irq is executed,the same irq may be added into
|
||||||
|
rebalance_irq_list again, resulting in failed irqbalance service. Thus, a function
|
||||||
|
named irq_in_rebalance_list which is used to check if the irq is in rebalance_irq_list
|
||||||
|
will be executed before force_rebalance_irq. And this patch fixex the bug introduced
|
||||||
|
by feature-introduce-verifyhint-to-detect-hint-variation.patch.
|
||||||
|
|
||||||
|
---
|
||||||
|
classify.c | 11 +++++++++++
|
||||||
|
irqbalance.h | 2 +-
|
||||||
|
procinterrupts.c | 8 ++++++--
|
||||||
|
3 files changed, 18 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/classify.c b/classify.c
|
||||||
|
index 0951c72..4d699da 100644
|
||||||
|
--- a/classify.c
|
||||||
|
+++ b/classify.c
|
||||||
|
@@ -288,6 +288,17 @@ static void add_banned_irq(int irq, GList **list)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int irq_in_rebalance_list(int irq)
|
||||||
|
+{
|
||||||
|
+ GList *entry = NULL;
|
||||||
|
+ struct irq_info find = {0};
|
||||||
|
+
|
||||||
|
+ find.irq = irq;
|
||||||
|
+ entry = g_list_find_custom(rebalance_irq_list, &find, compare_ints);
|
||||||
|
+
|
||||||
|
+ return entry ? 1 : 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void add_cl_banned_irq(int irq)
|
||||||
|
{
|
||||||
|
add_banned_irq(irq, &cl_banned_irqs);
|
||||||
|
diff --git a/irqbalance.h b/irqbalance.h
|
||||||
|
index 80ec017..821de0e 100644
|
||||||
|
--- a/irqbalance.h
|
||||||
|
+++ b/irqbalance.h
|
||||||
|
@@ -107,7 +107,7 @@ 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)));
|
||||||
|
-
|
||||||
|
+int irq_in_rebalance_list(int irq);
|
||||||
|
/* huawei */
|
||||||
|
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);
|
||||||
|
diff --git a/procinterrupts.c b/procinterrupts.c
|
||||||
|
index fc4641a..9e38e49 100644
|
||||||
|
--- a/procinterrupts.c
|
||||||
|
+++ b/procinterrupts.c
|
||||||
|
@@ -348,7 +348,9 @@ void parse_proc_interrupts(void)
|
||||||
|
*/
|
||||||
|
if (count < info->irq_count) {
|
||||||
|
log(TO_CONSOLE, LOG_INFO, "Removed and reinserted IRQ %d added into rebalance list\n", number);
|
||||||
|
- force_rebalance_irq(info, NULL);
|
||||||
|
+ if (!irq_in_rebalance_list(info->irq)) {
|
||||||
|
+ force_rebalance_irq(info, NULL);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
info->last_irq_count = info->irq_count;
|
||||||
|
@@ -602,7 +604,9 @@ void update_affinity_hint(struct irq_info *info, void *data __attribute__((unuse
|
||||||
|
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);
|
||||||
|
+ if (!irq_in_rebalance_list(info->irq)) {
|
||||||
|
+ force_rebalance_irq(info, data);
|
||||||
|
+ }
|
||||||
|
log(TO_ALL, LOG_INFO, "IRQ(%d): affinity hint modified\n", info->irq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
@ -0,0 +1,472 @@
|
|||||||
|
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,11 @@ extern void free_cl_opts(void);
|
||||||
|
extern void add_cl_banned_module(char *modname);
|
||||||
|
#define irq_numa_node(irq) ((irq)->numa_node)
|
||||||
|
|
||||||
|
+/* huawei */
|
||||||
|
+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;
|
||||||
|
@@ -186,45 +220,13 @@ GList* collect_full_irq_list()
|
||||||
|
continue;
|
||||||
|
|
||||||
|
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;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
-#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 = strdupa(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
|
||||||
|
|
||||||
30
bugfix-guess_arm_irq_hints.patch
Normal file
30
bugfix-guess_arm_irq_hints.patch
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
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
|
||||||
123
bugfix-irqbalance-fix-wrong-pid-value-in-pid-file.patch
Normal file
123
bugfix-irqbalance-fix-wrong-pid-value-in-pid-file.patch
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
From d57caa98c082fb3bf746b0877aa368544e8e62dc Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zengruan Ye <yezengruan@huawei.com>
|
||||||
|
Date: Mon, 15 Jul 2019 21:37:39 +0800
|
||||||
|
Subject: [PATCH 4/6] 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 | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------
|
||||||
|
1 file changed, 73 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/irqbalance.c b/irqbalance.c
|
||||||
|
index 40ec65c..27cf2eb 100644
|
||||||
|
--- a/irqbalance.c
|
||||||
|
+++ b/irqbalance.c
|
||||||
|
@@ -584,6 +584,77 @@ 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;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+error_close_unlink:
|
||||||
|
+ (void) unlink(lockfile);
|
||||||
|
+
|
||||||
|
+error_close:
|
||||||
|
+ close(lf);
|
||||||
|
+ return err;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
struct sigaction action, hupaction;
|
||||||
|
@@ -676,17 +747,11 @@ 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) {
|
||||||
|
+ exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
@ -0,0 +1,108 @@
|
|||||||
|
From 3eab5a9cee8a3641988778b676caa4cf9dcb14ab Mon Sep 17 00:00:00 2001
|
||||||
|
From: xiashuang <xiashuang1@huawei.com>
|
||||||
|
Date: Sun, 11 Aug 2019 23:48:50 -0400
|
||||||
|
Subject: [PATCH] Prevent inserting a duplicate entry to avoid list chaos
|
||||||
|
|
||||||
|
Introduced by huawei-bugfix-force-irq-into-rebalance-list-when-irq-removed-and-reinserted.patch
|
||||||
|
and huawei-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
|
||||||
|
huawei-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 huawei-bugfix-fix-two-same-irq-insert-to-list.patch and add protection
|
||||||
|
in force_rebalance_irq instead.
|
||||||
|
---
|
||||||
|
classify.c | 13 +------------
|
||||||
|
irqbalance.c | 4 ++++
|
||||||
|
irqbalance.h | 3 ++-
|
||||||
|
procinterrupts.c | 8 ++------
|
||||||
|
4 files changed, 9 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/classify.c b/classify.c
|
||||||
|
index 34a2e9f..65aeae2 100644
|
||||||
|
--- a/classify.c
|
||||||
|
+++ b/classify.c
|
||||||
|
@@ -260,7 +260,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;
|
||||||
|
@@ -293,17 +293,6 @@ static void add_banned_irq(int irq, GList **list, int extra_flag)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int irq_in_rebalance_list(int irq)
|
||||||
|
-{
|
||||||
|
- GList *entry = NULL;
|
||||||
|
- struct irq_info find = {0};
|
||||||
|
-
|
||||||
|
- find.irq = irq;
|
||||||
|
- entry = g_list_find_custom(rebalance_irq_list, &find, compare_ints);
|
||||||
|
-
|
||||||
|
- return entry ? 1 : 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
#ifdef AARCH64
|
||||||
|
void add_banned_list_irq(int irq)
|
||||||
|
{
|
||||||
|
diff --git a/irqbalance.c b/irqbalance.c
|
||||||
|
index 6e9de88..fd72d44 100644
|
||||||
|
--- a/irqbalance.c
|
||||||
|
+++ b/irqbalance.c
|
||||||
|
@@ -314,6 +314,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 b6bdebd..120bc9b 100644
|
||||||
|
--- a/irqbalance.h
|
||||||
|
+++ b/irqbalance.h
|
||||||
|
@@ -114,7 +114,8 @@ 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)));
|
||||||
|
-int irq_in_rebalance_list(int irq);
|
||||||
|
+extern gint compare_ints(gconstpointer a, gconstpointer b);
|
||||||
|
+
|
||||||
|
/* huawei */
|
||||||
|
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);
|
||||||
|
diff --git a/procinterrupts.c b/procinterrupts.c
|
||||||
|
index 6b25fef..4bc68d7 100644
|
||||||
|
--- a/procinterrupts.c
|
||||||
|
+++ b/procinterrupts.c
|
||||||
|
@@ -446,9 +446,7 @@ void parse_proc_interrupts(void)
|
||||||
|
*/
|
||||||
|
if (count < info->irq_count) {
|
||||||
|
log(TO_CONSOLE, LOG_INFO, "Removed and reinserted IRQ %d added into rebalance list\n", number);
|
||||||
|
- if (!irq_in_rebalance_list(info->irq)) {
|
||||||
|
- force_rebalance_irq(info, NULL);
|
||||||
|
- }
|
||||||
|
+ force_rebalance_irq(info, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
info->last_irq_count = info->irq_count;
|
||||||
|
@@ -702,9 +700,7 @@ void update_affinity_hint(struct irq_info *info, void *data __attribute__((unuse
|
||||||
|
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);
|
||||||
|
- if (!irq_in_rebalance_list(info->irq)) {
|
||||||
|
- force_rebalance_irq(info, data);
|
||||||
|
- }
|
||||||
|
+ force_rebalance_irq(info, data);
|
||||||
|
log(TO_ALL, LOG_INFO, "IRQ(%d): affinity hint modified\n", info->irq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
151
bugfix-use-policy-prior-to-the-default-values.patch
Normal file
151
bugfix-use-policy-prior-to-the-default-values.patch
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
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
|
||||||
|
|
||||||
28
classify-remove-unused-label.patch
Normal file
28
classify-remove-unused-label.patch
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
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
|
||||||
|
|
||||||
91
cputree-adjust-snprintf-sizes-to-avoid-gcc-warnings.patch
Normal file
91
cputree-adjust-snprintf-sizes-to-avoid-gcc-warnings.patch
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
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
|
||||||
|
|
||||||
476
feature-add-new-user-irq-policy-config-rule.patch
Normal file
476
feature-add-new-user-irq-policy-config-rule.patch
Normal file
@ -0,0 +1,476 @@
|
|||||||
|
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 | 31 +++++----
|
||||||
|
irqbalance.h | 2 +-
|
||||||
|
misc/irqbalance.service | 2 +-
|
||||||
|
placement.c | 3 +-
|
||||||
|
procinterrupts.c | 3 +-
|
||||||
|
rules_config.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
rules_config.h | 38 +++++++++++
|
||||||
|
9 files changed, 260 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 sockapi.c
|
||||||
|
+ irqlist.c numa.c placement.c procinterrupts.c sockapi.c rules_config.c
|
||||||
|
irqbalance_LDADD = $(LIBCAP_NG_LIBS) $(GLIB2_LIBS) -lpthread
|
||||||
|
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;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/irqbalance.c b/irqbalance.c
|
||||||
|
index 21d578a..d41753c 100644
|
||||||
|
--- a/irqbalance.c
|
||||||
|
+++ b/irqbalance.c
|
||||||
|
@@ -148,6 +148,7 @@ struct option lopts[] = {
|
||||||
|
{"interval", 1 , NULL, 't'},
|
||||||
|
{"version", 0, NULL, 'V'},
|
||||||
|
{"verifyhint", 1, NULL, 'v'},
|
||||||
|
+ {"rulesconfig", 1, NULL, 'r'},
|
||||||
|
{0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -155,7 +156,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, " [--pid= | -s <file>] [--deepestcache= | -c <n>] [--interval= | -t <n>] [--verifyhint= | -v n] [--rulesconfig= | -r <config>]\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void version(void)
|
||||||
|
@@ -170,7 +171,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:",
|
||||||
|
+ "odfji:p:s:c:b:l:m:t:V:h:v:r:",
|
||||||
|
lopts, &longind)) != -1) {
|
||||||
|
|
||||||
|
switch(opt) {
|
||||||
|
@@ -268,6 +269,9 @@ static void parse_command_line(int argc, char **argv)
|
||||||
|
}
|
||||||
|
reset_verify_countdown();
|
||||||
|
break;
|
||||||
|
+ case 'r':
|
||||||
|
+ rules_config_file = strdup(optarg);
|
||||||
|
+ break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -586,6 +590,19 @@ int main(int argc, char** argv)
|
||||||
|
HZ = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (!foreground_mode) {
|
||||||
|
+ if (daemon(0,0))
|
||||||
|
+ exit(EXIT_FAILURE);
|
||||||
|
+ /* Write pidfile */
|
||||||
|
+ if (pidfile && create_lock_pidfile(pidfile) < 0) {
|
||||||
|
+ exit(EXIT_FAILURE);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (read_user_policy_config() != 0) {
|
||||||
|
+ log(TO_ALL, LOG_WARNING, "Read user policy config fail.\n");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
build_object_tree();
|
||||||
|
if (debug_mode)
|
||||||
|
dump_object_tree();
|
||||||
|
@@ -600,14 +617,6 @@ int main(int argc, char** argv)
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!foreground_mode) {
|
||||||
|
- if (daemon(0,0))
|
||||||
|
- exit(EXIT_FAILURE);
|
||||||
|
- /* Write pidfile */
|
||||||
|
- if (pidfile && create_lock_pidfile(pidfile) < 0) {
|
||||||
|
- exit(EXIT_FAILURE);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
|
||||||
|
action.sa_handler = handler;
|
||||||
|
sigemptyset(&action.sa_mask);
|
||||||
|
@@ -640,7 +649,7 @@ int main(int argc, char** argv)
|
||||||
|
log(TO_CONSOLE, LOG_WARNING, "WARNING: Failed to create irqbalance socket thread, return %d.\n", err);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
+ log(TO_ALL, LOG_INFO, "irqbalance start scan.\n");
|
||||||
|
while (keep_going) {
|
||||||
|
cond_sleep();
|
||||||
|
|
||||||
|
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,170 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (C) 2019. Huawei Technologies Co., Ltd. All rights reserved.
|
||||||
|
+ *
|
||||||
|
+ * This program is free software; you can redistribute it and/or modify
|
||||||
|
+ * it under the terms of the MuLan PSL v1.
|
||||||
|
+ *
|
||||||
|
+ * 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 MuLan PSL v1 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,38 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (C) 2019. Huawei Technologies Co., Ltd. All rights reserved.
|
||||||
|
+ *
|
||||||
|
+ * This program is free software; you can redistribute it and/or modify
|
||||||
|
+ * it under the terms of the MuLan PSL v1.
|
||||||
|
+ *
|
||||||
|
+ * 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 MuLan PSL v1 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
|
||||||
|
|
||||||
506
feature-introduce-verifyhint-to-detect-hint-variation.patch
Normal file
506
feature-introduce-verifyhint-to-detect-hint-variation.patch
Normal file
@ -0,0 +1,506 @@
|
|||||||
|
From 8541a67cdc3cbaf5c6ed04e9a3b3e2c3f584cb33 Mon Sep 17 00:00:00 2001
|
||||||
|
From: xiahuang <xiashuang1@huawei.com>
|
||||||
|
Date: Thu, 21 Mar 2019 19:08:17 -0400
|
||||||
|
Subject: [PATCH 2/2]
|
||||||
|
feature-introduce-verifyhint-to-detect-hint-variation
|
||||||
|
|
||||||
|
adapt by xiashuang xiashuang1@huawei.com when upgrade to 1.4.0
|
||||||
|
---
|
||||||
|
activate.c | 24 +++++-----
|
||||||
|
classify.c | 18 ++++++--
|
||||||
|
cpumask.h | 7 +++
|
||||||
|
irqbalance.c | 135 +++++++++++++++++++++++++++++++++++++++++++------------
|
||||||
|
irqbalance.h | 5 +++
|
||||||
|
placement.c | 14 ++++++
|
||||||
|
procinterrupts.c | 57 +++++++++++++++++++++++
|
||||||
|
types.h | 1 +
|
||||||
|
8 files changed, 217 insertions(+), 44 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/activate.c b/activate.c
|
||||||
|
index 8fd3dd0..1c4b867 100644
|
||||||
|
--- a/activate.c
|
||||||
|
+++ b/activate.c
|
||||||
|
@@ -61,26 +61,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 30a8d2a..aa391f4 100644
|
||||||
|
--- a/classify.c
|
||||||
|
+++ b/classify.c
|
||||||
|
@@ -66,8 +66,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
|
||||||
|
*
|
||||||
|
@@ -414,7 +412,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);
|
||||||
|
@@ -426,6 +424,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/irqbalance.c b/irqbalance.c
|
||||||
|
index e375a1a..bf9a2e4 100644
|
||||||
|
--- a/irqbalance.c
|
||||||
|
+++ b/irqbalance.c
|
||||||
|
@@ -61,10 +61,38 @@ char *banscript = NULL;
|
||||||
|
char *polscript = NULL;
|
||||||
|
long HZ;
|
||||||
|
int sleep_interval = SLEEP_INTERVAL;
|
||||||
|
-GMainLoop *main_loop;
|
||||||
|
+int hint_enabled = 0;
|
||||||
|
+int poll_hint_interval = SLEEP_INTERVAL / 5;
|
||||||
|
+unsigned int next_verify, next_balance;
|
||||||
|
|
||||||
|
char *banned_cpumask_from_ui = NULL;
|
||||||
|
|
||||||
|
+static inline void reset_verify_countdown(void)
|
||||||
|
+{
|
||||||
|
+ next_verify = poll_hint_interval;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void reset_balance_countdown(void)
|
||||||
|
+{
|
||||||
|
+ next_balance = sleep_interval;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline int need_verify(void)
|
||||||
|
+{
|
||||||
|
+ return !(poll_hint_interval - next_verify);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline int need_balance(void)
|
||||||
|
+{
|
||||||
|
+ return !(sleep_interval - next_balance);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void reset_countdown(void)
|
||||||
|
+{
|
||||||
|
+ reset_verify_countdown();
|
||||||
|
+ reset_balance_countdown();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void sleep_approx(int seconds)
|
||||||
|
{
|
||||||
|
struct timespec ts;
|
||||||
|
@@ -79,6 +107,26 @@ static void sleep_approx(int seconds)
|
||||||
|
nanosleep(&ts, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void cond_sleep(void)
|
||||||
|
+{
|
||||||
|
+ unsigned int timeout;
|
||||||
|
+
|
||||||
|
+ if (next_verify < next_balance) {
|
||||||
|
+ timeout = next_verify;
|
||||||
|
+ next_balance -= timeout;
|
||||||
|
+ reset_verify_countdown();
|
||||||
|
+ } else if (next_verify > next_balance) {
|
||||||
|
+ timeout = next_balance;
|
||||||
|
+ next_verify -= timeout;
|
||||||
|
+ reset_balance_countdown();
|
||||||
|
+ } else {
|
||||||
|
+ timeout = next_verify;
|
||||||
|
+ reset_countdown();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ sleep_approx(timeout);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
#ifdef HAVE_GETOPT_LONG
|
||||||
|
struct option lopts[] = {
|
||||||
|
{"oneshot", 0, NULL, 'o'},
|
||||||
|
@@ -95,14 +143,15 @@ struct option lopts[] = {
|
||||||
|
{"banmod", 1 , NULL, 'm'},
|
||||||
|
{"interval", 1 , NULL, 't'},
|
||||||
|
{"version", 0, NULL, 'V'},
|
||||||
|
+ {"verifyhint", 1, NULL, 'v'},
|
||||||
|
{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>]\n");
|
||||||
|
+ log(TO_CONSOLE, LOG_INFO, " [--pid= | -s <file>] [--deepestcache= | -c <n>] [--interval= | -t <n>] [--verifyhint= | -v n]\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void version(void)
|
||||||
|
@@ -117,7 +166,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:h:v:",
|
||||||
|
lopts, &longind)) != -1) {
|
||||||
|
|
||||||
|
switch(opt) {
|
||||||
|
@@ -190,12 +239,30 @@ static void parse_command_line(int argc, char **argv)
|
||||||
|
journal_logging=1;
|
||||||
|
foreground_mode=1;
|
||||||
|
break;
|
||||||
|
- case 't':
|
||||||
|
+ case 't':
|
||||||
|
sleep_interval = strtol(optarg, NULL, 10);
|
||||||
|
if (sleep_interval < 1) {
|
||||||
|
usage();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
+ reset_balance_countdown();
|
||||||
|
+ 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);
|
||||||
|
+ }
|
||||||
|
+ reset_verify_countdown();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -251,21 +318,18 @@ void force_rebalance_irq(struct irq_info *info, void *data __attribute__((unused
|
||||||
|
info->assigned_obj = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
-gboolean handler(gpointer data __attribute__((unused)))
|
||||||
|
+void handler(int signum __attribute__((unused)))
|
||||||
|
{
|
||||||
|
keep_going = 0;
|
||||||
|
- g_main_loop_quit(main_loop);
|
||||||
|
- return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
-gboolean force_rescan(gpointer data __attribute__((unused)))
|
||||||
|
+void force_rescan(int signum __attribute__((unused)))
|
||||||
|
{
|
||||||
|
if (cycle_count)
|
||||||
|
need_rescan = 1;
|
||||||
|
- return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
-gboolean scan(gpointer data)
|
||||||
|
+gboolean scan()
|
||||||
|
{
|
||||||
|
log(TO_CONSOLE, LOG_INFO, "\n\n\n-----------------------------------------------------------------------------\n");
|
||||||
|
clear_work_stats();
|
||||||
|
@@ -276,7 +340,7 @@ gboolean scan(gpointer data)
|
||||||
|
if (need_rescan) {
|
||||||
|
need_rescan = 0;
|
||||||
|
cycle_count = 0;
|
||||||
|
- log(TO_CONSOLE, LOG_INFO, "Rescanning cpu topology \n");
|
||||||
|
+ reset_countdown();
|
||||||
|
clear_work_stats();
|
||||||
|
|
||||||
|
free_object_tree();
|
||||||
|
@@ -303,16 +367,9 @@ gboolean scan(gpointer data)
|
||||||
|
keep_going = 0;
|
||||||
|
cycle_count++;
|
||||||
|
|
||||||
|
- if (data != &sleep_interval) {
|
||||||
|
- data = &sleep_interval;
|
||||||
|
- g_timeout_add_seconds(sleep_interval, scan, data);
|
||||||
|
- return FALSE;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
if (keep_going) {
|
||||||
|
return TRUE;
|
||||||
|
} else {
|
||||||
|
- g_main_loop_quit(main_loop);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -501,6 +558,7 @@ int init_socket(char *socket_name)
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
+ struct sigaction action, hupaction;
|
||||||
|
sigset_t sigset, old_sigset;
|
||||||
|
|
||||||
|
sigemptyset(&sigset);
|
||||||
|
@@ -600,11 +658,19 @@ int main(int argc, char** argv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- g_unix_signal_add(SIGINT, handler, NULL);
|
||||||
|
- g_unix_signal_add(SIGTERM, handler, NULL);
|
||||||
|
- g_unix_signal_add(SIGUSR1, handler, NULL);
|
||||||
|
- g_unix_signal_add(SIGUSR2, handler, NULL);
|
||||||
|
- g_unix_signal_add(SIGHUP, force_rescan, NULL);
|
||||||
|
+ action.sa_handler = handler;
|
||||||
|
+ sigemptyset(&action.sa_mask);
|
||||||
|
+ action.sa_flags = 0;
|
||||||
|
+ sigaction(SIGINT, &action, NULL);
|
||||||
|
+ sigaction(SIGTERM, &action, NULL);
|
||||||
|
+ sigaction(SIGUSR1, &action, NULL);
|
||||||
|
+ sigaction(SIGUSR2, &action, NULL);
|
||||||
|
+
|
||||||
|
+ hupaction.sa_handler = force_rescan;
|
||||||
|
+ sigemptyset(&hupaction.sa_mask);
|
||||||
|
+ hupaction.sa_flags = 0;
|
||||||
|
+ sigaction(SIGHUP, &hupaction, NULL);
|
||||||
|
+
|
||||||
|
sigprocmask(SIG_SETMASK, &old_sigset, NULL);
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBCAP_NG
|
||||||
|
@@ -624,12 +690,23 @@ int main(int argc, char** argv)
|
||||||
|
if (init_socket()) {
|
||||||
|
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);
|
||||||
|
- g_main_loop_run(main_loop);
|
||||||
|
|
||||||
|
- g_main_loop_quit(main_loop);
|
||||||
|
+ while (keep_going) {
|
||||||
|
+ cond_sleep();
|
||||||
|
+
|
||||||
|
+ if (need_verify() && hint_changed()) {
|
||||||
|
+ for_each_irq(NULL, update_affinity_hint, NULL);
|
||||||
|
+ reset_countdown();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!need_balance()) {
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!scan()) {
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
|
||||||
|
free_object_tree();
|
||||||
|
free_cl_opts();
|
||||||
|
diff --git a/irqbalance.h b/irqbalance.h
|
||||||
|
index 73737ed..b8141aa 100644
|
||||||
|
--- a/irqbalance.h
|
||||||
|
+++ b/irqbalance.h
|
||||||
|
@@ -106,12 +106,17 @@ 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)));
|
||||||
|
|
||||||
|
/* huawei */
|
||||||
|
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 void update_affinity_hint(struct irq_info *info, void *data __attribute__((unused)));
|
||||||
|
+extern int hint_changed(void);
|
||||||
|
+
|
||||||
|
+extern int hint_enabled, poll_hint_interval;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generic object functions
|
||||||
|
diff --git a/placement.c b/placement.c
|
||||||
|
index 5a82111..2085e09 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
|
||||||
|
@@ -59,6 +60,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/procinterrupts.c b/procinterrupts.c
|
||||||
|
index d384860..b446c55 100644
|
||||||
|
--- a/procinterrupts.c
|
||||||
|
+++ b/procinterrupts.c
|
||||||
|
@@ -544,3 +544,60 @@ void parse_proc_stat(void)
|
||||||
|
for_each_object(numa_nodes, compute_irq_branch_load_share, NULL);
|
||||||
|
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+int hint_changed(void)
|
||||||
|
+{
|
||||||
|
+ FILE *file;
|
||||||
|
+ char *line = NULL;
|
||||||
|
+ size_t size = 0;
|
||||||
|
+ int changed = 0;
|
||||||
|
+
|
||||||
|
+ file = fopen("/proc/irq/affinity_hint_notify", "r+");
|
||||||
|
+ if (!file)
|
||||||
|
+ return changed;
|
||||||
|
+
|
||||||
|
+ if (getline(&line, &size, file) > 0 && *line != '0') {
|
||||||
|
+ fprintf(file, "Done");
|
||||||
|
+ changed = 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ 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);
|
||||||
|
+ log(TO_ALL, LOG_INFO, "IRQ(%d): affinity hint modified\n", info->irq);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (line)
|
||||||
|
+ free(line);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
diff --git a/types.h b/types.h
|
||||||
|
index 9693cf4..62cc2bb 100644
|
||||||
|
--- a/types.h
|
||||||
|
+++ b/types.h
|
||||||
|
@@ -66,6 +66,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
|
||||||
|
|
||||||
826
feature-irqbalance-Add-ability-for-socket-communicat.patch
Normal file
826
feature-irqbalance-Add-ability-for-socket-communicat.patch
Normal file
@ -0,0 +1,826 @@
|
|||||||
|
From a7d86761f9c66eb6fb6d13b77e753d6c42b90e12 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zengruan Ye <yezengruan@huawei.com>
|
||||||
|
Date: Tue, 16 Jul 2019 00:07:36 +0800
|
||||||
|
Subject: [PATCH 6/6] feature: irqbalance: Add ability for 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>
|
||||||
|
---
|
||||||
|
Makefile.am | 6 +-
|
||||||
|
classify.c | 20 ++-
|
||||||
|
cputree.c | 5 +-
|
||||||
|
irqbalance.c | 164 ++----------------------
|
||||||
|
irqbalance.h | 2 +
|
||||||
|
sockapi.c | 400 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
sockapi.h | 18 +++
|
||||||
|
7 files changed, 452 insertions(+), 163 deletions(-)
|
||||||
|
create mode 100644 sockapi.c
|
||||||
|
create mode 100644 sockapi.h
|
||||||
|
|
||||||
|
diff --git a/Makefile.am b/Makefile.am
|
||||||
|
index abf1e8d..62ac482 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,8 +38,8 @@ 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
|
||||||
|
-irqbalance_LDADD = $(LIBCAP_NG_LIBS) $(GLIB2_LIBS)
|
||||||
|
+ irqlist.c numa.c placement.c procinterrupts.c sockapi.c
|
||||||
|
+irqbalance_LDADD = $(LIBCAP_NG_LIBS) $(GLIB2_LIBS) -lpthread
|
||||||
|
if IRQBALANCEUI
|
||||||
|
irqbalance_ui_SOURCES = $(UI_DIR)/helpers.c $(UI_DIR)/irqbalance-ui.c \
|
||||||
|
$(UI_DIR)/ui.c
|
||||||
|
diff --git a/classify.c b/classify.c
|
||||||
|
index 52fd74a..1e277c4 100644
|
||||||
|
--- a/classify.c
|
||||||
|
+++ b/classify.c
|
||||||
|
@@ -37,7 +37,10 @@ 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;
|
||||||
|
+
|
||||||
|
+pthread_mutex_t cl_banned_list_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
+pthread_mutex_t vm_banned_list_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
#define SYSFS_DIR "/sys"
|
||||||
|
#define SYSPCI_DIR "/sys/bus/pci/devices"
|
||||||
|
@@ -299,12 +302,16 @@ void add_banned_list_irq(int irq)
|
||||||
|
|
||||||
|
void add_cl_banned_irq(int irq)
|
||||||
|
{
|
||||||
|
+ irqbalance_mutex_lock(&cl_banned_list_mutex);
|
||||||
|
add_banned_irq(irq, &cl_banned_irqs, 0);
|
||||||
|
+ irqbalance_mutex_unlock(&cl_banned_list_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_vm_banned_irq(int irq)
|
||||||
|
{
|
||||||
|
+ irqbalance_mutex_lock(&vm_banned_list_mutex);
|
||||||
|
add_banned_irq(irq, &vm_banned_irqs, IRQ_FLAG_VM_BANNED);
|
||||||
|
+ irqbalance_mutex_unlock(&vm_banned_list_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int is_banned_irq(int irq)
|
||||||
|
@@ -314,7 +321,9 @@ static int is_banned_irq(int irq)
|
||||||
|
|
||||||
|
find.irq = irq;
|
||||||
|
|
||||||
|
+ irqbalance_mutex_lock(&vm_banned_list_mutex);
|
||||||
|
entry = g_list_find_custom(vm_banned_irqs, &find, compare_ints);
|
||||||
|
+ irqbalance_mutex_unlock(&vm_banned_list_mutex);
|
||||||
|
if (!entry)
|
||||||
|
entry = g_list_find_custom(banned_irqs, &find, compare_ints);
|
||||||
|
|
||||||
|
@@ -586,7 +595,9 @@ static int check_for_irq_ban(char *path __attribute__((unused)), int irq, GList
|
||||||
|
* Check to see if we banned this irq on the command line
|
||||||
|
*/
|
||||||
|
find.irq = irq;
|
||||||
|
+ irqbalance_mutex_lock(&cl_banned_list_mutex);
|
||||||
|
entry = g_list_find_custom(cl_banned_irqs, &find, compare_ints);
|
||||||
|
+ irqbalance_mutex_unlock(&cl_banned_list_mutex);
|
||||||
|
if (entry)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
@@ -821,9 +832,11 @@ void free_irq_db(void)
|
||||||
|
banned_irqs = NULL;
|
||||||
|
g_list_free(rebalance_irq_list);
|
||||||
|
rebalance_irq_list = NULL;
|
||||||
|
+ irqbalance_mutex_lock(&vm_banned_list_mutex);
|
||||||
|
for_each_irq(vm_banned_irqs, free_irq, NULL);
|
||||||
|
g_list_free(vm_banned_irqs);
|
||||||
|
vm_banned_irqs = NULL;
|
||||||
|
+ irqbalance_mutex_unlock(&vm_banned_list_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_cl_opts(void)
|
||||||
|
@@ -918,8 +931,11 @@ struct irq_info *get_irq_info(int irq)
|
||||||
|
find.irq = irq;
|
||||||
|
entry = g_list_find_custom(interrupts_db, &find, compare_ints);
|
||||||
|
|
||||||
|
- if (!entry)
|
||||||
|
+ if (!entry) {
|
||||||
|
+ irqbalance_mutex_lock(&vm_banned_list_mutex);
|
||||||
|
entry = g_list_find_custom(vm_banned_irqs, &find, compare_ints);
|
||||||
|
+ irqbalance_mutex_unlock(&vm_banned_list_mutex);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (!entry)
|
||||||
|
entry = g_list_find_custom(banned_irqs, &find, compare_ints);
|
||||||
|
diff --git a/cputree.c b/cputree.c
|
||||||
|
index 5551784..0dbb5c8 100644
|
||||||
|
--- a/cputree.c
|
||||||
|
+++ b/cputree.c
|
||||||
|
@@ -39,6 +39,7 @@
|
||||||
|
#include "irqbalance.h"
|
||||||
|
|
||||||
|
extern char *banned_cpumask_from_ui;
|
||||||
|
+extern int is_set_banned_cpumask_from_ui;
|
||||||
|
|
||||||
|
GList *cpus;
|
||||||
|
GList *cache_domains;
|
||||||
|
@@ -77,8 +78,8 @@ static void setup_banned_cpus(void)
|
||||||
|
cpus_clear(nohz_full);
|
||||||
|
|
||||||
|
/* A manually specified cpumask overrides auto-detection. */
|
||||||
|
- if (banned_cpumask_from_ui != NULL) {
|
||||||
|
- cpulist_parse(banned_cpumask_from_ui,
|
||||||
|
+ if (is_set_banned_cpumask_from_ui) {
|
||||||
|
+ cpumask_parse_user(banned_cpumask_from_ui,
|
||||||
|
strlen(banned_cpumask_from_ui), banned_cpus);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
diff --git a/irqbalance.c b/irqbalance.c
|
||||||
|
index 27cf2eb..6e9de88 100644
|
||||||
|
--- a/irqbalance.c
|
||||||
|
+++ b/irqbalance.c
|
||||||
|
@@ -34,6 +34,7 @@
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
+#include <pthread.h>
|
||||||
|
#ifdef HAVE_GETOPT_LONG
|
||||||
|
#include <getopt.h>
|
||||||
|
#endif
|
||||||
|
@@ -42,6 +43,7 @@
|
||||||
|
#include <cap-ng.h>
|
||||||
|
#endif
|
||||||
|
#include "irqbalance.h"
|
||||||
|
+#include "sockapi.h"
|
||||||
|
|
||||||
|
volatile int keep_going = 1;
|
||||||
|
volatile int ban_pci_assigned_irq = 1;
|
||||||
|
@@ -430,160 +432,6 @@ 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];
|
||||||
|
- int sock;
|
||||||
|
- int recv_size = 0;
|
||||||
|
- int valid_user = 0;
|
||||||
|
-
|
||||||
|
- struct iovec iov = { buff, 500 };
|
||||||
|
- struct msghdr msg = { 0 };
|
||||||
|
- msg.msg_iov = &iov;
|
||||||
|
- msg.msg_iovlen = 1;
|
||||||
|
- msg.msg_control = malloc(CMSG_SPACE(sizeof(struct ucred)));
|
||||||
|
- msg.msg_controllen = CMSG_SPACE(sizeof(struct ucred));
|
||||||
|
-
|
||||||
|
- struct cmsghdr *cmsg;
|
||||||
|
-
|
||||||
|
- if (condition == G_IO_IN) {
|
||||||
|
- sock = accept(fd, NULL, NULL);
|
||||||
|
- if (sock < 0) {
|
||||||
|
- log(TO_ALL, LOG_WARNING, "Connection couldn't be accepted.\n");
|
||||||
|
- goto out;
|
||||||
|
- }
|
||||||
|
- if ((recv_size = recvmsg(sock, &msg, 0)) < 0) {
|
||||||
|
- log(TO_ALL, LOG_WARNING, "Error while receiving data.\n");
|
||||||
|
- 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, "stats", strlen("stats"))) {
|
||||||
|
- char *stats = NULL;
|
||||||
|
- for_each_object(numa_nodes, get_object_stat, &stats);
|
||||||
|
- send(sock, stats, strlen(stats), 0);
|
||||||
|
- free(stats);
|
||||||
|
- }
|
||||||
|
- if (!strncmp(buff, "settings ", strlen("settings "))) {
|
||||||
|
- if (!(strncmp(buff + strlen("settings "), "sleep ",
|
||||||
|
- strlen("sleep ")))) {
|
||||||
|
- char *sleep_string = malloc(
|
||||||
|
- sizeof(char) * (recv_size - strlen("settings sleep ")));
|
||||||
|
- strncpy(sleep_string, buff + strlen("settings sleep "),
|
||||||
|
- recv_size - strlen("settings sleep "));
|
||||||
|
- int new_iterval = strtoul(sleep_string, NULL, 10);
|
||||||
|
- if (new_iterval >= 1) {
|
||||||
|
- sleep_interval = new_iterval;
|
||||||
|
- }
|
||||||
|
- free(sleep_string);
|
||||||
|
- } else if (!(strncmp(buff + strlen("settings "), "ban irqs ",
|
||||||
|
- strlen("ban irqs ")))) {
|
||||||
|
- char *end;
|
||||||
|
- char *irq_string = malloc(
|
||||||
|
- sizeof(char) * (recv_size - strlen("settings ban irqs ")));
|
||||||
|
- strncpy(irq_string, buff + strlen("settings ban irqs "),
|
||||||
|
- recv_size - strlen("settings ban irqs "));
|
||||||
|
- g_list_free_full(cl_banned_irqs, free);
|
||||||
|
- cl_banned_irqs = NULL;
|
||||||
|
- need_rescan = 1;
|
||||||
|
- if (!strncmp(irq_string, "NONE", strlen("NONE"))) {
|
||||||
|
- free(irq_string);
|
||||||
|
- goto out_close;
|
||||||
|
- }
|
||||||
|
- 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(
|
||||||
|
- sizeof(char) * (recv_size - strlen("settings cpus ")));
|
||||||
|
- strncpy(cpu_ban_string, buff + strlen("settings cpus "),
|
||||||
|
- recv_size - strlen("settings cpus "));
|
||||||
|
- banned_cpumask_from_ui = strtok(cpu_ban_string, " ");
|
||||||
|
- if (!strncmp(banned_cpumask_from_ui, "NULL", strlen("NULL"))) {
|
||||||
|
- banned_cpumask_from_ui = NULL;
|
||||||
|
- }
|
||||||
|
- need_rescan = 1;
|
||||||
|
- free(cpu_ban_string);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- if (!strncmp(buff, "setup", strlen("setup"))) {
|
||||||
|
- char banned[512];
|
||||||
|
- 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);
|
||||||
|
- }
|
||||||
|
- cpumask_scnprintf(banned, 512, banned_cpus);
|
||||||
|
- setup = realloc(setup, strlen(setup) + strlen(banned) + 7 + 1);
|
||||||
|
- snprintf(setup + strlen(setup), strlen(banned) + 7 + 1,
|
||||||
|
- "BANNED %s", banned);
|
||||||
|
- send(sock, setup, strlen(setup), 0);
|
||||||
|
- free(setup);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
-out_close:
|
||||||
|
- close(sock);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
-out:
|
||||||
|
- free(msg.msg_control);
|
||||||
|
- return TRUE;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-int init_socket()
|
||||||
|
-{
|
||||||
|
- struct sockaddr_un addr;
|
||||||
|
- memset(&addr, 0, sizeof(struct sockaddr_un));
|
||||||
|
-
|
||||||
|
- 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).
|
||||||
|
- */
|
||||||
|
- 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, 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");
|
||||||
|
- return 1;
|
||||||
|
- }
|
||||||
|
- listen(socket_fd, 1);
|
||||||
|
- g_unix_fd_add(socket_fd, G_IO_IN, sock_handle, NULL);
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static int create_lock_pidfile(const char *lockfile)
|
||||||
|
{
|
||||||
|
struct flock lock = { 0 };
|
||||||
|
@@ -657,7 +505,9 @@ error_close:
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
- struct sigaction action, hupaction;
|
||||||
|
+ int err;
|
||||||
|
+ pthread_t socket_tid;
|
||||||
|
+ struct sigaction action, hupaction;
|
||||||
|
sigset_t sigset, old_sigset;
|
||||||
|
|
||||||
|
sigemptyset(&sigset);
|
||||||
|
@@ -781,7 +631,9 @@ int main(int argc, char** argv)
|
||||||
|
parse_proc_interrupts();
|
||||||
|
parse_proc_stat();
|
||||||
|
|
||||||
|
- if (init_socket()) {
|
||||||
|
+ err = pthread_create(&socket_tid, NULL, &handle_socket_api_event, NULL);
|
||||||
|
+ if (0 != err) {
|
||||||
|
+ log(TO_CONSOLE, LOG_WARNING, "WARNING: Failed to create irqbalance socket thread, return %d.\n", err);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/irqbalance.h b/irqbalance.h
|
||||||
|
index 339e2a3..f9b554e 100644
|
||||||
|
--- a/irqbalance.h
|
||||||
|
+++ b/irqbalance.h
|
||||||
|
@@ -44,6 +44,8 @@ extern void set_msi_interrupt_numa(int number);
|
||||||
|
|
||||||
|
extern GList *rebalance_irq_list;
|
||||||
|
|
||||||
|
+void irqbalance_mutex_lock(pthread_mutex_t *lock);
|
||||||
|
+void irqbalance_mutex_unlock(pthread_mutex_t *lock);
|
||||||
|
void update_migration_status(void);
|
||||||
|
void dump_workloads(void);
|
||||||
|
void sort_irq_list(GList **list);
|
||||||
|
diff --git a/sockapi.c b/sockapi.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..4a0e683
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/sockapi.c
|
||||||
|
@@ -0,0 +1,410 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (C) 2019. Huawei Technologies Co., Ltd. All rights reserved.
|
||||||
|
+ *
|
||||||
|
+ * This program is free software; you can redistribute it and/or modify
|
||||||
|
+ * it under the terms of the MuLan PSL v1.
|
||||||
|
+ *
|
||||||
|
+ * 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 MuLan PSL v1 for more details.
|
||||||
|
+ */
|
||||||
|
+#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 pthread_mutex_t cl_banned_list_mutex;
|
||||||
|
+extern GList *cl_banned_irqs;
|
||||||
|
+extern pthread_mutex_t vm_banned_list_mutex;
|
||||||
|
+extern GList *vm_banned_irqs;
|
||||||
|
+extern cpumask_t banned_cpus;
|
||||||
|
+extern int keep_going;
|
||||||
|
+
|
||||||
|
+void irqbalance_mutex_lock(pthread_mutex_t *lock)
|
||||||
|
+{
|
||||||
|
+ int err = 0;
|
||||||
|
+
|
||||||
|
+ err = pthread_mutex_lock(lock);
|
||||||
|
+ if (err) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "irqbalance: err(%d) irqbalance_mutex_lock failed", err);
|
||||||
|
+ exit(-1);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void irqbalance_mutex_unlock(pthread_mutex_t *lock)
|
||||||
|
+{
|
||||||
|
+ int err = 0;
|
||||||
|
+
|
||||||
|
+ err = pthread_mutex_unlock(lock);
|
||||||
|
+ if (err) {
|
||||||
|
+ log(TO_ALL, LOG_ERR, "irqbalance: err(%d) irqbalance_mutex_unlock failed", err);
|
||||||
|
+ exit(-1);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+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:");
|
||||||
|
+
|
||||||
|
+ irqbalance_mutex_lock(&cl_banned_list_mutex);
|
||||||
|
+ 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;
|
||||||
|
+ }
|
||||||
|
+ irqbalance_mutex_unlock(&cl_banned_list_mutex);
|
||||||
|
+
|
||||||
|
+ (void)snprintf(irqstr + strlen(irqstr) - 1, length - strlen(irqstr), " PCI:");
|
||||||
|
+
|
||||||
|
+ irqbalance_mutex_lock(&vm_banned_list_mutex);
|
||||||
|
+ 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;
|
||||||
|
+ }
|
||||||
|
+ irqbalance_mutex_unlock(&vm_banned_list_mutex);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+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, fcntl(socket_fd, F_GETFD, 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;
|
||||||
|
+
|
||||||
|
+ irqbalance_mutex_lock(&cl_banned_list_mutex);
|
||||||
|
+ g_list_free_full(cl_banned_irqs, free);
|
||||||
|
+ cl_banned_irqs = NULL;
|
||||||
|
+ irqbalance_mutex_unlock(&cl_banned_list_mutex);
|
||||||
|
+
|
||||||
|
+ 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);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * recived cmdline format:
|
||||||
|
+ * 1: settings sleep <int>
|
||||||
|
+ * 2: settings ban irqs "<int> <int> <int> <int> ..." or settings ban irqs "NONE"
|
||||||
|
+ * 3: settings ban cpus <cpumask> <cpumask> or settings ban cpus NONE
|
||||||
|
+ * */
|
||||||
|
+int sock_handle(int client_fd)
|
||||||
|
+{
|
||||||
|
+ char buff[FILE_LINE_MAX_NUM] = { 0 };
|
||||||
|
+ int ret = -1;
|
||||||
|
+ int recv_size = 0;
|
||||||
|
+ int valid_user = 0;
|
||||||
|
+ int new_iterval = 0;
|
||||||
|
+
|
||||||
|
+ struct cmsghdr *cmsg = NULL;
|
||||||
|
+ struct ucred *credentials = NULL;
|
||||||
|
+ struct iovec iov = { buff, FILE_LINE_MAX_NUM - 1 };
|
||||||
|
+ struct msghdr msg = { NULL, 0, &iov, 1, NULL, 0, 0 };
|
||||||
|
+
|
||||||
|
+ msg.msg_control = malloc(CMSG_SPACE(sizeof(struct ucred)));
|
||||||
|
+ 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.\n");
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ cmsg = CMSG_FIRSTHDR(&msg);
|
||||||
|
+ if (cmsg == NULL) {
|
||||||
|
+ log(TO_ALL, LOG_INFO, "There isn't enough space for a cmsghdr in the buffer.\n");
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((cmsg->cmsg_level == SOL_SOCKET) &&
|
||||||
|
+ (cmsg->cmsg_type == SCM_CREDENTIALS)) {
|
||||||
|
+ 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 cleanup;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ 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, "Recived error setting cpus string %s, ONLY %d cpus support.\n", buff, NR_CPUS);
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+ 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));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = 0;
|
||||||
|
+
|
||||||
|
+cleanup:
|
||||||
|
+ free(msg.msg_control);
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int init_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");
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (access(SOCKET_TMPFS, F_OK) != 0) {
|
||||||
|
+ if (mkdir(SOCKET_TMPFS, 0644) == -1) {
|
||||||
|
+ log(TO_ALL, LOG_WARNING, "Daemon couldn't create directory %s.\n", SOCKET_TMPFS);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * 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;
|
||||||
|
+ 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, bailing out.\n");
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (chmod(socket_name, SOCK_RWX_MODE) != 0) {
|
||||||
|
+ log(TO_ALL, LOG_WARNING, "socket name : %s, chmod failed\n", socket_name);
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ 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));
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (listen(socket_fd, MAX_CLIENT) != 0) {
|
||||||
|
+ log(TO_ALL, LOG_WARNING, "Daemon couldn't be listening to the socket: %s.\n", strerror(errno));
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (setnonblocking(socket_fd) < 0) {
|
||||||
|
+ log(TO_ALL, LOG_WARNING, "Daemon set connection(listen) nonblocking failed: %s.\n", strerror(errno));
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return socket_fd;
|
||||||
|
+
|
||||||
|
+cleanup:
|
||||||
|
+ if (socket_fd >= 0)
|
||||||
|
+ close(socket_fd);
|
||||||
|
+
|
||||||
|
+ return -1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void *handle_socket_api_event(void *args __attribute__((unused)))
|
||||||
|
+{
|
||||||
|
+ int epoll_fd = -1;
|
||||||
|
+ int conn_fd = -1;
|
||||||
|
+ int nfds = -1;
|
||||||
|
+ int i = 0;
|
||||||
|
+ int cur_fd_count = 1;
|
||||||
|
+
|
||||||
|
+ struct epoll_event ev;
|
||||||
|
+ struct epoll_event *events = NULL;
|
||||||
|
+
|
||||||
|
+ snprintf(socket_name, 64, "%s/%s%d.sock", SOCKET_TMPFS, SOCKET_PATH, getpid());
|
||||||
|
+
|
||||||
|
+ memset((void*)&ev, 0, sizeof(ev));
|
||||||
|
+ socket_fd = init_socket();
|
||||||
|
+ if (socket_fd < 0)
|
||||||
|
+ exit(-1);
|
||||||
|
+
|
||||||
|
+ epoll_fd = epoll_create(MAX_EVENTS);
|
||||||
|
+ if (epoll_fd < 0) {
|
||||||
|
+ log(TO_ALL, LOG_WARNING, "Unable to create epoll: %s.\n", strerror(errno));
|
||||||
|
+ exit(-1);
|
||||||
|
+ }
|
||||||
|
+ ev.events = EPOLLIN | EPOLLRDHUP;
|
||||||
|
+ ev.data.fd = socket_fd;
|
||||||
|
+ if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, socket_fd, &ev) < 0) {
|
||||||
|
+ log(TO_ALL, LOG_WARNING, "Daemon epoll set insertion error: %s.\n", strerror(errno));
|
||||||
|
+ exit(-1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ events = (struct epoll_event *)malloc(sizeof(struct epoll_event) * MAX_EVENTS);
|
||||||
|
+ if (NULL == events) {
|
||||||
|
+ log(TO_ALL, LOG_WARNING, "Daemon faild to malloc epoll event space.\n");
|
||||||
|
+ exit(-1);
|
||||||
|
+ }
|
||||||
|
+ memset((void*)events, 0, sizeof(struct epoll_event) * MAX_EVENTS);
|
||||||
|
+
|
||||||
|
+ banned_cpumask_from_ui = (char*)malloc(NR_CPUS + 1);
|
||||||
|
+ memset((void*)banned_cpumask_from_ui, 0, NR_CPUS + 1);
|
||||||
|
+
|
||||||
|
+ while (keep_going) {
|
||||||
|
+ nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
|
||||||
|
+ if ( 0 == nfds) {
|
||||||
|
+ log(TO_ALL, LOG_WARNING, "Daemon epoll wait failed: %s.\n", strerror(errno));
|
||||||
|
+ (void)usleep(SLEEP_TIME);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ for (i = 0; i < nfds; i++) {
|
||||||
|
+ if (events[i].data.fd == socket_fd) {
|
||||||
|
+ conn_fd = accept(socket_fd, NULL, NULL);
|
||||||
|
+ if (conn_fd < 0) {
|
||||||
|
+ log(TO_ALL, LOG_WARNING, "Daemon accept failed: %s\n", strerror(errno));
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ if (cur_fd_count >= MAX_EVENTS) {
|
||||||
|
+ log(TO_ALL, LOG_WARNING, "Daemon support no more than %d connection\n", MAX_EVENTS);
|
||||||
|
+ close(conn_fd);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ if (setnonblocking(conn_fd) < 0) {
|
||||||
|
+ log(TO_ALL, LOG_WARNING, "Daemon set connection nonblocking failed: %s.\n", strerror(errno));
|
||||||
|
+ close(conn_fd);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ memset((void*)&ev, 0, sizeof(ev));
|
||||||
|
+ ev.events = EPOLLIN | EPOLLRDHUP;
|
||||||
|
+ ev.data.fd = conn_fd;
|
||||||
|
+ if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, conn_fd, &ev) < 0) {
|
||||||
|
+ log(TO_ALL, LOG_WARNING, "Daemonadd socket '%d' to poll failed: %s\n", conn_fd, strerror(errno));
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ cur_fd_count++;
|
||||||
|
+ continue;
|
||||||
|
+ } else if (events[i].events&EPOLLERR || events[i].events&EPOLLHUP ) {
|
||||||
|
+ log(TO_ALL, LOG_WARNING, "epoll is error: %u\n", events[i].events);
|
||||||
|
+ } else {
|
||||||
|
+ /* one socket connection only support send&recv data once */
|
||||||
|
+ sock_handle(events[i].data.fd);
|
||||||
|
+ }
|
||||||
|
+ epoll_ctl(epoll_fd, EPOLL_CTL_DEL, events[i].data.fd, &ev);
|
||||||
|
+ close(events[i].data.fd);
|
||||||
|
+ events[i].data.fd = -1;
|
||||||
|
+ cur_fd_count--;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ free(events);
|
||||||
|
+ free(banned_cpumask_from_ui);
|
||||||
|
+ banned_cpumask_from_ui = NULL;
|
||||||
|
+ if (socket_fd >= 0)
|
||||||
|
+ close(socket_fd);
|
||||||
|
+ if (socket_name[0])
|
||||||
|
+ unlink(socket_name);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
diff --git a/sockapi.h b/sockapi.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..254dd3f
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/sockapi.h
|
||||||
|
@@ -0,0 +1,28 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (C) 2019. Huawei Technologies Co., Ltd. All rights reserved.
|
||||||
|
+ *
|
||||||
|
+ * This program is free software; you can redistribute it and/or modify
|
||||||
|
+ * it under the terms of the MuLan PSL v1.
|
||||||
|
+ *
|
||||||
|
+ * 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 MuLan PSL v1 for more details.
|
||||||
|
+ */
|
||||||
|
+#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)
|
||||||
|
+
|
||||||
|
+void *handle_socket_api_event(void *args);
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
83
feature-irqbalance-aarch64-add-the-regular-to-get-th.patch
Normal file
83
feature-irqbalance-aarch64-add-the-regular-to-get-th.patch
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
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
|
||||||
|
|
||||||
131
feature-irqbalance-arm64-Add-irq-aff-change-check.patch
Normal file
131
feature-irqbalance-arm64-Add-irq-aff-change-check.patch
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
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 @@ int irq_in_rebalance_list(int irq)
|
||||||
|
return entry ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#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
|
||||||
|
|
||||||
345
feature-irqbalance-auto-banned-pci-assigned-irq.patch
Normal file
345
feature-irqbalance-auto-banned-pci-assigned-irq.patch
Normal file
@ -0,0 +1,345 @@
|
|||||||
|
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
|
||||||
|
|
||||||
36
feature-supplement-irqbalance-service-config.patch
Normal file
36
feature-supplement-irqbalance-service-config.patch
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
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
|
||||||
|
|
||||||
105
fix-balancing-when-numa-information-isn-t-available.patch
Normal file
105
fix-balancing-when-numa-information-isn-t-available.patch
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
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
|
||||||
|
|
||||||
43
irq_balancer
Normal file
43
irq_balancer
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
# Copyright (c) 2015 HUAWEI TECHNOLOGIES CO., LTD.
|
||||||
|
# All rights reserved.
|
||||||
|
|
||||||
|
# Check for missing binaries (stale symlinks should not happen)
|
||||||
|
IRQBALANCE_BIN=/usr/sbin/irqbalance
|
||||||
|
test -x $IRQBALANCE_BIN || exit 5
|
||||||
|
|
||||||
|
IRQBALANCE_PIDFILE="/var/run/irqbalance.pid"
|
||||||
|
IRQBALANCE_CONFIG_FILE="/etc/sysconfig/irqbalance"
|
||||||
|
|
||||||
|
if [ -f $IRQBALANCE_CONFIG_FILE ]; then
|
||||||
|
. $IRQBALANCE_CONFIG_FILE
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Note: There maybe IRQBALANCE_ARGS env in $IRQBALANCE_CONFIG_FILE
|
||||||
|
# So, here we should add this.
|
||||||
|
IRQBALANCE_ARGS=$IRQBALANCE_ARGS" --pid=$IRQBALANCE_PIDFILE"
|
||||||
|
|
||||||
|
if [ -n "$IRQBALANCE_BANNED_CPUS" ]; then
|
||||||
|
export IRQBALANCE_BANNED_CPUS
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$IRQBALANCE_ONESHOT" != "auto" ]; then
|
||||||
|
export IRQBALANCE_ONESHOT
|
||||||
|
fi
|
||||||
|
|
||||||
|
IRQS_BANNED="$IRQBALANCE_BANNED_INTERRUPTS"
|
||||||
|
if [ -n "$IRQBALANCE_BANNED_INTERRUPTS" ]; then
|
||||||
|
export IRQBALANCE_BANNED_INTERRUPTS
|
||||||
|
fi
|
||||||
|
|
||||||
|
for ban_irq in $IRQS_BANNED;
|
||||||
|
do
|
||||||
|
if [ -z "${ban_irq//[0-9]/}" ];then
|
||||||
|
IRQBALANCE_ARGS=$IRQBALANCE_ARGS" --banirq=$ban_irq"
|
||||||
|
else
|
||||||
|
echo "Bad irq number $ban_irq, please check config file!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
$IRQBALANCE_BIN $IRQBALANCE_ARGS
|
||||||
86
irq_db-don-t-fail-entirely-if-we-don-t-have-a-pci-bu.patch
Normal file
86
irq_db-don-t-fail-entirely-if-we-don-t-have-a-pci-bu.patch
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
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
|
||||||
|
|
||||||
12
irqbalance-1.0.4-env-file-path.patch
Normal file
12
irqbalance-1.0.4-env-file-path.patch
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
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]
|
||||||
BIN
irqbalance-1.4.0.tar.gz
Normal file
BIN
irqbalance-1.4.0.tar.gz
Normal file
Binary file not shown.
105
irqbalance-Add-support-for-file-based-socket-for-IPC.patch
Normal file
105
irqbalance-Add-support-for-file-based-socket-for-IPC.patch
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
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
|
||||||
|
|
||||||
2
irqbalance.rules
Normal file
2
irqbalance.rules
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
echo > /dev/null
|
||||||
141
irqbalance.spec
Normal file
141
irqbalance.spec
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
Summary: A dynamic adaptive IRQ balancing daemon
|
||||||
|
Name: irqbalance
|
||||||
|
Version: 1.4.0
|
||||||
|
Release: 6
|
||||||
|
Epoch: 3
|
||||||
|
|
||||||
|
License: GPLv2
|
||||||
|
Source0: https://github.com/Irqbalance/irqbalance/archive/irqbalance-%{version}.tar.gz
|
||||||
|
Source1: irqbalance.sysconfig
|
||||||
|
Source2: irqbalance.rules
|
||||||
|
Source3: irq_balancer
|
||||||
|
Url: https://github.com/Irqbalance/irqbalance
|
||||||
|
|
||||||
|
BuildRequires: autoconf automake libtool libcap-ng systemd
|
||||||
|
BuildRequires: glib2-devel pkgconf libcap-ng-devel ncurses-devel
|
||||||
|
|
||||||
|
Requires: ncurses-libs
|
||||||
|
|
||||||
|
%ifnarch %{arm}
|
||||||
|
BuildRequires: numactl-devel
|
||||||
|
Requires: numactl-libs
|
||||||
|
%endif
|
||||||
|
|
||||||
|
%define _hardened_build 1
|
||||||
|
|
||||||
|
ExcludeArch: s390 s390x
|
||||||
|
|
||||||
|
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: procinterrupts-check-xen-dyn-event-more-flexible.patch
|
||||||
|
Patch10:Fix-ambiguous-parsing-of-node-entries-in-sys.patch
|
||||||
|
Patch11:Don-t-leak-socket-fd-on-connection-error.patch
|
||||||
|
Patch12:Fix-string-truncation-issues-detected-by-GCC-8.patch
|
||||||
|
Patch13:fix-balancing-when-numa-information-isn-t-available.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-introduce-verifyhint-to-detect-hint-variation.patch
|
||||||
|
Patch9005: bugfix-fix-two-same-irq-insert-to-list.patch
|
||||||
|
Patch9006: feature-irqbalance-aarch64-add-the-regular-to-get-th.patch
|
||||||
|
Patch9007: feature-irqbalance-arm64-Add-irq-aff-change-check.patch
|
||||||
|
Patch9008: feature-irqbalance-auto-banned-pci-assigned-irq.patch
|
||||||
|
Patch9009: bugfix-irqbalance-fix-wrong-pid-value-in-pid-file.patch
|
||||||
|
Patch9010: feature-supplement-irqbalance-service-config.patch
|
||||||
|
Patch9011: feature-irqbalance-Add-ability-for-socket-communicat.patch
|
||||||
|
Patch9012: bugfix-fgets-will-get-a-redundant-new-line.patch
|
||||||
|
Patch9013: bugfix-prevent-inserting-a-duplicate-entry-to-avoid-list-ch.patch
|
||||||
|
Patch9014: bugfix-guess_arm_irq_hints.patch
|
||||||
|
Patch9015: feature-add-new-user-irq-policy-config-rule.patch
|
||||||
|
|
||||||
|
%description
|
||||||
|
Irqbalance is a daemon to help balance the cpu load generated by
|
||||||
|
interrupts across all of a systems cpus. Irqbalance identifies the
|
||||||
|
highest volume interrupt sources, and isolates each of them to a
|
||||||
|
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.
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%autosetup -p1
|
||||||
|
|
||||||
|
%build
|
||||||
|
./autogen.sh
|
||||||
|
%configure
|
||||||
|
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 %{buildroot}%{_mandir}/man1/
|
||||||
|
install -p -m 0644 ./%{name}.1 %{buildroot}%{_mandir}/man1/
|
||||||
|
|
||||||
|
%check
|
||||||
|
make check
|
||||||
|
|
||||||
|
%files
|
||||||
|
%doc COPYING AUTHORS
|
||||||
|
%{_sbindir}/%{name}
|
||||||
|
%{_unitdir}/%{name}.service
|
||||||
|
%{_mandir}/man1/*
|
||||||
|
%config(noreplace) %{_sysconfdir}/sysconfig/%{name}
|
||||||
|
%{_sysconfdir}/sysconfig/%{name}.rules
|
||||||
|
%{_sbindir}/irq_balancer
|
||||||
|
|
||||||
|
%post
|
||||||
|
%systemd_post %{name}.service
|
||||||
|
|
||||||
|
%preun
|
||||||
|
%systemd_preun %{name}.service
|
||||||
|
|
||||||
|
%postun
|
||||||
|
%systemd_postun_with_restart %{name}.service
|
||||||
|
|
||||||
|
%triggerun -- %{name} < 2:0.56-3
|
||||||
|
if /sbin/chkconfig --level 3 %{name} ; then
|
||||||
|
/bin/systemctl enable %{name}.service >/dev/null 2>&1 || :
|
||||||
|
fi
|
||||||
|
/sbin/chkconfig --del %{name} >/dev/null 2>&1 || :
|
||||||
|
|
||||||
|
%changelog
|
||||||
|
* Mon Sep 23 2019 hejingxian<hejingxian@huawei.com> - 3:1.4.0-6
|
||||||
|
- Type: enhancement
|
||||||
|
- ID:NA
|
||||||
|
- SUG:NA
|
||||||
|
- DESC: add avoid duplicate-entry insert, guess_arm_irq_hints and new config rule patches
|
||||||
|
|
||||||
|
* Thu Sep 12 2019 caomeng<caomeng5@huawei.com> - 3:1.4.0-5
|
||||||
|
- Type:other
|
||||||
|
- ID:NA
|
||||||
|
- SUG:NA
|
||||||
|
- DESC: fix make in parallel way
|
||||||
|
|
||||||
|
* Fri Aug 30 2019 caomeng<caomeng5@huawei.com> - 3:1.4.0-4
|
||||||
|
- Type:other
|
||||||
|
- ID:NA
|
||||||
|
- SUG:NA
|
||||||
|
- DESC: fix SP comile option
|
||||||
|
|
||||||
|
* Thu Aug 29 2019 caomeng<caomeng5@huawei.com> - 3:1.4.0-3
|
||||||
|
- Type:other
|
||||||
|
- ID:NA
|
||||||
|
- SUG:NA
|
||||||
|
- DESC: openeuler rewrite spec file
|
||||||
|
|
||||||
|
* Thu Aug 29 2019 caomeng<caomeng5@huawei.com> - 3:1.4.0-2
|
||||||
|
- Package init
|
||||||
|
|
||||||
|
|
||||||
39
irqbalance.sysconfig
Normal file
39
irqbalance.sysconfig
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# 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=
|
||||||
|
|
||||||
|
|
||||||
49
parse_proc_interrupts-ensure-that-buffer-is-long-eno.patch
Normal file
49
parse_proc_interrupts-ensure-that-buffer-is-long-eno.patch
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
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
|
||||||
|
|
||||||
72
procinterrupts-check-xen-dyn-event-more-flexible.patch
Normal file
72
procinterrupts-check-xen-dyn-event-more-flexible.patch
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
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