!12 rebase to v1.6.0

Merge pull request !12 from SuperSix/master
This commit is contained in:
openeuler-ci-bot 2020-07-03 19:30:09 +08:00 committed by Gitee
commit 21aef43a2f
88 changed files with 2877 additions and 5128 deletions

View File

@ -0,0 +1,26 @@
From a79530b6d77456b304c58f7ea706bef869fa00a0 Mon Sep 17 00:00:00 2001
From: Paride Legovini <pl@ninthfloor.org>
Date: Sun, 21 Jul 2019 12:18:49 +0200
Subject: [PATCH 08/53] Add irqbalance-ui.1 to dist_man_MANS
---
Makefile.am | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Makefile.am b/Makefile.am
index abf1e8d..73988b3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -47,6 +47,9 @@ irqbalance_ui_LDADD = $(GLIB2_LIBS) $(CURSES_LIBS)
endif
dist_man_MANS = irqbalance.1
+if IRQBALANCEUI
+dist_man_MANS += irqbalance-ui.1
+endif
CONFIG_CLEAN_FILES = debug*.list config/*
clean-generic:
--
2.23.0

View File

@ -0,0 +1,33 @@
From 724243f1744a263b3777e920526c0a4a3c042ca6 Mon Sep 17 00:00:00 2001
From: Neil Horman <nhorman@tuxdriver.com>
Date: Tue, 17 Sep 2019 08:56:11 -0400
Subject: [PATCH 13/53] Add optional config file in /usr/lib
immutable distributions have a need for distribution specific configs in
a read only space, and so modify the service file to optionally read a
config file from /usr/lib/irqbalance/default.env
Addresses https://github.com/Irqbalance/irqbalance/issues/118
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
---
misc/irqbalance.service | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/misc/irqbalance.service b/misc/irqbalance.service
index bb6ed98..cb7937a 100644
--- a/misc/irqbalance.service
+++ b/misc/irqbalance.service
@@ -5,7 +5,8 @@ Documentation=https://github.com/Irqbalance/irqbalance
ConditionVirtualization=!container
[Service]
-EnvironmentFile=/path/to/irqbalance.env
+Environmentfile=-/usr/lib/irqbalance/defaults.env
+EnvironmentFile=-/path/to/irqbalance.env
ExecStart=/usr/sbin/irqbalance --foreground $IRQBALANCE_ARGS
CapabilityBoundingSet=
NoNewPrivileges=yes
--
2.23.0

View File

@ -0,0 +1,59 @@
From 418d919c10be2430e60f81d5df35b262f072fbe5 Mon Sep 17 00:00:00 2001
From: Paride Legovini <pl@ninthfloor.org>
Date: Sun, 21 Jul 2019 12:15:14 +0200
Subject: [PATCH 06/53] Add stub manpage for irqbalance-ui
---
irqbalance-ui.1 | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
create mode 100644 irqbalance-ui.1
diff --git a/irqbalance-ui.1 b/irqbalance-ui.1
new file mode 100644
index 0000000..7ca4d28
--- /dev/null
+++ b/irqbalance-ui.1
@@ -0,0 +1,40 @@
+.de Sh \" Subsection
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Ip \" List item
+.br
+.ie \\n(.$>=3 .ne \\$3
+.el .ne 3
+.IP "\\$1" \\$2
+..
+.TH "IRQBALANCE-UI" 1 "Jul 2019" "Linux" "irqbalance-ui"
+.SH NAME
+irqbalance-ui \- user interface for irqbalance
+.SH "SYNOPSIS"
+
+.nf
+\fBirqbalance-ui\fR
+.fi
+
+.SH "DESCRIPTION"
+
+.PP
+\fBirqbalance-ui\fR provides an ncurses-based textual user interface to
+\fBirqbalance\fR, a daemon responsible for IRQ distribution on Linux systems.
+It shows how IRQs are distributed over CPUs at given moment, and allows one to
+setup of the sleep interval and the IRQ and CPU banning at runtime.
+
+.SH "HOMEPAGE"
+https://github.com/Irqbalance/irqbalance
+
+.SH "SEE ALSO"
+irqbalance(1)
--
2.23.0

View File

@ -0,0 +1,24 @@
From 30154d546fdaba74d45d1296b8d2bb8e7f139ca7 Mon Sep 17 00:00:00 2001
From: Paride Legovini <pl@ninthfloor.org>
Date: Sun, 21 Jul 2019 12:15:24 +0200
Subject: [PATCH 07/53] Capitalize HOMEPAGE in irqbalance.1
---
irqbalance.1 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/irqbalance.1 b/irqbalance.1
index aad27bc..3005f6b 100644
--- a/irqbalance.1
+++ b/irqbalance.1
@@ -192,6 +192,6 @@ Ban listed IRQs from being balanced, all old values of banned IRQs are forgotten
irqbalance checks SCM_CREDENTIALS of sender (only root user is allowed to interact).
Based on chosen tools, ancillary message with credentials needs to be sent with request.
-.SH "Homepage"
+.SH "HOMEPAGE"
https://github.com/Irqbalance/irqbalance
--
2.23.0

View File

@ -1,7 +1,7 @@
From 7dafc4d5c8d8229f107c90d97f33a4094eb89c6e Mon Sep 17 00:00:00 2001
From: liuchao173 <liuchao173@huawei.com>
Date: Thu, 7 Nov 2019 09:12:42 +0000
Subject: [PATCH 1/8] backport: Checking return value of strdup() in
From 7265665307ab991d0aa452e0b4590b3c1072d0a0 Mon Sep 17 00:00:00 2001
From: Yunfeng Ye <yeyunfeng@huawei.com>
Date: Sun, 22 Sep 2019 13:40:35 +0800
Subject: [PATCH 18/53] Checking return value of strdup() in
collect_full_irq_list()
strdup() may return NULL if memory allocation fail, checking the return
@ -13,10 +13,10 @@ Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
1 file changed, 2 insertions(+)
diff --git a/procinterrupts.c b/procinterrupts.c
index 2c8118a..87fae2f 100644
index 44c5c76..f3f57ad 100644
--- a/procinterrupts.c
+++ b/procinterrupts.c
@@ -188,6 +188,8 @@ GList* collect_full_irq_list()
@@ -189,6 +189,8 @@ GList* collect_full_irq_list()
continue;
savedline = strdup(line);
@ -26,4 +26,5 @@ index 2c8118a..87fae2f 100644
if (strstr(irq_name, "xen-dyn") != NULL)
is_xen_dyn = 1;
--
2.19.1
2.23.0

View File

@ -0,0 +1,31 @@
From 77a3914fb48c4f5ef72c8b84bba43f8a852d1725 Mon Sep 17 00:00:00 2001
From: Paride Legovini <pl@ninthfloor.org>
Date: Fri, 5 Jul 2019 00:00:05 +0200
Subject: [PATCH 02/53] Clarify the README description
---
README.md | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index 8e394bd..23427a9 100644
--- a/README.md
+++ b/README.md
@@ -2,10 +2,10 @@ What is Irqbalance
==================
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 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.
+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.
## Building and Installing [![Build Status](https://travis-ci.org/Irqbalance/irqbalance.svg?branch=master)](https://travis-ci.org/Irqbalance/irqbalance)
--
2.23.0

View File

@ -0,0 +1,43 @@
From 761a3e73cfa0016e7a5f19fb2fe94702cc6925e9 Mon Sep 17 00:00:00 2001
From: Felix Yan <felixonmars@archlinux.org>
Date: Tue, 25 Feb 2020 04:15:50 +0800
Subject: [PATCH 50/53] Correct typos in irqbalance.c
---
irqbalance.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/irqbalance.c b/irqbalance.c
index aa9941c..35c762d 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -198,7 +198,7 @@ static void parse_command_line(int argc, char **argv)
#endif
/*
- * This builds our object tree. The Heirarchy is typically pretty
+ * This builds our object tree. The Hierarchy is typically pretty
* straightforward.
* At the top are numa_nodes
* CPU packages belong to a single numa_node, unless the cache domains are in
@@ -633,7 +633,7 @@ int main(int argc, char** argv)
HZ = sysconf(_SC_CLK_TCK);
if (HZ == -1) {
- log(TO_ALL, LOG_WARNING, "Unable to determin HZ defaulting to 100\n");
+ log(TO_ALL, LOG_WARNING, "Unable to determine HZ defaulting to 100\n");
HZ = 100;
}
@@ -641,7 +641,7 @@ int main(int argc, char** argv)
int pidfd = -1;
if (daemon(0,0))
exit(EXIT_FAILURE);
- /* Write pidfile which can be used to avoid starting mutiple instances */
+ /* Write pidfile which can be used to avoid starting multiple instances */
if (pidfile && (pidfd = open(pidfile,
O_WRONLY | O_CREAT | O_EXCL | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) >= 0) {
--
2.23.0

View File

@ -1,65 +0,0 @@
From f2623176c2997e7803d485084fa5150556caddcf Mon Sep 17 00:00:00 2001
From: Kairui Song <kasong@redhat.com>
Date: Mon, 5 Nov 2018 17:18:49 +0800
Subject: [PATCH 102/112] Don't leak socket fd on connection error
Signed-off-by: Kairui Song <kasong@redhat.com>
---
irqbalance.c | 7 ++++---
ui/irqbalance-ui.c | 1 +
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/irqbalance.c b/irqbalance.c
index 0946603..364ca72 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -376,7 +376,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
}
if ((recv_size = recvmsg(sock, &msg, 0)) < 0) {
log(TO_ALL, LOG_WARNING, "Error while receiving data.\n");
- goto out;
+ goto out_close;
}
cmsg = CMSG_FIRSTHDR(&msg);
if ((cmsg->cmsg_level == SOL_SOCKET) &&
@@ -388,7 +388,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
}
if (!valid_user) {
log(TO_ALL, LOG_INFO, "Permission denied for user to connect to socket.\n");
- goto out;
+ goto out_close;
}
if (!strncmp(buff, "stats", strlen("stats"))) {
@@ -421,7 +421,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
need_rescan = 1;
if (!strncmp(irq_string, "NONE", strlen("NONE"))) {
free(irq_string);
- goto out;
+ goto out_close;
}
int irq = strtoul(irq_string, &end, 10);
do {
@@ -457,6 +457,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
free(setup);
}
+out_close:
close(sock);
}
diff --git a/ui/irqbalance-ui.c b/ui/irqbalance-ui.c
index 5a76ddf..005eea4 100644
--- a/ui/irqbalance-ui.c
+++ b/ui/irqbalance-ui.c
@@ -66,6 +66,7 @@ int init_connection()
memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
if (connect(socket_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ close(socket_fd);
return 0;
}
--
1.8.3.1

View File

@ -1,73 +0,0 @@
From 721460664afad79e2d96bbcb173eda68eed9743b Mon Sep 17 00:00:00 2001
From: Gerd Rausch <gerd.rausch@oracle.com>
Date: Thu, 18 Oct 2018 11:21:40 -0700
Subject: [PATCH 100/112] Fix ambiguous parsing of *node* entries in /sys.
The code used to use strstr(..., "node") while iterating over
sysfs directories such as /sys/devices/system/cpu/cpu*.
It then made an assumption that the entry would start with "node",
which is not necessarily the case (e.g. the "firmware_node" entry).
The code happened to work for as long as the node[0-9]* entry
would be processed before the "firmware_node" entry shows up.
A change to the linux kernel "end_name_hash" function resulted
in a different hash, and ultimately in a different order
by which entries were returned by readdir(3).
This led to the exposure of this bug.
Signed-off-by: Gerd Rausch <gerd.rausch@oracle.com>
---
cputree.c | 11 ++++++++---
numa.c | 5 ++++-
2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/cputree.c b/cputree.c
index c88143f..f08ce84 100644
--- a/cputree.c
+++ b/cputree.c
@@ -368,9 +368,14 @@ static void do_one_cpu(char *path)
entry = readdir(dir);
if (!entry)
break;
- if (strstr(entry->d_name, "node")) {
- nodeid = strtoul(&entry->d_name[4], NULL, 10);
- break;
+ if (strncmp(entry->d_name, "node", 4) == 0) {
+ char *end;
+ int num;
+ num = strtol(entry->d_name + 4, &end, 10);
+ if (!*end && num >= 0) {
+ nodeid = num;
+ break;
+ }
}
} while (entry);
closedir(dir);
diff --git a/numa.c b/numa.c
index cd67ec8..f0b1a98 100644
--- a/numa.c
+++ b/numa.c
@@ -29,6 +29,7 @@
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
+#include <ctype.h>
#include <sys/types.h>
#include <dirent.h>
@@ -115,7 +116,9 @@ void build_numa_node_list(void)
entry = readdir(dir);
if (!entry)
break;
- if ((entry->d_type == DT_DIR) && (strstr(entry->d_name, "node"))) {
+ if ((entry->d_type == DT_DIR) &&
+ (strncmp(entry->d_name, "node", 4) == 0) &&
+ isdigit(entry->d_name[4])) {
add_one_node(entry->d_name);
}
} while (entry);
--
1.8.3.1

View File

@ -1,34 +0,0 @@
From 702cab67df2bafd9735a753387eae7febd74263b Mon Sep 17 00:00:00 2001
From: Kairui Song <kasong@redhat.com>
Date: Sun, 2 Sep 2018 23:40:45 +0800
Subject: [PATCH 095/112] Fix an possible overflow error
Got:
"specified bound 2048 exceeds the size 19 of the destination"
when -O2 is used, and a "*** buffer overflow detected ***" error output
with no backtrace.
With -O0, it's gone, guess it's some gcc optimization problem, and the
size there is wrong anyway, this patch could fix it.
---
irqbalance.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/irqbalance.c b/irqbalance.c
index 81bf8d8..0946603 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -444,8 +444,8 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
}
if (!strncmp(buff, "setup", strlen("setup"))) {
char banned[512];
- char *setup = calloc(strlen("SLEEP ") + 11 +1, 1);
- snprintf(setup, 2048, "SLEEP %d ", sleep_interval);
+ char *setup = calloc(strlen("SLEEP ") + 11 + 1, 1);
+ snprintf(setup, strlen("SLEEP ") + 11 + 1, "SLEEP %d ", sleep_interval);
if(g_list_length(cl_banned_irqs) > 0) {
for_each_irq(cl_banned_irqs, get_irq_data, setup);
}
--
1.8.3.1

View File

@ -1,57 +0,0 @@
From ce806df0081cf09344197285e32bd2113d86f554 Mon Sep 17 00:00:00 2001
From: Kairui Song <kasong@redhat.com>
Date: Mon, 3 Sep 2018 00:30:14 +0800
Subject: [PATCH 23/58] Fix irqbalance ui failing to connect to irqbalance
daemon
irqbalance ui is faling due to the changes in commit 19c25dd.
This patch align irqbalance-ui's socket connecting routine with
irqbalance.c
---
ui/irqbalance-ui.c | 16 +++++++++++-----
ui/irqbalance-ui.h | 1 +
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/ui/irqbalance-ui.c b/ui/irqbalance-ui.c
index 47dd5dc..5a76ddf 100644
--- a/ui/irqbalance-ui.c
+++ b/ui/irqbalance-ui.c
@@ -57,12 +57,18 @@ int init_connection()
}
addr.sun_family = AF_UNIX;
char socket_name[64];
- snprintf(socket_name, 64, "%s%d.sock", SOCKET_PATH, irqbalance_pid);
- strncpy(addr.sun_path, socket_name, strlen(addr.sun_path));
- if(connect(socket_fd, (struct sockaddr *)&addr,
- sizeof(sa_family_t) + strlen(socket_name) + 1) < 0) {
- return 0;
+ snprintf(socket_name, 64, "%s/%s%d.sock", SOCKET_TMPFS, SOCKET_PATH, irqbalance_pid);
+ strncpy(addr.sun_path, socket_name, strlen(socket_name));
+
+ if(connect(socket_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ /* Try connect to abstract */
+ memset(&addr, 0, sizeof(struct sockaddr_un));
+ addr.sun_family = AF_UNIX;
+ if (connect(socket_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ return 0;
+ }
+
}
return socket_fd;
diff --git a/ui/irqbalance-ui.h b/ui/irqbalance-ui.h
index f97fcb1..b32d58a 100644
--- a/ui/irqbalance-ui.h
+++ b/ui/irqbalance-ui.h
@@ -8,6 +8,7 @@
#include <glib-unix.h>
#define SOCKET_PATH "irqbalance"
+#define SOCKET_TMPFS "/var/run"
#define STATS "stats"
#define SET_SLEEP "settings sleep "
--
1.8.3.1

View File

@ -1,253 +0,0 @@
From 85d37098a551034061d4b77be275d664e109c3fb Mon Sep 17 00:00:00 2001
From: Kairui Song <kasong@redhat.com>
Date: Thu, 30 Aug 2018 17:45:53 +0800
Subject: [PATCH 094/112] Fix several memleak problems found by covscan
Some memleak issues is found by static analysis tools, and can confirm
irqbalance is leaking memory slowly when there are incomming connection
to socket.
This patch could solve the memleak problem.
---
irqbalance.c | 16 ++++++++++++----
ui/irqbalance-ui.c | 31 +++++++++++++++++++++++++++----
ui/ui.c | 2 ++
3 files changed, 41 insertions(+), 8 deletions(-)
diff --git a/irqbalance.c b/irqbalance.c
index bce9d56..81bf8d8 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -372,11 +372,11 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
sock = accept(fd, NULL, NULL);
if (sock < 0) {
log(TO_ALL, LOG_WARNING, "Connection couldn't be accepted.\n");
- return TRUE;
+ goto out;
}
if ((recv_size = recvmsg(sock, &msg, 0)) < 0) {
log(TO_ALL, LOG_WARNING, "Error while receiving data.\n");
- return TRUE;
+ goto out;
}
cmsg = CMSG_FIRSTHDR(&msg);
if ((cmsg->cmsg_level == SOL_SOCKET) &&
@@ -388,7 +388,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
}
if (!valid_user) {
log(TO_ALL, LOG_INFO, "Permission denied for user to connect to socket.\n");
- return TRUE;
+ goto out;
}
if (!strncmp(buff, "stats", strlen("stats"))) {
@@ -408,6 +408,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
if (new_iterval >= 1) {
sleep_interval = new_iterval;
}
+ free(sleep_string);
} else if (!(strncmp(buff + strlen("settings "), "ban irqs ",
strlen("ban irqs ")))) {
char *end;
@@ -419,12 +420,14 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
cl_banned_irqs = NULL;
need_rescan = 1;
if (!strncmp(irq_string, "NONE", strlen("NONE"))) {
- return TRUE;
+ free(irq_string);
+ goto out;
}
int irq = strtoul(irq_string, &end, 10);
do {
add_cl_banned_irq(irq);
} while((irq = strtoul(end, &end, 10)));
+ free(irq_string);
} else if (!(strncmp(buff + strlen("settings "), "cpus ",
strlen("cpus")))) {
char *cpu_ban_string = malloc(
@@ -436,6 +439,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
banned_cpumask_from_ui = NULL;
}
need_rescan = 1;
+ free(cpu_ban_string);
}
}
if (!strncmp(buff, "setup", strlen("setup"))) {
@@ -450,10 +454,14 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
snprintf(setup + strlen(setup), strlen(banned) + 7 + 1,
"BANNED %s", banned);
send(sock, setup, strlen(setup), 0);
+ free(setup);
}
close(sock);
}
+
+out:
+ free(msg.msg_control);
return TRUE;
}
diff --git a/ui/irqbalance-ui.c b/ui/irqbalance-ui.c
index d4deee0..47dd5dc 100644
--- a/ui/irqbalance-ui.c
+++ b/ui/irqbalance-ui.c
@@ -41,6 +41,7 @@ struct msghdr * create_credentials_msg()
cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred));
memcpy(CMSG_DATA(cmsg), credentials, sizeof(struct ucred));
+ free(credentials);
return msg;
}
@@ -87,6 +88,8 @@ void send_settings(char *data)
sendmsg(socket_fd, msg, 0);
close(socket_fd);
+ free(msg->msg_control);
+ free(msg);
}
char * get_data(char *string)
@@ -115,6 +118,8 @@ char * get_data(char *string)
int len = recv(socket_fd, data, 8192, 0);
close(socket_fd);
data[len] = '\0';
+ free(msg->msg_control);
+ free(msg);
return data;
}
@@ -123,6 +128,7 @@ void parse_setup(char *setup_data)
char *token, *ptr;
int i,j;
char *copy;
+ irq_t *new_irq = NULL;
if((setup_data == NULL) || (strlen(setup_data) == 0)) return;
copy = strdup(setup_data);
if (!copy)
@@ -136,7 +142,7 @@ void parse_setup(char *setup_data)
token = strtok_r(NULL, " ", &ptr);
/* Parse banned IRQ data */
while(!strncmp(token, "IRQ", strlen("IRQ"))) {
- irq_t *new_irq = malloc(sizeof(irq_t));
+ new_irq = malloc(sizeof(irq_t));
new_irq->vector = strtol(strtok_r(NULL, " ", &ptr), NULL, 10);
token = strtok_r(NULL, " ", &ptr);
if(strncmp(token, "LOAD", strlen("LOAD"))) goto out;
@@ -151,6 +157,7 @@ void parse_setup(char *setup_data)
new_irq->assigned_to = NULL;
setup.banned_irqs = g_list_append(setup.banned_irqs, new_irq);
token = strtok_r(NULL, " ", &ptr);
+ new_irq = NULL;
}
if(strncmp(token, "BANNED", strlen("BANNED"))) goto out;
@@ -165,6 +172,7 @@ void parse_setup(char *setup_data)
banned_cpu);
}
}
+ free(map);
}
free(copy);
@@ -173,6 +181,9 @@ void parse_setup(char *setup_data)
out: {
/* Invalid data presented */
printf("Invalid data sent. Unexpected token: %s", token);
+ if (new_irq) {
+ free(new_irq);
+ }
free(copy);
g_list_free(tree);
exit(1);
@@ -240,7 +251,9 @@ void parse_into_tree(char *data)
cpu_node_t *parent = NULL;
char *copy;
tree = NULL;
-
+ irq_t *new_irq = NULL;
+ cpu_node_t *new = NULL;
+
if (!data || strlen(data) == 0)
return;
@@ -255,7 +268,7 @@ void parse_into_tree(char *data)
free(copy);
goto out;
}
- cpu_node_t *new = malloc(sizeof(cpu_node_t));
+ new = malloc(sizeof(cpu_node_t));
new->irqs = NULL;
new->children = NULL;
new->cpu_list = NULL;
@@ -279,7 +292,7 @@ void parse_into_tree(char *data)
/* Parse assigned IRQ data */
while((token != NULL) && (!strncmp(token, "IRQ", strlen("IRQ")))) {
- irq_t *new_irq = malloc(sizeof(irq_t));
+ new_irq = malloc(sizeof(irq_t));
new_irq->vector = strtol(strtok_r(NULL, " ", &ptr), NULL, 10);
token = strtok_r(NULL, " ", &ptr);
if(strncmp(token, "LOAD", strlen("LOAD"))) goto out;
@@ -293,6 +306,7 @@ void parse_into_tree(char *data)
new_irq->is_banned = 0;
new->irqs = g_list_append(new->irqs, new_irq);
token = strtok_r(NULL, " ", &ptr);
+ new_irq = NULL;
}
if((token == NULL) || (strncmp(token, "IRQ", strlen("IRQ")))) {
@@ -306,6 +320,8 @@ void parse_into_tree(char *data)
parent = new;
}
}
+
+ new = NULL;
}
free(copy);
for_each_node(tree, assign_cpu_lists, NULL);
@@ -315,6 +331,12 @@ void parse_into_tree(char *data)
out: {
/* Invalid data presented */
printf("Invalid data sent. Unexpected token: %s\n", token);
+ if (new_irq) {
+ free(new_irq);
+ }
+ if (new) {
+ free(new);
+ }
g_list_free(tree);
exit(1);
}
@@ -330,6 +352,7 @@ gboolean rescan_tree(gpointer data __attribute__((unused)))
display_tree();
}
free(setup_data);
+ free(irqbalance_data);
return TRUE;
}
diff --git a/ui/ui.c b/ui/ui.c
index 4054f0e..06ec472 100644
--- a/ui/ui.c
+++ b/ui/ui.c
@@ -71,6 +71,7 @@ char * check_control_in_sleep_input(int max_len, int column_offest, int line_off
attrset(COLOR_PAIR(6));
break;
case 27:
+ free(input_to);
return NULL;
default:
input_to[iteration] = new;
@@ -115,6 +116,7 @@ int get_valid_sleep_input(int column_offest)
input);
refresh();
}
+ free(input);
}
attrset(COLOR_PAIR(1));
--
1.8.3.1

View File

@ -1,58 +0,0 @@
From d6abbe898baa111207e1e9316dde75c38d555325 Mon Sep 17 00:00:00 2001
From: Neil Horman <nhorman@tuxdriver.com>
Date: Mon, 9 Jul 2018 10:12:41 -0400
Subject: [PATCH 091/112] Fix some string copy limitations
Latest gcc caught some errors in our string copying routines. Fix those
up
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
---
irqbalance.c | 3 +--
procinterrupts.c | 2 +-
ui/irqbalance-ui.c | 2 +-
3 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/irqbalance.c b/irqbalance.c
index 66e56f8..2614719 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -468,8 +468,7 @@ int init_socket(char *socket_name)
}
addr.sun_family = AF_UNIX;
- addr.sun_path[0] = '\0';
- strncpy(addr.sun_path + 1, socket_name, strlen(socket_name));
+ strncpy(addr.sun_path, socket_name, strlen(addr.sun_path));
if (bind(socket_fd, (struct sockaddr *)&addr,
sizeof(sa_family_t) + strlen(socket_name) + 1) < 0) {
log(TO_ALL, LOG_WARNING, "Daemon couldn't be bound to the socket.\n");
diff --git a/procinterrupts.c b/procinterrupts.c
index 4ef8751..7283998 100644
--- a/procinterrupts.c
+++ b/procinterrupts.c
@@ -274,7 +274,7 @@ void parse_proc_interrupts(void)
if (!c)
continue;
- strncpy(savedline, line, sizeof(savedline));
+ strncpy(savedline, line, sizeof(savedline)-1);
*c = 0;
c++;
diff --git a/ui/irqbalance-ui.c b/ui/irqbalance-ui.c
index 3fc46af..d4deee0 100644
--- a/ui/irqbalance-ui.c
+++ b/ui/irqbalance-ui.c
@@ -57,7 +57,7 @@ int init_connection()
addr.sun_family = AF_UNIX;
char socket_name[64];
snprintf(socket_name, 64, "%s%d.sock", SOCKET_PATH, irqbalance_pid);
- strncpy(addr.sun_path + 1, socket_name, strlen(socket_name));
+ strncpy(addr.sun_path, socket_name, strlen(addr.sun_path));
if(connect(socket_fd, (struct sockaddr *)&addr,
sizeof(sa_family_t) + strlen(socket_name) + 1) < 0) {
--
1.8.3.1

48
Fix-spelling-errors.patch Normal file
View File

@ -0,0 +1,48 @@
From c30406b2b6f0e9c23b7b0e4b9c2024d871b01557 Mon Sep 17 00:00:00 2001
From: Paride Legovini <pl@ninthfloor.org>
Date: Thu, 4 Jul 2019 23:53:37 +0200
Subject: [PATCH 01/53] Fix spelling errors
---
irqbalance.1 | 4 ++--
ui/irqbalance-ui.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/irqbalance.1 b/irqbalance.1
index 07f47d8..aad27bc 100644
--- a/irqbalance.1
+++ b/irqbalance.1
@@ -68,7 +68,7 @@ example to ban IRQs 43 and 44 from balancing, use the following command line:
.TP
.B -m, --banmod=<module_name>
-Add the specified module to the set of banned modules, similiar to --banirq.
+Add the specified module to the set of banned modules, similar to --banirq.
irqbalance will not affect the affinity of any IRQs of given modules, allowing
them to be specified manually. This option is additive and can be specified
multiple times. For example to ban all IRQs of module foo and module bar from
@@ -131,7 +131,7 @@ This indicates that the script has no policy for the referenced irq, and that
script processing should continue
.TP
.I 2
-This indicates that an error has occured in the script, and it should be skipped
+This indicates that an error has occurred in the script, and it should be skipped
(further processing to continue)
.TP
diff --git a/ui/irqbalance-ui.c b/ui/irqbalance-ui.c
index 1119665..fe00e94 100644
--- a/ui/irqbalance-ui.c
+++ b/ui/irqbalance-ui.c
@@ -390,7 +390,7 @@ gboolean key_loop(gpointer data __attribute__((unused)))
int main(int argc, char **argv)
{
if(getuid() != 0) {
- printf("This program needs to be executed with root priviledges\n");
+ printf("This program needs to be executed with root privileges\n");
return EACCES;
}
if(argc > 1) {
--
2.23.0

View File

@ -1,54 +0,0 @@
From 8adbe9aacb93c5a160f3ecfc00adc10a64d27c14 Mon Sep 17 00:00:00 2001
From: Sekhar Nori <nsekhar@ti.com>
Date: Tue, 19 Feb 2019 08:29:58 +0000
Subject: [PATCH 108/112] Fix string truncation issues detected by GCC 8
This fixes string truncation warning generated by GCC of the form:
irqbalance.c:485:2: warning: 'strncpy' output truncated before terminating nul copying as many bytes from a string as its length [-Wstringop-truncation]
strncpy(addr.sun_path, socket_name, strlen(socket_name));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Using source size in strncpy so fix that by using destination size.
For the instance of this issue in irqbalance-ui.c, fix the issue by
eliminating the unneeded temporary buffer.
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
---
irqbalance.c | 2 +-
ui/irqbalance-ui.c | 5 ++---
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/irqbalance.c b/irqbalance.c
index 60d8a5e..c1a0e15 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -482,7 +482,7 @@ int init_socket()
*/
addr.sun_family = AF_UNIX;
snprintf(socket_name, 64, "%s/%s%d.sock", SOCKET_TMPFS, SOCKET_PATH, getpid());
- strncpy(addr.sun_path, socket_name, strlen(socket_name));
+ strncpy(addr.sun_path, socket_name, sizeof(addr.sun_path));
if (bind(socket_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
log(TO_ALL, LOG_WARNING, "Daemon couldn't be bound to the file-based socket.\n");
diff --git a/ui/irqbalance-ui.c b/ui/irqbalance-ui.c
index 005eea4..1119665 100644
--- a/ui/irqbalance-ui.c
+++ b/ui/irqbalance-ui.c
@@ -56,10 +56,9 @@ int init_connection()
return 0;
}
addr.sun_family = AF_UNIX;
- char socket_name[64];
- snprintf(socket_name, 64, "%s/%s%d.sock", SOCKET_TMPFS, SOCKET_PATH, irqbalance_pid);
- strncpy(addr.sun_path, socket_name, strlen(socket_name));
+ snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s%d.sock", SOCKET_TMPFS,
+ SOCKET_PATH, irqbalance_pid);
if(connect(socket_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
/* Try connect to abstract */
--
1.8.3.1

View File

@ -0,0 +1,28 @@
From 3a19387fb712c509f8137f06dbf899350ad2f84c Mon Sep 17 00:00:00 2001
From: Neil Horman <nhorman@tuxdriver.com>
Date: Mon, 8 Jun 2020 06:24:56 -0400
Subject: [PATCH 52/53] Fix typo in service unit file
Environmentfile should be EnvironmentFile
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
---
misc/irqbalance.service | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/misc/irqbalance.service b/misc/irqbalance.service
index cb7937a..e7a3336 100644
--- a/misc/irqbalance.service
+++ b/misc/irqbalance.service
@@ -5,7 +5,7 @@ Documentation=https://github.com/Irqbalance/irqbalance
ConditionVirtualization=!container
[Service]
-Environmentfile=-/usr/lib/irqbalance/defaults.env
+EnvironmentFile=-/usr/lib/irqbalance/defaults.env
EnvironmentFile=-/path/to/irqbalance.env
ExecStart=/usr/sbin/irqbalance --foreground $IRQBALANCE_ARGS
CapabilityBoundingSet=
--
2.23.0

25
Update-classify.c.patch Normal file
View File

@ -0,0 +1,25 @@
From 27335d21e392b1d17b030a7bfc1d99a9e61db421 Mon Sep 17 00:00:00 2001
From: liuchao173 <55137861+liuchao173@users.noreply.github.com>
Date: Fri, 20 Sep 2019 11:31:04 +0800
Subject: [PATCH 16/53] Update classify.c
---
classify.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/classify.c b/classify.c
index 15d0ab2..de78bba 100644
--- a/classify.c
+++ b/classify.c
@@ -692,7 +692,7 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
new = get_irq_info(irqnum);
if (new)
goto done;
- get_irq_user_policy(irqnum, &pol);
+ get_irq_user_policy(devpath, irqnum, &pol);
if ((pol.ban == 1) || (check_for_irq_ban(irqnum, tmp_irqs))) {
add_banned_irq(irqnum, &banned_irqs);
goto done;
--
2.23.0

View File

@ -1,52 +0,0 @@
From 0906c9dcf1754bb2f32f9247608cc937650d2a0e Mon Sep 17 00:00:00 2001
From: Neil Horman <nhorman@tuxdriver.com>
Date: Fri, 4 May 2018 06:15:51 -0400
Subject: [PATCH] arm: Add a catchall guessing mechanism
Instead of spamming the logs to indicate we are guessing at an irq type,
and then not finding one, add a catchall regex to match on everything
last to assign the type and class as legacy/other, and report that
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
---
procinterrupts.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/procinterrupts.c b/procinterrupts.c
index eb84a1c..1aa4413 100644
--- a/procinterrupts.c
+++ b/procinterrupts.c
@@ -105,10 +105,12 @@ static void guess_arm_irq_hints(char *name, struct irq_info *info)
{
int i, rc;
static int compiled = 0;
+ /* Note: Last entry is a catchall */
static struct irq_match matches[] = {
{ "eth.*" ,{NULL} ,NULL, IRQ_TYPE_LEGACY, IRQ_GBETH },
{ "[A-Z0-9]{4}[0-9a-f]{4}", {NULL} ,check_platform_device, IRQ_TYPE_LEGACY, IRQ_OTHER},
{ "PNP[0-9a-f]{4}", {NULL} ,check_platform_device, IRQ_TYPE_LEGACY, IRQ_OTHER},
+ { ".*", {NULL}, NULL, IRQ_TYPE_LEGACY, IRQ_OTHER},
{NULL},
};
@@ -134,8 +136,7 @@ static void guess_arm_irq_hints(char *name, struct irq_info *info)
info->class = matches[i].class;
if (matches[i].refine_match)
matches[i].refine_match(name, info);
-
- log(TO_ALL, LOG_DEBUG, "IRQ %s(%d) is class %d\n", name, info->irq,info->class);
+ log(TO_ALL, LOG_DEBUG, "IRQ %s(%d) guessed as class %d\n", name, info->irq,info->class);
}
}
@@ -214,7 +215,6 @@ GList* collect_full_irq_list()
info->class = IRQ_VIRT_EVENT;
} else {
#ifdef AARCH64
- log(TO_ALL, LOG_DEBUG, "GUESSING AARCH64 CLASS FOR %s\n", irq_name);
guess_arm_irq_hints(irq_name, info);
#else
info->type = IRQ_TYPE_LEGACY;
--
2.21.0.windows.1

View File

@ -1,7 +1,7 @@
From 55c5c321c73e4c9b54e041ba8c7d542598685bae Mon Sep 17 00:00:00 2001
From: liuchao <liuchao173@huawei.com>
From: l00520965 <liuchao173@huawei.com>
Date: Wed, 11 Mar 2020 11:46:42 +0800
Subject: [PATCH 48/48] arm64: Add irq aff change check For aarch64, the PPIs
Subject: [PATCH 51/53] 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.
@ -11,15 +11,15 @@ Acctually, the PPIs cannot change aff, and it should not be added to interrupt d
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.
---
activate.c | 8 +++++++-
classify.c | 32 +++++++++++++++++++++++++++-----
classify.c | 28 +++++++++++++++++++++++++---
irqbalance.h | 2 ++
3 files changed, 36 insertions(+), 6 deletions(-)
3 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/activate.c b/activate.c
index 2812976..f933347 100644
index ab9702d..065f880 100644
--- a/activate.c
+++ b/activate.c
@@ -60,6 +60,7 @@ static void activate_mapping(struct irq_info *info, void *data __attribute__((un
@@ -48,6 +48,7 @@ static void activate_mapping(struct irq_info *info, void *data __attribute__((un
{
char buf[PATH_MAX];
FILE *file;
@ -27,7 +27,7 @@ index 2812976..f933347 100644
/*
* only activate mappings for irqs that have moved
@@ -82,7 +83,12 @@ static void activate_mapping(struct irq_info *info, void *data __attribute__((un
@@ -70,7 +71,12 @@ static void activate_mapping(struct irq_info *info, void *data __attribute__((un
return;
cpumask_scnprintf(buf, PATH_MAX, info->assigned_obj->mask);
@ -42,10 +42,10 @@ index 2812976..f933347 100644
info->moved = 0; /*migration is done*/
}
diff --git a/classify.c b/classify.c
index 2fa303a..b40fcc1 100644
index fa900f4..9f588bc 100644
--- a/classify.c
+++ b/classify.c
@@ -264,7 +264,7 @@ static gint compare_ints(gconstpointer a, gconstpointer b)
@@ -256,7 +256,7 @@ static gint compare_ints(gconstpointer a, gconstpointer b)
return ai->irq - bi->irq;
}
@ -54,7 +54,7 @@ index 2fa303a..b40fcc1 100644
{
struct irq_info find, *new;
GList *entry;
@@ -288,9 +288,14 @@ static void add_banned_irq(int irq, GList **list)
@@ -280,9 +280,14 @@ static void add_banned_irq(int irq, GList **list)
return;
}
@ -69,8 +69,8 @@ index 2fa303a..b40fcc1 100644
+ __add_banned_irq(irq, &cl_banned_irqs);
}
static int is_banned_irq(int irq)
@@ -429,6 +434,23 @@ out:
gint substr_find(gconstpointer a, gconstpointer b)
@@ -376,6 +381,23 @@ get_numa_node:
return new;
}
@ -94,38 +94,20 @@ index 2fa303a..b40fcc1 100644
static void parse_user_policy_key(char *buf, int irq, struct user_irq_policy *pol)
{
char *key, *value, *end;
@@ -636,7 +658,7 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
continue;
get_irq_user_policy(devpath, irqnum, &pol);
if ((pol.ban == 1) || (check_for_irq_ban(devpath, irqnum, tmp_irqs))) {
- add_banned_irq(irqnum, &banned_irqs);
+ __add_banned_irq(irqnum, &banned_irqs);
continue;
}
hint.irq = irqnum;
@@ -671,7 +693,7 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
goto done;
get_irq_user_policy(devpath, irqnum, &pol);
if ((pol.ban == 1) || (check_for_irq_ban(devpath, irqnum, tmp_irqs))) {
- add_banned_irq(irqnum, &banned_irqs);
+ __add_banned_irq(irqnum, &banned_irqs);
goto done;
}
@@ -723,7 +745,7 @@ static void add_new_irq(int irq, struct irq_info *hint, GList *proc_interrupts)
@@ -585,7 +607,7 @@ static void add_new_irq(char *path, struct irq_info *hint, GList *proc_interrupt
/* 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*/
get_irq_user_policy(path, irq, &pol);
if ((pol.ban == 1) || check_for_irq_ban(irq, proc_interrupts)) { /*FIXME*/
- add_banned_irq(irq, &banned_irqs);
+ __add_banned_irq(irq, &banned_irqs);
new = get_irq_info(irq);
} else
new = add_one_irq_to_db(NULL, hint, &pol);
new = add_one_irq_to_db(path, hint, &pol);
diff --git a/irqbalance.h b/irqbalance.h
index 6cdd9e2..3a78c7f 100644
index cd93167..bc34d7e 100644
--- a/irqbalance.h
+++ b/irqbalance.h
@@ -105,6 +105,8 @@ extern struct irq_info *get_irq_info(int irq);
@@ -106,6 +106,8 @@ extern struct irq_info *get_irq_info(int irq);
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);
@ -133,7 +115,7 @@ index 6cdd9e2..3a78c7f 100644
+extern void remove_one_irq_from_db(int irq);
#define irq_numa_node(irq) ((irq)->numa_node)
extern unsigned long migrate_val;
--
1.8.3.1
--
2.23.0

View File

@ -1,30 +0,0 @@
From 2c040ddc5869635598e4fbf5c63217f60fdef5f1 Mon Sep 17 00:00:00 2001
From: xiashuang <xiashuang1@huawei.com>
Date: Sun, 17 Mar 2019 18:59:09 -0400
Subject: [PATCH 2/4] bugfix fix a hole that flees hotplug event
from 1.0.9, original infoformation is missing
---
irqbalance.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/irqbalance.c b/irqbalance.c
index 6412447..2f699b8 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -284,9 +284,9 @@ gboolean scan(gpointer data)
for_each_irq(NULL, force_rebalance_irq, NULL);
parse_proc_interrupts();
parse_proc_stat();
- sleep_approx(sleep_interval);
- clear_work_stats();
- parse_proc_interrupts();
+
+ /* Still need to check hotplugged or not next round */
+ return TRUE;
}
parse_proc_stat();
--
1.8.3.1

View File

@ -1,562 +0,0 @@
From a501662e98e2937cb63f3308d6497e723f838238 Mon Sep 17 00:00:00 2001
From: liuchao <liuchao173@huawei.com>
Date: Wed, 18 Mar 2020 22:08:33 +0800
Subject: [PATCH] force irq into rebalance list when irq removed and reinserted
prevent irq may be inserted to rebalance list more than once and add one msi irq
at one time to prevent new msi irqs stay on one numa node
---
classify.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++++------
irqbalance.c | 6 ++-
irqbalance.h | 7 +++
procinterrupts.c | 145 ++++++++++++++++++++++++++++++++++-----------------
types.h | 1 +
5 files changed, 250 insertions(+), 63 deletions(-)
diff --git a/classify.c b/classify.c
index b40fcc1..2dc93ca 100644
--- a/classify.c
+++ b/classify.c
@@ -37,6 +37,7 @@ static GList *interrupts_dbs = NULL;
static GList *banned_irqs = NULL;
GList *cl_banned_irqs = NULL;
static GList *cl_banned_modules = NULL;
+extern int need_add_single;
#define SYSFS_DIR "/sys"
#define SYSPCI_DIR "/sys/bus/pci/devices"
@@ -259,7 +259,7 @@
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;
@@ -584,11 +585,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
@@ -624,16 +627,32 @@ static int check_for_irq_ban(char *path __attribute__((unused)), int irq, GList
return 0;
}
+int is_proc_irq_info_exist(int irq, GList *tmp_list)
+{
+ GList *entry;
+ struct irq_info find;
+
+ if (!tmp_list) {
+ return 1;
+ }
+
+ find.irq = irq;
+ entry = g_list_find_custom(tmp_list, &find, compare_ints);
+
+ return entry ? 1 : 0;
+}
+
/*
* Figures out which interrupt(s) relate to the device we"re looking at in dirname
*/
-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;
@@ -657,10 +676,16 @@ 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;
}
+ if (!is_proc_irq_info_exist(irqnum, tmp_list)) {
+ continue;
+ }
+ if (need_add_single && need_add_single != irqnum) {
+ continue;
+ }
hint.irq = irqnum;
hint.type = IRQ_TYPE_MSIX;
new = add_one_irq_to_db(devpath, &hint, &pol);
@@ -669,13 +694,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;
@@ -692,10 +717,13 @@ 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(devpath, irqnum, tmp_irqs))) {
+ if ((pol.ban == 1) || (check_for_irq_ban(devpath, irqnum, tmp_list))) {
__add_banned_irq(irqnum, &banned_irqs);
goto done;
}
+ if (!is_proc_irq_info_exist(irqnum, tmp_list)) {
+ goto done;
+ }
hint.irq = irqnum;
hint.type = IRQ_TYPE_LEGACY;
@@ -706,7 +734,60 @@ 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;
+ size_t dirlen;
+
+ 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);
+ /* 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;
+ }
+ 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 && (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;
+ }
+ pclose(output);
+
}
static void free_irq(struct irq_info *info, void *data __attribute__((unused)))
@@ -714,6 +795,45 @@ 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);
+ if (banned_irqs){
+ for_each_irq(banned_irqs, remove_no_existing_irq, NULL);
+ }
+}
+
void free_irq_db(void)
{
for_each_irq(NULL, free_irq, NULL);
@@ -733,14 +853,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);
@@ -752,6 +872,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 f965a2a..4d0a417 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -251,11 +251,15 @@ 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;
+ /* 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 3a78c7f..9e28285 100644
--- a/irqbalance.h
+++ b/irqbalance.h
@@ -109,6 +109,13 @@ extern void add_banned_irq(int irq);
extern void remove_one_irq_from_db(int irq);
#define irq_numa_node(irq) ((irq)->numa_node)
+extern struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list);
+extern void find_irq_dev_path(int irq, char *dirname, int length);
+extern struct irq_info *add_new_irq(int irq, struct irq_info *hint, GList *proc_interrupts);
+extern void clear_no_existing_irqs(void);
+extern void force_rebalance_irq(struct irq_info *info, void *data __attribute__((unused)));
+extern gint compare_ints(gconstpointer a, gconstpointer b);
+
extern unsigned long migrate_val;
extern unsigned long load_limit;
/*
diff --git a/procinterrupts.c b/procinterrupts.c
index 70831b4..358458c 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;
+int need_add_single = 0;
#ifdef AARCH64
struct irq_match {
@@ -144,6 +145,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()
{
@@ -151,10 +198,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)
@@ -169,7 +212,6 @@ GList* collect_full_irq_list()
while (!feof(file)) {
int number;
- int is_xen_dyn = 0;
struct irq_info *info;
char *c;
char *savedline = NULL;
@@ -191,45 +233,13 @@ GList* collect_full_irq_list()
savedline = strdup(line);
if (!savedline)
break;
- irq_name = strtok_r(savedline, " ", &savedptr);
- if (strstr(irq_name, "xen-dyn") != NULL)
- is_xen_dyn = 1;
- last_token = strtok_r(NULL, " ", &savedptr);
- while ((p = strtok_r(NULL, " ", &savedptr))) {
- irq_name = last_token;
- if (strstr(irq_name, "xen-dyn") != NULL)
- is_xen_dyn = 1;
- last_token = p;
- }
-
-#ifdef AARCH64
- /* Of course the formatting for /proc/interrupts is different on different arches */
- irq_name = last_token;
- tmp = strchr(irq_name, '\n');
- if (tmp)
- *tmp = 0;
-#endif
- irq_mod = last_token;
-
*c = 0;
c++;
number = strtoul(line, NULL, 10);
info = calloc(sizeof(struct irq_info), 1);
if (info) {
- info->irq = number;
- if (strstr(irq_name, "-event") != NULL && is_xen_dyn == 1) {
- info->type = IRQ_TYPE_VIRT_EVENT;
- info->class = IRQ_VIRT_EVENT;
- } else {
-#ifdef AARCH64
- guess_arm_irq_hints(irq_name, info);
-#else
- info->type = IRQ_TYPE_LEGACY;
- info->class = IRQ_OTHER;
-#endif
- }
- info->name = strdup(irq_mod);
+ init_irq_class_and_type(savedline, info, number);
tmp_list = g_list_append(tmp_list, info);
}
free(savedline);
@@ -239,6 +249,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;
@@ -262,7 +280,10 @@ void parse_proc_interrupts(void)
uint64_t count;
char *c, *c2;
struct irq_info *info;
- char savedline[1024];
+ struct irq_info tmp_info = {0};
+ char *savedline = NULL;
+ char dirname[PATH_MAX] = {'\0'};
+ struct irq_info *lookup;
if (getline(&line, &size, file)<=0)
break;
@@ -282,7 +303,9 @@ void parse_proc_interrupts(void)
if (!c)
continue;
- strncpy(savedline, line, sizeof(savedline)-1);
+ savedline = strdup(line);
+ if (!savedline)
+ continue;
*c = 0;
c++;
@@ -290,9 +313,37 @@ void parse_proc_interrupts(void)
info = get_irq_info(number);
if (!info) {
- need_rescan = 1;
- break;
+ init_irq_class_and_type(savedline, &tmp_info, number);
+ find_irq_dev_path(number, dirname, PATH_MAX);
+ if (strlen(dirname) > 0) {
+ need_add_single = number;
+ info = build_one_dev_entry(dirname, NULL);
+ need_add_single = 0;
+ lookup = get_irq_info(number);
+ if (lookup != NULL) {
+ lookup->existing = 1;
+ info = lookup;
+ }
+ log(TO_CONSOLE, LOG_INFO, "new IRQ %d added into database, dirname %s\n", number, dirname);
+ } else {
+ info = add_new_irq(number, &tmp_info, NULL);
+ }
+ if (tmp_info.name) {
+ free(tmp_info.name);
+ tmp_info.name = NULL;
+ }
+
+ if (info) {
+ force_rebalance_irq(info, NULL);
+ log(TO_CONSOLE, LOG_INFO, "new IRQ %d added into rebalance list\n", number);
+ } else {
+ need_rescan = 1;
+ free(savedline);
+ break;
+ }
}
+ free(savedline);
+ info->existing = 1;
count = 0;
cpunr = 0;
@@ -316,17 +367,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

View File

@ -1,29 +0,0 @@
From 73c26ac2d6e856c5a9ffd1c48ed7c1abc85de3df Mon Sep 17 00:00:00 2001
From: liuchao <liuchao173@huawei.com>
Date: Sat, 12 Oct 2019 03:34:44 +0000
Subject: [PATCH] irqbalance: change irq ban check path to devpath
keep the parameters 'path' of check_for_irq_ban function consistent with line 699.
In check_for_irq_ban,
sprintf(cmd, "%s %s %d > /dev/null",banscript, path, irq);
the banscript is unique, so the path should keep consistent.
---
classify.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/classify.c b/classify.c
index 7c97d47..3681c48 100644
--- a/classify.c
+++ b/classify.c
@@ -719,7 +719,7 @@ struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list)
if (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(devpath, irqnum, tmp_irqs))) {
add_banned_irq(irqnum, &banned_irqs);
goto done;
}
--
2.19.1

View File

@ -0,0 +1,29 @@
From 5cb5795d8be047b4bc23ccf47ac3086ac98f1b06 Mon Sep 17 00:00:00 2001
From: liuchao173 <55137861+liuchao173@users.noreply.github.com>
Date: Tue, 10 Sep 2019 18:46:24 +0800
Subject: [PATCH 12/53] change path to devpath
keep the parameters 'path' of check_for_irq_ban function consistent with line 699.
In check_for_irq_ban,
sprintf(cmd, "%s %s %d > /dev/null",banscript, path, irq);
the banscript is unique, so i think the path should keep consistent.
---
classify.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/classify.c b/classify.c
index f40ea99..9b0177d 100644
--- a/classify.c
+++ b/classify.c
@@ -693,7 +693,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(devpath, irqnum, tmp_irqs))) {
add_banned_irq(irqnum, &banned_irqs);
goto done;
}
--
2.23.0

View File

@ -1,28 +0,0 @@
From ff28f445a0808677c983d85a3b8331e4c090d70d Mon Sep 17 00:00:00 2001
From: Neil Horman <nhorman@tuxdriver.com>
Date: Tue, 29 May 2018 10:27:37 -0400
Subject: [PATCH 084/112] classify: remove unused label
A recent refactoring in commit a4fbf90c2395ffa13176e8b002b7ef89a0ffc667
left us with an unused label 'free' in rebuild_irq_db, just remove it
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
---
classify.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/classify.c b/classify.c
index 3394823..3136fc3 100644
--- a/classify.c
+++ b/classify.c
@@ -777,7 +777,6 @@ void rebuild_irq_db(void)
for_each_irq(tmp_irqs, add_missing_irq, interrupts_db);
-free:
g_list_free_full(tmp_irqs, free);
}
--
1.8.3.1

View File

@ -1,7 +1,7 @@
From 22a40e9d0dd59ee58ff06d2b6360007e046d608f Mon Sep 17 00:00:00 2001
From: liuchao173 <liuchao173@huawei.com>
Date: Thu, 7 Nov 2019 09:33:47 +0000
Subject: [PATCH 6/8] irqbalance: correct to use realloc() function
From 503a3e6e9fc8aa1d7dd9e8ba86fb21edcdcfe502 Mon Sep 17 00:00:00 2001
From: Yunfeng Ye <yeyunfeng@huawei.com>
Date: Fri, 11 Oct 2019 23:41:17 +0800
Subject: [PATCH 23/53] correct to use realloc() function
The man doc about realloc() say:
"
@ -20,10 +20,10 @@ Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
1 file changed, 23 insertions(+), 10 deletions(-)
diff --git a/irqbalance.c b/irqbalance.c
index c9378d0..cace4d8 100644
index a06809c..e53bf65 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -321,14 +321,18 @@ gboolean scan(gpointer data)
@@ -308,14 +308,18 @@ gboolean scan(gpointer data __attribute__((unused)))
void get_irq_data(struct irq_info *irq, void *data)
{
char **irqdata = (char **)data;
@ -45,7 +45,7 @@ index c9378d0..cace4d8 100644
sprintf(*irqdata + strlen(*irqdata),
"IRQ %d LOAD %lu DIFF %lu CLASS %d ", irq->irq, irq->load,
(irq->irq_count - irq->last_irq_count), irq->class);
@@ -338,6 +342,7 @@ void get_object_stat(struct topo_obj *object, void *data)
@@ -325,6 +329,7 @@ void get_object_stat(struct topo_obj *object, void *data)
{
char **stats = (char **)data;
char *irq_data = NULL;
@ -53,7 +53,7 @@ index c9378d0..cace4d8 100644
size_t irqdlen;
if (g_list_length(object->interrupts) > 0) {
@@ -355,13 +360,17 @@ void get_object_stat(struct topo_obj *object, void *data)
@@ -342,13 +347,17 @@ void get_object_stat(struct topo_obj *object, void *data)
* This should be adjusted if the string in the sprintf is changed
*/
if (!*stats) {
@ -74,11 +74,12 @@ index c9378d0..cace4d8 100644
sprintf(*stats + strlen(*stats), "TYPE %d NUMBER %d LOAD %lu SAVE_MODE %d %s",
object->obj_type, object->number, object->load,
@@ -475,19 +484,23 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
@@ -465,20 +474,24 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
if (!strncmp(buff, "setup", strlen("setup"))) {
char banned[512];
char *setup = calloc(strlen("SLEEP ") + 11 + 1, 1);
+ char *newptr = NULL;
if (!setup)
goto out_close;
snprintf(setup, strlen("SLEEP ") + 11 + 1, "SLEEP %d ", sleep_interval);
@ -103,4 +104,5 @@ index c9378d0..cace4d8 100644
}
--
2.19.1
2.23.0

View File

@ -1,91 +0,0 @@
From 0605850acfce6f2ae23759618604f02f946026c2 Mon Sep 17 00:00:00 2001
From: Neil Horman <nhorman@tuxdriver.com>
Date: Tue, 29 May 2018 10:26:00 -0400
Subject: [PATCH 129/152] cputree: adjust snprintf sizes to avoid gcc warnings
Gcc detects potential overruns in our use of PATH_MAX arrays when
parsing cpu topology. This commit corrects those issues by ensuing that
the print size is no longer than the array size in all cases
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
---
cputree.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/cputree.c b/cputree.c
index d09af43..c88143f 100644
--- a/cputree.c
+++ b/cputree.c
@@ -241,7 +241,8 @@ static struct topo_obj* add_cpu_to_cache_domain(struct topo_obj *cpu,
return cache;
}
-
+
+#define ADJ_SIZE(r,s) PATH_MAX-strlen(r)-strlen(#s)
static void do_one_cpu(char *path)
{
struct topo_obj *cpu;
@@ -256,7 +257,7 @@ static void do_one_cpu(char *path)
unsigned int max_cache_index, cache_index, cache_stat;
/* skip offline cpus */
- snprintf(new_path, PATH_MAX, "%s/online", path);
+ snprintf(new_path, ADJ_SIZE(path,"/online"), "%s/online", path);
file = fopen(new_path, "r");
if (file) {
char *line = NULL;
@@ -299,7 +300,8 @@ static void do_one_cpu(char *path)
/* try to read the package mask; if it doesn't exist assume solitary */
- snprintf(new_path, PATH_MAX, "%s/topology/core_siblings", path);
+ snprintf(new_path, ADJ_SIZE(path, "/topology/core_siblings"),
+ "%s/topology/core_siblings", path);
file = fopen(new_path, "r");
cpu_set(cpu->number, package_mask);
if (file) {
@@ -311,7 +313,8 @@ static void do_one_cpu(char *path)
free(line);
}
/* try to read the package id */
- snprintf(new_path, PATH_MAX, "%s/topology/physical_package_id", path);
+ snprintf(new_path, ADJ_SIZE(path, "/topology/physical_package_id"),
+ "%s/topology/physical_package_id", path);
file = fopen(new_path, "r");
if (file) {
char *line = NULL;
@@ -329,7 +332,9 @@ static void do_one_cpu(char *path)
cache_index = 1;
do {
struct stat sb;
- snprintf(new_path, PATH_MAX, "%s/cache/index%d/shared_cpu_map", path, cache_index);
+ /* Extra 10 subtraction is for the max character length of %d */
+ snprintf(new_path, ADJ_SIZE(path, "/cache/index%d/shared_cpu_map") - 10,
+ "%s/cache/index%d/shared_cpu_map", path, cache_index);
cache_stat = stat(new_path, &sb);
if (!cache_stat) {
max_cache_index = cache_index;
@@ -340,7 +345,9 @@ static void do_one_cpu(char *path)
} while(!cache_stat);
if (max_cache_index > 0) {
- snprintf(new_path, PATH_MAX, "%s/cache/index%d/shared_cpu_map", path, max_cache_index);
+ /* Extra 10 subtraction is for the max character length of %d */
+ snprintf(new_path, ADJ_SIZE(path, "/cache/index%d/shared_cpu_map") - 10,
+ "%s/cache/index%d/shared_cpu_map", path, max_cache_index);
file = fopen(new_path, "r");
if (file) {
char *line = NULL;
@@ -505,7 +512,7 @@ void parse_cpu_tree(void)
sscanf(entry->d_name, "cpu%d%c", &num, &pad) == 1 &&
!strchr(entry->d_name, ' ')) {
char new_path[PATH_MAX];
- sprintf(new_path, "/sys/devices/system/cpu/%s", entry->d_name);
+ snprintf(new_path, PATH_MAX, "/sys/devices/system/cpu/%s", entry->d_name);
do_one_cpu(new_path);
}
} while (entry);
--
1.8.3.1

View File

@ -0,0 +1,37 @@
From 926fbbc1a6992917a8e23d40da164301cfcf7f3a Mon Sep 17 00:00:00 2001
From: Yunfeng Ye <yeyunfeng@huawei.com>
Date: Thu, 24 Oct 2019 22:17:40 +0800
Subject: [PATCH 30/53] delete the useless free for banned_irqs in
free_cl_opts()
free_cl_opts() is invoked after free_irq_db(), the list @banned_irqs has
alreadly be freed in free_irq_db().
main()
--> free_object_tree();
--> free_irq_db();
--> g_list_free(banned_irqs);
-- >free_cl_opts();
So delete the useless free for @banned_irqs list in free_cl_opts().
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
---
classify.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/classify.c b/classify.c
index 7454c5f..2c0e7ed 100644
--- a/classify.c
+++ b/classify.c
@@ -718,7 +718,6 @@ void free_cl_opts(void)
{
g_list_free_full(cl_banned_modules, free);
g_list_free_full(cl_banned_irqs, free);
- g_list_free(banned_irqs);
}
static void add_new_irq(int irq, struct irq_info *hint, GList *proc_interrupts)
--
2.23.0

View File

@ -0,0 +1,38 @@
From 88af3aa8ddc395d187e2bb34f6d66e811c9a08d8 Mon Sep 17 00:00:00 2001
From: Yunfeng Ye <yeyunfeng@huawei.com>
Date: Sun, 22 Sep 2019 00:39:10 +0800
Subject: [PATCH 17/53] delete unused local variables in
parse_proc_interrupts()
The local variable @savedline[1024] is unused in parse_proc_interrupts(),
so delete it.
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
---
procinterrupts.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/procinterrupts.c b/procinterrupts.c
index 03b4593..44c5c76 100644
--- a/procinterrupts.c
+++ b/procinterrupts.c
@@ -260,7 +260,6 @@ void parse_proc_interrupts(void)
uint64_t count;
char *c, *c2;
struct irq_info *info;
- char savedline[1024];
if (getline(&line, &size, file)<=0)
break;
@@ -280,8 +279,6 @@ void parse_proc_interrupts(void)
if (!c)
continue;
- strncpy(savedline, line, sizeof(savedline)-1);
-
*c = 0;
c++;
number = strtoul(line, NULL, 10);
--
2.23.0

View File

@ -1,451 +0,0 @@
From 0406d202af914881af1a6caf5247e7ac40564366 Mon Sep 17 00:00:00 2001
From: hejingxian <hejingxian@huawei.com>
Date: Tue, 17 Sep 2019 23:32:54 +0800
Subject: [PATCH] add new user irq policy config rule
When there is many irqs, the old user irq policy script will cost too much time.
Therefore, we introduce a new user irq policy config rule which avoid policy script running
for every irq.
---
Makefile.am | 2 +-
classify.c | 32 +++++++--
irqbalance.c | 38 +++++----
irqbalance.h | 2 +-
placement.c | 3 +-
procinterrupts.c | 3 +-
rules_config.c | 172 ++++++++++++++++++++++++++++++++++++++++++++++++
rules_config.h | 40 +++++++++++
9 files changed, 271 insertions(+), 23 deletions(-)
create mode 100644 rules_config.c
create mode 100644 rules_config.h
diff --git a/Makefile.am b/Makefile.am
index 62ac482..9276bfb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -38,7 +38,7 @@ sbin_PROGRAMS += irqbalance-ui
endif
irqbalance_SOURCES = activate.c bitmap.c classify.c cputree.c irqbalance.c \
- irqlist.c numa.c placement.c procinterrupts.c
+ irqlist.c numa.c placement.c procinterrupts.c rules_config.c
irqbalance_LDADD = $(LIBCAP_NG_LIBS) $(GLIB2_LIBS)
if IRQBALANCEUI
irqbalance_ui_SOURCES = $(UI_DIR)/helpers.c $(UI_DIR)/irqbalance-ui.c \
diff --git a/classify.c b/classify.c
index 65aeae2..7c97d47 100644
--- a/classify.c
+++ b/classify.c
@@ -663,7 +663,7 @@ struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list)
sprintf(path, "%s/%s/msi_irqs", SYSPCI_DIR, dirname);
sprintf(devpath, "%s/%s", SYSPCI_DIR, dirname);
-
+ memset(&pol, -1, sizeof(struct user_irq_policy));
/* Needs to be further classified */
hint.class = IRQ_OTHER;
@@ -679,7 +679,9 @@ struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list)
new = get_irq_info(irqnum);
if (new)
continue;
- get_irq_user_policy(devpath, irqnum, &pol);
+ if (user_policy_list == NULL) {
+ get_irq_user_policy(devpath, irqnum, &pol);
+ }
if ((pol.ban == 1) || (check_for_irq_ban(devpath, irqnum, tmp_list))) {
__add_banned_irq(irqnum, &banned_irqs, 0);
continue;
@@ -714,7 +716,9 @@ struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list)
new = get_irq_info(irqnum);
if (new)
goto done;
- get_irq_user_policy(devpath, irqnum, &pol);
+ if (user_policy_list == NULL) {
+ get_irq_user_policy(devpath, irqnum, &pol);
+ }
if ((pol.ban == 1) || (check_for_irq_ban(devpath, irqnum, tmp_list))) {
__add_banned_irq(irqnum, &banned_irqs, 0);
goto done;
@@ -855,17 +859,23 @@ 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)
+ 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,13 @@ static void add_missing_irq(struct irq_info *info, void *attr)
if (!lookup)
add_new_irq(info->irq, info, proc_interrupts);
+ else
+ set_usr_irq_policy(info->name, lookup);
+ if (info->name) {
+ free(info->name);
+ info->name = NULL;
+ }
+
}
static void free_tmp_irqs(gpointer data)
diff --git a/irqbalance.c b/irqbalance.c
index 21d578a..d41753c 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -99,6 +99,7 @@ struct option lopts[] = {
{"version", 0, NULL, 'V'},
{"migrateval", 1, NULL, 'e'},
{"loadlimit", 1, NULL, 'g'},
+ {"rulesconfig", 1, NULL, 'r'},
{0, 0, 0, 0}
};
@@ -106,6 +107,7 @@ static void usage(void)
log(TO_CONSOLE, LOG_INFO, "irqbalance [--oneshot | -o] [--debug | -d] [--foreground | -f] [--journal | -j] [--hintpolicy= | -h [exact|subset|ignore]]\n");
log(TO_CONSOLE, LOG_INFO, " [--powerthresh= | -p <off> | <n>] [--banirq= | -i <n>] [--banmod= | -m <module>] [--policyscript= | -l <script>]\n");
log(TO_CONSOLE, LOG_INFO, " [--pid= | -s <file>] [--deepestcache= | -c <n>] [--interval= | -t <n>] [--migrateval= | -e <n>] [--loadlimit= | -g <n>]\n");
+ log(TO_CONSOLE, LOG_INFO, " [--rulesconfig= | -r <config>]\n");
}
static void version(void)
@@ -121,7 +123,7 @@ static void parse_command_line(int argc, char **argv)
unsigned long val;
while ((opt = getopt_long(argc, argv,
- "odfjVi:p:s:c:b:l:m:t:e:g:",
+ "odfjVi:p:s:c:b:l:m:t:e:g:r:",
lopts, &longind)) != -1) {
switch(opt) {
@@ -201,6 +203,9 @@ static void parse_command_line(int argc, char **argv)
case 'g':
load_limit = strtoul(optarg, NULL, 10);
break;
+ case 'r':
+ rules_config_file = strdup(optarg);
+ break;
}
}
}
@@ -539,6 +544,14 @@ int main(int argc, char** argv)
close(pidfd);
}
}
+
+ if (read_user_policy_config() != 0) {
+ log(TO_ALL, LOG_WARNING, "Read user policy config fail.\n");
+ }
+ if (rules_config_file) {
+ free(rules_config_file);
+ rules_config_file = NULL;
+ }
build_object_tree();
if (debug_mode)
@@ -589,6 +598,7 @@ int main(int argc, char** argv)
ret = EXIT_FAILURE;
goto out;
}
+ log(TO_ALL, LOG_INFO, "irqbalance start scan.\n");
main_loop = g_main_loop_new(NULL, FALSE);
last_interval = sleep_interval;
g_timeout_add_seconds(sleep_interval, scan, NULL);
diff --git a/irqbalance.h b/irqbalance.h
index 120bc9b..42f95cb 100644
--- a/irqbalance.h
+++ b/irqbalance.h
@@ -14,7 +14,7 @@
#include "types.h"
#include "config.h"
-
+#include "rules_config.h"
#ifdef __aarch64__
#define AARCH64
#endif
diff --git a/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,7 @@ 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);
}
@@ -391,6 +391,7 @@ void parse_proc_interrupts(void)
lookup = get_irq_info(number);
if (lookup != NULL) {
lookup->existing = 1;
+ set_usr_irq_policy(tmp_info.name, lookup);
info = lookup;
}
log(TO_CONSOLE, LOG_INFO, "new IRQ %d added into database, dirname %s\n", number, dirname);
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,176 @@
+/*
+ * Copyright (C) 2019. Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * This program file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include "irqbalance.h"
+
+char *rules_config_file = NULL;
+USER_IRQ_POLICY *user_policy_list = NULL;
+
+void add_usr_irq_policy(USER_IRQ_POLICY *policy)
+{
+ if (policy == NULL) {
+ return;
+ }
+ policy->next = user_policy_list;
+ user_policy_list = policy;
+}
+
+USER_IRQ_POLICY *get_usr_irq_policy(char *name)
+{
+ USER_IRQ_POLICY *p = user_policy_list;
+ if (name == NULL) {
+ return NULL;
+ }
+ while (p != NULL) {
+ if (strstr(name, p->irq_type) != NULL) {
+ return p;
+ }
+ p = p->next;
+ }
+ return NULL;
+}
+
+void set_usr_irq_policy(char *name, struct irq_info *info)
+{
+ USER_IRQ_POLICY *user_policy;
+
+ if (user_policy_list == NULL) {
+ return;
+ }
+
+ user_policy = get_usr_irq_policy(name);
+ if (user_policy != NULL) {
+ if (user_policy->numa_node_set) {
+ info->numa_node = get_numa_node(user_policy->numa_node);
+ log(TO_ALL, LOG_WARNING, "override irq (%d) numa_node to %d\n",
+ info->irq, user_policy->numa_node);
+ }
+ if (user_policy->balance_level_set) {
+ info->level = user_policy->balance_level;
+ log(TO_ALL, LOG_WARNING, "override irq (%d) balance_level to %d\n",
+ info->irq, info->level);
+ }
+ }
+
+}
+
+int read_user_policy_config()
+{
+ FILE *file;
+ char *line = NULL;
+ size_t size = 0;
+ size_t len;
+ char *key;
+ char *value;
+ char *c;
+ int level;
+ int node = -1;
+ char savedline[CONFIG_LINE_MAX_LEN] = {0};
+ USER_IRQ_POLICY *cur_policy = NULL;
+ char *levelvals[] = { "none", "package", "cache", "core" };
+
+ if (rules_config_file == NULL) {
+ return 0;
+ }
+ log(TO_ALL, LOG_INFO, "rules_config_file is: %s\n", rules_config_file);
+ file = fopen(rules_config_file, "r");
+ if (!file)
+ return -1;
+
+ while (!feof(file)) {
+ if (getline(&line, &size, file) <= 0)
+ break;
+ c = line;
+ if (*c == '#') {
+ continue;
+ }
+ len = strlen(line);
+ if (len > sizeof(savedline)-1) {
+ continue;
+ }
+ strncpy(savedline, line, len);
+ savedline[len] = '\0';
+ c = savedline;
+ while (*c == ' ') {
+ c++;
+ }
+ key = c;
+ /* make sure there is no space near '=' */
+ c = strchr(savedline, '=');
+ if (c != NULL) {
+ value = c + 1;
+ *c = '\0';
+ } else {
+ continue;
+ }
+ c = strchr(value, '\n');
+ if (c != NULL) {
+ *c = '\0';
+ }
+ if ((strlen(key) == 0) || (strlen(value) == 0)) {
+ continue;
+ }
+ log(TO_ALL, LOG_INFO, "User irq policy config read: key is %s, value is %s\n", key, value);
+ if (strcmp(key, "type") == 0) {
+ cur_policy = malloc(sizeof(USER_IRQ_POLICY));
+ if (cur_policy == NULL) {
+ goto out;
+ }
+ cur_policy->next = NULL;
+ cur_policy->numa_node_set = 0;
+ cur_policy->balance_level_set = 0;
+ if (strlen(value) > CONFIG_TYPE_MAX_LEN - 1) {
+ continue;
+ }
+ strncpy(cur_policy->irq_type, value, strlen(value) + 1);
+ add_usr_irq_policy(cur_policy);
+ } else if (strcmp(key, "balance_level") == 0) {
+ if (cur_policy == NULL) {
+ goto out;
+ }
+ for (level = 0; level < MAX_LEVEL_NUM; level++) {
+ if (strcasecmp(value, levelvals[level]) == 0) {
+ break;
+ }
+ }
+ if (level >= MAX_LEVEL_NUM) {
+ log(TO_ALL, LOG_WARNING, "Bad value for balance_level policy: %s\n", value);
+ } else {
+ cur_policy->balance_level = level;
+ cur_policy->balance_level_set = 1;
+ }
+ } else if (strcmp(key, "numa_node") == 0) {
+ if (cur_policy == NULL) {
+ goto out;
+ }
+ node = strtoul(value, NULL, 10);
+ /* check node */
+ if (!get_numa_node(node)) {
+ log(TO_ALL, LOG_WARNING, "NUMA node %d doesn't exist\n",
+ node);
+ continue;
+ }
+ cur_policy->numa_node = node;
+ cur_policy->numa_node_set = 1;
+ }
+ }
+out:
+ fclose(file);
+ if (line) {
+ free(line);
+ }
+ return 0;
+
+}
+
diff --git a/rules_config.h b/rules_config.h
new file mode 100644
index 0000000..b8f9dc5
--- /dev/null
+++ b/rules_config.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019. Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * This program file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef _INCLUDE_RULES_CONFIG_H
+#define _INCLUDE_RULES_CONFIG_H
+
+#define CONFIG_TYPE_MAX_LEN 32
+#define CONFIG_LINE_MAX_LEN 512
+#define MAX_LEVEL_NUM 4
+
+typedef struct user_irq_policy_config {
+ char irq_type[CONFIG_TYPE_MAX_LEN];
+ int numa_node;
+ int balance_level;
+ int numa_node_set;
+ int balance_level_set;
+ struct user_irq_policy_config *next;
+}USER_IRQ_POLICY;
+extern USER_IRQ_POLICY *user_policy_list;
+extern char *rules_config_file;
+
+void add_usr_irq_policy(USER_IRQ_POLICY *policy);
+
+USER_IRQ_POLICY *get_usr_irq_policy(char *name);
+
+int read_user_policy_config();
+
+void set_usr_irq_policy(char *name, struct irq_info *info);
+
+#endif
--
1.8.3.1

View File

@ -1,122 +0,0 @@
From e44eed4faef6ee1bd1ae41dd27a8513d37681f7f Mon Sep 17 00:00:00 2001
From: liuchao <liuchao173@huawei.com>
Date: Tue, 17 Dec 2019 02:54:57 +0000
Subject: [PATCH] add switch to clear affinity hint
All irqs' affinity hints are cleared in update_affinity_hint and forced
to rebalance. In some scenarios, it will affect performance.
---
hint_verify.c | 26 +++++++++++++++++++++++++-
irqbalance.c | 10 ++++++++--
2 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/hint_verify.c b/hint_verify.c
index 0718078..11ef868 100644
--- a/hint_verify.c
+++ b/hint_verify.c
@@ -16,6 +16,7 @@ extern int keep_going;
extern GMainLoop *main_loop;
extern gboolean scan();
extern int last_interval;
+extern int clear_affinity_hint;
int real_sleep_interval;
int sleep_interval_count;
@@ -57,7 +58,8 @@ void update_affinity_hint(struct irq_info *info, void *data __attribute__((unuse
if (!hint_enabled)
return;
- cpus_clear(info->affinity_hint);
+ if (clear_affinity_hint)
+ cpus_clear(info->affinity_hint);
sprintf(path, "/proc/irq/%d/affinity_hint", info->irq);
file = fopen(path, "r");
if (!file)
@@ -80,6 +82,27 @@ void update_affinity_hint(struct irq_info *info, void *data __attribute__((unuse
free(line);
}
+static void check_clear()
+{
+ char *line = NULL;
+ size_t size = 0;
+ FILE *file;
+
+ file = fopen("/etc/sysconfig/irqbalance_clear", "r");
+ if (!file)
+ return;
+ if (getline(&line, &size, file) <= 0)
+ goto out;
+ if (line != NULL && strstr(line, "0") != NULL)
+ clear_affinity_hint = 0;
+ else
+ clear_affinity_hint = 1;
+
+out:
+ fclose(file);
+ free(line);
+}
+
/*
* This function is the main loop of irqbalance, which include:
* 1. scan opration for irq balancing;
@@ -104,6 +127,7 @@ gboolean poll_hint_affinity_and_scan(gpointer data __attribute__((unused)))
sleep_count++;
if (need_verify_flag && hint_changed()) {
+ check_clear();
for_each_irq(NULL, update_affinity_hint, NULL);
if (hint_has_changed) {
hint_has_changed = FALSE;
diff --git a/irqbalance.c b/irqbalance.c
index 05eaa29..77076fa 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -55,6 +55,7 @@ int foreground_mode;
int numa_avail;
int journal_logging = 0;
int need_rescan;
+int clear_affinity_hint = 1;
unsigned int log_mask = TO_ALL;
const char *log_indent;
unsigned long power_thresh = ULONG_MAX;
@@ -104,15 +105,16 @@ struct option lopts[] = {
{"loadlimit", 1, NULL, 'g'},
{"rulesconfig", 1, NULL, 'r'},
{"verifyhint", 1, NULL, 'v'},
+ {"notclearhint", 0, NULL, 'n'},
{0, 0, 0, 0}
};
static void usage(void)
{
log(TO_CONSOLE, LOG_INFO, "irqbalance [--oneshot | -o] [--debug | -d] [--foreground | -f] [--journal | -j] [--hintpolicy | -h <subset>]\n");
log(TO_CONSOLE, LOG_INFO, " [--powerthresh= | -p <off> | <n>] [--banirq= | -i <n>] [--banmod= | -m <module>] [--policyscript= | -l <script>]\n");
log(TO_CONSOLE, LOG_INFO, " [--pid= | -s <file>] [--deepestcache= | -c <n>] [--interval= | -t <n>] [--migrateval= | -e <n>] [--loadlimit= | -g <n>]\n");
- log(TO_CONSOLE, LOG_INFO, " [--rulesconfig= | -r <config>] [--verifyhint= | -v n]\n");
+ log(TO_CONSOLE, LOG_INFO, " [--rulesconfig= | -r <config>] [--verifyhint= | -v n] [--notclearhint | -n]\n");
}
static void version(void)
@@ -126,7 +128,7 @@ static void parse_command_line(int argc, char **argv)
unsigned long val;
while ((opt = getopt_long(argc, argv,
- "odfjVi:p:s:c:b:l:m:t:e:g:r:h:v:",
+ "odfjVni:p:s:c:b:l:m:t:e:g:r:h:v:",
lopts, &longind)) != -1) {
switch(opt) {
@@ -225,6 +227,9 @@ static void parse_command_line(int argc, char **argv)
case 'r':
rules_config_file = strdup(optarg);
break;
+ case 'n':
+ clear_affinity_hint = 0;
+ break;
}
}
}
--
2.19.1

View File

@ -1,114 +0,0 @@
From b697a97436dafa13f0ae3febde299bfc20498f9d Mon Sep 17 00:00:00 2001
From: liuchao173 <liuchao173@huawei.com>
Date: Wed, 23 Oct 2019 11:42:26 +0000
Subject: [PATCH] irqbalance: add the switch of printing log
add the switch of printing log
---
cputree.c | 16 ++++++++--------
irqbalance.c | 25 +++++++++++++++++++++++++-
2 files changed, 32 insertions(+), 9 deletions(-)
diff --git a/cputree.c b/cputree.c
index 99f14d2..1465103 100644
--- a/cputree.c
+++ b/cputree.c
@@ -432,23 +432,23 @@ static void dump_irq(struct irq_info *info, void *data)
indent[i] = log_indent[0];
indent[i] = '\0';
- log(TO_CONSOLE, LOG_INFO, "%sInterrupt %i node_num is %d (%s/%lu:%lu) \n", indent,
+ log(TO_ALL, LOG_INFO, "%sInterrupt %i node_num is %d (%s/%lu:%lu) \n", indent,
info->irq, irq_numa_node(info)->number, classes[info->class], info->load, (info->irq_count - info->last_irq_count));
free(indent);
}
static void dump_numa_node_num(struct topo_obj *p, void *data __attribute__((unused)))
{
- log(TO_CONSOLE, LOG_INFO, "%d ", p->number);
+ log(TO_ALL, LOG_INFO, "%d ", p->number);
}
static void dump_balance_obj(struct topo_obj *d, void *data __attribute__((unused)))
{
struct topo_obj *c = (struct topo_obj *)d;
- log(TO_CONSOLE, LOG_INFO, "%s%s%s%sCPU number %i numa_node is ",
+ log(TO_ALL, LOG_INFO, "%s%s%s%sCPU number %i numa_node is ",
log_indent, log_indent, log_indent, log_indent, c->number);
for_each_object(cpu_numa_node(c), dump_numa_node_num, NULL);
- log(TO_CONSOLE, LOG_INFO, "(load %lu)\n", (unsigned long)c->load);
+ log(TO_ALL, LOG_INFO, "(load %lu)\n", (unsigned long)c->load);
if (c->interrupts)
for_each_irq(c->interrupts, dump_irq, (void *)18);
}
@@ -457,10 +457,10 @@ static void dump_cache_domain(struct topo_obj *d, void *data)
{
char *buffer = data;
cpumask_scnprintf(buffer, 4095, d->mask);
- log(TO_CONSOLE, LOG_INFO, "%s%sCache domain %i: numa_node is ",
+ log(TO_ALL, LOG_INFO, "%s%sCache domain %i: numa_node is ",
log_indent, log_indent, d->number);
for_each_object(d->numa_nodes, dump_numa_node_num, NULL);
- log(TO_CONSOLE, LOG_INFO, "cpu mask is %s (load %lu) \n", buffer,
+ log(TO_ALL, LOG_INFO, "cpu mask is %s (load %lu) \n", buffer,
(unsigned long)d->load);
if (d->children)
for_each_object(d->children, dump_balance_obj, NULL);
@@ -472,9 +472,9 @@ static void dump_package(struct topo_obj *d, void *data)
{
char *buffer = data;
cpumask_scnprintf(buffer, 4096, d->mask);
- log(TO_CONSOLE, LOG_INFO, "Package %i: numa_node ", d->number);
+ log(TO_ALL, LOG_INFO, "Package %i: numa_node ", d->number);
for_each_object(d->numa_nodes, dump_numa_node_num, NULL);
- log(TO_CONSOLE, LOG_INFO, "cpu mask is %s (load %lu)\n",
+ log(TO_ALL, LOG_INFO, "cpu mask is %s (load %lu)\n",
buffer, (unsigned long)d->load);
if (d->children)
for_each_object(d->children, dump_cache_domain, buffer);
diff --git a/irqbalance.c b/irqbalance.c
index d41753c..7d8d15c 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -273,6 +273,29 @@ gboolean force_rescan(gpointer data __attribute__((unused)))
return TRUE;
}
+static int check_debug()
+{
+ char *line = NULL;
+ size_t size = 0;
+ FILE *file;
+
+ file = fopen("/etc/sysconfig/irqbalance_debug", "r");
+ if (!file)
+ return 0;
+ if (getline(&line, &size, file) <= 0) {
+ goto out;
+ }
+ if (line != NULL && strstr(line, "1") != NULL) {
+ fclose(file);
+ free(line);
+ return 1;
+ }
+out:
+ fclose(file);
+ free(line);
+ return 0;
+}
+
gboolean scan(gpointer data __attribute__((unused)))
{
log(TO_CONSOLE, LOG_INFO, "\n\n\n-----------------------------------------------------------------------------\n");
@@ -305,7 +328,7 @@ gboolean scan(gpointer data)
calculate_placement();
activate_mappings();
- if (debug_mode)
+ if (debug_mode || check_debug())
dump_tree();
if (one_shot_mode)
keep_going = 0;
--
2.19.1

View File

@ -1,43 +0,0 @@
From 2fdfbc218be09a6335df8dde15498f75fa12bc0a Mon Sep 17 00:00:00 2001
From: liuchao <liuchao173@huawei.com>
Date: Thu, 6 Feb 2020 06:44:51 +0000
Subject: [PATCH] feature: enable irqbalance to link with multiple clients at
the same time
Type:bugfix/CVE/requirement/cleancode/testcode
CVE:
DTS/AR:
reason:
---
irqbalance.c | 2 +-
irqbalance.h | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/irqbalance.c b/irqbalance.c
index 1af23c6..dc8307d 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -622,7 +622,7 @@ int init_socket()
log(TO_ALL, LOG_WARNING, "Unable to set socket options.\n");
return 1;
}
- listen(socket_fd, 1);
+ listen(socket_fd, MAX_CLIENT_NUM);
g_unix_fd_add(socket_fd, G_IO_IN, sock_handle, NULL);
return 0;
}
diff --git a/irqbalance.h b/irqbalance.h
index 61b39dd..2d59d31 100644
--- a/irqbalance.h
+++ b/irqbalance.h
@@ -177,5 +177,7 @@ extern unsigned int log_mask;
#define SOCKET_PATH "irqbalance"
#define SOCKET_TMPFS "/var/run"
#define SOCKET_RECV_BUF_LEN 4096
+#define MAX_CLIENT_NUM 32
+
#endif /* __INCLUDE_GUARD_IRQBALANCE_H_ */
--
2.19.1

View File

@ -1,679 +0,0 @@
From 5390ed72086f1d9ffce2b4ca367daf2cbda4d358 Mon Sep 17 00:00:00 2001
From: hejingxian <hejingxian@huawei.com>
Date: Tue, 18 Feb 2020 14:49:31 +0800
Subject: [PATCH] encapsulate and compile the functions in irqbalance-ui
into a shared library
users can send settings msg to irqbalance or get information from irqbalance
by calling external functions in the shared library.
Signed-off-by: Liu Chao <liuchao173@huawei.com>
Signed-off-by: He Jingxian <hejingxian@huawei.com>
---
irqbalance.c | 4 +-
irqbalance.h | 2 +-
ui/Makefile | 30 ++++
ui/client.c | 435 +++++++++++++++++++++++++++++++++++++++++++++++++
ui/irqbalance-ui.c | 4 +-
ui/irqbalance-ui.h | 1 +
ui/irqbalance_client.h | 111 +++++++++++++
7 files changed, 582 insertions(+), 5 deletions(-)
create mode 100644 ui/Makefile
create mode 100644 ui/client.c
create mode 100644 ui/irqbalance_client.h
diff --git a/irqbalance.c b/irqbalance.c
index 1af23c6..7c79087 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -452,12 +452,12 @@ void get_object_stat(struct topo_obj *object, void *data)
gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attribute__((unused)))
{
- char buff[500];
+ char buff[SOCKET_RECV_BUF_LEN];
int sock;
int recv_size = 0;
int valid_user = 0;
- struct iovec iov = { buff, 500 };
+ struct iovec iov = { buff, SOCKET_RECV_BUF_LEN };
struct msghdr msg = { 0 };
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
diff --git a/irqbalance.h b/irqbalance.h
index b2e5409..842cead 100644
--- a/irqbalance.h
+++ b/irqbalance.h
@@ -175,6 +175,6 @@ extern unsigned int log_mask;
#define SOCKET_PATH "irqbalance"
#define SOCKET_TMPFS "/var/run"
-
+#define SOCKET_RECV_BUF_LEN 4096
#endif /* __INCLUDE_GUARD_IRQBALANCE_H_ */
diff --git a/ui/Makefile b/ui/Makefile
new file mode 100644
index 0000000..27e0fbf
--- /dev/null
+++ b/ui/Makefile
@@ -0,0 +1,30 @@
+#!/bin/make
+export SHELL = /bin/bash
+DIR = $(shell pwd)
+TARGET = libirqbalance_client.so
+
+RM = rm
+LINK = ld
+CC = gcc
+
+SRC = $(wildcard $(DIR)/*.c)
+OBJ = $(patsubst $(DIR)/%.c,$(DIR)/%.o,$(SRC))
+
+INC = -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include
+CFLAG = -g3 -Wall -fPIC -D_GNU_SOURCE
+SHARED = -shared
+LFLAG = -lglib-2.0 -lncursesw
+
+CFLAG += $(INC)
+
+all: $(TARGET)
+
+$(TARGET): $(OBJ)
+ $(LINK) $(SHARED) $(LFLAG) -o $@ $(OBJ)
+
+$(DIR)/%.o: $(DIR)/%.c
+ $(CC) $(CFLAG) -c $< -o $@
+
+clean:
+ -$(RM) $(DIR)/*.o
+ -$(RM) $(TARGET)
diff --git a/ui/client.c b/ui/client.c
new file mode 100644
index 0000000..027404b
--- /dev/null
+++ b/ui/client.c
@@ -0,0 +1,435 @@
+/*
+ * Copyright (C) 2020. Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * This program file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+#include <sys/socket.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "irqbalance-ui.h"
+#include "irqbalance_client.h"
+
+extern int irqbalance_pid;
+extern GList *tree;
+
+void irqbalance_set_pid(int pid)
+{
+ irqbalance_pid = pid;
+}
+
+/*
+ * string format:
+ * <int> <int> <int> <int> ... or NONE
+ */
+int irqbalance_set_ban_irqs(const char *irqs)
+{
+ char *data = NULL;
+ const char *tmp;
+ int ret = IRQBALANCE_SUCCESS;
+ int socket_fd = 0;
+ int i;
+ struct msghdr *msg = NULL;
+ struct iovec iov;
+
+ if (irqs == NULL || strlen(irqs) == 0) {
+ ret = IRQBALANCE_INPUT_ILLEGAL;
+ goto out;
+ }
+ if (strncmp(irqs, "NONE", strlen("NONE"))) {
+ tmp = irqs;
+ for (i = 0; i < strlen(irqs); i++) {
+ if (*tmp != ' ' && (*tmp < '0' || *tmp > '9')) {
+ ret = IRQBALANCE_INPUT_ILLEGAL;
+ goto out;
+ }
+ tmp++;
+ }
+ }
+
+ socket_fd = init_connection();
+ if (!socket_fd) {
+ ret = IRQBALANCE_CONNECT_FAIL;
+ goto out;
+ }
+
+ data = (char *)malloc(strlen(irqs) + strlen(BAN_IRQS) + 1);
+ if (!data) {
+ ret = IRQBALANCE_MALLOC_FAIL;
+ goto out;
+ }
+ msg = create_credentials_msg();
+ if (!msg) {
+ ret = IRQBALANCE_MALLOC_FAIL;
+ goto out;
+ }
+ snprintf(data, strlen(irqs) + strlen(BAN_IRQS) + 1,
+ "%s%s", BAN_IRQS, irqs);
+ iov.iov_base = (void *) data;
+ iov.iov_len = strlen(data) + 1;
+ msg->msg_iov = &iov;
+ if (sendmsg(socket_fd, msg, 0) == -1)
+ ret = IRQBALANCE_SEND_FAIL;
+
+out:
+ if (socket_fd > 0)
+ close(socket_fd);
+ if (msg)
+ free(msg->msg_control);
+ free(msg);
+ free(data);
+ return ret;
+}
+
+unsigned int char_to_hex(char c)
+{
+ unsigned int hex;
+
+ if (c >= '0' && c <= '9') {
+ hex = c - '0';
+ } else {
+ hex = c - 'a' + 10;
+ }
+ return hex;
+}
+
+char *parse_cpus_to_cpulist(const char *cpus)
+{
+ int i, ret;
+ const char *tmp;
+ char *cpulist;
+ int cpus_len;
+ unsigned int hex;
+ int index;
+
+ if (cpus == NULL
+ || strlen(cpus) == 0
+ || strlen(cpus) > CPU_MASK_MAX_LEN)
+ return NULL;
+
+ if (strncmp(cpus, "NULL", strlen("NULL"))) {
+ tmp = cpus;
+ cpus_len = strlen(cpus);
+ for (i = 0; i < cpus_len; i++) {
+ if ((*tmp < '0' || *tmp > '9')
+ && (*tmp < 'a' || *tmp > 'f'))
+ return NULL;
+ tmp++;
+ }
+ cpulist = (char *)malloc(CPU_LIST_MAX_LEN);
+ if (!cpulist)
+ return NULL;
+ cpulist[0] = 0;
+ for (i = 0; i < cpus_len; i++) {
+ hex = char_to_hex(cpus[cpus_len - 1 - i]);
+ index = 0;
+ while (hex) {
+ if (hex & 1) {
+ ret = snprintf(cpulist + strlen(cpulist),
+ CPU_LIST_MAX_LEN - strlen(cpulist), "%d,", (i << 2) + index);
+ if (ret < 0)
+ break;
+ }
+ index++;
+ hex = (hex >> 1);
+ }
+ }
+ } else {
+ cpulist = strdup(cpus);
+ }
+ return cpulist;
+}
+
+/*
+ * string format:
+ * 00000001 or NULL
+ */
+int irqbalance_set_ban_cpus(const char *cpus)
+{
+ int socket_fd = 0;
+ int ret = IRQBALANCE_SUCCESS;
+ char *data = NULL;
+ char *cpulist = NULL;
+ struct msghdr *msg = NULL;
+ struct iovec iov;
+
+ cpulist = parse_cpus_to_cpulist(cpus);
+ if(!cpulist) {
+ ret = IRQBALANCE_INPUT_ILLEGAL;
+ goto out;
+ }
+
+ socket_fd = init_connection();
+ if(!socket_fd) {
+ ret = IRQBALANCE_CONNECT_FAIL;
+ goto out;
+ }
+
+ data = (char *)malloc(strlen(cpulist) + strlen(BAN_CPUS) + 1);
+ if (!data) {
+ ret = IRQBALANCE_MALLOC_FAIL;
+ goto out;
+ }
+ msg = create_credentials_msg();
+ if (!msg) {
+ ret = IRQBALANCE_MALLOC_FAIL;
+ goto out;
+ }
+ snprintf(data, strlen(cpulist) + strlen(BAN_CPUS) + 1,
+ "%s%s", BAN_CPUS, cpulist);
+ iov.iov_base = (void *) data;
+ iov.iov_len = strlen(data) + 1;
+ msg->msg_iov = &iov;
+ if (sendmsg(socket_fd, msg, 0) == -1)
+ ret = IRQBALANCE_SEND_FAIL;
+
+out:
+ if (socket_fd)
+ close(socket_fd);
+ if (msg)
+ free(msg->msg_control);
+ free(msg);
+ free(data);
+ free(cpulist);
+ return ret;
+}
+
+int irqbalance_set_sleep_interval(int sleep)
+{
+ char data[DATA_BUF_MAX_LEN];
+ int ret = IRQBALANCE_SUCCESS;
+ int socket_fd = 0;
+ struct msghdr *msg = NULL;
+ struct iovec iov;
+
+ if (sleep < 1) {
+ ret = IRQBALANCE_INPUT_ILLEGAL;
+ goto out;
+ }
+
+ socket_fd = init_connection();
+ if(!socket_fd) {
+ ret = IRQBALANCE_CONNECT_FAIL;
+ goto out;
+ }
+
+ msg = create_credentials_msg();
+ if (!msg) {
+ ret = IRQBALANCE_MALLOC_FAIL;
+ goto out;
+ }
+ snprintf(data, DATA_BUF_MAX_LEN, "%s %d", SET_SLEEP, sleep);
+ iov.iov_base = (void *) data;
+ iov.iov_len = strlen(data) + 1;
+ msg->msg_iov = &iov;
+ if (sendmsg(socket_fd, msg, 0) == -1)
+ ret = IRQBALANCE_SEND_FAIL;
+
+out:
+ if (socket_fd)
+ close(socket_fd);
+ if (msg)
+ free(msg->msg_control);
+ free(msg);
+ return ret;
+}
+
+void free_banned_irq_list(irqbalance_banned_irq_list_t *list_head)
+{
+ irqbalance_banned_irq_list_t *banned_irq = list_head;
+ irqbalance_banned_irq_list_t *next_banned_irq;
+
+ while (banned_irq) {
+ next_banned_irq = banned_irq->next;
+ free(banned_irq);
+ banned_irq = next_banned_irq;
+ }
+}
+
+/* get user setup info, including sleep setting, banned irqs and banned cpus info */
+irqbalance_setup_t *irqbalance_get_setup_info()
+{
+ char *token, *ptr, *setup_info;
+ char *copy = NULL;
+ char *scan;
+ int i, sleep, setup_size;
+ int ban_irq_num = 0;
+ int ban_irq_size = sizeof(irqbalance_banned_irq_t);
+ irqbalance_setup_t *setup_data = NULL;
+ irqbalance_banned_irq_list_t *banned_irq = NULL;
+ irqbalance_banned_irq_list_t *list_head = NULL;
+
+ setup_info = get_data(SETUP);
+ if (setup_info == NULL || strlen(setup_info) == 0)
+ return NULL;
+ copy = strdup(setup_info);
+ if (!copy)
+ goto out;
+
+ token = strtok_r(copy, " ", &ptr);
+ if (!token)
+ goto out;
+ if(strncmp(token, "SLEEP", strlen("SLEEP")))
+ goto out;
+ scan = strtok_r(NULL, " ", &ptr);
+ if (!scan)
+ goto out;
+ sleep = strtol(scan, NULL, 10);
+ token = strtok_r(NULL, " ", &ptr);
+ while(token && !strncmp(token, "IRQ", strlen("IRQ"))) {
+ banned_irq = (irqbalance_banned_irq_list_t *)malloc(sizeof(irqbalance_banned_irq_list_t));
+ if (!banned_irq)
+ goto out;
+ scan = strtok_r(NULL, " ", &ptr);
+ if (!scan)
+ goto out;
+ banned_irq->irq = strtol(scan, NULL, 10);
+ token = strtok_r(NULL, " ", &ptr);
+ if (!token || strncmp(token, "LOAD", strlen("LOAD")))
+ goto out;
+ scan = strtok_r(NULL, " ", &ptr);
+ if (!scan)
+ goto out;
+ banned_irq->load = strtol(scan, NULL, 10);
+ token = strtok_r(NULL, " ", &ptr);
+ if (!token || strncmp(token, "DIFF", strlen("DIFF")))
+ goto out;
+ scan = strtok_r(NULL, " ", &ptr);
+ if (!scan)
+ goto out;
+ banned_irq->diff = strtol(scan, NULL, 10);
+ token = strtok_r(ptr, " ", &ptr);
+ if (!token || strncmp(token, "CLASS", strlen("CLASS")))
+ goto out;
+ scan = strtok_r(NULL, " ", &ptr);
+ if (!scan)
+ goto out;
+ banned_irq->class = strtol(scan, NULL, 10);
+ banned_irq->next = list_head;
+ list_head = banned_irq;
+ ban_irq_num++;
+ token = strtok_r(NULL, " ", &ptr);
+ banned_irq = NULL;
+ }
+ if (ban_irq_num > 1)
+ setup_size = sizeof(irqbalance_setup_t) + (ban_irq_num - 1) * ban_irq_size;
+ else
+ setup_size = sizeof(irqbalance_setup_t);
+ setup_data = (irqbalance_setup_t *)malloc(setup_size);
+ if (!setup_data)
+ goto out;
+ memset(setup_data->banned_cpus, 0, NR_CPUS + 1);
+ setup_data->sleep = sleep;
+ setup_data->ban_irq_num = ban_irq_num;
+ banned_irq = list_head;
+ for (i = ban_irq_num; i > 0; i--) {
+ memcpy(&(setup_data->banned_irqs[i - 1]), banned_irq, ban_irq_size);
+ banned_irq = banned_irq->next;
+ }
+ if(strncmp(token, "BANNED", strlen("BANNED")))
+ goto out;
+ token = strtok_r(NULL, " ", &ptr);
+ if (strlen(token) > NR_CPUS)
+ goto out;
+ strcpy(setup_data->banned_cpus, token);
+out:
+ free(setup_info);
+ free(copy);
+ free_banned_irq_list(list_head);
+ return setup_data;
+}
+
+/* the type of the GList pointer data is irqbalance_cpu_node_t*/
+GList *irqbalance_get_stats_info()
+{
+ char *stats_data;
+
+ stats_data = get_data(STATS);
+ if (stats_data == NULL)
+ return NULL;
+ parse_into_tree(stats_data);
+ free(stats_data);
+ return tree;
+}
+
+/* get banned cpus mask */
+char *irqbalance_get_banned_cpus()
+{
+ char *setup_info;
+ char *copy;
+ char *bancpu_str;
+
+ setup_info = get_data(SETUP);
+ if (setup_info == NULL)
+ return NULL;
+ bancpu_str = strstr(setup_info, "BANNED");
+ if (bancpu_str == NULL) {
+ free(setup_info);
+ return NULL;
+ }
+ copy = strdup(bancpu_str + strlen("BANNED") + 1);
+ free(setup_info);
+ return copy;
+}
+
+/* get banned irqs string */
+char *irqbalance_get_banned_irqs()
+{
+ char *setup_info;
+ char *copy;
+ char *start_ptr, *end_ptr;
+ char *ret_str, *temp, *last_temp;;
+
+ setup_info = get_data(SETUP);
+ if (setup_info == NULL)
+ return NULL;
+ start_ptr = strstr(setup_info, "IRQ");
+ if (start_ptr == NULL) {
+ free(setup_info);
+ return NULL;
+ }
+ copy = strdup(start_ptr);
+ free(setup_info);
+ if (copy == NULL)
+ return NULL;
+ end_ptr = strstr(copy, "BANNED");
+ if (end_ptr)
+ *end_ptr = '\0';
+
+ ret_str = (char*)malloc(strlen(copy) + 1);
+ if (ret_str == NULL) {
+ free(copy);
+ return NULL;
+ }
+ memset(ret_str, 0, strlen(copy) + 1);
+ temp = copy + strlen("IRQ") + 1;
+ last_temp = temp;
+ while (*temp) {
+ temp = strstr(last_temp, " ");
+ if (temp)
+ *temp = '\0';
+ else
+ break;
+ strcat(ret_str, last_temp);
+ strcat(ret_str, " ");
+ last_temp = strstr(temp + 1, "IRQ");
+ if (last_temp == NULL)
+ break;
+ last_temp = last_temp + strlen("IRQ") + 1;
+ temp = last_temp;
+ }
+ free(copy);
+ if (strlen(ret_str) == 0) {
+ free(ret_str);
+ return NULL;
+ }
+ return ret_str;
+}
+
diff --git a/ui/irqbalance-ui.c b/ui/irqbalance-ui.c
index 943f008..f0deaf8 100644
--- a/ui/irqbalance-ui.c
+++ b/ui/irqbalance-ui.c
@@ -120,8 +120,8 @@ char * get_data(char *string)
* With a select, ioctl to determine size, and malloc based
* on that
*/
- char *data = malloc(8192);
- int len = recv(socket_fd, data, 8192, 0);
+ char *data = malloc(RECV_BUF_SIZE);
+ int len = recv(socket_fd, data, RECV_BUF_SIZE, 0);
close(socket_fd);
data[len] = '\0';
free(msg->msg_control);
diff --git a/ui/irqbalance-ui.h b/ui/irqbalance-ui.h
index b32d58a..503c0c5 100644
--- a/ui/irqbalance-ui.h
+++ b/ui/irqbalance-ui.h
@@ -26,6 +26,7 @@
#define IRQ_10GBETH 6
#define IRQ_VIRT_EVENT 7
+#define RECV_BUF_SIZE (4096 * 8)
/* Typedefs */
diff --git a/ui/irqbalance_client.h b/ui/irqbalance_client.h
new file mode 100644
index 0000000..8f18b79
--- /dev/null
+++ b/ui/irqbalance_client.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2020. Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * This program file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+#include <glib.h>
+#include <glib-unix.h>
+
+#ifndef IRQBALANCE_CLIENT_H
+#define IRQBALANCE_CLIENT_H
+
+/* ERRORNO */
+#define IRQBALANCE_SUCCESS 0
+#define IRQBALANCE_INPUT_ILLEGAL 1
+#define IRQBALANCE_CONNECT_FAIL 2
+#define IRQBALANCE_SEND_FAIL 3
+#define IRQBALANCE_MALLOC_FAIL 4
+
+#define BAN_CPUS "settings cpus "
+#define DATA_BUF_MAX_LEN 128
+#define NR_CPUS 1024
+#define CPU_LIST_MAX_LEN 4096
+#define CPU_MASK_MAX_LEN 256
+
+typedef enum irqbalance_node_type {
+ IRQ_OBJ_TYPE_CPU,
+ IRQ_OBJ_TYPE_CACHE,
+ IRQ_OBJ_TYPE_PACKAGE,
+ IRQ_OBJ_TYPE_NODE
+} irqbalance_node_type_e;
+
+typedef struct irqbalance_irq {
+ int vector;
+ unsigned long load;
+ unsigned long diff;
+ char is_banned;
+ GList *assigned_to;
+ int class;
+} irqbalance_irq_t;
+
+typedef struct irqbalance_cpu_node {
+ irqbalance_node_type_e type;
+ int number;
+ unsigned long load;
+ int is_powersave;
+ struct irqbalance_cpu_node *parent;
+ GList *children;
+ GList *irqs;
+ GList *cpu_list;
+ char *cpu_mask;
+} irqbalance_cpu_node_t;
+
+typedef struct irqbalance_banned_irq_list {
+ int irq;
+ int class;
+ unsigned long load;
+ unsigned long diff;
+ struct irqbalance_banned_irq_list *next;
+} irqbalance_banned_irq_list_t;
+
+typedef struct irqbalance_banned_irq_info {
+ int irq;
+ int class;
+ unsigned long load;
+ unsigned long diff;
+} irqbalance_banned_irq_t;
+
+typedef struct irqbalance_setup_data {
+ int sleep;
+ char banned_cpus[NR_CPUS + 1];
+ int ban_irq_num;
+ irqbalance_banned_irq_t banned_irqs[1];
+} irqbalance_setup_t;
+
+/*
+ * set_ban_irqs string format:
+ * <int> <int> <int> <int> ... or NONE
+ * */
+int irqbalance_set_ban_irqs(const char *irqs);
+
+/*
+ * set_ban_cpus string format:
+ * 00000001 or NULL
+ * */
+int irqbalance_set_ban_cpus(const char *cpus);
+
+/* set sleep interval of irqbalance main loop */
+int irqbalance_set_sleep_interval(int sleep);
+
+/* get user setup info, including sleep setting, banned irqs and banned cpus info */
+irqbalance_setup_t *irqbalance_get_setup_info();
+
+/* get irqbalance stats tree */
+GList *irqbalance_get_stats_info();
+
+/* get banned cpus mask */
+char *irqbalance_get_banned_cpus();
+
+/* get banned irqs string */
+char *irqbalance_get_banned_irqs();
+
+/* set the pid of irqbalance server */
+void irqbalance_set_pid(int pid);
+#endif
--
1.8.3.1

View File

@ -1,499 +0,0 @@
From e5b83ac140634830b8f8d9ca8d40a1d9d16d2d5b Mon Sep 17 00:00:00 2001
From: hejingxian <hejingxian@huawei.com>
Date: Tue, 12 Nov 2019 15:29:16 +0800
Subject: [PATCH] feature: introduce affinity hint verify to detect user hint variation
In order to make the user affinity hint becomes effective quickly,
introduce the periodically affinity hint verify.
---
Makefile.am | 2 +-
activate.c | 24 +++++------
classify.c | 18 ++++++--
cpumask.h | 7 +++
hint_verify.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
hint_verify.h | 21 +++++++++
irqbalance.c | 40 +++++++++++------
irqbalance.h | 4 ++
placement.c | 14 ++++++
types.h | 1 +
10 files changed, 252 insertions(+), 30 deletions(-)
create mode 100644 hint_verify.c
create mode 100644 hint_verify.h
diff --git a/Makefile.am b/Makefile.am
index 9276bfb..5fac265 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -38,7 +38,7 @@ sbin_PROGRAMS += irqbalance-ui
endif
irqbalance_SOURCES = activate.c bitmap.c classify.c cputree.c irqbalance.c \
- irqlist.c numa.c placement.c procinterrupts.c rules_config.c
+ irqlist.c numa.c placement.c procinterrupts.c rules_config.c hint_verify.c
irqbalance_LDADD = $(LIBCAP_NG_LIBS) $(GLIB2_LIBS)
if IRQBALANCEUI
irqbalance_ui_SOURCES = $(UI_DIR)/helpers.c $(UI_DIR)/irqbalance-ui.c \
diff --git a/activate.c b/activate.c
index d9e1fc3..87336f4 100644
--- a/activate.c
+++ b/activate.c
@@ -88,20 +88,27 @@ static void activate_mapping(struct irq_info *info, void *data __attribute__((un
char buf[PATH_MAX];
FILE *file;
int ret = 0;
+ cpumask_t applied_mask;
- /*
- * only activate mappings for irqs that have moved
- */
- if (!info->moved)
- return;
-
if (!info->assigned_obj)
return;
+ 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 (check_affinity(info, info->assigned_obj->mask))
+ if (check_affinity(info, applied_mask))
return;
sprintf(buf, "/proc/irq/%i/smp_affinity", info->irq);
@@ -120,7 +120,7 @@ static void activate_mapping(struct irq_info *info, void *data __attribute__((un
if (!file)
return;
- cpumask_scnprintf(buf, PATH_MAX, info->assigned_obj->mask);
+ cpumask_scnprintf(buf, PATH_MAX, applied_mask);
if (ban_pci_assigned_irq) {
if (!is_still_pci_assigned_irq(info->irq)) {
ret = fprintf(file, "%s", buf);
diff --git a/classify.c b/classify.c
index 5aed9e5..75677f4 100644
--- a/classify.c
+++ b/classify.c
@@ -448,7 +446,7 @@ get_numa_node:
fd = fopen(path, "r");
if (!fd) {
cpus_setall(new->cpumask);
- goto out;
+ goto assign_affinity_hint;
}
lcpu_mask = NULL;
ret = getline(&lcpu_mask, &blen, fd);
@@ -460,6 +458,20 @@ get_numa_node:
}
free(lcpu_mask);
+assign_affinity_hint:
+ cpus_clear(new->affinity_hint);
+ sprintf(path, "/proc/irq/%d/affinity_hint", irq);
+ fd = fopen(path, "r");
+ if (!fd)
+ goto out;
+ lcpu_mask = NULL;
+ ret = getline(&lcpu_mask, &blen, fd);
+ fclose(fd);
+ if (ret <= 0)
+ goto out;
+ cpumask_parse_user(lcpu_mask, ret, new->affinity_hint);
+ free(lcpu_mask);
+
out:
log(TO_CONSOLE, LOG_INFO, "Adding IRQ %d to database\n", irq);
return new;
diff --git a/cpumask.h b/cpumask.h
index 0774a88..8dd3703 100644
--- a/cpumask.h
+++ b/cpumask.h
@@ -30,6 +30,7 @@
* void cpus_xor(dst, src1, src2) dst = src1 ^ src2
* void cpus_andnot(dst, src1, src2) dst = src1 & ~src2
* void cpus_complement(dst, src) dst = ~src
+ * void cpumask_copy(dst, src)dst = src
*
* int cpus_equal(mask1, mask2) Does mask1 == mask2?
* int cpus_intersects(mask1, mask2) Do mask1 and mask2 intersect?
@@ -150,6 +151,12 @@ static inline void __cpus_complement(cpumask_t *dstp,
bitmap_complement(dstp->bits, srcp->bits, nbits);
}
+#define cpumask_copy(dst, src) __cpumask_copy(&(dst), &(src), NR_CPUS)
+static inline void __cpumask_copy(cpumask_t *dstp, const cpumask_t *srcp, int nbits)
+{
+ bitmap_copy(dstp->bits, srcp->bits, nbits);
+}
+
#define cpus_equal(src1, src2) __cpus_equal(&(src1), &(src2), NR_CPUS)
static inline int __cpus_equal(const cpumask_t *src1p,
const cpumask_t *src2p, int nbits)
diff --git a/hint_verify.c b/hint_verify.c
new file mode 100644
index 0000000..7a904b0
--- /dev/null
+++ b/hint_verify.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2019. Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * This program file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include "irqbalance.h"
+
+extern int keep_going;
+extern GMainLoop *main_loop;
+extern gboolean scan();
+extern int last_interval;
+
+int real_sleep_interval;
+int sleep_interval_count;
+int poll_hint_interval_count;
+int sleep_count = 0;
+gboolean hint_has_changed = FALSE;
+
+int hint_changed(void)
+{
+ FILE *file;
+ char *line = NULL;
+ size_t size = 0;
+ gboolean changed = FALSE;
+
+ file = fopen("/proc/irq/affinity_hint_notify", "r+");
+ if (!file)
+ return changed;
+
+ if (getline(&line, &size, file) > 0 && *line != '0') {
+ fprintf(file, "Done");
+ changed = TRUE;
+ }
+
+ fclose(file);
+ if (line)
+ free(line);
+ return changed;
+}
+
+void update_affinity_hint(struct irq_info *info, void *data __attribute__((unused)))
+{
+ FILE *file = NULL;
+ cpumask_t current_affinity_hint;
+ char path[PATH_MAX];
+ char *line = NULL;
+ size_t size = 0;
+ ssize_t len;
+
+ if (!hint_enabled)
+ return;
+
+ cpus_clear(info->affinity_hint);
+ sprintf(path, "/proc/irq/%d/affinity_hint", info->irq);
+ file = fopen(path, "r");
+ if (!file)
+ return;
+
+ len = getline(&line, &size, file);
+ fclose(file);
+
+ if (len > 0) {
+ cpumask_parse_user(line, len, current_affinity_hint);
+ if (!cpus_equal(current_affinity_hint, info->affinity_hint)) {
+ cpumask_copy(info->affinity_hint, current_affinity_hint);
+ force_rebalance_irq(info, data);
+ hint_has_changed = TRUE;
+ log(TO_ALL, LOG_INFO, "IRQ(%d): affinity hint modified %s\n", info->irq, line);
+ }
+ }
+
+ if (line)
+ free(line);
+}
+
+/*
+ * This function is the main loop of irqbalance, which include:
+ * 1. scan opration for irq balancing;
+ * 2. poll irq affinity hint changes for quickly applying them.
+ */
+gboolean poll_hint_affinity_and_scan(gpointer data __attribute__((unused)))
+{
+ gboolean need_verify_flag = FALSE;
+ gboolean need_scan_flag = FALSE;
+
+ if (!sleep_interval_count)
+ sleep_interval_count = 1;
+ if (!poll_hint_interval_count)
+ poll_hint_interval_count = 1;
+
+ if (sleep_count % sleep_interval_count == 0) {
+ need_scan_flag = TRUE;
+ }
+ if (sleep_count % poll_hint_interval_count == 0) {
+ need_verify_flag = TRUE;
+ }
+ sleep_count++;
+
+ if (need_verify_flag && hint_changed()) {
+ for_each_irq(NULL, update_affinity_hint, NULL);
+ if (hint_has_changed) {
+ hint_has_changed = FALSE;
+ sleep_count = 1;
+ need_scan_flag = TRUE;
+ }
+ }
+
+ if (need_scan_flag) {
+ if (!scan()) {
+ g_main_loop_quit(main_loop);
+ return FALSE;
+ }
+ }
+
+ update_interval_and_count();
+ if (last_interval != real_sleep_interval) {
+ last_interval = real_sleep_interval;
+ g_timeout_add_seconds(real_sleep_interval, poll_hint_affinity_and_scan, NULL);
+ return FALSE;
+ }
+
+ if (keep_going) {
+ return TRUE;
+ } else {
+ g_main_loop_quit(main_loop);
+ return FALSE;
+ }
+}
+
+void update_interval_and_count()
+{
+ real_sleep_interval =
+ sleep_interval > poll_hint_interval ? poll_hint_interval : sleep_interval;
+ if (!real_sleep_interval) {
+ sleep_interval_count = 1;
+ poll_hint_interval_count = 1;
+ return;
+ }
+ sleep_interval_count = sleep_interval / real_sleep_interval;
+ poll_hint_interval_count = poll_hint_interval / real_sleep_interval;
+}
+
diff --git a/hint_verify.h b/hint_verify.h
new file mode 100644
index 0000000..a309461
--- /dev/null
+++ b/hint_verify.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2019. Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * This program file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef _INCLUDE_HINT_VERIFY_H
+#define _INCLUDE_HINT_VERIFY_H
+
+extern int real_sleep_interval;
+extern gboolean poll_hint_affinity_and_scan();
+extern void update_interval_and_count();
+
+#endif
diff --git a/irqbalance.c b/irqbalance.c
index faa8e6a..4a7eb39 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -65,6 +65,8 @@ char *banscript = NULL;
long HZ;
int sleep_interval = SLEEP_INTERVAL;
int last_interval;
+int hint_enabled = 0;
+int poll_hint_interval = SLEEP_INTERVAL / 5;
unsigned long migrate_val = 0;
unsigned long load_limit = 0;
GMainLoop *main_loop;
@@ -99,15 +101,16 @@ struct option lopts[] = {
{"migrateval", 1, NULL, 'e'},
{"loadlimit", 1, NULL, 'g'},
{"rulesconfig", 1, NULL, 'r'},
+ {"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>] [--migrateval= | -e <n>] [--loadlimit= | -g <n>]\n");
- log(TO_CONSOLE, LOG_INFO, " [--rulesconfig= | -r <config>]\n");
+ log(TO_CONSOLE, LOG_INFO, " [--rulesconfig= | -r <config>] [--verifyhint= | -v n]\n");
}
static void version(void)
@@ -122,7 +125,7 @@ static void parse_command_line(int argc, char **argv)
unsigned long val;
while ((opt = getopt_long(argc, argv,
- "odfjVi:p:s:c:b:l:m:t:e:g:r:",
+ "odfjVi:p:s:c:b:l:m:t:e:g:r:h:v:",
lopts, &longind)) != -1) {
switch(opt) {
@@ -202,6 +205,22 @@ static void parse_command_line(int argc, char **argv)
case 'g':
load_limit = strtoul(optarg, NULL, 10);
break;
+ case 'h':
+ if (!strncmp(optarg, "subset", strlen(optarg)))
+ hint_enabled = 1;
+ else {
+ usage();
+ exit(1);
+ }
+
+ break;
+ case 'v':
+ poll_hint_interval = strtol(optarg, NULL, 10);
+ if (poll_hint_interval < 1) {
+ usage();
+ exit(1);
+ }
+ break;
case 'r':
rules_config_file = strdup(optarg);
break;
@@ -300,7 +319,7 @@ out:
return 0;
}
-gboolean scan(gpointer data __attribute__((unused)))
+gboolean scan()
{
log(TO_CONSOLE, LOG_INFO, "\n\n\n-----------------------------------------------------------------------------\n");
clear_work_stats();
@@ -338,17 +357,9 @@ gboolean scan(gpointer data)
keep_going = 0;
cycle_count++;
- /* sleep_interval may be changed by socket */
- if (last_interval != sleep_interval) {
- last_interval = sleep_interval;
- g_timeout_add_seconds(sleep_interval, scan, NULL);
- return FALSE;
- }
-
if (keep_going) {
return TRUE;
} else {
- g_main_loop_quit(main_loop);
return FALSE;
}
}
@@ -626,9 +638,10 @@ int main(int argc, char** argv)
goto out;
}
log(TO_ALL, LOG_INFO, "irqbalance start scan.\n");
+ update_interval_and_count();
main_loop = g_main_loop_new(NULL, FALSE);
- last_interval = sleep_interval;
- g_timeout_add_seconds(sleep_interval, scan, NULL);
+ last_interval = real_sleep_interval;
+ g_timeout_add_seconds(real_sleep_interval, poll_hint_affinity_and_scan, NULL);
g_main_loop_run(main_loop);
g_main_loop_quit(main_loop);
diff --git a/irqbalance.h b/irqbalance.h
index 1befb46..72e141b 100644
--- a/irqbalance.h
+++ b/irqbalance.h
@@ -15,6 +15,7 @@
#include "types.h"
#include "config.h"
#include "rules_config.h"
+#include "hint_verify.h"
#ifdef __aarch64__
#define AARCH64
#endif
@@ -120,6 +122,8 @@ extern gint compare_ints(gconstpointer a, gconstpointer b);
extern unsigned long migrate_val;
extern unsigned long load_limit;
+extern int hint_enabled, poll_hint_interval;
+extern int sleep_interval;
/*
* Generic object functions
*/
diff --git a/placement.c b/placement.c
index 48ac68b..d887c60 100644
--- a/placement.c
+++ b/placement.c
@@ -41,6 +41,7 @@ static void find_best_object(struct topo_obj *d, void *data)
{
struct obj_placement *best = (struct obj_placement *)data;
uint64_t newload;
+ cpumask_t subset;
/*
* Don't consider the unspecified numa node here
@@ -58,6 +59,19 @@ static void find_best_object(struct topo_obj *d, void *data)
if (d->powersave_mode)
return;
+ /*
+ * If the hint feature is enabled, then we only want
+ * to consider objects that are within the irqs hint, but
+ * only if that irq in fact has published a hint
+ */
+ if (hint_enabled) {
+ if (!cpus_empty(best->info->affinity_hint)) {
+ cpus_and(subset, best->info->affinity_hint, d->mask);
+ if (cpus_empty(subset))
+ return;
+ }
+ }
+
newload = d->load;
if (newload < best->best_cost) {
best->best = d;
diff --git a/types.h b/types.h
index e1f3dc6..c0950ee 100644
--- a/types.h
+++ b/types.h
@@ -67,6 +67,7 @@ struct irq_info {
int flags;
struct topo_obj *numa_node;
cpumask_t cpumask;
+ cpumask_t affinity_hint;
uint64_t irq_count;
uint64_t last_irq_count;
uint64_t load;
--
1.8.3.1

View File

@ -1,549 +0,0 @@
From 8e84d5ba4aad02509165cb1926091baa3630e418 Mon Sep 17 00:00:00 2001
From: hejingxian <hejingxian@huawei.com>
Date: Fri, 14 Feb 2020 16:42:01 +0800
Subject: [PATCH] feature: add ability for unblock socket communication
This will be used with user interface and also can be used as API for users
to create their own scripts on top of. The socket communication can be used
for receiving data about IRQs-to-CPUs assignments and setup, as well as
setting some options during runtime.
Socket address: /var/run/uvp_irqbalance.socket
Data to send to socket:
settings sleep <int>: set new sleep interval value
settings cpus <cpumask> <cpumask> ... : ban listed CPUs from
IRQ handling (old values are forgotten, not added to)
settings ban irqs <irq1> <irq2> ... : ban listed IRQs from balancing (old
values are forgotten, not added to)
Signed-off-by: Xu Yandong <xuyandong2@huawei.com>
Signed-off-by: He Jingxian <hejingxian@huawei.com>
---
Makefile.am | 4 +-
classify.c | 2 +-
cputree.c | 20 ++--
irqbalance.c | 33 +++++--
irqbalance.h | 1 +
sockapi.c | 297 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
sockapi.h | 19 ++++
7 files changed, 359 insertions(+), 17 deletions(-)
create mode 100644 sockapi.c
create mode 100644 sockapi.h
diff --git a/Makefile.am b/Makefile.am
index 46e7173..c7be22d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -30,7 +30,7 @@ UI_DIR = ui
AM_CFLAGS = $(LIBCAP_NG_CFLAGS) $(GLIB2_CFLAGS)
AM_CPPFLAGS = -I${top_srcdir} -W -Wall -Wshadow -Wformat -Wundef -D_GNU_SOURCE
noinst_HEADERS = bitmap.h constants.h cpumask.h irqbalance.h non-atomic.h \
- types.h $(UI_DIR)/helpers.h $(UI_DIR)/irqbalance-ui.h $(UI_DIR)/ui.h
+ types.h sockapi.h $(UI_DIR)/helpers.h $(UI_DIR)/irqbalance-ui.h $(UI_DIR)/ui.h
sbin_PROGRAMS = irqbalance
if IRQBALANCEUI
@@ -38,7 +38,7 @@ sbin_PROGRAMS += irqbalance-ui
endif
irqbalance_SOURCES = activate.c bitmap.c classify.c cputree.c irqbalance.c \
- irqlist.c numa.c placement.c procinterrupts.c rules_config.c hint_verify.c
+ irqlist.c numa.c placement.c procinterrupts.c rules_config.c hint_verify.c sockapi.c
irqbalance_LDADD = $(LIBCAP_NG_LIBS) $(GLIB2_LIBS)
if IRQBALANCEUI
irqbalance_ui_SOURCES = $(UI_DIR)/helpers.c $(UI_DIR)/irqbalance-ui.c \
diff --git a/classify.c b/classify.c
index 91ff022..b0bb3b4 100644
--- a/classify.c
+++ b/classify.c
@@ -37,7 +37,7 @@ static GList *interrupts_db = NULL;
static GList *banned_irqs = NULL;
GList *cl_banned_irqs = NULL;
static GList *cl_banned_modules = NULL;
-static GList *vm_banned_irqs = NULL;
+GList *vm_banned_irqs = NULL;
extern int need_add_single;
#define SYSFS_DIR "/sys"
diff --git a/cputree.c b/cputree.c
index 741c7c8..5a96e30 100644
--- a/cputree.c
+++ b/cputree.c
@@ -40,6 +40,8 @@
extern char *banned_cpumask_from_ui;
extern char *cpu_ban_string;
+extern int use_unblock_socket;
+extern int is_set_banned_cpumask_from_ui;
GList *cpus;
GList *cache_domains;
@@ -78,12 +80,18 @@ static void setup_banned_cpus(void)
cpus_clear(nohz_full);
/* A manually specified cpumask overrides auto-detection. */
- if (cpu_ban_string != NULL && banned_cpumask_from_ui != NULL) {
- cpulist_parse(banned_cpumask_from_ui,
- strlen(banned_cpumask_from_ui), banned_cpus);
- goto out;
- }
- if (getenv("IRQBALANCE_BANNED_CPUS")) {
+ if (!use_unblock_socket && cpu_ban_string != NULL && banned_cpumask_from_ui != NULL) {
+ cpulist_parse(banned_cpumask_from_ui,
+ strlen(banned_cpumask_from_ui), banned_cpus);
+ goto out;
+ }
+ if (use_unblock_socket && is_set_banned_cpumask_from_ui) {
+ cpumask_parse_user(banned_cpumask_from_ui,
+ strlen(banned_cpumask_from_ui), banned_cpus);
+ goto out;
+ }
+
+ if (getenv("IRQBALANCE_BANNED_CPUS")) {
cpumask_parse_user(getenv("IRQBALANCE_BANNED_CPUS"), strlen(getenv("IRQBALANCE_BANNED_CPUS")), banned_cpus);
goto out;
}
diff --git a/irqbalance.c b/irqbalance.c
index dc8307d..1774eda 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -42,6 +42,7 @@
#include <cap-ng.h>
#endif
#include "irqbalance.h"
+#include "sockapi.h"
volatile int keep_going = 1;
volatile int ban_pci_assigned_irq = 1;
@@ -73,6 +74,7 @@ GMainLoop *main_loop;
char *cpu_ban_string = NULL;
char *banned_cpumask_from_ui = NULL;
+int use_unblock_socket = 1;
static void sleep_approx(int seconds)
{
@@ -109,6 +111,7 @@ struct option lopts[] = {
{"rulesconfig", 1, NULL, 'r'},
{"verifyhint", 1, NULL, 'v'},
{"notclearhint", 0, NULL, 'n'},
+ {"blocksocket", 0, NULL, 'k'},
{0, 0, 0, 0}
};
@@ -116,7 +119,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>] [--migrateval= | -e <n>] [--loadlimit= | -g <n>]\n");
- log(TO_CONSOLE, LOG_INFO, " [--rulesconfig= | -r <config>] [--verifyhint= | -v n] [--notclearhint | -n]\n");
+ log(TO_CONSOLE, LOG_INFO, " [--rulesconfig= | -r <config>] [--verifyhint= | -v n] [--notclearhint | -n] [--blocksocket | -k]\n");
}
static void version(void)
@@ -132,7 +135,7 @@ static void parse_command_line(int argc, char **argv)
unsigned long val;
while ((opt = getopt_long(argc, argv,
- "odfjVni:p:s:c:b:l:m:t:e:g:r:h:v:",
+ "odfjVnki:p:s:c:b:l:m:t:e:g:r:h:v:",
lopts, &longind)) != -1) {
switch(opt) {
@@ -240,6 +243,9 @@ static void parse_command_line(int argc, char **argv)
case 'n':
clear_affinity_hint = 0;
break;
+ case 'k':
+ use_unblock_socket = 0;
+ break;
}
}
}
@@ -562,9 +567,12 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
if (!setup)
goto out_close;
snprintf(setup, strlen("SLEEP ") + 11 + 1, "SLEEP %d ", sleep_interval);
- if(g_list_length(cl_banned_irqs) > 0) {
+ if (g_list_length(cl_banned_irqs) > 0) {
for_each_irq(cl_banned_irqs, get_irq_data, &setup);
}
+ if (g_list_length(vm_banned_irqs) > 0) {
+ for_each_irq(vm_banned_irqs, get_irq_data, &setup);
+ }
cpumask_scnprintf(banned, 512, banned_cpus);
newptr = realloc(setup, strlen(setup) + strlen(banned) + 7 + 1);
if (!newptr)
@@ -827,10 +835,18 @@ int main(int argc, char** argv)
parse_proc_interrupts();
parse_proc_stat();
- if (init_socket()) {
- ret = EXIT_FAILURE;
- goto out;
+ if (use_unblock_socket) {
+ if (init_unblock_socket()) {
+ ret = EXIT_FAILURE;
+ goto out;
+ }
+ } else {
+ if (init_socket()) {
+ ret = EXIT_FAILURE;
+ goto out;
+ }
}
+
log(TO_ALL, LOG_INFO, "irqbalance start scan.\n");
update_interval_and_count();
main_loop = g_main_loop_new(NULL, FALSE);
@@ -852,6 +868,7 @@ out:
close(socket_fd);
if (socket_name[0])
unlink(socket_name);
+ free(banned_cpumask_from_ui);
return ret;
}
diff --git a/irqbalance.h b/irqbalance.h
index fc42a9b..7473ee7 100644
--- a/irqbalance.h
+++ b/irqbalance.h
@@ -65,6 +65,7 @@ extern GList *cache_domains;
extern GList *cpus;
extern int numa_avail;
extern GList *cl_banned_irqs;
+extern GList *vm_banned_irqs;
extern int debug_mode;
extern int journal_logging;
diff --git a/sockapi.c b/sockapi.c
new file mode 100644
index 0000000..9891978
--- /dev/null
+++ b/sockapi.c
@@ -0,0 +1,297 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/epoll.h>
+#include <pthread.h>
+
+#include "sockapi.h"
+#include "irqbalance.h"
+
+volatile int is_set_banned_cpumask_from_ui = 0;
+
+extern char *banned_cpumask_from_ui;
+extern int socket_fd;
+extern char socket_name[64];
+extern int sleep_interval;
+extern GList *cl_banned_irqs;
+extern GList *vm_banned_irqs;
+extern cpumask_t banned_cpus;
+extern int keep_going;
+int cur_fd_count = 0;
+
+static void fill_banned_cpus(char *cpustr, int length)
+{
+ (void)snprintf(cpustr, length, "CPU:");
+ cpumask_scnprintf(cpustr + strlen(cpustr), length - strlen(cpustr), banned_cpus);
+}
+
+static void fill_banned_irqs(char *irqstr, int length)
+{
+ GList *entry = NULL;
+ GList *next = NULL;
+ struct irq_info *info = NULL;
+
+ (void)snprintf(irqstr, length, "IRQ:");
+ entry = g_list_first(cl_banned_irqs);
+ if (!entry)
+ (void)snprintf(irqstr + strlen(irqstr), length - strlen(irqstr), "None ");
+ while (entry) {
+ next = g_list_next(entry);
+ info = entry->data;
+ (void)snprintf(irqstr + strlen(irqstr), length - strlen(irqstr),
+ "%d,", info->irq);
+ entry = next;
+ }
+
+ (void)snprintf(irqstr + strlen(irqstr) - 1, length - strlen(irqstr), " PCI:");
+
+ entry = g_list_first(vm_banned_irqs);
+ if (!entry)
+ (void)snprintf(irqstr + strlen(irqstr), length - strlen(irqstr), "None");
+ while (entry) {
+ next = g_list_next(entry);
+ info = entry->data;
+ (void)snprintf(irqstr + strlen(irqstr), length - strlen(irqstr),
+ "%d,", info->irq);
+ entry = next;
+ }
+}
+
+static int send_msg(int fd, char* buf, int len)
+{
+ int ret = -1;
+
+ do {
+ ret = send(fd, buf, len, 0);
+ } while ((ret <= 0) && (errno == EINTR));
+
+ return ret;
+}
+
+static int setnonblocking(int fd)
+{
+ if (fcntl(fd, F_SETFL,
+ (int)((unsigned int)fcntl(socket_fd, F_GETFL, 0) | O_NONBLOCK)) < 0) {
+ return -1;
+ }
+ return 0;
+}
+
+static void prase_banned_irq_string(char *irq_string)
+{
+ char *end = NULL;
+ char *last = irq_string;
+ int irq;
+
+ g_list_free_full(cl_banned_irqs, free);
+ cl_banned_irqs = NULL;
+
+ log(TO_ALL, LOG_INFO, "Ban irqs(%s) online.\n", irq_string);
+ if (!strncmp(irq_string, "NONE", strlen("NONE"))) {
+ return;
+ }
+
+ irq = strtoul(irq_string, &end, 10);
+ while (last != end) {
+ add_cl_banned_irq(irq);
+ log(TO_ALL, LOG_INFO, "add banned irq %d from api.\n", irq);
+ last = end;
+ irq = strtoul(end, &end, 10);
+ };
+}
+
+static void prase_banned_cpu_string(char *cpu_ban_string)
+{
+ if (strlen(cpu_ban_string) < 1)
+ return;
+ if (!is_set_banned_cpumask_from_ui)
+ is_set_banned_cpumask_from_ui = 1;
+
+ strcpy(banned_cpumask_from_ui, cpu_ban_string);
+ log(TO_ALL, LOG_INFO, "Ban cpus(%s) online.\n", cpu_ban_string);
+ if (!strncmp(banned_cpumask_from_ui, "NONE", strlen("NONE"))) {
+ memset((void*)banned_cpumask_from_ui, 0, NR_CPUS + 1);
+ }
+}
+
+gboolean recv_msg_handle(gint client_fd,
+ GIOCondition condition,
+ gpointer user_data __attribute__((unused)))
+{
+ char buff[FILE_LINE_MAX_NUM];
+ struct cmsghdr *cmsg;
+ int recv_size = 0;
+ int valid_user = 0;
+ struct iovec iov = { buff, FILE_LINE_MAX_NUM - 1 };
+ struct msghdr msg = { 0 };
+ int new_iterval = 0;
+
+ if (condition == G_IO_IN) {
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = malloc(CMSG_SPACE(sizeof(struct ucred)));
+ if (!msg.msg_control) {
+ goto out_close;
+ }
+ msg.msg_controllen = CMSG_SPACE(sizeof(struct ucred));
+ if ((recv_size = recvmsg(client_fd, &msg, 0)) < 0) {
+ log(TO_ALL, LOG_WARNING, "Error while receiving data:%d %s\n", recv_size, strerror(errno));
+ goto out_close;
+ }
+ cmsg = CMSG_FIRSTHDR(&msg);
+ if ((cmsg->cmsg_level == SOL_SOCKET) &&
+ (cmsg->cmsg_type == SCM_CREDENTIALS)) {
+ struct ucred *credentials = (struct ucred *) CMSG_DATA(cmsg);
+ if (!credentials->uid) {
+ valid_user = 1;
+ }
+ }
+ if (!valid_user) {
+ log(TO_ALL, LOG_INFO, "Permission denied for user to connect to socket.\n");
+ goto out_close;
+ }
+ if (!strncmp(buff, "settings ", strlen("settings "))) {
+ if (!(strncmp(buff + strlen("settings "), "sleep ",
+ strlen("sleep ")))) {
+ new_iterval = strtoul(buff + strlen("settings sleep "), NULL, 10);
+ if (new_iterval >= 1) {
+ sleep_interval = new_iterval;
+ }
+ } else if (!(strncmp(buff + strlen("settings "), "ban irqs \"",
+ strlen("ban irqs \"")))
+ && buff[recv_size - 1] == '\"') {
+ buff[recv_size - 1] = '\0';
+ prase_banned_irq_string(buff + strlen("settings ban irqs \""));
+ need_rescan = 1;
+ } else if (!(strncmp(buff + strlen("settings "), "cpus ",
+ strlen("cpus")))) {
+ if (recv_size > (int)(NR_CPUS + strlen("settings cpus "))) {
+ log(TO_ALL, LOG_WARNING, "Setting cpus more than limit: %d.\n",
+ NR_CPUS);
+ goto out_close;
+ }
+ buff[recv_size] = '\0';
+ prase_banned_cpu_string(buff + strlen("settings cpus "));
+ need_rescan = 1;
+ }
+ } else if (!strncmp(buff, "stats ", strlen("stats "))) {
+ if (!(strncmp(buff + strlen("stats "), "cpu", strlen("cpu")))) {
+ fill_banned_cpus(buff, FILE_LINE_MAX_NUM - 1);
+ send_msg(client_fd, buff, strlen(buff));
+ } else if (!(strncmp(buff + strlen("stats "), "irq", strlen("irq")))) {
+ fill_banned_irqs(buff, FILE_LINE_MAX_NUM - 1);
+ send_msg(client_fd, buff, strlen(buff));
+ }
+ }
+out_close:
+ close(client_fd);
+ free(msg.msg_control);
+ cur_fd_count--;
+ }
+ return FALSE;
+}
+
+gboolean accept_handle(gint fd,
+ GIOCondition condition,
+ gpointer user_data __attribute__((unused)))
+{
+ int client_fd;
+
+ if (condition != G_IO_IN) {
+ return TRUE;
+ }
+ client_fd = accept(fd, NULL, NULL);
+ if (client_fd < 0) {
+ log(TO_ALL, LOG_WARNING, "Connection couldn't be accepted.\n");
+ return TRUE;
+ }
+ if (cur_fd_count >= MAX_EVENTS) {
+ log(TO_ALL, LOG_WARNING, "Daemon support no more than %d connection\n",
+ MAX_EVENTS);
+ close(client_fd);
+ return TRUE;
+ }
+ if (setnonblocking(client_fd) < 0) {
+ log(TO_ALL, LOG_WARNING, "Daemon set connection nonblocking failed: %s.\n",
+ strerror(errno));
+ close(client_fd);
+ return TRUE;
+ }
+ cur_fd_count++;
+ g_unix_fd_add(client_fd, G_IO_IN, recv_msg_handle, NULL);
+ return TRUE;
+}
+
+
+int init_unblock_socket()
+{
+ struct sockaddr_un addr;
+ int optval = 1;
+
+ (void)unlink(socket_name);
+
+ socket_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
+ if (socket_fd < 0) {
+ log(TO_ALL, LOG_WARNING, "Socket couldn't be created.\n");
+ return 1;
+ }
+
+ /*
+ * First try to create a file-based socket in tmpfs. If that doesn't
+ * succeed, fall back to an abstract socket (non file-based).
+ */
+ memset(&addr, 0, sizeof(struct sockaddr_un));
+ addr.sun_family = AF_UNIX;
+ snprintf(socket_name, 64, "%s/%s%d.sock", SOCKET_TMPFS, SOCKET_PATH, getpid());
+ strncpy(addr.sun_path, socket_name, sizeof(addr.sun_path));
+ if (bind(socket_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ log(TO_ALL, LOG_WARNING, "Daemon couldn't be bound to the file-based socket.\n");
+ /* Try binding to abstract */
+ memset(&addr, 0, sizeof(struct sockaddr_un));
+ addr.sun_family = AF_UNIX;
+ if (bind(socket_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ log(TO_ALL, LOG_WARNING, "Daemon couldn't be bound to the abstract socket.\n");
+ return 1;
+ }
+ }
+
+ if (chmod(socket_name, SOCK_RWX_MODE) != 0) {
+ /* when use abstract socket, chmod may fail. No need return here. */
+ log(TO_ALL, LOG_WARNING, "socket name : %s, chmod failed\n", socket_name);
+ }
+
+ if (setsockopt(socket_fd, SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval)) < 0) {
+ log(TO_ALL, LOG_WARNING, "Unable to set socket options: %s.\n", strerror(errno));
+ return 1;
+ }
+
+ if (listen(socket_fd, MAX_CLIENT) != 0) {
+ log(TO_ALL, LOG_WARNING, "Daemon couldn't be listening to the socket: %s.\n",
+ strerror(errno));
+ return 1;
+ }
+
+ if (setnonblocking(socket_fd) < 0) {
+ log(TO_ALL, LOG_WARNING, "Daemon set connection(listen) nonblocking failed: %s.\n",
+ strerror(errno));
+ return 1;
+ }
+ banned_cpumask_from_ui = (char*)malloc(NR_CPUS + 1);
+ if (!banned_cpumask_from_ui) {
+ log(TO_ALL, LOG_WARNING, "Daemon faild to malloc banned_cpumask_from_ui space.\n");
+ return 1;
+ }
+ memset((void*)banned_cpumask_from_ui, 0, NR_CPUS + 1);
+
+ g_unix_fd_add(socket_fd, G_IO_IN, accept_handle, NULL);
+
+ return 0;
+}
diff --git a/sockapi.h b/sockapi.h
new file mode 100644
index 0000000..3875234
--- /dev/null
+++ b/sockapi.h
@@ -0,0 +1,19 @@
+#ifndef UVP_IRQBALANCE_SOCKAPI_H_
+#define UVP_IRQBALANCE_SOCKAPI_H_
+
+#include <sys/stat.h>
+
+/* set socket file mode to 660 */
+#define SOCK_RWX_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)
+
+#define SLEEP_TIME (100 * 1000) /* 100ms */
+
+#define MAX_CLIENT 512
+
+#define MAX_EVENTS 1024
+
+#define FILE_LINE_MAX_NUM (4096*6)
+
+int init_unblock_socket();
+
+#endif
--
1.8.3.1

View File

@ -1,95 +0,0 @@
From c924f1df705a301a0ffc01fce4c7712756c8b1d2 Mon Sep 17 00:00:00 2001
From: Zengruan Ye <yezengruan@huawei.com>
Date: Sat, 13 Jul 2019 19:09:09 +0800
Subject: [PATCH 1/6] feature: irqbalance: aarch64: add the regular to get the
correct irq class on hisi board
First, get the full irq desc name, include that the name split by blank, just like
(hisi_sas_v2_hw sata). We use the irq type to mark the begin of the name.
Second, for hisi bord, we consider to match the IRQ_SCSI class (which the
irqbalance service concerned, and the eth device match follow the
open community rule) by keywords group hisi & sas or hisi & sata.
Signed-off-by: wanghaibin <wanghaibin.wang@huawei.com>
---
procinterrupts.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/procinterrupts.c b/procinterrupts.c
index fc4641a..99bcf50 100644
--- a/procinterrupts.c
+++ b/procinterrupts.c
@@ -107,7 +107,9 @@ static void guess_arm_irq_hints(char *name, struct irq_info *info)
static int compiled = 0;
/* Note: Last entry is a catchall */
static struct irq_match matches[] = {
- { "eth.*" ,{NULL} ,NULL, IRQ_TYPE_LEGACY, IRQ_GBETH },
+ { "eth.*" ,{NULL} ,NULL, IRQ_TYPE_LEGACY, IRQ_GBETH},
+ { "hisi\\w*? *sas" ,{NULL} ,NULL, IRQ_TYPE_LEGACY, IRQ_SCSI},
+ { "hisi\\w*? *sata" ,{NULL} ,NULL, IRQ_TYPE_LEGACY, IRQ_SCSI},
{ "[A-Z0-9]{4}[0-9a-f]{4}", {NULL} ,check_platform_device, IRQ_TYPE_LEGACY, IRQ_OTHER},
{ "PNP[0-9a-f]{4}", {NULL} ,check_platform_device, IRQ_TYPE_LEGACY, IRQ_OTHER},
{ ".*", {NULL}, NULL, IRQ_TYPE_LEGACY, IRQ_OTHER},
@@ -152,6 +154,8 @@ static void init_irq_class_and_type(char *savedline, struct irq_info *info, int
int is_xen_dyn = 0;
#ifdef AARCH64
char *tmp = NULL;
+ char irq_fullname_valid = 1;
+ char irq_fullname[PATH_MAX] = {0};
#endif
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,17 @@ static void init_irq_class_and_type(char *savedline, struct irq_info *info, int
tmp = strchr(irq_name, '\n');
if (tmp)
*tmp = 0;
+
+ if (strlen(irq_name) + strlen(savedptr) + 1 < PATH_MAX) {
+ strcat(irq_fullname, irq_name);
+ strcat(irq_fullname, " ");
+ strcat(irq_fullname, savedptr);
+ tmp = strchr(irq_fullname, '\n');
+ if (tmp)
+ *tmp = 0;
+ } else {
+ irq_fullname_valid = 0;
+ }
#endif
irq_mod = last_token;
info->irq = irq;
@@ -180,7 +200,13 @@ static void init_irq_class_and_type(char *savedline, struct irq_info *info, int
info->class = IRQ_VIRT_EVENT;
} else {
#ifdef AARCH64
- guess_arm_irq_hints(irq_name, info);
+ if (irq_fullname_valid) {
+ irq_name = irq_fullname;
+ guess_arm_irq_hints(irq_name, info);
+ } else {
+ info->type = IRQ_TYPE_LEGACY;
+ info->class = IRQ_OTHER;
+ }
#else
info->type = IRQ_TYPE_LEGACY;
info->class = IRQ_OTHER;
--
1.8.3.1

View File

@ -1,343 +0,0 @@
From fd447c6f129769fcb685d8a2e22c75a922efe342 Mon Sep 17 00:00:00 2001
From: Zengruan Ye <yezengruan@huawei.com>
Date: Mon, 15 Jul 2019 21:35:29 +0800
Subject: [PATCH 3/6] feature: irqbalance: auto banned pci-assigned irq
checkout VM pci-assigned pci device irq, and banned it
Signed-off-by: Xu Yandong <xuyandong2@huawei.com>
---
activate.c | 38 ++++++++++++++++++++++++++++++++++++-
classify.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++-------
irqbalance.c | 11 +++++++++++
irqbalance.h | 2 ++
procinterrupts.c | 23 ++++++++++++++++++++++
types.h | 1 +
6 files changed, 125 insertions(+), 8 deletions(-)
diff --git a/activate.c b/activate.c
index 1c4b867..ad60fde 100644
--- a/activate.c
+++ b/activate.c
@@ -29,9 +29,12 @@
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
+#include <dirent.h>
#include "irqbalance.h"
+extern int ban_pci_assigned_irq;
+
static int check_affinity(struct irq_info *info, cpumask_t applied_mask)
{
cpumask_t current_mask;
@@ -56,6 +59,30 @@ static int check_affinity(struct irq_info *info, cpumask_t applied_mask)
return cpus_equal(applied_mask, current_mask);
}
+static int is_still_pci_assigned_irq(int irq)
+{
+ DIR *dir = NULL;
+ struct dirent *ptr = NULL;
+ char irq_path[PATH_MAX] = { 0 };
+
+ snprintf(irq_path, PATH_MAX - 1, "/proc/irq/%i/", irq);
+ if ((dir = opendir(irq_path)) == NULL) {
+ return 0;
+ }
+
+ while ((ptr = readdir(dir)) != NULL) {
+ if(strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) {
+ continue;
+ } else if (is_pci_assigned_irq(ptr->d_name)) {
+ closedir(dir);
+ return 1;
+ }
+ }
+
+ closedir(dir);
+ return 0;
+}
+
static void activate_mapping(struct irq_info *info, void *data __attribute__((unused)))
{
char buf[PATH_MAX];
@@ -89,7 +116,16 @@ static void activate_mapping(struct irq_info *info, void *data __attribute__((un
return;
cpumask_scnprintf(buf, PATH_MAX, info->assigned_obj->mask);
- ret = fprintf(file, "%s", buf);
+ if (ban_pci_assigned_irq) {
+ if (!is_still_pci_assigned_irq(info->irq)) {
+ ret = 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 {
+ ret = fprintf(file, "%s", buf);
+ }
if (ret < 0) {
log(TO_ALL, LOG_WARNING, "cannot change irq %i's affinity, add it to banned list", info->irq);
add_banned_irq(info->irq);
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;
extern int need_add_single;
#define SYSFS_DIR "/sys"
@@ -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,12 +293,17 @@ static void __add_banned_irq(int irq, GList **list)
void add_banned_irq(int irq)
{
- __add_banned_irq(irq, &banned_irqs);
+ __add_banned_irq(irq, &banned_irqs, 0);
}
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;
}
if (!is_proc_irq_info_exist(irqnum, tmp_list)) {
@@ -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(devpath, irqnum, tmp_list))) {
- __add_banned_irq(irqnum, &banned_irqs);
+ __add_banned_irq(irqnum, &banned_irqs, 0);
goto done;
}
if (!is_proc_irq_info_exist(irqnum, tmp_list)) {
@@ -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,6 +103,8 @@ extern void free_cl_opts(void);
extern void add_cl_banned_module(char *modname);
extern void add_banned_irq(int irq);
extern void remove_one_irq_from_db(int irq);
+extern void add_vm_banned_irq(int irq);
+extern int is_pci_assigned_irq(const char *line);
#define irq_numa_node(irq) ((irq)->numa_node)
extern struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list);
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;
int need_add_single = 0;
+extern int ban_pci_assigned_irq;
#ifdef AARCH64
struct irq_match {
@@ -269,6 +270,13 @@ 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);
+ free(savedline);
+ continue;
+ }
+
info = calloc(sizeof(struct irq_info), 1);
if (info) {
init_irq_class_and_type(savedline, info, 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)
free(savedline);
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

View File

@ -1,36 +0,0 @@
From aeb65d281ba122ba7539d551984bd37115d48811 Mon Sep 17 00:00:00 2001
From: hejingxian <hejingxian@huawei.com>
Date: Tue, 10 Sep 2019 22:48:24 +0800
Subject: [PATCH] supplement irqbalance service config
Add irqbalance service config: OOMScoreAdjust, Type, PIDFile, StartLimitInterval, StartLimitBurst, and so on.
Modify ExecStart script to improve banirq args config.
---
irqbalance.service | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/misc/irqbalance.service b/misc/irqbalance.service
index 8a5b1f4..ce0022c 100644
--- a/misc/irqbalance.service
+++ b/misc/irqbalance.service
@@ -1,10 +1,16 @@
[Unit]
Description=irqbalance daemon
ConditionVirtualization=!container
+After=syslog.target
[Service]
+OOMScoreAdjust=-500
+Type=forking
+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

View File

@ -1,105 +0,0 @@
From 9f7b1a93150c6bb1f54a7bf5ce36b344f10cdf4a Mon Sep 17 00:00:00 2001
From: Neil Horman <nhorman@tuxdriver.com>
Date: Wed, 20 Feb 2019 12:03:16 -0500
Subject: [PATCH 110/112] fix balancing when numa information isn't available
Discovered a bug in which, when numa isn't available we failed to assign
the unspecified node to the device tree, leading us to not balance any
interrupts. Make sure it gets added so irq get parsed down through the
tree to the proper topology node
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
---
cputree.c | 22 +++++++++++++++++++---
placement.c | 9 +++++----
2 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/cputree.c b/cputree.c
index f08ce84..5551784 100644
--- a/cputree.c
+++ b/cputree.c
@@ -126,9 +126,10 @@ static void add_numa_node_to_topo_obj(struct topo_obj *obj, int nodeid)
GList *entry;
struct topo_obj *node;
struct topo_obj *cand_node;
+ struct topo_obj *package;
node = get_numa_node(nodeid);
- if (!node || node->number == -1)
+ if (!node || (numa_avail && (node->number == -1)))
return;
entry = g_list_first(obj->numa_nodes);
@@ -141,6 +142,21 @@ static void add_numa_node_to_topo_obj(struct topo_obj *obj, int nodeid)
if (!entry)
obj->numa_nodes = g_list_append(obj->numa_nodes, node);
+
+ if (!numa_avail && obj->obj_type == OBJ_TYPE_PACKAGE) {
+ entry = g_list_first(node->children);
+ while (entry) {
+ package = entry->data;
+ if (package == obj)
+ break;
+ entry = g_list_next(entry);
+ }
+
+ if (!entry) {
+ node->children = g_list_append(node->children, obj);
+ obj->parent = node;
+ }
+ }
}
static struct topo_obj* add_cache_domain_to_package(struct topo_obj *cache,
@@ -189,7 +205,7 @@ static struct topo_obj* add_cache_domain_to_package(struct topo_obj *cache,
cache->parent = package;
}
- if (nodeid > -1)
+ if (!numa_avail || (nodeid > -1))
add_numa_node_to_topo_obj(package, nodeid);
return package;
@@ -236,7 +252,7 @@ static struct topo_obj* add_cpu_to_cache_domain(struct topo_obj *cpu,
cpu->parent = (struct topo_obj *)cache;
}
- if (nodeid > -1)
+ if (!numa_avail || (nodeid > -1))
add_numa_node_to_topo_obj(cache, nodeid);
return cache;
diff --git a/placement.c b/placement.c
index 5a82111..efa8c57 100644
--- a/placement.c
+++ b/placement.c
@@ -130,7 +130,7 @@ static void place_irq_in_node(struct irq_info *info, void *data __attribute__((u
if ((info->level == BALANCE_NONE) && cpus_empty(banned_cpus))
return;
- if (irq_numa_node(info)->number != -1) {
+ if (irq_numa_node(info)->number != -1 || !numa_avail) {
/*
* Need to make sure this node is elligible for migration
* given the banned cpu list
@@ -138,12 +138,13 @@ static void place_irq_in_node(struct irq_info *info, void *data __attribute__((u
if (!cpus_intersects(irq_numa_node(info)->mask, unbanned_cpus))
goto find_placement;
/*
- * This irq belongs to a device with a preferred numa node
- * put it on that node
- */
+ * This irq belongs to a device with a preferred numa node
+ * put it on that node
+ */
migrate_irq(&rebalance_irq_list, &irq_numa_node(info)->interrupts, info);
info->assigned_obj = irq_numa_node(info);
irq_numa_node(info)->load += info->load + 1;
+
return;
}
--
1.8.3.1

View File

@ -0,0 +1,29 @@
From e4c249868cb33620691b77c570ea3b4064e4389f Mon Sep 17 00:00:00 2001
From: Pyxisha <xiashuang1@huawei.com>
Date: Thu, 29 Aug 2019 14:31:25 +0800
Subject: [PATCH 10/53] 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_OTHER.
---
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.23.0

View File

@ -1,7 +1,7 @@
From 6c350eb9af2e36c40f4c1f2122e4b5b270c011b2 Mon Sep 17 00:00:00 2001
From: Weiping Zhang <zhangweiping@didiglobal.com>
Date: Fri, 8 Nov 2019 23:43:55 +0800
Subject: [PATCH 5/5] fix invalid pointer dereference banned_cpumask_from_ui
Subject: [PATCH 41/53] fix invalid pointer dereference banned_cpumask_from_ui
The memory of cpu_ban_string was release in sock_handle function,
so the banned_cpumask_from_ui will dereference an invalid memory.
@ -70,8 +70,8 @@ index c9379ad..7630e38 100644
+
+ cpu_ban_string = malloc(
sizeof(char) * (recv_size - strlen("settings cpus ")));
if (!cpu_ban_string)
goto out_close;
@@ -479,9 +487,16 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
banned_cpumask_from_ui = strtok(cpu_ban_string, " ");
if (!strncmp(banned_cpumask_from_ui, "NULL", strlen("NULL"))) {
@ -92,5 +92,5 @@ index c9379ad..7630e38 100644
}
if (!strncmp(buff, "setup", strlen("setup"))) {
--
1.8.3.1
2.23.0

View File

@ -1,21 +1,32 @@
From d85897487c5f523ebc9ba8a56de911592703fed3 Mon Sep 17 00:00:00 2001
From: liuchao173 <liuchao173@huawei.com>
Date: Thu, 7 Nov 2019 09:27:55 +0000
Subject: [PATCH 5/8] backport: fix resource leak for not invoking closedir()
after opendir()
fix resource leak for not invoking closedir() after opendir()
From d23f36745e4523122fbe986e53f7133e06b7d877 Mon Sep 17 00:00:00 2001
From: Yunfeng Ye <yeyunfeng@huawei.com>
Date: Fri, 11 Oct 2019 17:30:08 +0800
Subject: [PATCH 22/53] fix resource leak for not invoking closedir() after
opendir()
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
---
classify.c | 1 +
ui/irqbalance-ui.c | 1 +
1 file changed, 1 insertion(+)
2 files changed, 2 insertions(+)
diff --git a/classify.c b/classify.c
index de78bba..be1ad0c 100644
--- a/classify.c
+++ b/classify.c
@@ -583,6 +583,7 @@ static void get_irq_user_policy(char *path, int irq, struct user_irq_policy *pol
break;
}
}
+ closedir(poldir);
}
}
}
diff --git a/ui/irqbalance-ui.c b/ui/irqbalance-ui.c
index 47dd5dc..4dfbd46 100644
index fe00e94..ed8f408 100644
--- a/ui/irqbalance-ui.c
+++ b/ui/irqbalance-ui.c
@@ -418,6 +418,7 @@ int main(int argc, char **argv)
@@ -424,6 +424,7 @@ int main(int argc, char **argv)
fclose(f);
}
} while((entry) && (irqbalance_pid == -1));
@ -24,4 +35,5 @@ index 47dd5dc..4dfbd46 100644
if(irqbalance_pid == -1) {
printf("Unable to determine irqbalance PID\n");
--
2.19.1
2.23.0

View File

@ -1,7 +1,7 @@
From 4bddf961e18f59b27301b73895c0ae3a6cde9b7b Mon Sep 17 00:00:00 2001
From: liuchao173 <liuchao173@huawei.com>
Date: Thu, 7 Nov 2019 09:38:21 +0000
Subject: [PATCH 8/8] backport: fix resource leak on the error paths in main()
From eab9ac80148b6c70dd025c18ecac86fae6d6bf8e Mon Sep 17 00:00:00 2001
From: Yunfeng Ye <yeyunfeng@huawei.com>
Date: Sun, 20 Oct 2019 22:48:22 +0800
Subject: [PATCH 28/53] fix resource leak on the error paths in main()
Currently, both checking for core count < 2 and init_socket() fail, just
return directly, so lead to resource leak.
@ -14,10 +14,10 @@ Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/irqbalance.c b/irqbalance.c
index cace4d8..5e5ef9b 100644
index e53bf65..3ff5f13 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -556,6 +556,7 @@ int init_socket()
@@ -547,6 +547,7 @@ int init_socket()
int main(int argc, char** argv)
{
sigset_t sigset, old_sigset;
@ -25,7 +25,7 @@ index cace4d8..5e5ef9b 100644
sigemptyset(&sigset);
sigaddset(&sigset,SIGINT);
@@ -636,7 +637,7 @@ int main(int argc, char** argv)
@@ -637,7 +638,7 @@ int main(int argc, char** argv)
"single cpu. Shutting down\n";
log(TO_ALL, LOG_WARNING, "%s", msg);
@ -34,7 +34,7 @@ index cace4d8..5e5ef9b 100644
}
@@ -673,7 +674,8 @@ int main(int argc, char** argv)
@@ -660,7 +661,8 @@ int main(int argc, char** argv)
parse_proc_stat();
if (init_socket()) {
@ -44,7 +44,7 @@ index cace4d8..5e5ef9b 100644
}
main_loop = g_main_loop_new(NULL, FALSE);
last_interval = sleep_interval;
@@ -682,6 +684,7 @@ int main(int argc, char** argv)
@@ -669,6 +671,7 @@ int main(int argc, char** argv)
g_main_loop_quit(main_loop);
@ -52,7 +52,7 @@ index cace4d8..5e5ef9b 100644
free_object_tree();
free_cl_opts();
@@ -689,9 +692,10 @@ int main(int argc, char** argv)
@@ -676,9 +679,10 @@ int main(int argc, char** argv)
if (!foreground_mode && pidfile)
unlink(pidfile);
/* Remove socket */
@ -66,5 +66,5 @@ index cace4d8..5e5ef9b 100644
+ return ret;
}
--
2.19.1
2.23.0

View File

@ -1,7 +1,7 @@
From 97730f051e042e67da5728a3b59528c9d0fb72d2 Mon Sep 17 00:00:00 2001
From: Pyxisha <xiashuang1@huawei.com>
Date: Mon, 15 Jul 2019 20:47:07 +0800
Subject: [PATCH 45/50] fix sleep interval when sleep_interval is changed by
Subject: [PATCH 05/53] fix sleep interval when sleep_interval is changed by
socket
currently, in scan, irqbalance compare sleep_interval's address to decide if sleep_interval is changed, accutually this judgement is always false now.
@ -58,5 +58,5 @@ index c1a0e15..d424326 100644
g_main_loop_quit(main_loop);
--
2.19.1
2.23.0

View File

@ -1,7 +1,7 @@
From a23a3b9881eff000f79ca4cf9bd0e526399e6a68 Mon Sep 17 00:00:00 2001
From: hejingxian 00273181 <hejingxian@huawei.com>
Date: Fri, 6 Sep 2019 21:00:52 +0800
Subject: [PATCH 08/48] * fix the pid file generates too late problem
Subject: [PATCH 11/53] * fix the pid file generates too late problem
When the system processes many irqs with using user policy script,
the build_object_tree function will fork many child processes which costs several minutes.
@ -61,5 +61,5 @@ index d424326..8199c06 100644
g_unix_signal_add(SIGINT, handler, NULL);
g_unix_signal_add(SIGTERM, handler, NULL);
--
2.21.0.windows.1
2.23.0

View File

@ -1,8 +1,8 @@
From 559980c2e1dea1082949c17d52794c43c35f40ce Mon Sep 17 00:00:00 2001
From: liuchao173 <liuchao173@huawei.com>
Date: Thu, 7 Nov 2019 09:35:42 +0000
Subject: [PATCH 7/8] backport: fix the problem of banmod that memory is freed
before using
From fc30c5e39428196a075aec92135bd6c10baae19b Mon Sep 17 00:00:00 2001
From: Yunfeng Ye <yeyunfeng@huawei.com>
Date: Mon, 14 Oct 2019 20:44:27 +0800
Subject: [PATCH 25/53] fix the problem of banmod that memory is freed before
using
Currently strdupa() is used to allocate memory for irq_info's name in
collect_full_irq_list(), we know that it allocate memory from stack,
@ -23,10 +23,10 @@ Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/classify.c b/classify.c
index 3136fc3..ed3f3ba 100644
index c1ac230..550f3b6 100644
--- a/classify.c
+++ b/classify.c
@@ -748,6 +748,13 @@ static void add_missing_irq(struct irq_info *info, void *attr)
@@ -750,6 +750,13 @@ static void add_missing_irq(struct irq_info *info, void *attr)
add_new_irq(info->irq, info, proc_interrupts);
}
@ -40,7 +40,7 @@ index 3136fc3..ed3f3ba 100644
void rebuild_irq_db(void)
{
@@ -777,7 +784,7 @@ void rebuild_irq_db(void)
@@ -779,7 +786,7 @@ void rebuild_irq_db(void)
for_each_irq(tmp_irqs, add_missing_irq, interrupts_db);
@ -50,10 +50,10 @@ index 3136fc3..ed3f3ba 100644
}
diff --git a/procinterrupts.c b/procinterrupts.c
index 87fae2f..11fe1bc 100644
index f3f57ad..4a7a5d5 100644
--- a/procinterrupts.c
+++ b/procinterrupts.c
@@ -228,7 +228,7 @@ GList* collect_full_irq_list()
@@ -229,7 +229,7 @@ GList* collect_full_irq_list()
info->class = IRQ_OTHER;
#endif
}
@ -63,4 +63,5 @@ index 87fae2f..11fe1bc 100644
}
free(savedline);
--
2.19.1
2.23.0

View File

@ -1,7 +1,7 @@
From 0fab11043aef5b835ed5564dc15476cdbfb54d5b Mon Sep 17 00:00:00 2001
From: SuperSix173 <liuchao173@huawei.com>
Date: Thu, 6 Feb 2020 11:43:48 +0800
Subject: [PATCH] free cpu_ban_string when the next request come
Subject: [PATCH 49/53] free cpu_ban_string when the next request come
---
cputree.c | 4 ----
@ -62,5 +62,5 @@ index e76d27b..9f65c88 100644
}
if (!strncmp(buff, "setup", strlen("setup"))) {
--
2.21.0.windows.1
2.23.0

View File

@ -0,0 +1,26 @@
From 3768776c7b4f7f79f52dc025d50a5e2d214f5b2c Mon Sep 17 00:00:00 2001
From: liuchao173 <55137861+liuchao173@users.noreply.github.com>
Date: Mon, 2 Dec 2019 19:46:53 +0800
Subject: [PATCH 44/53] free polscript if irqbalance exit
polscript is alloced in parse_command_line and isn't freed when irqbalance exit
---
irqbalance.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/irqbalance.c b/irqbalance.c
index 7630e38..5134f9d 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -702,6 +702,8 @@ int main(int argc, char** argv)
out:
free_object_tree();
free_cl_opts();
+ if (polscript)
+ free(polscript);
/* Remove pidfile */
if (!foreground_mode && pidfile)
--
2.23.0

View File

@ -0,0 +1,35 @@
From 6e4ef7f8a13147c15ac542f829b5a7b6a93ce239 Mon Sep 17 00:00:00 2001
From: liuchao173 <55137861+liuchao173@users.noreply.github.com>
Date: Tue, 3 Dec 2019 09:30:40 +0800
Subject: [PATCH 45/53] free polscript to avoid resource leak
free polscript when irqbalance exit or the same option is passed twice on the comand line
---
irqbalance.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/irqbalance.c b/irqbalance.c
index 5134f9d..e76d27b 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -153,6 +153,7 @@ static void parse_command_line(int argc, char **argv)
add_cl_banned_irq((int)val);
break;
case 'l':
+ free(polscript);
polscript = strdup(optarg);
break;
case 'm':
@@ -702,8 +703,7 @@ int main(int argc, char** argv)
out:
free_object_tree();
free_cl_opts();
- if (polscript)
- free(polscript);
+ free(polscript);
/* Remove pidfile */
if (!foreground_mode && pidfile)
--
2.23.0

View File

@ -1,8 +1,7 @@
From 0f7965c9cc3963c4dbfa7b61820ff973ef5da539 Mon Sep 17 00:00:00 2001
From: liuchao173 <liuchao173@huawei.com>
Date: Thu, 7 Nov 2019 09:22:15 +0000
Subject: [PATCH 3/8] backport: free the memory when getline() fail in
add_one_node()
From 403b17259db89fed7a037a98948da3930fed6b24 Mon Sep 17 00:00:00 2001
From: yeyunfeng <yyfeng615@126.com>
Date: Sun, 6 Oct 2019 22:04:22 +0800
Subject: [PATCH 20/53] free the memory when getline() fail in add_one_node()
when getline() fail, the memory still need to be freed.
@ -32,4 +31,5 @@ index f0b1a98..542e1f4 100644
fclose(f);
new->obj_type = OBJ_TYPE_NODE;
--
2.19.1
2.23.0

View File

@ -1,8 +1,7 @@
From 9fd716f6627c0bb3b63cef94780e20101d9616c3 Mon Sep 17 00:00:00 2001
From: liuchao173 <liuchao173@huawei.com>
Date: Thu, 7 Nov 2019 09:19:33 +0000
Subject: [PATCH 2/8] backport:
getline-clean-up-freeing-of-lines-from-getline.patch
From 50f7f4641534c8137b329f2c6cdeaa20987c9382 Mon Sep 17 00:00:00 2001
From: Neil Horman <nhorman@hmswarspite.think-freely.org>
Date: Mon, 30 Sep 2019 11:46:37 -0400
Subject: [PATCH 19/53] getline: clean up freeing of lines from getline
It was noted that several calls to getline failed to free the resultant line,
which the man page for getline says to do even if the call fails. Clean that up
@ -17,7 +16,7 @@ Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
1 file changed, 17 insertions(+), 12 deletions(-)
diff --git a/cputree.c b/cputree.c
index 5551784..91919ec 100644
index 91c6111..a90cbbe 100644
--- a/cputree.c
+++ b/cputree.c
@@ -91,10 +91,10 @@ static void setup_banned_cpus(void)
@ -60,7 +59,7 @@ index 5551784..91919ec 100644
if (file) {
char *line = NULL;
size_t size = 0;
- if (getline(&line, &size, file)==0)
- if (getline(&line, &size, file)<=0)
- return;
+ if (getline(&line, &size, file)>0)
+ ret = (line && line[0]=='0') ? 1 : 0;
@ -103,4 +102,5 @@ index 5551784..91919ec 100644
}
--
2.19.1
2.23.0

View File

@ -1,30 +0,0 @@
From a8ad43cc682e268c9f35633a15636222b6933649 Mon Sep 17 00:00:00 2001
From:Xia Shuang <xiashuang1@huawei.com>
Date: Thu, 29 Aug 2019 14:31:25 +0800
Subject: [PATCH] fix guess_arm_irq_hints
in aarch64, irqbalance will guess
irq's class and type according to irq's name, but it did't work properly now,
a irq's name will be matched twice and class will always be IRQ_OTHER. such
as a nic interrupt, the debug log will be:
IRQ eth3-tx0 (109) guessed as class 5
IRQ eth3-tx0 (109) guessed as class 0
irq's class should be IRQ_GBETH but is IRQ_GBETH.
---
procinterrupts.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/procinterrupts.c b/procinterrupts.c
index 2088c58..3898b10 100644
--- a/procinterrupts.c
+++ b/procinterrupts.c
@@ -137,6 +137,7 @@ static void guess_arm_irq_hints(char *name, struct irq_info *info)
if (matches[i].refine_match)
matches[i].refine_match(name, info);
log(TO_ALL, LOG_DEBUG, "IRQ %s(%d) guessed as class %d\n", name, info->irq,info->class);
+ break;
}
}
--
2.21.0.windows.1

View File

@ -0,0 +1,55 @@
From 0a28c3a67e43ec8f96ed046e9e076fb8a454ab01 Mon Sep 17 00:00:00 2001
From: Adrian Friedli <adi@koalatux.ch>
Date: Tue, 27 Aug 2019 22:30:22 +0200
Subject: [PATCH 09/53] improve comments in env file
---
misc/irqbalance.env | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/misc/irqbalance.env b/misc/irqbalance.env
index bd87e3d..23570b2 100644
--- a/misc/irqbalance.env
+++ b/misc/irqbalance.env
@@ -1,26 +1,29 @@
# 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
+# 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.
+# system you're using has).
+
#
-# ONESHOT=yes
-# after starting, wait for a minute, then look at the interrupt
+# IRQBALANCE_ONESHOT
+# 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
+# 64 bit bitmask which allows you to indicate which CPUs 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
+# IRQs assigned to them on rebalance.
#
#IRQBALANCE_BANNED_CPUS=
#
# IRQBALANCE_ARGS
-# append any args here to the irqbalance daemon as documented in the man page
+# Append any args here to the irqbalance daemon as documented in the man
+# page.
#
#IRQBALANCE_ARGS=
--
2.23.0

View File

@ -1,85 +1,76 @@
From 84a2df1c9962a87f55e1c0d3bd2118fd754a4b48 Mon Sep 17 00:00:00 2001
From: hejingxian <hejingxian@huawei.com>
Date: Fri, 3 Jan 2020 16:43:28 +0800
Subject: [PATCH] add new irq migrate rule to avoid high cpu irq load
From e9e28114036a198b311ee17dd542540f749e6a68 Mon Sep 17 00:00:00 2001
From: hejingxian 00273181 <hejingxian@huawei.com>
Date: Mon, 20 Jan 2020 23:20:47 +0800
Subject: [PATCH 48/53] improve irq migrate rule to avoid high irq load
By the old irq migrate rule, the irqs cannot be moved if the adjustment_load will become smaller then
the min_load after moving irq. However, we can accept that the delta load become smaller after moving irq.
---
irqbalance.c | 14 ++++++++++++--
irqbalance.h | 3 ++-
irqlist.c | 15 ++++++++++++++-
3 files changed, 28 insertions(+), 4 deletions(-)
irqbalance.c | 9 +++++++--
irqbalance.h | 1 +
irqlist.c | 10 +++++++++-
3 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/irqbalance.c b/irqbalance.c
index 1ca401e..15fb0fe 100644
index be111f1..513ab5a 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -69,6 +69,8 @@ int sleep_interval = SLEEP_INTERVAL;
long HZ;
int sleep_interval = SLEEP_INTERVAL;
int last_interval;
+unsigned long migrate_val = 0;
+unsigned long load_limit = 0;
GMainLoop *main_loop;
@@ -67,6 +67,7 @@ GMainLoop *main_loop;
char *cpu_ban_string = NULL;
@@ -106,6 +108,8 @@ struct option lopts[] = {
char *banned_cpumask_from_ui = NULL;
+unsigned long migrate_ratio = 0;
static void sleep_approx(int seconds)
{
@@ -96,6 +97,7 @@ struct option lopts[] = {
{"banmod", 1 , NULL, 'm'},
{"interval", 1 , NULL, 't'},
{"version", 0, NULL, 'V'},
+ {"migrateval", 1, NULL, 'e'},
+ {"loadlimit", 1, NULL, 'g'},
{0, 0, 0, 0}
};
@@ -114,7 +118,7 @@ static void usage(void)
@@ -103,7 +105,7 @@ static void usage(void)
{
log(TO_CONSOLE, LOG_INFO, "irqbalance [--oneshot | -o] [--debug | -d] [--foreground | -f] [--journal | -j] [--hintpolicy= | -h [exact|subset|ignore]]\n");
log(TO_CONSOLE, LOG_INFO, "irqbalance [--oneshot | -o] [--debug | -d] [--foreground | -f] [--journal | -j]\n");
log(TO_CONSOLE, LOG_INFO, " [--powerthresh= | -p <off> | <n>] [--banirq= | -i <n>] [--banmod= | -m <module>] [--policyscript= | -l <script>]\n");
- log(TO_CONSOLE, LOG_INFO, " [--pid= | -s <file>] [--deepestcache= | -c <n>] [--interval= | -t <n>]\n");
+ log(TO_CONSOLE, LOG_INFO, " [--pid= | -s <file>] [--deepestcache= | -c <n>] [--interval= | -t <n>] [--migrateval= | -e <n>] [--loadlimit= | -g <n>]\n");
+ log(TO_CONSOLE, LOG_INFO, " [--pid= | -s <file>] [--deepestcache= | -c <n>] [--interval= | -t <n>] [--migrateval= | -e <n>]\n");
}
static void version(void)
@@ -129,7 +133,7 @@ static void parse_command_line(int argc, char **argv)
@@ -118,7 +120,7 @@ static void parse_command_line(int argc, char **argv)
unsigned long val;
while ((opt = getopt_long(argc, argv,
- "odfjVi:p:s:c:b:l:m:t:",
+ "odfjVi:p:s:c:b:l:m:t:e:g:",
- "odfjVi:p:s:c:l:m:t:",
+ "odfjVi:p:s:c:l:m:t:e:",
lopts, &longind)) != -1) {
switch(opt) {
@@ -231,6 +235,12 @@ static void parse_command_line(int argc, char **argv)
@@ -187,6 +189,9 @@ static void parse_command_line(int argc, char **argv)
exit(1);
}
break;
+ case 'e':
+ migrate_val = strtoul(optarg, NULL, 10);
+ break;
+ case 'g':
+ load_limit = strtoul(optarg, NULL, 10);
+ migrate_ratio = strtoul(optarg, NULL, 10);
+ break;
}
}
}
diff --git a/irqbalance.h b/irqbalance.h
index 72e141b..d4f6e7a 100644
index 3e3ea5d..cd93167 100644
--- a/irqbalance.h
+++ b/irqbalance.h
@@ -124,7 +124,8 @@ extern struct irq_info *add_new_irq(int irq, struct irq_info *hint, GList *proc_
extern void add_cl_banned_module(char *modname);
#define irq_numa_node(irq) ((irq)->numa_node)
@@ -77,6 +77,7 @@ extern char *polscript;
extern cpumask_t banned_cpus;
extern cpumask_t unbanned_cpus;
extern long HZ;
+extern unsigned long migrate_ratio;
-
+extern unsigned long migrate_val;
+extern unsigned long load_limit;
/*
* Generic object functions
*/
* Numa node access routines
diff --git a/irqlist.c b/irqlist.c
index 95ccc7a..3c38b18 100644
index 95ccc7a..9ab321a 100644
--- a/irqlist.c
+++ b/irqlist.c
@@ -76,6 +76,7 @@ static void compute_deviations(struct topo_obj *obj, void *data)
@ -90,32 +81,25 @@ index 95ccc7a..3c38b18 100644
/* Don't rebalance irqs that don't want it */
if (info->level == BALANCE_NONE)
@@ -91,12 +92,24 @@ static void move_candidate_irqs(struct irq_info *info, void *data)
@@ -91,10 +92,17 @@ static void move_candidate_irqs(struct irq_info *info, void *data)
if (info->load <= 1)
return;
+ if (migrate_val > 0) {
+ delta_load = (lb_info->adjustment_load - lb_info->min_load) / migrate_val;
+ if (migrate_ratio > 0) {
+ delta_load = (lb_info->adjustment_load - lb_info->min_load) / migrate_ratio;
+ }
+
/* If we can migrate an irq without swapping the imbalance do it. */
if ((lb_info->adjustment_load - info->load) > (lb_info->min_load + info->load)) {
- if ((lb_info->adjustment_load - info->load) > (lb_info->min_load + info->load)) {
+ if ((lb_info->min_load + info->load) - (lb_info->adjustment_load - info->load) < delta_load) {
lb_info->adjustment_load -= info->load;
lb_info->min_load += info->load;
- } else
+ } else if (delta_load && load_limit && (lb_info->adjustment_load > load_limit) &&
+ (lb_info->min_load + info->load) - (lb_info->adjustment_load - info->load) < delta_load) {
+ lb_info->adjustment_load -= info->load;
+ lb_info->min_load += info->load;
+ if (lb_info->min_load > lb_info->adjustment_load) {
+ lb_info->min_load = lb_info->adjustment_load;
+ }
+ } else {
} else
return;
+ }
log(TO_CONSOLE, LOG_INFO, "Selecting irq %d for rebalancing\n", info->irq);
--
1.8.3.1
2.23.0

View File

@ -1,86 +0,0 @@
From a4fbf90c2395ffa13176e8b002b7ef89a0ffc667 Mon Sep 17 00:00:00 2001
From: Neil Horman <nhorman@tuxdriver.com>
Date: Mon, 28 May 2018 08:33:08 -0400
Subject: [PATCH 079/112] irq_db: don't fail entirely if we don't have a pci
bus
aarch64 expects to have several interrupts that aren't associated to
devices on a pci bus. However, rebuild_irq_db skips all interrupts if
/sys/bus/pci/devices doesn't exist. Fix this by still calling
add_missing_irq on all collected interrupts regardless of the pci bus
directory.
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
---
classify.c | 29 ++++++++++++++---------------
1 file changed, 14 insertions(+), 15 deletions(-)
diff --git a/classify.c b/classify.c
index d3688fe..a977dc9 100644
--- a/classify.c
+++ b/classify.c
@@ -39,7 +39,7 @@ GList *cl_banned_irqs = NULL;
static GList *cl_banned_modules = NULL;
#define SYSFS_DIR "/sys"
-#define SYSDEV_DIR "/sys/bus/pci/devices"
+#define SYSPCI_DIR "/sys/bus/pci/devices"
#define PCI_MAX_CLASS 0x14
#define PCI_MAX_SERIAL_SUBCLASS 0x81
@@ -616,8 +616,8 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
char devpath[PATH_MAX];
struct user_irq_policy pol;
- sprintf(path, "%s/%s/msi_irqs", SYSDEV_DIR, dirname);
- sprintf(devpath, "%s/%s", SYSDEV_DIR, dirname);
+ sprintf(path, "%s/%s/msi_irqs", SYSPCI_DIR, dirname);
+ sprintf(devpath, "%s/%s", SYSPCI_DIR, dirname);
msidir = opendir(path);
@@ -646,7 +646,7 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
return;
}
- sprintf(path, "%s/%s/irq", SYSDEV_DIR, dirname);
+ sprintf(path, "%s/%s/irq", SYSPCI_DIR, dirname);
fd = fopen(path, "r");
if (!fd)
return;
@@ -764,22 +764,21 @@ void rebuild_irq_db(void)
tmp_irqs = collect_full_irq_list();
- devdir = opendir(SYSDEV_DIR);
- if (!devdir)
- goto free;
+ devdir = opendir(SYSPCI_DIR);
- do {
- entry = readdir(devdir);
-
- if (!entry)
- break;
+ if (devdir) {
+ do {
+ entry = readdir(devdir);
- build_one_dev_entry(entry->d_name, tmp_irqs);
+ if (!entry)
+ break;
- } while (entry != NULL);
+ build_one_dev_entry(entry->d_name, tmp_irqs);
- closedir(devdir);
+ } while (entry != NULL);
+ closedir(devdir);
+ }
for_each_irq(tmp_irqs, add_missing_irq, interrupts_db);
--
1.8.3.1

View File

@ -1,12 +0,0 @@
diff -up ./misc/irqbalance.service.path ./misc/irqbalance.service
--- ./misc/irqbalance.service.path 2017-11-14 13:09:56.011146473 -0500
+++ ./misc/irqbalance.service 2017-11-14 13:10:13.480075654 -0500
@@ -4,7 +4,7 @@ After=syslog.target
ConditionVirtualization=!container
[Service]
-EnvironmentFile=/path/to/irqbalance.env
+EnvironmentFile=/etc/sysconfig/irqbalance
ExecStart=/usr/sbin/irqbalance --foreground $IRQBALANCE_ARGS
[Install]

Binary file not shown.

BIN
irqbalance-1.6.0.tar.gz Normal file

Binary file not shown.

View File

@ -1,105 +0,0 @@
From 19c25ddc5a13cf0b993cdb0edac0eee80143be34 Mon Sep 17 00:00:00 2001
From: PJ Waskiewicz <peter.waskiewicz.jr@intel.com>
Date: Thu, 9 Aug 2018 10:56:03 -0700
Subject: [PATCH 093/112] irqbalance: Add support for file-based socket for IPC
This patch adds support for a file-based socket in tmpfs. It
also fixes an inadvertent bug that caused the socket in use to
be an abstract socket, which wasn't the intent.
This addresses Issue #72.
Signed-off-by: PJ Waskiewicz <pjwaskiewicz@gmail.com>
---
irqbalance.c | 32 ++++++++++++++++++++++----------
irqbalance.h | 1 +
2 files changed, 23 insertions(+), 10 deletions(-)
diff --git a/irqbalance.c b/irqbalance.c
index 2614719..bce9d56 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -45,6 +45,7 @@
volatile int keep_going = 1;
int socket_fd;
+char socket_name[64];
int one_shot_mode;
int debug_mode;
int foreground_mode;
@@ -456,7 +457,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
return TRUE;
}
-int init_socket(char *socket_name)
+int init_socket()
{
struct sockaddr_un addr;
memset(&addr, 0, sizeof(struct sockaddr_un));
@@ -467,13 +468,25 @@ int init_socket(char *socket_name)
return 1;
}
+ /*
+ * First try to create a file-based socket in tmpfs. If that doesn't
+ * succeed, fall back to an abstract socket (non file-based).
+ */
addr.sun_family = AF_UNIX;
- strncpy(addr.sun_path, socket_name, strlen(addr.sun_path));
- if (bind(socket_fd, (struct sockaddr *)&addr,
- sizeof(sa_family_t) + strlen(socket_name) + 1) < 0) {
- log(TO_ALL, LOG_WARNING, "Daemon couldn't be bound to the socket.\n");
- return 1;
+ snprintf(socket_name, 64, "%s/%s%d.sock", SOCKET_TMPFS, SOCKET_PATH, getpid());
+ strncpy(addr.sun_path, socket_name, strlen(socket_name));
+ if (bind(socket_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ log(TO_ALL, LOG_WARNING, "Daemon couldn't be bound to the file-based socket.\n");
+
+ /* Try binding to abstract */
+ memset(&addr, 0, sizeof(struct sockaddr_un));
+ addr.sun_family = AF_UNIX;
+ if (bind(socket_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ log(TO_ALL, LOG_WARNING, "Daemon couldn't be bound to the abstract socket, bailing out.\n");
+ return 1;
+ }
}
+
int optval = 1;
if (setsockopt(socket_fd, SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval)) < 0) {
log(TO_ALL, LOG_WARNING, "Unable to set socket options.\n");
@@ -598,10 +611,7 @@ int main(int argc, char** argv)
parse_proc_interrupts();
parse_proc_stat();
- char socket_name[64];
- snprintf(socket_name, 64, "%s%d.sock", SOCKET_PATH, getpid());
-
- if (init_socket(socket_name)) {
+ if (init_socket()) {
return EXIT_FAILURE;
}
main_loop = g_main_loop_new(NULL, FALSE);
@@ -619,6 +629,8 @@ int main(int argc, char** argv)
unlink(pidfile);
/* Remove socket */
close(socket_fd);
+ if (socket_name[0])
+ unlink(socket_name);
return EXIT_SUCCESS;
}
diff --git a/irqbalance.h b/irqbalance.h
index b7a26fc..c4717d3 100644
--- a/irqbalance.h
+++ b/irqbalance.h
@@ -158,6 +158,7 @@ extern unsigned int log_mask;
#endif /* HAVE_LIBSYSTEMD */
#define SOCKET_PATH "irqbalance"
+#define SOCKET_TMPFS "/var/run"
#endif /* __INCLUDE_GUARD_IRQBALANCE_H_ */
--
1.8.3.1

View File

@ -0,0 +1,50 @@
From 47137bb3e74cdc35630cf48ed839bf82b4fcc01e Mon Sep 17 00:00:00 2001
From: Yunfeng Ye <yeyunfeng@huawei.com>
Date: Wed, 6 Nov 2019 11:44:43 +0800
Subject: [PATCH 39/53] irqbalance: initialize package_mask before using in
do_one_cpu()
The local variable package_mask is used without initialized. add
cpus_clear(package_mask) before using, and move it to the error path
where getting packpage_mask fail from core_siblings.
In addition, the variable cache_mask is called cpu_set() twice, which
is unnecessary, so delete the redundant code.
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
---
cputree.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/cputree.c b/cputree.c
index 8178ba8..aa69f56 100644
--- a/cputree.c
+++ b/cputree.c
@@ -299,12 +299,13 @@ static void do_one_cpu(char *path)
return;
}
- cpu_set(cpu->number, package_mask);
-
/* try to read the package mask; if it doesn't exist assume solitary */
snprintf(new_path, ADJ_SIZE(path, "/topology/core_siblings"),
"%s/topology/core_siblings", path);
- process_one_line(new_path, get_mask_from_bitmap, &package_mask);
+ if (process_one_line(new_path, get_mask_from_bitmap, &package_mask)) {
+ cpus_clear(package_mask);
+ cpu_set(cpu->number, package_mask);
+ }
/* try to read the package id */
snprintf(new_path, ADJ_SIZE(path, "/topology/physical_package_id"),
@@ -313,7 +314,6 @@ static void do_one_cpu(char *path)
/* try to read the cache mask; if it doesn't exist assume solitary */
/* We want the deepest cache level available */
- cpu_set(cpu->number, cache_mask);
max_cache_index = 0;
cache_index = 1;
do {
--
2.23.0

View File

@ -0,0 +1,91 @@
From 28df9e6207b4e894d9232b7c6d8eab7a0f02c7ad Mon Sep 17 00:00:00 2001
From: Yunfeng Ye <yeyunfeng@huawei.com>
Date: Wed, 30 Oct 2019 19:15:29 +0800
Subject: [PATCH 34/53] irqbalance: modify the order of input parameter for
calloc()
The man docs about calloc:
void *calloc(size_t nmemb, size_t size);
The calloc() function allocates memory for an array of nmemb elements
of size bytes each
The first parameter is elements count, so change the order of input
parameters for calloc().
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
---
classify.c | 4 ++--
cputree.c | 6 +++---
procinterrupts.c | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/classify.c b/classify.c
index 2c0e7ed..b999cab 100644
--- a/classify.c
+++ b/classify.c
@@ -275,7 +275,7 @@ static void add_banned_irq(int irq, GList **list)
if (entry)
return;
- new = calloc(sizeof(struct irq_info), 1);
+ new = calloc(1, sizeof(struct irq_info));
if (!new) {
log(TO_CONSOLE, LOG_WARNING, "No memory to ban irq %d\n", irq);
return;
@@ -366,7 +366,7 @@ static struct irq_info *add_one_irq_to_db(const char *devpath, struct irq_info *
return NULL;
}
- new = calloc(sizeof(struct irq_info), 1);
+ new = calloc(1, sizeof(struct irq_info));
if (!new)
return NULL;
diff --git a/cputree.c b/cputree.c
index 1c1c99b..97d4a78 100644
--- a/cputree.c
+++ b/cputree.c
@@ -192,7 +192,7 @@ static struct topo_obj* add_cache_domain_to_package(struct topo_obj *cache,
}
if (!entry) {
- package = calloc(sizeof(struct topo_obj), 1);
+ package = calloc(1, sizeof(struct topo_obj));
if (!package)
return NULL;
package->mask = package_mask;
@@ -238,7 +238,7 @@ static struct topo_obj* add_cpu_to_cache_domain(struct topo_obj *cpu,
}
if (!entry) {
- cache = calloc(sizeof(struct topo_obj), 1);
+ cache = calloc(1, sizeof(struct topo_obj));
if (!cache)
return NULL;
cache->obj_type = OBJ_TYPE_CACHE;
@@ -302,7 +302,7 @@ static void do_one_cpu(char *path)
if (offline_status)
return;
- cpu = calloc(sizeof(struct topo_obj), 1);
+ cpu = calloc(1, sizeof(struct topo_obj));
if (!cpu)
return;
diff --git a/procinterrupts.c b/procinterrupts.c
index 1a7ff26..35d3be8 100644
--- a/procinterrupts.c
+++ b/procinterrupts.c
@@ -214,7 +214,7 @@ GList* collect_full_irq_list()
*c = 0;
number = strtoul(line, NULL, 10);
- info = calloc(sizeof(struct irq_info), 1);
+ info = calloc(1, sizeof(struct irq_info));
if (info) {
info->irq = number;
if (strstr(irq_name, "-event") != NULL && is_xen_dyn == 1) {
--
2.23.0

View File

@ -0,0 +1,154 @@
From c2d1429ba289e9cea76dd08e24e2d40af3ab0435 Mon Sep 17 00:00:00 2001
From: Yunfeng Ye <yeyunfeng@huawei.com>
Date: Thu, 31 Oct 2019 00:39:11 +0800
Subject: [PATCH 36/53] irqbalance: prevent NULL pointer dereference in
do_one_cpu()
add_cpu_to_cache_domain() will return NULL if memory allocation failure,
so check the return value before invoking add_cache_domain_to_package(),
and add a global variable need_rebuild to check this situation, if
need_rebuild is set, then invoke free_object_tree() and try again a few
times, if it still fail, then return scan().
In addition, also set need_rebuild where calloc fails throughout the
build_object_tree process.
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
---
cputree.c | 16 +++++++++++-----
irqbalance.c | 19 ++++++++++++++++---
irqbalance.h | 1 +
numa.c | 4 +++-
4 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/cputree.c b/cputree.c
index c1b4950..6bbc2cb 100644
--- a/cputree.c
+++ b/cputree.c
@@ -176,8 +176,10 @@ static struct topo_obj* add_cache_domain_to_package(struct topo_obj *cache,
if (!entry) {
package = calloc(1, sizeof(struct topo_obj));
- if (!package)
+ if (!package) {
+ need_rebuild = 1;
return NULL;
+ }
package->mask = package_mask;
package->obj_type = OBJ_TYPE_PACKAGE;
package->obj_type_list = &packages;
@@ -214,8 +216,10 @@ static struct topo_obj* add_cpu_to_cache_domain(struct topo_obj *cpu,
if (!entry) {
cache = calloc(1, sizeof(struct topo_obj));
- if (!cache)
+ if (!cache) {
+ need_rebuild = 1;
return NULL;
+ }
cache->obj_type = OBJ_TYPE_CACHE;
cache->mask = cache_mask;
cache->number = cache_domain_count;
@@ -271,8 +275,10 @@ static void do_one_cpu(char *path)
return;
cpu = calloc(1, sizeof(struct topo_obj));
- if (!cpu)
+ if (!cpu) {
+ need_rebuild = 1;
return;
+ }
cpu->obj_type = OBJ_TYPE_CPU;
@@ -372,8 +378,8 @@ static void do_one_cpu(char *path)
cpus_and(package_mask, package_mask, unbanned_cpus);
cache = add_cpu_to_cache_domain(cpu, cache_mask, nodeid);
- add_cache_domain_to_package(cache, packageid, package_mask,
- nodeid);
+ if (cache)
+ add_cache_domain_to_package(cache, packageid, package_mask, nodeid);
cpu->obj_type_list = &cpus;
cpus = g_list_append(cpus, cpu);
diff --git a/irqbalance.c b/irqbalance.c
index 3ff5f13..619f51f 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -52,6 +52,7 @@ int foreground_mode;
int numa_avail;
int journal_logging = 0;
int need_rescan;
+int need_rebuild;
unsigned int log_mask = TO_ALL;
const char *log_indent;
unsigned long power_thresh = ULONG_MAX;
@@ -260,14 +261,25 @@ gboolean scan(gpointer data __attribute__((unused)))
/* cope with cpu hotplug -- detected during /proc/interrupts parsing */
- if (need_rescan) {
+ if (need_rescan || need_rebuild) {
+ int try_times = 0;
+
need_rescan = 0;
cycle_count = 0;
log(TO_CONSOLE, LOG_INFO, "Rescanning cpu topology \n");
clear_work_stats();
- free_object_tree();
- build_object_tree();
+ do {
+ free_object_tree();
+ if (++try_times > 3) {
+ log(TO_CONSOLE, LOG_WARNING, "Rescanning cpu topology: fail\n");
+ goto out;
+ }
+
+ need_rebuild = 0;
+ build_object_tree();
+ } while (need_rebuild);
+
for_each_irq(NULL, force_rebalance_irq, NULL);
parse_proc_interrupts();
parse_proc_stat();
@@ -284,6 +296,7 @@ gboolean scan(gpointer data __attribute__((unused)))
calculate_placement();
activate_mappings();
+out:
if (debug_mode)
dump_tree();
if (one_shot_mode)
diff --git a/irqbalance.h b/irqbalance.h
index 62c7151..79f5450 100644
--- a/irqbalance.h
+++ b/irqbalance.h
@@ -67,6 +67,7 @@ extern int debug_mode;
extern int journal_logging;
extern int one_shot_mode;
extern int need_rescan;
+extern int need_rebuild;
extern unsigned long long cycle_count;
extern unsigned long power_thresh;
extern unsigned long deepest_cache;
diff --git a/numa.c b/numa.c
index e76b6e0..9d55784 100644
--- a/numa.c
+++ b/numa.c
@@ -58,8 +58,10 @@ static void add_one_node(const char *nodename)
struct topo_obj *new;
new = calloc(1, sizeof(struct topo_obj));
- if (!new)
+ if (!new) {
+ need_rebuild = 1;
return;
+ }
cpus_clear(new->mask);
sprintf(path, "%s/%s/cpumap", SYSFS_NODE_PATH, nodename);
--
2.23.0

View File

@ -0,0 +1,61 @@
From 4ed5d04734a2c4d80acc582ab72c7c5225b2e7e3 Mon Sep 17 00:00:00 2001
From: Yunfeng Ye <yeyunfeng@huawei.com>
Date: Sun, 10 Nov 2019 22:08:25 +0000
Subject: [PATCH 43/53] irqbalance: remove redundancy check in
add_one_irq_to_db()
Before calling add_one_irq_to_db(), it has been checked by calling
get_irq_info(), so remove unnecessary redundancy check.
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
---
classify.c | 26 --------------------------
1 file changed, 26 deletions(-)
diff --git a/classify.c b/classify.c
index 90b0f30..c99e0f7 100644
--- a/classify.c
+++ b/classify.c
@@ -285,17 +285,6 @@ void add_cl_banned_irq(int irq)
add_banned_irq(irq, &cl_banned_irqs);
}
-static int is_banned_irq(int irq)
-{
- GList *entry;
- struct irq_info find;
-
- find.irq = irq;
-
- entry = g_list_find_custom(banned_irqs, &find, compare_ints);
- return entry ? 1:0;
-}
-
gint substr_find(gconstpointer a, gconstpointer b)
{
if (strstr(b, a))
@@ -340,21 +329,6 @@ static struct irq_info *add_one_irq_to_db(const char *devpath, struct irq_info *
struct irq_info *new;
int numa_node;
char path[PATH_MAX];
- GList *entry;
-
- /*
- * First check to make sure this isn't a duplicate entry
- */
- 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;
- }
-
- if (is_banned_irq(irq)) {
- log(TO_ALL, LOG_INFO, "SKIPPING BANNED IRQ %d\n", irq);
- return NULL;
- }
new = calloc(1, sizeof(struct irq_info));
if (!new)
--
2.23.0

View File

@ -0,0 +1,59 @@
From 2efbc92fd249ff524b3acdefccb3d679ac20f080 Mon Sep 17 00:00:00 2001
From: Yunfeng Ye <yeyunfeng@huawei.com>
Date: Wed, 30 Oct 2019 18:44:13 +0800
Subject: [PATCH 33/53] irqbalance: remove unused package_count variable
package_count variable is unused, so remote it. and cache_domain_count
variable only used in the local file, which no need to extern in
irqbalance.h
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
---
cputree.c | 3 ---
irqbalance.h | 2 --
2 files changed, 5 deletions(-)
diff --git a/cputree.c b/cputree.c
index c88feda..1c1c99b 100644
--- a/cputree.c
+++ b/cputree.c
@@ -44,7 +44,6 @@ GList *cpus;
GList *cache_domains;
GList *packages;
-int package_count;
int cache_domain_count;
int core_count;
@@ -201,7 +200,6 @@ static struct topo_obj* add_cache_domain_to_package(struct topo_obj *cache,
package->obj_type_list = &packages;
package->number = packageid;
packages = g_list_append(packages, package);
- package_count++;
}
entry = g_list_first(package->children);
@@ -558,7 +556,6 @@ void clear_cpu_tree(void)
{
g_list_free_full(packages, free_cpu_topo);
packages = NULL;
- package_count = 0;
g_list_free_full(cache_domains, free_cpu_topo);
cache_domains = NULL;
diff --git a/irqbalance.h b/irqbalance.h
index a3e561e..62c7151 100644
--- a/irqbalance.h
+++ b/irqbalance.h
@@ -29,8 +29,6 @@
#include <systemd/sd-journal.h>
#endif
-extern int package_count;
-extern int cache_domain_count;
extern int core_count;
extern char *classes[];
--
2.23.0

View File

@ -0,0 +1,131 @@
From f31f3a01ccc2e78c49fc8b61a1c95ec94236bfb8 Mon Sep 17 00:00:00 2001
From: Yunfeng Ye <yeyunfeng@huawei.com>
Date: Sun, 3 Nov 2019 21:56:53 +0800
Subject: [PATCH 37/53] irqbalance: use NUMA_NO_NODE macro instead of -1 for
numa
node id -1 is stand for no specific numa, and is used in many place, so
using NUMA_NO_NODE macro instead is better readability.
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
---
classify.c | 2 +-
cputree.c | 8 ++++----
irqbalance.h | 2 ++
numa.c | 4 ++--
placement.c | 4 ++--
5 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/classify.c b/classify.c
index b999cab..5fb8233 100644
--- a/classify.c
+++ b/classify.c
@@ -391,7 +391,7 @@ static struct irq_info *add_one_irq_to_db(const char *devpath, struct irq_info *
new->level = map_class_to_level[new->class];
get_numa_node:
- numa_node = -1;
+ numa_node = NUMA_NO_NODE;
if (devpath != NULL && numa_avail) {
sprintf(path, "%s/numa_node", devpath);
fd = fopen(path, "r");
diff --git a/cputree.c b/cputree.c
index 6bbc2cb..69f4c6d 100644
--- a/cputree.c
+++ b/cputree.c
@@ -138,7 +138,7 @@ static void add_numa_node_to_topo_obj(struct topo_obj *obj, int nodeid)
struct topo_obj *node;
node = get_numa_node(nodeid);
- if (!node || (numa_avail && (node->number == -1)))
+ if (!node || (numa_avail && (node->number == NUMA_NO_NODE)))
return;
entry = g_list_find(obj->numa_nodes, node);
@@ -193,7 +193,7 @@ static struct topo_obj* add_cache_domain_to_package(struct topo_obj *cache,
cache->parent = package;
}
- if (!numa_avail || (nodeid > -1))
+ if (!numa_avail || (nodeid > NUMA_NO_NODE))
add_numa_node_to_topo_obj(package, nodeid);
return package;
@@ -234,7 +234,7 @@ static struct topo_obj* add_cpu_to_cache_domain(struct topo_obj *cpu,
cpu->parent = (struct topo_obj *)cache;
}
- if (!numa_avail || (nodeid > -1))
+ if (!numa_avail || (nodeid > NUMA_NO_NODE))
add_numa_node_to_topo_obj(cache, nodeid);
return cache;
@@ -340,7 +340,7 @@ static void do_one_cpu(char *path)
process_one_line(new_path, get_mask_from_bitmap, &cache_mask);
}
- nodeid=-1;
+ nodeid = NUMA_NO_NODE;
if (numa_avail) {
struct topo_obj *node;
diff --git a/irqbalance.h b/irqbalance.h
index 79f5450..61d7550 100644
--- a/irqbalance.h
+++ b/irqbalance.h
@@ -29,6 +29,8 @@
#include <systemd/sd-journal.h>
#endif
+#define NUMA_NO_NODE (-1)
+
extern int core_count;
extern char *classes[];
diff --git a/numa.c b/numa.c
index 9d55784..a2f99e2 100644
--- a/numa.c
+++ b/numa.c
@@ -41,7 +41,7 @@ GList *numa_nodes = NULL;
static struct topo_obj unspecified_node_template = {
.load = 0,
- .number = -1,
+ .number = NUMA_NO_NODE,
.obj_type = OBJ_TYPE_NODE,
.mask = CPU_MASK_ALL,
.interrupts = NULL,
@@ -178,7 +178,7 @@ struct topo_obj *get_numa_node(int nodeid)
if (!numa_avail)
return &unspecified_node;
- if (nodeid == -1)
+ if (nodeid == NUMA_NO_NODE)
return &unspecified_node;
find.number = nodeid;
diff --git a/placement.c b/placement.c
index efa8c57..17a9f2e 100644
--- a/placement.c
+++ b/placement.c
@@ -45,7 +45,7 @@ static void find_best_object(struct topo_obj *d, void *data)
/*
* Don't consider the unspecified numa node here
*/
- if (numa_avail && (d->obj_type == OBJ_TYPE_NODE) && (d->number == -1))
+ if (numa_avail && (d->obj_type == OBJ_TYPE_NODE) && (d->number == NUMA_NO_NODE))
return;
/*
@@ -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 || !numa_avail) {
+ if (irq_numa_node(info)->number != NUMA_NO_NODE || !numa_avail) {
/*
* Need to make sure this node is elligible for migration
* given the banned cpu list
--
2.23.0

View File

@ -0,0 +1,138 @@
From 5dbcee82bfd5fa0585a69286ea3b0030d4ecd222 Mon Sep 17 00:00:00 2001
From: Yunfeng Ye <yeyunfeng@huawei.com>
Date: Wed, 11 Dec 2019 21:18:56 +0800
Subject: [PATCH 46/53] irqbalance: use add_new_irq() instead of the same logic
There are some same logic codes in build_one_dev_entry() that can be
replaced by add_new_irq().
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
---
classify.c | 73 +++++++++++++++++++-----------------------------------
1 file changed, 26 insertions(+), 47 deletions(-)
diff --git a/classify.c b/classify.c
index c99e0f7..fa900f4 100644
--- a/classify.c
+++ b/classify.c
@@ -572,6 +572,28 @@ static int check_for_irq_ban(int irq, GList *proc_interrupts)
return 0;
}
+static void add_new_irq(char *path, struct irq_info *hint, GList *proc_interrupts)
+{
+ struct irq_info *new;
+ struct user_irq_policy pol;
+ int irq = hint->irq;
+
+ new = get_irq_info(irq);
+ if (new)
+ return;
+
+ /* Set NULL devpath for the irq has no sysfs entries */
+ get_irq_user_policy(path, irq, &pol);
+ if ((pol.ban == 1) || check_for_irq_ban(irq, proc_interrupts)) { /*FIXME*/
+ add_banned_irq(irq, &banned_irqs);
+ new = get_irq_info(irq);
+ } else
+ new = add_one_irq_to_db(path, hint, &pol);
+
+ if (!new)
+ log(TO_CONSOLE, LOG_WARNING, "add_new_irq: Failed to add irq %d\n", irq);
+}
+
/*
* Figures out which interrupt(s) relate to the device we"re looking at in dirname
*/
@@ -580,10 +602,9 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
struct dirent *entry;
DIR *msidir;
int irqnum;
- struct irq_info *new, hint;
+ struct irq_info 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);
@@ -600,19 +621,9 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
break;
irqnum = strtol(entry->d_name, NULL, 10);
if (irqnum) {
- new = get_irq_info(irqnum);
- if (new)
- continue;
- get_irq_user_policy(devpath, irqnum, &pol);
- if ((pol.ban == 1) || (check_for_irq_ban(irqnum, tmp_irqs))) {
- add_banned_irq(irqnum, &banned_irqs);
- continue;
- }
hint.irq = irqnum;
hint.type = IRQ_TYPE_MSIX;
- new = add_one_irq_to_db(devpath, &hint, &pol);
- if (!new)
- continue;
+ add_new_irq(devpath, &hint, tmp_irqs);
}
} while (entry != NULL);
closedir(msidir);
@@ -632,20 +643,9 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
#else
if (irqnum) {
#endif
- new = get_irq_info(irqnum);
- if (new)
- goto done;
- get_irq_user_policy(devpath, irqnum, &pol);
- if ((pol.ban == 1) || (check_for_irq_ban(irqnum, tmp_irqs))) {
- add_banned_irq(irqnum, &banned_irqs);
- goto done;
- }
-
hint.irq = irqnum;
hint.type = IRQ_TYPE_LEGACY;
- new = add_one_irq_to_db(devpath, &hint, &pol);
- if (!new)
- goto done;
+ add_new_irq(devpath, &hint, tmp_irqs);
}
done:
@@ -675,32 +675,11 @@ void free_cl_opts(void)
g_list_free_full(cl_banned_irqs, free);
}
-static void add_new_irq(int irq, struct irq_info *hint, GList *proc_interrupts)
-{
- struct irq_info *new;
- struct user_irq_policy pol;
-
- new = get_irq_info(irq);
- if (new)
- return;
-
- /* 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(irq, proc_interrupts)) { /*FIXME*/
- add_banned_irq(irq, &banned_irqs);
- new = get_irq_info(irq);
- } else
- new = add_one_irq_to_db(NULL, hint, &pol);
-
- if (!new)
- log(TO_CONSOLE, LOG_WARNING, "add_new_irq: Failed to add irq %d\n", irq);
-}
-
static void add_missing_irq(struct irq_info *info, void *attr)
{
GList *proc_interrupts = (GList *) attr;
- add_new_irq(info->irq, info, proc_interrupts);
+ add_new_irq(NULL, info, proc_interrupts);
}
static void free_tmp_irqs(gpointer data)
--
2.23.0

View File

@ -0,0 +1,158 @@
From 4f361d0a7cd1d764855d5fcd49d849e8a17381cb Mon Sep 17 00:00:00 2001
From: Yunfeng Ye <yeyunfeng@huawei.com>
Date: Mon, 4 Nov 2019 15:16:51 +0800
Subject: [PATCH 40/53] irqbalance: use add_one_node() to create unspecified
node for numa
Use add_one_node(NUMA_NO_NODE) to create a unspecified node instead of
global variable.
It can reuse the function add_one_node() and delete two global variable
unspecified_node_template and unspecified_node. Also it can reuse the
function free_cpu_topo() instead of free_numa_node().
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
---
cputree.c | 2 +-
irqbalance.h | 1 +
numa.c | 62 ++++++++++++----------------------------------------
3 files changed, 16 insertions(+), 49 deletions(-)
diff --git a/cputree.c b/cputree.c
index aa69f56..305f617 100644
--- a/cputree.c
+++ b/cputree.c
@@ -508,7 +508,7 @@ void parse_cpu_tree(void)
}
-static void free_cpu_topo(gpointer data)
+void free_cpu_topo(gpointer data)
{
struct topo_obj *obj = data;
diff --git a/irqbalance.h b/irqbalance.h
index 85fcbf2..900db9d 100644
--- a/irqbalance.h
+++ b/irqbalance.h
@@ -51,6 +51,7 @@ void dump_tree(void);
void activate_mappings(void);
void clear_cpu_tree(void);
+void free_cpu_topo(gpointer data);
/*===================NEW BALANCER FUNCTIONS============================*/
diff --git a/numa.c b/numa.c
index a2f99e2..13d7ebd 100644
--- a/numa.c
+++ b/numa.c
@@ -39,20 +39,7 @@
GList *numa_nodes = NULL;
-static struct topo_obj unspecified_node_template = {
- .load = 0,
- .number = NUMA_NO_NODE,
- .obj_type = OBJ_TYPE_NODE,
- .mask = CPU_MASK_ALL,
- .interrupts = NULL,
- .children = NULL,
- .parent = NULL,
- .obj_type_list = &numa_nodes,
-};
-
-static struct topo_obj unspecified_node;
-
-static void add_one_node(const char *nodename)
+static void add_one_node(int nodeid)
{
char path[PATH_MAX];
struct topo_obj *new;
@@ -63,12 +50,16 @@ static void add_one_node(const char *nodename)
return;
}
- cpus_clear(new->mask);
- sprintf(path, "%s/%s/cpumap", SYSFS_NODE_PATH, nodename);
- process_one_line(path, get_mask_from_bitmap, &new->mask);
+ if (nodeid == NUMA_NO_NODE) {
+ cpus_setall(new->mask);
+ } else {
+ cpus_clear(new->mask);
+ sprintf(path, "%s/node%d/cpumap", SYSFS_NODE_PATH, nodeid);
+ process_one_line(path, get_mask_from_bitmap, &new->mask);
+ }
new->obj_type = OBJ_TYPE_NODE;
- new->number = strtoul(&nodename[4], NULL, 10);
+ new->number = nodeid;
new->obj_type_list = &numa_nodes;
numa_nodes = g_list_append(numa_nodes, new);
}
@@ -78,17 +69,8 @@ void build_numa_node_list(void)
DIR *dir;
struct dirent *entry;
- /*
- * Note that we copy the unspcified node from the template here
- * in the event we just freed the object tree during a rescan.
- * This ensures we don't get stale list pointers anywhere
- */
- memcpy(&unspecified_node, &unspecified_node_template, sizeof (struct topo_obj));
-
- /*
- * Add the unspecified node
- */
- numa_nodes = g_list_append(numa_nodes, &unspecified_node);
+ /* Add the unspecified node */
+ add_one_node(NUMA_NO_NODE);
if (!numa_avail)
return;
@@ -104,25 +86,15 @@ void build_numa_node_list(void)
if ((entry->d_type == DT_DIR) &&
(strncmp(entry->d_name, "node", 4) == 0) &&
isdigit(entry->d_name[4])) {
- add_one_node(entry->d_name);
+ add_one_node(strtoul(&entry->d_name[4], NULL, 10));
}
} while (entry);
closedir(dir);
}
-static void free_numa_node(gpointer data)
-{
- struct topo_obj *obj = data;
- g_list_free(obj->children);
- g_list_free(obj->interrupts);
-
- if (data != &unspecified_node)
- free(data);
-}
-
void free_numa_node_list(void)
{
- g_list_free_full(numa_nodes, free_numa_node);
+ g_list_free_full(numa_nodes, free_cpu_topo);
numa_nodes = NULL;
}
@@ -175,13 +147,7 @@ struct topo_obj *get_numa_node(int nodeid)
struct topo_obj find;
GList *entry;
- if (!numa_avail)
- return &unspecified_node;
-
- if (nodeid == NUMA_NO_NODE)
- return &unspecified_node;
-
- find.number = nodeid;
+ find.number = numa_avail ? nodeid : NUMA_NO_NODE;
entry = g_list_find_custom(numa_nodes, &find, compare_node);
return entry ? entry->data : NULL;
--
2.23.0

View File

@ -0,0 +1,135 @@
From 82f05296c7b8e53791047fb1668d4f41149c91d8 Mon Sep 17 00:00:00 2001
From: Yunfeng Ye <yeyunfeng@huawei.com>
Date: Wed, 30 Oct 2019 19:55:18 +0800
Subject: [PATCH 35/53] irqbalance: use g_list_find() instead of the search
logic for cpu_topo
There are some search logic of list can be replaced by g_list_find(),
which can make the code more simpler. the list to be search is start
from head, so remove g_list_first().
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
---
cputree.c | 40 ++++------------------------------------
numa.c | 10 +---------
2 files changed, 5 insertions(+), 45 deletions(-)
diff --git a/cputree.c b/cputree.c
index 97d4a78..c1b4950 100644
--- a/cputree.c
+++ b/cputree.c
@@ -136,33 +136,17 @@ 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 || (numa_avail && (node->number == -1)))
return;
- entry = g_list_first(obj->numa_nodes);
- while (entry) {
- cand_node = entry->data;
- if (cand_node == node)
- break;
- entry = g_list_next(entry);
- }
-
+ entry = g_list_find(obj->numa_nodes, node);
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);
- }
-
+ entry = g_list_find(node->children, obj);
if (!entry) {
node->children = g_list_append(node->children, obj);
obj->parent = node;
@@ -177,7 +161,6 @@ static struct topo_obj* add_cache_domain_to_package(struct topo_obj *cache,
{
GList *entry;
struct topo_obj *package;
- struct topo_obj *lcache;
entry = g_list_first(packages);
@@ -202,14 +185,7 @@ static struct topo_obj* add_cache_domain_to_package(struct topo_obj *cache,
packages = g_list_append(packages, package);
}
- entry = g_list_first(package->children);
- while (entry) {
- lcache = entry->data;
- if (lcache == cache)
- break;
- entry = g_list_next(entry);
- }
-
+ entry = g_list_find(package->children, cache);
if (!entry) {
package->children = g_list_append(package->children, cache);
cache->parent = package;
@@ -226,7 +202,6 @@ static struct topo_obj* add_cpu_to_cache_domain(struct topo_obj *cpu,
{
GList *entry;
struct topo_obj *cache;
- struct topo_obj *lcpu;
entry = g_list_first(cache_domains);
@@ -249,14 +224,7 @@ static struct topo_obj* add_cpu_to_cache_domain(struct topo_obj *cpu,
cache_domain_count++;
}
- entry = g_list_first(cache->children);
- while (entry) {
- lcpu = entry->data;
- if (lcpu == cpu)
- break;
- entry = g_list_next(entry);
- }
-
+ entry = g_list_find(cache->children, cpu);
if (!entry) {
cache->children = g_list_append(cache->children, cpu);
cpu->parent = (struct topo_obj *)cache;
diff --git a/numa.c b/numa.c
index f1284da..e76b6e0 100644
--- a/numa.c
+++ b/numa.c
@@ -136,7 +136,6 @@ void connect_cpu_mem_topo(struct topo_obj *p, void *data __attribute__((unused))
{
GList *entry;
struct topo_obj *node;
- struct topo_obj *lchild;
int len;
len = g_list_length(p->numa_nodes);
@@ -154,14 +153,7 @@ void connect_cpu_mem_topo(struct topo_obj *p, void *data __attribute__((unused))
if (p->obj_type == OBJ_TYPE_PACKAGE && !p->parent)
p->parent = node;
- entry = g_list_first(node->children);
- while (entry) {
- lchild = entry->data;
- if (lchild == p)
- break;
- entry = g_list_next(entry);
- }
-
+ entry = g_list_find(node->children, p);
if (!entry)
node->children = g_list_append(node->children, p);
}
--
2.23.0

View File

@ -0,0 +1,89 @@
From d289ecd663a43d59c68b52c33e981b0096519063 Mon Sep 17 00:00:00 2001
From: Yunfeng Ye <yeyunfeng@huawei.com>
Date: Mon, 28 Oct 2019 19:03:19 +0800
Subject: [PATCH 32/53] irqbalance: use g_list_free_full() in clear_cpu_tree()
Resource is freed by traversing each list in clear_cpu_tree(), which can
be replaced by g_list_free_full(), so make the code simpler.
In addition, the children and numa_nodes list of cpus is empty, so
free_cpu_topo() also free the list for cpus have no impact.
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
---
cputree.c | 47 +++++++++++++++--------------------------------
1 file changed, 15 insertions(+), 32 deletions(-)
diff --git a/cputree.c b/cputree.c
index acf6a47..c88feda 100644
--- a/cputree.c
+++ b/cputree.c
@@ -540,6 +540,15 @@ void parse_cpu_tree(void)
}
+static void free_cpu_topo(gpointer data)
+{
+ struct topo_obj *obj = data;
+
+ g_list_free(obj->children);
+ g_list_free(obj->interrupts);
+ g_list_free(obj->numa_nodes);
+ free(obj);
+}
/*
* This function frees all memory related to a cpu tree so that a new tree
@@ -547,43 +556,17 @@ void parse_cpu_tree(void)
*/
void clear_cpu_tree(void)
{
- GList *item;
- struct topo_obj *cpu;
- struct topo_obj *cache_domain;
- struct topo_obj *package;
-
- while (packages) {
- item = g_list_first(packages);
- package = item->data;
- g_list_free(package->children);
- g_list_free(package->interrupts);
- g_list_free(package->numa_nodes);
- free(package);
- packages = g_list_delete_link(packages, item);
- }
+ g_list_free_full(packages, free_cpu_topo);
+ packages = NULL;
package_count = 0;
- while (cache_domains) {
- item = g_list_first(cache_domains);
- cache_domain = item->data;
- g_list_free(cache_domain->children);
- g_list_free(cache_domain->interrupts);
- g_list_free(cache_domain->numa_nodes);
- free(cache_domain);
- cache_domains = g_list_delete_link(cache_domains, item);
- }
+ g_list_free_full(cache_domains, free_cpu_topo);
+ cache_domains = NULL;
cache_domain_count = 0;
-
- while (cpus) {
- item = g_list_first(cpus);
- cpu = item->data;
- g_list_free(cpu->interrupts);
- free(cpu);
- cpus = g_list_delete_link(cpus, item);
- }
+ g_list_free_full(cpus, free_cpu_topo);
+ cpus = NULL;
core_count = 0;
-
}
static gint compare_cpus(gconstpointer a, gconstpointer b)
--
2.23.0

View File

@ -0,0 +1,36 @@
From c0da4d95c2b86003ebe20a7c5e88df54648411fe Mon Sep 17 00:00:00 2001
From: Yunfeng Ye <yeyunfeng@huawei.com>
Date: Sat, 26 Oct 2019 20:51:15 +0800
Subject: [PATCH 31/53] irqbalance: use isdigit() instead of the logic of
character judgment
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
---
procinterrupts.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/procinterrupts.c b/procinterrupts.c
index 29b0fef..1a7ff26 100644
--- a/procinterrupts.c
+++ b/procinterrupts.c
@@ -182,7 +182,7 @@ GList* collect_full_irq_list()
while (isblank(*(c)))
c++;
- if (!(*c>='0' && *c<='9'))
+ if (!isdigit(*c))
break;
c = strchr(line, ':');
if (!c)
@@ -274,7 +274,7 @@ void parse_proc_interrupts(void)
while (isblank(*(c)))
c++;
- if (!(*c>='0' && *c<='9'))
+ if (!isdigit(*c))
break;
c = strchr(line, ':');
if (!c)
--
2.23.0

View File

@ -0,0 +1,227 @@
From 8799a564dc331732af431bad25a8744e043f8409 Mon Sep 17 00:00:00 2001
From: Yunfeng Ye <yeyunfeng@huawei.com>
Date: Mon, 4 Nov 2019 11:51:46 +0800
Subject: [PATCH 38/53] irqbalance: use num_online_cpus() instead core_count
The variable core_count is actually the number of online cpus, and
cpu_possible_map is unused, so change cpu_possible_map to cpu_online_map
and use num_online_cpus() instead of core_count.
In addition, remove cpu_possible_map and cpu_present_map, also its
associated macros, which there are unused.
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
---
cpumask.h | 79 +-----------------------------------------------
cputree.c | 10 ++----
irqbalance.c | 2 +-
irqbalance.h | 1 -
procinterrupts.c | 2 +-
5 files changed, 6 insertions(+), 88 deletions(-)
diff --git a/cpumask.h b/cpumask.h
index 0774a88..5bebbeb 100644
--- a/cpumask.h
+++ b/cpumask.h
@@ -59,18 +59,10 @@
* for_each_cpu_mask(cpu, mask) for-loop cpu over mask
*
* int num_online_cpus() Number of online CPUs
- * int num_possible_cpus() Number of all possible CPUs
- * int num_present_cpus() Number of present CPUs
*
* int cpu_online(cpu) Is some cpu online?
- * int cpu_possible(cpu) Is some cpu possible?
- * int cpu_present(cpu) Is some cpu present (can schedule)?
*
- * int any_online_cpu(mask) First online cpu in mask
- *
- * for_each_possible_cpu(cpu) for-loop cpu over cpu_possible_map
* for_each_online_cpu(cpu) for-loop cpu over cpu_online_map
- * for_each_present_cpu(cpu) for-loop cpu over cpu_present_map
*
* Subtlety:
* 1) The 'type-checked' form of cpu_isset() causes gcc (3.3.2, anyway)
@@ -314,87 +306,18 @@ static inline void __cpus_remap(cpumask_t *dstp, const cpumask_t *srcp,
#endif /* NR_CPUS */
/*
- * The following particular system cpumasks and operations manage
- * possible, present and online cpus. Each of them is a fixed size
- * bitmap of size NR_CPUS.
- *
- * #ifdef CONFIG_HOTPLUG_CPU
- * cpu_possible_map - has bit 'cpu' set iff cpu is populatable
- * cpu_present_map - has bit 'cpu' set iff cpu is populated
- * cpu_online_map - has bit 'cpu' set iff cpu available to scheduler
- * #else
- * cpu_possible_map - has bit 'cpu' set iff cpu is populated
- * cpu_present_map - copy of cpu_possible_map
- * cpu_online_map - has bit 'cpu' set iff cpu available to scheduler
- * #endif
- *
- * In either case, NR_CPUS is fixed at compile time, as the static
- * size of these bitmaps. The cpu_possible_map is fixed at boot
- * time, as the set of CPU id's that it is possible might ever
- * be plugged in at anytime during the life of that system boot.
- * The cpu_present_map is dynamic(*), representing which CPUs
- * are currently plugged in. And cpu_online_map is the dynamic
- * subset of cpu_present_map, indicating those CPUs available
- * for scheduling.
- *
- * If HOTPLUG is enabled, then cpu_possible_map is forced to have
- * all NR_CPUS bits set, otherwise it is just the set of CPUs that
- * ACPI reports present at boot.
- *
- * If HOTPLUG is enabled, then cpu_present_map varies dynamically,
- * depending on what ACPI reports as currently plugged in, otherwise
- * cpu_present_map is just a copy of cpu_possible_map.
- *
- * (*) Well, cpu_present_map is dynamic in the hotplug case. If not
- * hotplug, it's a copy of cpu_possible_map, hence fixed at boot.
- *
- * Subtleties:
- * 1) UP arch's (NR_CPUS == 1, CONFIG_SMP not defined) hardcode
- * assumption that their single CPU is online. The UP
- * cpu_{online,possible,present}_maps are placebos. Changing them
- * will have no useful affect on the following num_*_cpus()
- * and cpu_*() macros in the UP case. This ugliness is a UP
- * optimization - don't waste any instructions or memory references
- * asking if you're online or how many CPUs there are if there is
- * only one CPU.
- * 2) Most SMP arch's #define some of these maps to be some
- * other map specific to that arch. Therefore, the following
- * must be #define macros, not inlines. To see why, examine
- * the assembly code produced by the following. Note that
- * set1() writes phys_x_map, but set2() writes x_map:
- * int x_map, phys_x_map;
- * #define set1(a) x_map = a
- * inline void set2(int a) { x_map = a; }
- * #define x_map phys_x_map
- * main(){ set1(3); set2(5); }
+ * cpu_online_map - has bit 'cpu' set iff cpu available to scheduler
*/
-
-extern cpumask_t cpu_possible_map;
extern cpumask_t cpu_online_map;
-extern cpumask_t cpu_present_map;
#if NR_CPUS > 1
#define num_online_cpus() cpus_weight(cpu_online_map)
-#define num_possible_cpus() cpus_weight(cpu_possible_map)
-#define num_present_cpus() cpus_weight(cpu_present_map)
#define cpu_online(cpu) cpu_isset((cpu), cpu_online_map)
-#define cpu_possible(cpu) cpu_isset((cpu), cpu_possible_map)
-#define cpu_present(cpu) cpu_isset((cpu), cpu_present_map)
#else
#define num_online_cpus() 1
-#define num_possible_cpus() 1
-#define num_present_cpus() 1
#define cpu_online(cpu) ((cpu) == 0)
-#define cpu_possible(cpu) ((cpu) == 0)
-#define cpu_present(cpu) ((cpu) == 0)
#endif
-int highest_possible_processor_id(void);
-#define any_online_cpu(mask) __any_online_cpu(&(mask))
-int __any_online_cpu(const cpumask_t *mask);
-
-#define for_each_possible_cpu(cpu) for_each_cpu_mask((cpu), cpu_possible_map)
#define for_each_online_cpu(cpu) for_each_cpu_mask((cpu), cpu_online_map)
-#define for_each_present_cpu(cpu) for_each_cpu_mask((cpu), cpu_present_map)
#endif /* __LINUX_CPUMASK_H */
diff --git a/cputree.c b/cputree.c
index 69f4c6d..8178ba8 100644
--- a/cputree.c
+++ b/cputree.c
@@ -45,12 +45,11 @@ GList *cache_domains;
GList *packages;
int cache_domain_count;
-int core_count;
/* Users want to be able to keep interrupts away from some cpus; store these in a cpumask_t */
cpumask_t banned_cpus;
-cpumask_t cpu_possible_map;
+cpumask_t cpu_online_map;
/*
it's convenient to have the complement of banned_cpus available so that
@@ -284,7 +283,7 @@ static void do_one_cpu(char *path)
cpu->number = strtoul(&path[27], NULL, 10);
- cpu_set(cpu->number, cpu_possible_map);
+ cpu_set(cpu->number, cpu_online_map);
cpu_set(cpu->number, cpu->mask);
@@ -297,8 +296,6 @@ static void do_one_cpu(char *path)
/* if the cpu is on the banned list, just don't add it */
if (cpus_intersects(cpu->mask, banned_cpus)) {
free(cpu);
- /* even though we don't use the cpu we do need to count it */
- core_count++;
return;
}
@@ -383,7 +380,6 @@ static void do_one_cpu(char *path)
cpu->obj_type_list = &cpus;
cpus = g_list_append(cpus, cpu);
- core_count++;
}
static void dump_irq(struct irq_info *info, void *data)
@@ -537,7 +533,7 @@ void clear_cpu_tree(void)
g_list_free_full(cpus, free_cpu_topo);
cpus = NULL;
- core_count = 0;
+ cpus_clear(cpu_online_map);
}
static gint compare_cpus(gconstpointer a, gconstpointer b)
diff --git a/irqbalance.c b/irqbalance.c
index 619f51f..c9379ad 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -646,7 +646,7 @@ int main(int argc, char** argv)
/* On single core UP systems irqbalance obviously has no work to do */
- if (core_count<2) {
+ if (num_online_cpus() <= 1) {
char *msg = "Balancing is ineffective on systems with a "
"single cpu. Shutting down\n";
diff --git a/irqbalance.h b/irqbalance.h
index 61d7550..85fcbf2 100644
--- a/irqbalance.h
+++ b/irqbalance.h
@@ -31,7 +31,6 @@
#define NUMA_NO_NODE (-1)
-extern int core_count;
extern char *classes[];
extern void parse_cpu_tree(void);
diff --git a/procinterrupts.c b/procinterrupts.c
index 35d3be8..858b66b 100644
--- a/procinterrupts.c
+++ b/procinterrupts.c
@@ -303,7 +303,7 @@ void parse_proc_interrupts(void)
c=c2;
cpunr++;
}
- if (cpunr != core_count) {
+ if (cpunr != num_online_cpus()) {
need_rescan = 1;
break;
}
--
2.23.0

View File

@ -0,0 +1,176 @@
From 56679afd67ba2706387407ea258eb0d2413c0c1e Mon Sep 17 00:00:00 2001
From: Yunfeng Ye <yeyunfeng@huawei.com>
Date: Sun, 10 Nov 2019 19:18:07 +0000
Subject: [PATCH 42/53] irqbalance: use process_one_line() instead of fscanf()
The logic using fscanf() to get data from open file can be instead by
process_one_line(), and provide two functions get_hex() and get_int()
to convert string to integer. also use get_int() instead of
get_offline_status() and get_packageid().
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
---
classify.c | 27 ++++-----------------------
cputree.c | 32 ++++++++++++++------------------
irqbalance.h | 2 ++
3 files changed, 20 insertions(+), 41 deletions(-)
diff --git a/classify.c b/classify.c
index 5fb8233..90b0f30 100644
--- a/classify.c
+++ b/classify.c
@@ -187,20 +187,11 @@ static int map_pci_irq_class(unsigned int pci_class)
static unsigned int read_pci_data(const char *devpath, const char* file)
{
char path[PATH_MAX];
- FILE *fd;
unsigned int data = PCI_INVAL_DATA;
sprintf(path, "%s/%s", devpath, file);
-
- fd = fopen(path, "r");
-
- if (!fd) {
- log(TO_CONSOLE, LOG_WARNING, "PCI: can't open file:%s\n", path);
- return data;
- }
-
- (void) fscanf(fd, "%x", &data);
- fclose(fd);
+ if (process_one_line(path, get_hex, &data) < 0)
+ log(TO_CONSOLE, LOG_WARNING, "PCI: can't get from file:%s\n", path);
return data;
}
@@ -349,7 +340,6 @@ static struct irq_info *add_one_irq_to_db(const char *devpath, struct irq_info *
struct irq_info *new;
int numa_node;
char path[PATH_MAX];
- FILE *fd;
GList *entry;
/*
@@ -394,11 +384,7 @@ get_numa_node:
numa_node = NUMA_NO_NODE;
if (devpath != NULL && numa_avail) {
sprintf(path, "%s/numa_node", devpath);
- fd = fopen(path, "r");
- if (fd) {
- fscanf(fd, "%d", &numa_node);
- fclose(fd);
- }
+ process_one_line(path, get_int, &numa_node);
}
if (pol->numa_node_set == 1)
@@ -619,7 +605,6 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
{
struct dirent *entry;
DIR *msidir;
- FILE *fd;
int irqnum;
struct irq_info *new, hint;
char path[PATH_MAX];
@@ -661,10 +646,7 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
}
sprintf(path, "%s/%s/irq", SYSPCI_DIR, dirname);
- fd = fopen(path, "r");
- if (!fd)
- return;
- if (fscanf(fd, "%d", &irqnum) < 0)
+ if (process_one_line(path, get_int, &irqnum) < 0)
goto done;
/*
@@ -693,7 +675,6 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
}
done:
- fclose(fd);
return;
}
diff --git a/cputree.c b/cputree.c
index 4c5fdf5..9aa4794 100644
--- a/cputree.c
+++ b/cputree.c
@@ -78,6 +78,16 @@ int process_one_line(char *path, void (*cb)(char *line, void *data), void *data)
return ret;
}
+void get_hex(char *line, void *data)
+{
+ *(int *)data = strtoul(line, NULL, 16);
+}
+
+void get_int(char *line, void *data)
+{
+ *(int *)data = strtoul(line, NULL, 10);
+}
+
void get_mask_from_bitmap(char *line, void *mask)
{
cpumask_parse_user(line, strlen(line), *(cpumask_t *)mask);
@@ -244,20 +254,6 @@ static struct topo_obj* add_cpu_to_cache_domain(struct topo_obj *cpu,
return cache;
}
-static void get_offline_status(char *line, void *data)
-{
- int *status = (int *)data;
-
- *status = (line && line[0] == '0') ? 1 : 0;
-}
-
-static void get_packageid(char *line, void *data)
-{
- int *packageid = (int *)data;
-
- *packageid = strtoul(line, NULL, 10);
-}
-
#define ADJ_SIZE(r,s) PATH_MAX-strlen(r)-strlen(#s)
static void do_one_cpu(char *path)
{
@@ -270,12 +266,12 @@ static void do_one_cpu(char *path)
int nodeid;
int packageid = 0;
unsigned int max_cache_index, cache_index, cache_stat;
- int offline_status = 0;
+ int online_status = 1;
/* skip offline cpus */
snprintf(new_path, ADJ_SIZE(path,"/online"), "%s/online", path);
- process_one_line(new_path, get_offline_status, &offline_status);
- if (offline_status)
+ process_one_line(new_path, get_int, &online_status);
+ if (!online_status)
return;
cpu = calloc(1, sizeof(struct topo_obj));
@@ -315,7 +311,7 @@ static void do_one_cpu(char *path)
/* try to read the package id */
snprintf(new_path, ADJ_SIZE(path, "/topology/physical_package_id"),
"%s/topology/physical_package_id", path);
- process_one_line(new_path, get_packageid, &packageid);
+ process_one_line(new_path, get_int, &packageid);
/* try to read the cache mask; if it doesn't exist assume solitary */
/* We want the deepest cache level available */
diff --git a/irqbalance.h b/irqbalance.h
index 900db9d..3e3ea5d 100644
--- a/irqbalance.h
+++ b/irqbalance.h
@@ -163,6 +163,8 @@ extern unsigned int log_mask;
extern int process_one_line(char *path, void (*cb)(char *line, void *data), void *data);
extern void get_mask_from_bitmap(char *line, void *mask);
+extern void get_int(char *line, void *data);
+extern void get_hex(char *line, void *data);
#endif /* __INCLUDE_GUARD_IRQBALANCE_H_ */
--
2.23.0

View File

@ -1,2 +0,0 @@
#!/bin/bash
echo > /dev/null

19
irqbalance.service Normal file
View File

@ -0,0 +1,19 @@
[Unit]
Description=irqbalance daemon
Documentation=man:irqbalance(1)
Documentation=https://github.com/Irqbalance/irqbalance
ConditionVirtualization=!container
After=syslog.target
[Service]
OOMScoreAdjust=-500
Type=forking
PIDFile=/var/run/irqbalance.pid
EnvironmentFile=/etc/sysconfig/irqbalance
ExecStart=/usr/sbin/irq_balancer
StartLimitInterval=10
StartLimitBurst=10000
RuntimeDirectory=irqbalance/
[Install]
WantedBy=multi-user.target

View File

@ -1,14 +1,12 @@
Summary: A dynamic adaptive IRQ balancing daemon
Name: irqbalance
Version: 1.4.0
Release: 19
Version: 1.6.0
Release: 1
Epoch: 3
License: GPLv2
Source0: https://github.com/Irqbalance/irqbalance/archive/irqbalance-%{version}.tar.gz
Source1: irqbalance.sysconfig
Source2: irqbalance.rules
Source3: irq_balancer
Source1: irqbalance.service
Source2: irq_balancer
Url: https://github.com/irqbalance/irqbalance
BuildRequires: gdb autoconf automake libtool libcap-ng systemd
@ -23,56 +21,58 @@ Requires: numactl-libs
%define _hardened_build 1
Patch0: add-a-catchall-guessing-mechanis.patch
Patch1: irq_db-don-t-fail-entirely-if-we-don-t-have-a-pci-bu.patch
Patch2: cputree-adjust-snprintf-sizes-to-avoid-gcc-warnings.patch
Patch3: classify-remove-unused-label.patch
Patch4: parse_proc_interrupts-ensure-that-buffer-is-long-eno.patch
Patch5: Fix-some-string-copy-limitations.patch
Patch6: irqbalance-Add-support-for-file-based-socket-for-IPC.patch
Patch7: Fix-several-memleak-problems-found-by-covscan.patch
Patch8: Fix-an-possible-overflow-error.patch
Patch9: Fix-irqbalance-ui-failing-to-connect-to-irqbalance-d.patch
Patch10: procinterrupts-check-xen-dyn-event-more-flexible.patch
Patch11: Fix-ambiguous-parsing-of-node-entries-in-sys.patch
Patch12: Don-t-leak-socket-fd-on-connection-error.patch
Patch13: Fix-string-truncation-issues-detected-by-GCC-8.patch
Patch14: fix-balancing-when-numa-information-isn-t-available.patch
Patch6000: use-policy-prior-to-the-default-values.patch
Patch6001: some-variable-and-judgement-are-unnecessary-in-activ.patch
Patch6002: fix-sleep-interval-when-sleep_interval-is-changed-by.patch
Patch6003: guess_arm_irq_hints.patch
Patch6004: fix-the-pid-file-generates-too-late-problem.patch
Patch6005: make-the-return-value-of-getline-handled-correct.patch
Patch6006: change-irq-ban-check-path-to-devpath.patch
Patch6007: Checking-return-value-of-strdup-in-collect_full_irq_.patch
Patch6008: getline-clean-up-freeing-of-lines-from-getline.patch
Patch6009: free-the-memory-when-getline-fail-in-add_one_node.patch
Patch6010: prevent-NULL-pointer-dereference-when-memory-allocat.patch
Patch6011: fix-resource-leak-for-not-invoking-closedir-after-op.patch
Patch6012: correct-to-use-realloc-function.patch
Patch6013: fix-the-problem-of-banmod-that-memory-is-freed-befor.patch
Patch6014: fix-resource-leak-on-the-error-paths-in-main.patch
Patch6015: fix-invalid-pointer-dereference-banned_cpumask_from_.patch
Patch6016: free-cpu_ban_string-when-the-next-request-come.patch
Patch6017: make-the-option-V-closer-to-the-option-with-no-arg.patch
Patch6018: improve-irq-migrate-rule-to-avoid-high-irq-load.patch
Patch6019: arm64-Add-irq-aff-change-check.patch
Patch9000: irqbalance-1.0.4-env-file-path.patch
Patch9001: bugfix-fix-a-hole-that-flees-hotplug-event.patch
Patch9002: bugfix-force-irq-into-rebalance-list-when-irq-removed-and-reinserted.patch
Patch9003: feature-irqbalance-aarch64-add-the-regular-to-get-th.patch
Patch9004: feature-irqbalance-auto-banned-pci-assigned-irq.patch
Patch9005: feature-supplement-irqbalance-service-config.patch
Patch9006: feature-add-new-user-irq-policy-config-rule.patch
Patch9007: feature-add-the-switch-of-printing-log.patch
Patch9008: feature-introduce-verifyhint-to-detect-hint-variation.patch
Patch9009: feature-add-switch-to-clear-affinity-hint.patch
Patch9010: feature-encapsulate-and-compile-the-functions-in-irqbalance-ui.patch
Patch9011: feature-enable-irqbalance-to-link-with-multiple-clie.patch
Patch9012: feature-irqbalance-Add-ability-for-socket-communicat.patch
Patch0001:Fix-spelling-errors.patch
Patch0002:Clarify-the-README-description.patch
Patch0003:use-policy-prior-to-the-default-values.patch
Patch0004:some-variable-and-judgement-are-unnecessary-in-activ.patch
Patch0005:fix-sleep-interval-when-sleep_interval-is-changed-by.patch
Patch0006:Add-stub-manpage-for-irqbalance-ui.patch
Patch0007:Capitalize-HOMEPAGE-in-irqbalance.1.patch
Patch0008:Add-irqbalance-ui.1-to-dist_man_MANS.patch
Patch0009:improve-comments-in-env-file.patch
Patch0010:fix-guess_arm_irq_hints.patch
Patch0011:fix-the-pid-file-generates-too-late-problem.patch
Patch0012:change-path-to-devpath.patch
Patch0013:Add-optional-config-file-in-usr-lib.patch
Patch0014:make-the-return-value-of-getline-handled-correct.patch
Patch0015:remove-unused-path-in-check_for_irq_ban.patch
Patch0016:Update-classify.c.patch
Patch0017:delete-unused-local-variables-in-parse_proc_interrup.patch
Patch0018:Checking-return-value-of-strdup-in-collect_full_irq_.patch
Patch0019:getline-clean-up-freeing-of-lines-from-getline.patch
Patch0020:free-the-memory-when-getline-fail-in-add_one_node.patch
Patch0021:prevent-NULL-pointer-dereference-when-memory-allocat.patch
Patch0022:fix-resource-leak-for-not-invoking-closedir-after-op.patch
Patch0023:correct-to-use-realloc-function.patch
Patch0024:reduce-redundant-code-for-file-processing.patch
Patch0025:fix-the-problem-of-banmod-that-memory-is-freed-befor.patch
Patch0026:when-devpath-is-NULL-skip-reading-files.patch
Patch0027:remove-c-in-parse_proc_interrupts.patch
Patch0028:fix-resource-leak-on-the-error-paths-in-main.patch
Patch0029:reduce-redundant-check-in-add_missing_irq.patch
Patch0030:delete-the-useless-free-for-banned_irqs-in-free_cl_o.patch
Patch0031:irqbalance-use-isdigit-instead-of-the-logic-of-chara.patch
Patch0032:irqbalance-use-g_list_free_full-in-clear_cpu_tree.patch
Patch0033:irqbalance-remove-unused-package_count-variable.patch
Patch0034:irqbalance-modify-the-order-of-input-parameter-for-c.patch
Patch0035:irqbalance-use-g_list_find-instead-of-the-search-log.patch
Patch0036:irqbalance-prevent-NULL-pointer-dereference-in-do_on.patch
Patch0037:irqbalance-use-NUMA_NO_NODE-macro-instead-of-1-for-n.patch
Patch0038:irqbalance-use-num_online_cpus-instead-core_count.patch
Patch0039:irqbalance-initialize-package_mask-before-using-in-d.patch
Patch0040:irqbalance-use-add_one_node-to-create-unspecified-no.patch
Patch0041:fix-invalid-pointer-dereference-banned_cpumask_from_.patch
Patch0042:irqbalance-use-process_one_line-instead-of-fscanf.patch
Patch0043:irqbalance-remove-redundancy-check-in-add_one_irq_to.patch
Patch0044:free-polscript-if-irqbalance-exit.patch
Patch0045:free-polscript-to-avoid-resource-leak.patch
Patch0046:irqbalance-use-add_new_irq-instead-of-the-same-logic.patch
Patch0047:make-the-option-V-closer-to-the-option-with-no-arg.patch
Patch0048:improve-irq-migrate-rule-to-avoid-high-irq-load.patch
Patch0049:free-cpu_ban_string-when-the-next-request-come.patch
Patch0050:Correct-typos-in-irqbalance.c.patch
Patch0051:arm64-Add-irq-aff-change-check.patch
Patch0052:Fix-typo-in-service-unit-file.patch
%description
Irqbalance is a daemon to help balance the cpu load generated by
@ -82,20 +82,6 @@ single unique cpu, so that load is spread as much as possible over
an entire processor set, while minimizing cache miss rates for irq
handlers.
%package devel
Summary: The development files of irqbalance client
Requires: glib2-devel ncurses-devel irqbalance-libs
%description devel
Development files for irqbalance client.
%package libs
Summary: The shared librariy of irqbalance client
Requires: glib2 ncurses-libs
%description libs
Shared librariy for irqbalanace client
%package_help
%prep
@ -105,20 +91,12 @@ Shared librariy for irqbalanace client
./autogen.sh
%configure
CFLAGS="%{optflags}" %make_build CFLAGS+='-fstack-protector-strong '
cd ui
rm -rf *.o
make
cd -
%install
install -D -p -m 0755 %{name} %{buildroot}%{_sbindir}/%{name}
install -D -p -m 0644 ./misc/%{name}.service %{buildroot}/%{_unitdir}/%{name}.service
install -D -p -m 0644 %{SOURCE1} %{buildroot}%{_sysconfdir}/sysconfig/%{name}
install -D -p -m 0755 %{SOURCE2} %{buildroot}%{_sysconfdir}/sysconfig/%{name}.rules
install -D -p -m 0755 %{SOURCE3} %{buildroot}%{_sbindir}/irq_balancer
install -D -p -m 0640 ui/irqbalance_client.h %{buildroot}%{_includedir}/irqbalance_client.h
install -D -p -m 0640 ui/libirqbalance_client.so %{buildroot}%{_libdir}/libirqbalance_client.so
install -D -p -m 0644 %{SOURCE1} %{buildroot}/%{_unitdir}/%{name}.service
install -D -p -m 0644 ./misc/irqbalance.env %{buildroot}%{_sysconfdir}/sysconfig/%{name}
install -D -p -m 0755 %{SOURCE2} %{buildroot}%{_sbindir}/irq_balancer
install -d %{buildroot}%{_mandir}/man1/
install -p -m 0644 ./%{name}.1 %{buildroot}%{_mandir}/man1/
@ -131,15 +109,8 @@ make check
%{_sbindir}/%{name}
%{_unitdir}/%{name}.service
%config(noreplace) %{_sysconfdir}/sysconfig/%{name}
%{_sysconfdir}/sysconfig/%{name}.rules
%{_sbindir}/irq_balancer
%files devel
%{_includedir}/irqbalance_client.h
%files libs
%{_libdir}/libirqbalance_client.so
%files help
%{_mandir}/man1/*
@ -159,6 +130,12 @@ fi
/sbin/chkconfig --del %{name} >/dev/null 2>&1 || :
%changelog
* Fri Jul 3 2020 Liu Chao <liuchao173@huawei.com> - 3:1.6.0-1
- Type:enhanced
- ID:NA
- SUG:restart
- DESC:rebase to v1.6.0
* Tue Mar 24 2020 Liu chao <liuchao173@huawei.com> - 3:1.4.0-19
- Type:bugfix
- ID:NA

View File

@ -1,39 +0,0 @@
# irqbalance is a daemon process that distributes interrupts across
# CPUS on SMP systems. The default is to rebalance once every 10
# seconds. This is the environment file that is specified to systemd via the
# EnvironmentFile key in the service unit file (or via whatever method the init
# system you're using has.
#
# ONESHOT=yes
# after starting, wait for a minute, then look at the interrupt
# load and balance it once; after balancing exit and do not change
# it again.
#IRQBALANCE_ONESHOT=
#
# IRQBALANCE_BANNED_CPUS
# 64 bit bitmask which allows you to indicate which cpu's should
# be skipped when reblancing irqs. Cpu numbers which have their
# corresponding bits set to one in this mask will not have any
# irq's assigned to them on rebalance
#
IRQBALANCE_BANNED_CPUS=
## Type: string
## Default: ""
## ServiceRestart: Iirq_balancer
#
# Interrupt that don't get balanced as list (separation character doesn't
# matter). For example broken chipsets don't allow the timer interrupt
# to be set to another CPU than the first, and with this option that
# policy can be applied.
#
IRQBALANCE_BANNED_INTERRUPTS=""
#
# IRQBALANCE_ARGS
# append any args here to the irqbalance daemon as documented in the man page
#
IRQBALANCE_ARGS=

View File

@ -1,7 +1,7 @@
From 7f77fc97cb259da3f6097be347e4fcacd4f864d9 Mon Sep 17 00:00:00 2001
From: hejingxian 00273181 <hejingxian@huawei.com>
Date: Mon, 20 Jan 2020 23:01:19 +0800
Subject: [PATCH 29/33] make the option 'V' closer to the option with no arg
Subject: [PATCH 47/53] make the option 'V' closer to the option with no arg
---
irqbalance.c | 2 +-
@ -15,11 +15,11 @@ index e76d27b..be111f1 100644
unsigned long val;
while ((opt = getopt_long(argc, argv,
- "odfji:p:s:c:b:l:m:t:V",
+ "odfjVi:p:s:c:b:l:m:t:",
- "odfji:p:s:c:l:m:t:V",
+ "odfjVi:p:s:c:l:m:t:",
lopts, &longind)) != -1) {
switch(opt) {
--
2.21.0.windows.1
2.23.0

View File

@ -1,21 +1,23 @@
From 74970054568728d11dbbb160e0c5cacdfeb07ff3 Mon Sep 17 00:00:00 2001
From: liuchao <liuchao173@huawei.com>
Date: Fri, 11 Oct 2019 07:49:55 +0000
Subject: [PATCH] irqbalance: make the return value of getline() handled correct
From 735c0241afa78459eefb7eb9a60fe0b7b0029430 Mon Sep 17 00:00:00 2001
From: Yunfeng Ye <yeyunfeng@huawei.com>
Date: Wed, 18 Sep 2019 22:26:44 +0800
Subject: [PATCH 14/53] make the return value of getline() handled correct
getline() will return -1 when fail, so make the return value handle correct.
getline() will return -1 when fail, so make the return value handle
correct.
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
---
activate.c | 2 +-
cputree.c | 6 +++---
cputree.c | 8 ++++----
procinterrupts.c | 12 ++++++------
3 files changed, 10 insertions(+), 10 deletions(-)
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/activate.c b/activate.c
index ad60fde..87336f4 100644
index 8fd9bde..2812976 100644
--- a/activate.c
+++ b/activate.c
@@ -47,7 +47,7 @@ static int check_affinity(struct irq_info *info, cpumask_t applied_mask)
@@ -44,7 +44,7 @@ static int check_affinity(struct irq_info *info, cpumask_t applied_mask)
file = fopen(buf, "r");
if (!file)
return 1;
@ -25,10 +27,19 @@ index ad60fde..87336f4 100644
fclose(file);
return 1;
diff --git a/cputree.c b/cputree.c
index 0dbb5c8..51ef357 100644
index 5551784..91c6111 100644
--- a/cputree.c
+++ b/cputree.c
@@ -324,7 +324,7 @@ static void do_one_cpu(char *path)
@@ -278,7 +278,7 @@ static void do_one_cpu(char *path)
if (file) {
char *line = NULL;
size_t size = 0;
- if (getline(&line, &size, file)==0)
+ if (getline(&line, &size, file)<=0)
return;
fclose(file);
if (line && line[0]=='0') {
@@ -323,7 +323,7 @@ static void do_one_cpu(char *path)
if (file) {
char *line = NULL;
size_t size = 0;
@ -37,7 +48,7 @@ index 0dbb5c8..51ef357 100644
cpumask_parse_user(line, strlen(line), package_mask);
fclose(file);
free(line);
@@ -336,7 +336,7 @@ static void do_one_cpu(char *path)
@@ -335,7 +335,7 @@ static void do_one_cpu(char *path)
if (file) {
char *line = NULL;
size_t size = 0;
@ -46,7 +57,7 @@ index 0dbb5c8..51ef357 100644
packageid = strtoul(line, NULL, 10);
fclose(file);
free(line);
@@ -369,7 +369,7 @@ static void do_one_cpu(char *path)
@@ -368,7 +368,7 @@ static void do_one_cpu(char *path)
if (file) {
char *line = NULL;
size_t size = 0;
@ -56,10 +67,10 @@ index 0dbb5c8..51ef357 100644
fclose(file);
free(line);
diff --git a/procinterrupts.c b/procinterrupts.c
index 18b3ceb..c32c1b2 100644
index 3898b10..03b4593 100644
--- a/procinterrupts.c
+++ b/procinterrupts.c
@@ -236,7 +236,7 @@ GList* collect_full_irq_list()
@@ -161,7 +161,7 @@ GList* collect_full_irq_list()
return NULL;
/* first line is the header we don't need; nuke it */
@ -68,7 +79,7 @@ index 18b3ceb..c32c1b2 100644
free(line);
fclose(file);
return NULL;
@@ -248,7 +248,7 @@ GList* collect_full_irq_list()
@@ -174,7 +174,7 @@ GList* collect_full_irq_list()
char *c;
char *savedline = NULL;
@ -77,7 +88,7 @@ index 18b3ceb..c32c1b2 100644
break;
/* lines with letters in front are special, like NMI count. Ignore */
@@ -308,7 +308,7 @@ void parse_proc_interrupts(void)
@@ -248,7 +248,7 @@ void parse_proc_interrupts(void)
return;
/* first line is the header we don't need; nuke it */
@ -86,7 +97,7 @@ index 18b3ceb..c32c1b2 100644
free(line);
fclose(file);
return;
@@ -325,7 +325,7 @@ void parse_proc_interrupts(void)
@@ -262,7 +262,7 @@ void parse_proc_interrupts(void)
struct irq_info *info;
char savedline[1024];
@ -95,7 +106,7 @@ index 18b3ceb..c32c1b2 100644
break;
if (!proc_int_has_msi)
@@ -579,7 +579,7 @@ void parse_proc_stat(void)
@@ -444,7 +444,7 @@ void parse_proc_stat(void)
}
/* first line is the header we don't need; nuke it */
@ -104,7 +115,7 @@ index 18b3ceb..c32c1b2 100644
free(line);
log(TO_ALL, LOG_WARNING, "WARNING read /proc/stat. balancing is broken\n");
fclose(file);
@@ -588,7 +588,7 @@ void parse_proc_stat(void)
@@ -453,7 +453,7 @@ void parse_proc_stat(void)
cpucount = 0;
while (!feof(file)) {
@ -114,5 +125,5 @@ index 18b3ceb..c32c1b2 100644
if (!strstr(line, "cpu"))
--
2.19.1
2.23.0

View File

@ -1,49 +0,0 @@
From 8ab70a85bbda79d47c8cc8e1c2767e1cb307f536 Mon Sep 17 00:00:00 2001
From: Neil Horman <nhorman@tuxdriver.com>
Date: Tue, 29 May 2018 11:07:32 -0400
Subject: [PATCH 085/112] parse_proc_interrupts: ensure that buffer is long
enough for a string
Instead of using strcpy to a save each line in /proc/interrupts, use
strdup and free to ensure that the buffer will hold the string
consistently, avoiding the gcc error that using a fixed size stack
variable triggers
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
---
procinterrupts.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/procinterrupts.c b/procinterrupts.c
index 1aa4413..4ef8751 100644
--- a/procinterrupts.c
+++ b/procinterrupts.c
@@ -170,7 +170,7 @@ GList* collect_full_irq_list()
int number;
struct irq_info *info;
char *c;
- char savedline[1024];
+ char *savedline = NULL;
if (getline(&line, &size, file)==0)
break;
@@ -186,7 +186,7 @@ GList* collect_full_irq_list()
if (!c)
continue;
- strncpy(savedline, line, sizeof(savedline));
+ savedline = strdup(line);
irq_name = strtok_r(savedline, " ", &savedptr);
last_token = strtok_r(NULL, " ", &savedptr);
while ((p = strtok_r(NULL, " ", &savedptr))) {
@@ -224,6 +224,7 @@ GList* collect_full_irq_list()
info->name = strdupa(irq_mod);
tmp_list = g_list_append(tmp_list, info);
}
+ free(savedline);
}
fclose(file);
free(line);
--
1.8.3.1

View File

@ -1,8 +1,8 @@
From f37fe357b21ffd7ab210b088c36300d9562406cb Mon Sep 17 00:00:00 2001
From: liuchao173 <liuchao173@huawei.com>
Date: Thu, 7 Nov 2019 09:26:30 +0000
Subject: [PATCH 4/8] backport: prevent NULL pointer dereference when memory
allocation failure
From 0e741b26246bf7bd5630812c551221d3f87f43d7 Mon Sep 17 00:00:00 2001
From: Yunfeng Ye <yeyunfeng@huawei.com>
Date: Mon, 7 Oct 2019 11:52:08 +0800
Subject: [PATCH 21/53] prevent NULL pointer dereference when memory allocation
failure
There are several places where memory allocation does not check return
values, adding null pointer checks.
@ -10,11 +10,11 @@ values, adding null pointer checks.
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
---
cputree.c | 2 ++
irqbalance.c | 20 ++++++++++++++++++++
2 files changed, 22 insertions(+)
irqbalance.c | 24 ++++++++++++++++++++++++
2 files changed, 26 insertions(+)
diff --git a/cputree.c b/cputree.c
index 91919ec..9cd2db8 100644
index a90cbbe..8b9413b 100644
--- a/cputree.c
+++ b/cputree.c
@@ -432,6 +432,8 @@ static void dump_irq(struct irq_info *info, void *data)
@ -27,10 +27,10 @@ index 91919ec..9cd2db8 100644
indent[i] = log_indent[0];
diff --git a/irqbalance.c b/irqbalance.c
index 93e4909..c9378d0 100644
index 8199c06..a06809c 100644
--- a/irqbalance.c
+++ b/irqbalance.c
@@ -326,6 +326,9 @@ void get_irq_data(struct irq_info *irq, void *data)
@@ -313,6 +313,9 @@ void get_irq_data(struct irq_info *irq, void *data)
else
*irqdata = realloc(*irqdata, strlen(*irqdata) + 24 + 1 + 11 + 20 + 20 + 11);
@ -40,7 +40,7 @@ index 93e4909..c9378d0 100644
sprintf(*irqdata + strlen(*irqdata),
"IRQ %d LOAD %lu DIFF %lu CLASS %d ", irq->irq, irq->load,
(irq->irq_count - irq->last_irq_count), irq->class);
@@ -357,6 +360,9 @@ void get_object_stat(struct topo_obj *object, void *data)
@@ -344,6 +347,9 @@ void get_object_stat(struct topo_obj *object, void *data)
*stats = realloc(*stats, strlen(*stats) + irqdlen + 31 + 11 + 20 + 11 + 1);
}
@ -50,7 +50,7 @@ index 93e4909..c9378d0 100644
sprintf(*stats + strlen(*stats), "TYPE %d NUMBER %d LOAD %lu SAVE_MODE %d %s",
object->obj_type, object->number, object->load,
object->powersave_mode, irq_data ? irq_data : "");
@@ -393,6 +399,10 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
@@ -380,6 +386,10 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
goto out_close;
}
cmsg = CMSG_FIRSTHDR(&msg);
@ -61,37 +61,41 @@ index 93e4909..c9378d0 100644
if ((cmsg->cmsg_level == SOL_SOCKET) &&
(cmsg->cmsg_type == SCM_CREDENTIALS)) {
struct ucred *credentials = (struct ucred *) CMSG_DATA(cmsg);
@@ -416,6 +426,8 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
@@ -403,6 +413,9 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
strlen("sleep ")))) {
char *sleep_string = malloc(
sizeof(char) * (recv_size - strlen("settings sleep ")));
+
+ if (!sleep_string)
+ goto out_close;
strncpy(sleep_string, buff + strlen("settings sleep "),
recv_size - strlen("settings sleep "));
int new_iterval = strtoul(sleep_string, NULL, 10);
@@ -428,6 +440,8 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
@@ -415,6 +428,9 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
char *end;
char *irq_string = malloc(
sizeof(char) * (recv_size - strlen("settings ban irqs ")));
+
+ if (!irq_string)
+ goto out_close;
strncpy(irq_string, buff + strlen("settings ban irqs "),
recv_size - strlen("settings ban irqs "));
g_list_free_full(cl_banned_irqs, free);
@@ -446,6 +460,8 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
@@ -433,6 +449,9 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
strlen("cpus")))) {
char *cpu_ban_string = malloc(
sizeof(char) * (recv_size - strlen("settings cpus ")));
+
+ if (!cpu_ban_string)
+ goto out_close;
strncpy(cpu_ban_string, buff + strlen("settings cpus "),
recv_size - strlen("settings cpus "));
banned_cpumask_from_ui = strtok(cpu_ban_string, " ");
@@ -459,12 +475,16 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
@@ -446,12 +465,17 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri
if (!strncmp(buff, "setup", strlen("setup"))) {
char banned[512];
char *setup = calloc(strlen("SLEEP ") + 11 + 1, 1);
+
+ if (!setup)
+ goto out_close;
snprintf(setup, strlen("SLEEP ") + 11 + 1, "SLEEP %d ", sleep_interval);
@ -106,4 +110,5 @@ index 93e4909..c9378d0 100644
"BANNED %s", banned);
send(sock, setup, strlen(setup), 0);
--
2.19.1
2.23.0

View File

@ -1,72 +0,0 @@
From 0ba1d8a59e209cef20955b8437989e730cd19cb3 Mon Sep 17 00:00:00 2001
From: Xiao Liang <xiliang@redhat.com>
Date: Thu, 18 Oct 2018 21:50:33 +0800
Subject: [PATCH 099/112] procinterrupts: check xen-dyn-event more flexible
In current /proc/interrupts, the 'xen-dyn-event' was split to 'xen-dyn -event'.
It causes interrupts not balanced inside xen guest.
Below result is without this patch:
70: 29 0 0 0 xen-dyn -event vif0-q0-tx
71: 120 0 0 0 xen-dyn -event vif0-q0-rx
72: 586350 0 0 0 xen-dyn -event vif0-q1-tx
73: 44 0 0 0 xen-dyn -event vif0-q1-rx
74: 19 0 0 0 xen-dyn -event vif0-q2-tx
75: 179 0 0 0 xen-dyn -event vif0-q2-rx
76: 67 0 0 0 xen-dyn -event vif0-q3-tx
77: 299637 0 0 0 xen-dyn -event vif0-q3-rx
Below result is with this patch:
[root@dhcp-3-194 ~]# grep vif0 /proc/interrupts
70: 30 0 0 0 xen-dyn -event vif0-q0-tx
71: 305 0 11 0 xen-dyn -event vif0-q0-rx
72: 586354 0 27 0 xen-dyn -event vif0-q1-tx
73: 49 7 5 0 xen-dyn -event vif0-q1-rx
74: 27 0 0 509373 xen-dyn -event vif0-q2-tx
75: 420 0 5 0 xen-dyn -event vif0-q2-rx
76: 179 0 38 0 xen-dyn -event vif0-q3-tx
77: 299803 281433 0 0 xen-dyn -event vif0-q3-rx
Signed-off-by: Xiao Liang <xiliang@redhat.com>
---
procinterrupts.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/procinterrupts.c b/procinterrupts.c
index 7283998..2c8118a 100644
--- a/procinterrupts.c
+++ b/procinterrupts.c
@@ -168,6 +168,7 @@ GList* collect_full_irq_list()
while (!feof(file)) {
int number;
+ int is_xen_dyn = 0;
struct irq_info *info;
char *c;
char *savedline = NULL;
@@ -188,9 +189,13 @@ GList* collect_full_irq_list()
savedline = strdup(line);
irq_name = strtok_r(savedline, " ", &savedptr);
+ if (strstr(irq_name, "xen-dyn") != NULL)
+ is_xen_dyn = 1;
last_token = strtok_r(NULL, " ", &savedptr);
while ((p = strtok_r(NULL, " ", &savedptr))) {
irq_name = last_token;
+ if (strstr(irq_name, "xen-dyn") != NULL)
+ is_xen_dyn = 1;
last_token = p;
}
@@ -210,7 +215,7 @@ GList* collect_full_irq_list()
info = calloc(sizeof(struct irq_info), 1);
if (info) {
info->irq = number;
- if (strstr(irq_name, "xen-dyn-event") != NULL) {
+ if (strstr(irq_name, "-event") != NULL && is_xen_dyn == 1) {
info->type = IRQ_TYPE_VIRT_EVENT;
info->class = IRQ_VIRT_EVENT;
} else {
--
1.8.3.1

View File

@ -0,0 +1,33 @@
From 4c22b5fa6009a2f7262801925105749aee9ff0bc Mon Sep 17 00:00:00 2001
From: Yunfeng Ye <yeyunfeng@huawei.com>
Date: Thu, 24 Oct 2019 21:51:54 +0800
Subject: [PATCH 29/53] reduce redundant check in add_missing_irq()
get_irq_info() is invoked in add_new_irq(), it is unnecessary to invoke
again in add_missing_irq().
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
---
classify.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/classify.c b/classify.c
index 81ad8a6..7454c5f 100644
--- a/classify.c
+++ b/classify.c
@@ -744,11 +744,9 @@ static void add_new_irq(int irq, struct irq_info *hint, GList *proc_interrupts)
static void add_missing_irq(struct irq_info *info, void *attr)
{
- struct irq_info *lookup = get_irq_info(info->irq);
GList *proc_interrupts = (GList *) attr;
- if (!lookup)
- add_new_irq(info->irq, info, proc_interrupts);
+ add_new_irq(info->irq, info, proc_interrupts);
}
static void free_tmp_irqs(gpointer data)
--
2.23.0

View File

@ -0,0 +1,347 @@
From c7122666e0f72634512284fe90258daf1dca5914 Mon Sep 17 00:00:00 2001
From: Yunfeng Ye <yeyunfeng@huawei.com>
Date: Sat, 12 Oct 2019 12:00:59 +0800
Subject: [PATCH 24/53] reduce redundant code for file processing
There are some redundant codes about file processing which with the same
logic. so abstract the same logic to the one function, and invoke it
where it need.
A different is that in add_one_node(), not return if fopen() fail, and
remove the ferror() judgement, I think it has no effect.
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
---
activate.c | 14 +-----
classify.c | 21 ++------
cputree.c | 132 +++++++++++++++++++++++----------------------------
irqbalance.h | 3 ++
numa.c | 24 ++--------
5 files changed, 71 insertions(+), 123 deletions(-)
diff --git a/activate.c b/activate.c
index 2812976..ab9702d 100644
--- a/activate.c
+++ b/activate.c
@@ -36,22 +36,10 @@ static int check_affinity(struct irq_info *info, cpumask_t applied_mask)
{
cpumask_t current_mask;
char buf[PATH_MAX];
- char *line = NULL;
- size_t size = 0;
- FILE *file;
sprintf(buf, "/proc/irq/%i/smp_affinity", info->irq);
- file = fopen(buf, "r");
- if (!file)
+ if (process_one_line(buf, get_mask_from_bitmap, &current_mask) < 0)
return 1;
- if (getline(&line, &size, file)<=0) {
- free(line);
- fclose(file);
- return 1;
- }
- cpumask_parse_user(line, strlen(line), current_mask);
- fclose(file);
- free(line);
return cpus_equal(applied_mask, current_mask);
}
diff --git a/classify.c b/classify.c
index be1ad0c..c1ac230 100644
--- a/classify.c
+++ b/classify.c
@@ -350,10 +350,7 @@ static struct irq_info *add_one_irq_to_db(const char *devpath, struct irq_info *
int numa_node;
char path[PATH_MAX];
FILE *fd;
- char *lcpu_mask;
GList *entry;
- ssize_t ret;
- size_t blen;
/*
* First check to make sure this isn't a duplicate entry
@@ -409,23 +406,11 @@ get_numa_node:
else
new->numa_node = get_numa_node(numa_node);
+ cpus_setall(new->cpumask);
+
sprintf(path, "%s/local_cpus", devpath);
- fd = fopen(path, "r");
- if (!fd) {
- cpus_setall(new->cpumask);
- goto out;
- }
- lcpu_mask = NULL;
- ret = getline(&lcpu_mask, &blen, fd);
- fclose(fd);
- if (ret <= 0) {
- cpus_setall(new->cpumask);
- } else {
- cpumask_parse_user(lcpu_mask, ret, new->cpumask);
- }
- free(lcpu_mask);
+ process_one_line(path, get_mask_from_bitmap, &new->cpumask);
-out:
log(TO_CONSOLE, LOG_INFO, "Adding IRQ %d to database\n", irq);
return new;
}
diff --git a/cputree.c b/cputree.c
index 8b9413b..acf6a47 100644
--- a/cputree.c
+++ b/cputree.c
@@ -59,6 +59,37 @@ cpumask_t cpu_possible_map;
*/
cpumask_t unbanned_cpus;
+int process_one_line(char *path, void (*cb)(char *line, void *data), void *data)
+{
+ FILE *file;
+ char *line = NULL;
+ size_t size = 0;
+ int ret = -1;
+
+ file = fopen(path, "r");
+ if (!file)
+ return ret;
+
+ if (getline(&line, &size, file) > 0) {
+ cb(line, data);
+ ret = 0;
+ }
+ free(line);
+ fclose(file);
+ return ret;
+}
+
+void get_mask_from_bitmap(char *line, void *mask)
+{
+ cpumask_parse_user(line, strlen(line), *(cpumask_t *)mask);
+}
+
+static void get_mask_from_cpulist(char *line, void *mask)
+{
+ if (strlen(line) && line[0] != '\n')
+ cpulist_parse(line, strlen(line), *(cpumask_t *)mask);
+}
+
/*
* By default do not place IRQs on CPUs the kernel keeps isolated or
* nohz_full, as specified through the boot commandline. Users can
@@ -66,9 +97,7 @@ cpumask_t unbanned_cpus;
*/
static void setup_banned_cpus(void)
{
- FILE *file;
- char *line = NULL;
- size_t size = 0;
+ char *path = NULL;
char buffer[4096];
cpumask_t nohz_full;
cpumask_t isolated_cpus;
@@ -86,29 +115,12 @@ static void setup_banned_cpus(void)
cpumask_parse_user(getenv("IRQBALANCE_BANNED_CPUS"), strlen(getenv("IRQBALANCE_BANNED_CPUS")), banned_cpus);
goto out;
}
- file = fopen("/sys/devices/system/cpu/isolated", "r");
- if (file) {
- if (getline(&line, &size, file) > 0) {
- if (strlen(line) && line[0] != '\n')
- cpulist_parse(line, strlen(line), isolated_cpus);
- }
- free(line);
- line = NULL;
- size = 0;
- fclose(file);
- }
- file = fopen("/sys/devices/system/cpu/nohz_full", "r");
- if (file) {
- if (getline(&line, &size, file) > 0) {
- if (strlen(line) && line[0] != '\n')
- cpulist_parse(line, strlen(line), nohz_full);
- }
- free(line);
- line = NULL;
- size = 0;
- fclose(file);
- }
+ path = "/sys/devices/system/cpu/isolated";
+ process_one_line(path, get_mask_from_cpulist, &isolated_cpus);
+
+ path = "/sys/devices/system/cpu/nohz_full";
+ process_one_line(path, get_mask_from_cpulist, &nohz_full);
cpus_or(banned_cpus, nohz_full, isolated_cpus);
@@ -258,11 +270,24 @@ static struct topo_obj* add_cpu_to_cache_domain(struct topo_obj *cpu,
return cache;
}
+static void get_offline_status(char *line, void *data)
+{
+ int *status = (int *)data;
+
+ *status = (line && line[0] == '0') ? 1 : 0;
+}
+
+static void get_packageid(char *line, void *data)
+{
+ int *packageid = (int *)data;
+
+ *packageid = strtoul(line, NULL, 10);
+}
+
#define ADJ_SIZE(r,s) PATH_MAX-strlen(r)-strlen(#s)
static void do_one_cpu(char *path)
{
struct topo_obj *cpu;
- FILE *file;
char new_path[PATH_MAX];
cpumask_t cache_mask, package_mask;
struct topo_obj *cache;
@@ -271,21 +296,13 @@ static void do_one_cpu(char *path)
int nodeid;
int packageid = 0;
unsigned int max_cache_index, cache_index, cache_stat;
- int ret = 1;
+ int offline_status = 0;
/* skip offline cpus */
snprintf(new_path, ADJ_SIZE(path,"/online"), "%s/online", path);
- file = fopen(new_path, "r");
- if (file) {
- char *line = NULL;
- size_t size = 0;
- if (getline(&line, &size, file)>0)
- ret = (line && line[0]=='0') ? 1 : 0;
- fclose(file);
- free(line);
- if (ret)
- return;
- }
+ process_one_line(new_path, get_offline_status, &offline_status);
+ if (offline_status)
+ return;
cpu = calloc(sizeof(struct topo_obj), 1);
if (!cpu)
@@ -313,36 +330,17 @@ static void do_one_cpu(char *path)
return;
}
+ cpu_set(cpu->number, package_mask);
/* try to read the package mask; if it doesn't exist assume solitary */
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) {
- char *line = NULL;
- size_t size = 0;
- if (getline(&line, &size, file) > 0)
- cpumask_parse_user(line, strlen(line), package_mask);
- fclose(file);
- free(line);
- line = NULL;
- size = 0;
- }
+ process_one_line(new_path, get_mask_from_bitmap, &package_mask);
+
/* try to read the package id */
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;
- size_t size = 0;
- if (getline(&line, &size, file) > 0)
- packageid = strtoul(line, NULL, 10);
- fclose(file);
- free(line);
- line = NULL;
- size = 0;
- }
+ process_one_line(new_path, get_packageid, &packageid);
/* try to read the cache mask; if it doesn't exist assume solitary */
/* We want the deepest cache level available */
@@ -367,17 +365,7 @@ static void do_one_cpu(char *path)
/* 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;
- size_t size = 0;
- if (getline(&line, &size, file) > 0)
- cpumask_parse_user(line, strlen(line), cache_mask);
- fclose(file);
- free(line);
- line = NULL;
- size = 0;
- }
+ process_one_line(new_path, get_mask_from_bitmap, &cache_mask);
}
nodeid=-1;
diff --git a/irqbalance.h b/irqbalance.h
index 5895e34..a3e561e 100644
--- a/irqbalance.h
+++ b/irqbalance.h
@@ -160,5 +160,8 @@ extern unsigned int log_mask;
#define SOCKET_PATH "irqbalance"
#define SOCKET_TMPFS "/run/irqbalance/"
+extern int process_one_line(char *path, void (*cb)(char *line, void *data), void *data);
+extern void get_mask_from_bitmap(char *line, void *mask);
+
#endif /* __INCLUDE_GUARD_IRQBALANCE_H_ */
diff --git a/numa.c b/numa.c
index 542e1f4..f1284da 100644
--- a/numa.c
+++ b/numa.c
@@ -56,31 +56,15 @@ static void add_one_node(const char *nodename)
{
char path[PATH_MAX];
struct topo_obj *new;
- char *cpustr = NULL;
- FILE *f;
- ssize_t ret;
- size_t blen;
new = calloc(1, sizeof(struct topo_obj));
if (!new)
return;
+
+ cpus_clear(new->mask);
sprintf(path, "%s/%s/cpumap", SYSFS_NODE_PATH, nodename);
- f = fopen(path, "r");
- if (!f) {
- free(new);
- return;
- }
- if (ferror(f)) {
- cpus_clear(new->mask);
- } else {
- ret = getline(&cpustr, &blen, f);
- if (ret <= 0)
- cpus_clear(new->mask);
- else
- cpumask_parse_user(cpustr, ret, new->mask);
- free(cpustr);
- }
- fclose(f);
+ process_one_line(path, get_mask_from_bitmap, &new->mask);
+
new->obj_type = OBJ_TYPE_NODE;
new->number = strtoul(&nodename[4], NULL, 10);
new->obj_type_list = &numa_nodes;
--
2.23.0

View File

@ -0,0 +1,25 @@
From 83917c1c266ee2c3b3f948fc7785d5ff73d3b297 Mon Sep 17 00:00:00 2001
From: liuchao173 <55137861+liuchao173@users.noreply.github.com>
Date: Mon, 21 Oct 2019 19:41:49 +0800
Subject: [PATCH 27/53] remove "c++;" in parse_proc_interrupts
in parse_proc_interrupts, just get irq's name. After "*c = 0", characters after ":" in line and c are useless. There is no need to let c increase.
---
procinterrupts.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/procinterrupts.c b/procinterrupts.c
index 4a7a5d5..29b0fef 100644
--- a/procinterrupts.c
+++ b/procinterrupts.c
@@ -212,7 +212,6 @@ GList* collect_full_irq_list()
irq_mod = last_token;
*c = 0;
- c++;
number = strtoul(line, NULL, 10);
info = calloc(sizeof(struct irq_info), 1);
--
2.23.0

View File

@ -0,0 +1,55 @@
From 9e6048da9767b9695d3bd5d95bfa604a358b2cf2 Mon Sep 17 00:00:00 2001
From: liuchao173 <55137861+liuchao173@users.noreply.github.com>
Date: Fri, 20 Sep 2019 10:15:51 +0800
Subject: [PATCH 15/53] remove unused path in check_for_irq_ban
that path variable is actually unused in check_for_irq_ban. And in build_one_dev_entry, sometimes the path is a file, sometimes it's a path. So remove the path variable entirely.
---
classify.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/classify.c b/classify.c
index 9b0177d..15d0ab2 100644
--- a/classify.c
+++ b/classify.c
@@ -599,7 +599,7 @@ static int check_for_module_ban(char *name)
return 0;
}
-static int check_for_irq_ban(char *path __attribute__((unused)), int irq, GList *proc_interrupts)
+static int check_for_irq_ban(int irq, GList *proc_interrupts)
{
struct irq_info find, *res;
GList *entry;
@@ -658,7 +658,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(irqnum, tmp_irqs))) {
add_banned_irq(irqnum, &banned_irqs);
continue;
}
@@ -692,8 +692,8 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
new = get_irq_info(irqnum);
if (new)
goto done;
- get_irq_user_policy(devpath, irqnum, &pol);
- if ((pol.ban == 1) || (check_for_irq_ban(devpath, irqnum, tmp_irqs))) {
+ get_irq_user_policy(irqnum, &pol);
+ if ((pol.ban == 1) || (check_for_irq_ban(irqnum, tmp_irqs))) {
add_banned_irq(irqnum, &banned_irqs);
goto done;
}
@@ -745,7 +745,7 @@ static void add_new_irq(int irq, struct irq_info *hint, GList *proc_interrupts)
/* 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*/
+ if ((pol.ban == 1) || check_for_irq_ban(irq, proc_interrupts)) { /*FIXME*/
add_banned_irq(irq, &banned_irqs);
new = get_irq_info(irq);
} else
--
2.23.0

View File

@ -1,7 +1,7 @@
From cfe3d10d37e44be4bb94cb715dbe6fde9e8a60ff Mon Sep 17 00:00:00 2001
From: Pyxisha <xiashuang1@huawei.com>
Date: Mon, 15 Jul 2019 10:44:50 +0800
Subject: [PATCH 01/48] some variable and judgement are unnecessary in
Subject: [PATCH 04/53] some variable and judgement are unnecessary in
activate_mappings
sign_off_by Shuang Xia <xiashuang1@huawei.com>
@ -54,5 +54,5 @@ index 8fd3dd0..8fd9bde 100644
fclose(file);
info->moved = 0; /*migration is done*/
--
2.21.0.windows.1
2.23.0

View File

@ -1,7 +1,7 @@
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
From 0c097c000e6af0f317c54ef1ded53610ec54194d Mon Sep 17 00:00:00 2001
From: x00456305 <xiashuang1@huawei.com>
Date: Thu, 11 Jul 2019 16:08:08 +0800
Subject: [PATCH 03/53] use policy prior to the default values
Currently user-defined policies against non-PCI devices' interrupts
are not working properly.
@ -13,16 +13,17 @@ 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: Shuang Xia <xiashuang1@huawei.com>
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
index 8a0dc14..f40ea99 100644
--- a/classify.c
+++ b/classify.c
@@ -342,10 +342,10 @@ void add_cl_banned_module(char *modname)
@@ -343,10 +343,10 @@ void add_cl_banned_module(char *modname)
* related device. NULL devpath means no sysfs entries for
* this irq.
*/
@ -36,7 +37,7 @@ index df8a89b..9868633 100644
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
@@ -358,8 +358,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
*/
@ -46,7 +47,7 @@ index df8a89b..9868633 100644
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
@@ -375,23 +374,24 @@ static struct irq_info *add_one_irq_to_db(const char *devpath, int irq, struct u
return NULL;
new->irq = irq;
@ -75,7 +76,7 @@ index df8a89b..9868633 100644
get_numa_node:
numa_node = -1;
@@ -611,13 +611,16 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
@@ -634,13 +634,16 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
DIR *msidir;
FILE *fd;
int irqnum;
@ -93,7 +94,7 @@ index df8a89b..9868633 100644
msidir = opendir(path);
@@ -636,10 +639,11 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
@@ -659,10 +662,11 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
add_banned_irq(irqnum, &banned_irqs);
continue;
}
@ -107,7 +108,7 @@ index df8a89b..9868633 100644
}
} while (entry != NULL);
closedir(msidir);
@@ -671,10 +675,11 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
@@ -694,10 +698,11 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs)
goto done;
}
@ -121,7 +122,7 @@ index df8a89b..9868633 100644
}
done:
@@ -721,22 +726,10 @@ static void add_new_irq(int irq, struct irq_info *hint, GList *proc_interrupts)
@@ -744,22 +749,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
@ -147,5 +148,5 @@ index df8a89b..9868633 100644
static void add_missing_irq(struct irq_info *info, void *attr)
--
1.8.3.1
2.23.0

View File

@ -0,0 +1,40 @@
From 083c99d9bfaf8a0a04ea533bb2a17457d56945ec Mon Sep 17 00:00:00 2001
From: liuchao173 <55137861+liuchao173@users.noreply.github.com>
Date: Mon, 21 Oct 2019 19:15:11 +0800
Subject: [PATCH 26/53] when devpath is NULL, skip reading files
If devpath is NULL, read devpath/numa_node and devpath/local_cpus will fail. So just skip it. The old code won't cause any bugs.
---
classify.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/classify.c b/classify.c
index 550f3b6..81ad8a6 100644
--- a/classify.c
+++ b/classify.c
@@ -392,7 +392,7 @@ static struct irq_info *add_one_irq_to_db(const char *devpath, struct irq_info *
get_numa_node:
numa_node = -1;
- if (numa_avail) {
+ if (devpath != NULL && numa_avail) {
sprintf(path, "%s/numa_node", devpath);
fd = fopen(path, "r");
if (fd) {
@@ -407,9 +407,10 @@ get_numa_node:
new->numa_node = get_numa_node(numa_node);
cpus_setall(new->cpumask);
-
- sprintf(path, "%s/local_cpus", devpath);
- process_one_line(path, get_mask_from_bitmap, &new->cpumask);
+ if (devpath != NULL) {
+ sprintf(path, "%s/local_cpus", devpath);
+ process_one_line(path, get_mask_from_bitmap, &new->cpumask);
+ }
log(TO_CONSOLE, LOG_INFO, "Adding IRQ %d to database\n", irq);
return new;
--
2.23.0