From aa0afbee66021157d091b5cbe708ca5813f49999 Mon Sep 17 00:00:00 2001 From: overweight <5324761+overweight@user.noreply.gitee.com> Date: Mon, 30 Sep 2019 10:53:30 -0400 Subject: [PATCH] Package init --- ...t-leak-socket-fd-on-connection-error.patch | 53 ++ ...guous-parsing-of-node-entries-in-sys.patch | 73 ++ Fix-an-possible-overflow-error.patch | 34 + ...al-memleak-problems-found-by-covscan.patch | 253 ++++++ Fix-some-string-copy-limitations.patch | 58 ++ ...-truncation-issues-detected-by-GCC-8.patch | 37 + add-a-catchall-guessing-mechanis.patch | 52 ++ ...-fgets-will-get-a-redundant-new-line.patch | 50 ++ ...-fix-a-hole-that-flees-hotplug-event.patch | 30 + bugfix-fix-two-same-irq-insert-to-list.patch | 81 ++ ...list-when-irq-removed-and-reinserted.patch | 472 ++++++++++ bugfix-guess_arm_irq_hints.patch | 30 + ...ance-fix-wrong-pid-value-in-pid-file.patch | 123 +++ ...g-a-duplicate-entry-to-avoid-list-ch.patch | 108 +++ ...e-policy-prior-to-the-default-values.patch | 151 ++++ classify-remove-unused-label.patch | 28 + ...snprintf-sizes-to-avoid-gcc-warnings.patch | 91 ++ ...-add-new-user-irq-policy-config-rule.patch | 476 ++++++++++ ...-verifyhint-to-detect-hint-variation.patch | 506 +++++++++++ ...ce-Add-ability-for-socket-communicat.patch | 826 ++++++++++++++++++ ...ce-aarch64-add-the-regular-to-get-th.patch | 83 ++ ...lance-arm64-Add-irq-aff-change-check.patch | 131 +++ ...balance-auto-banned-pci-assigned-irq.patch | 345 ++++++++ ...supplement-irqbalance-service-config.patch | 36 + ...hen-numa-information-isn-t-available.patch | 105 +++ irq_balancer | 43 + ...l-entirely-if-we-don-t-have-a-pci-bu.patch | 86 ++ irqbalance-1.0.4-env-file-path.patch | 12 + irqbalance-1.4.0.tar.gz | Bin 0 -> 53431 bytes ...upport-for-file-based-socket-for-IPC.patch | 105 +++ irqbalance.rules | 2 + irqbalance.spec | 141 +++ irqbalance.sysconfig | 39 + ...rupts-ensure-that-buffer-is-long-eno.patch | 49 ++ ...ts-check-xen-dyn-event-more-flexible.patch | 72 ++ 35 files changed, 4781 insertions(+) create mode 100644 Don-t-leak-socket-fd-on-connection-error.patch create mode 100644 Fix-ambiguous-parsing-of-node-entries-in-sys.patch create mode 100644 Fix-an-possible-overflow-error.patch create mode 100644 Fix-several-memleak-problems-found-by-covscan.patch create mode 100644 Fix-some-string-copy-limitations.patch create mode 100644 Fix-string-truncation-issues-detected-by-GCC-8.patch create mode 100644 add-a-catchall-guessing-mechanis.patch create mode 100644 bugfix-fgets-will-get-a-redundant-new-line.patch create mode 100644 bugfix-fix-a-hole-that-flees-hotplug-event.patch create mode 100644 bugfix-fix-two-same-irq-insert-to-list.patch create mode 100644 bugfix-force-irq-into-rebalance-list-when-irq-removed-and-reinserted.patch create mode 100644 bugfix-guess_arm_irq_hints.patch create mode 100644 bugfix-irqbalance-fix-wrong-pid-value-in-pid-file.patch create mode 100644 bugfix-prevent-inserting-a-duplicate-entry-to-avoid-list-ch.patch create mode 100644 bugfix-use-policy-prior-to-the-default-values.patch create mode 100644 classify-remove-unused-label.patch create mode 100644 cputree-adjust-snprintf-sizes-to-avoid-gcc-warnings.patch create mode 100644 feature-add-new-user-irq-policy-config-rule.patch create mode 100644 feature-introduce-verifyhint-to-detect-hint-variation.patch create mode 100644 feature-irqbalance-Add-ability-for-socket-communicat.patch create mode 100644 feature-irqbalance-aarch64-add-the-regular-to-get-th.patch create mode 100644 feature-irqbalance-arm64-Add-irq-aff-change-check.patch create mode 100644 feature-irqbalance-auto-banned-pci-assigned-irq.patch create mode 100644 feature-supplement-irqbalance-service-config.patch create mode 100644 fix-balancing-when-numa-information-isn-t-available.patch create mode 100644 irq_balancer create mode 100644 irq_db-don-t-fail-entirely-if-we-don-t-have-a-pci-bu.patch create mode 100644 irqbalance-1.0.4-env-file-path.patch create mode 100644 irqbalance-1.4.0.tar.gz create mode 100644 irqbalance-Add-support-for-file-based-socket-for-IPC.patch create mode 100644 irqbalance.rules create mode 100644 irqbalance.spec create mode 100644 irqbalance.sysconfig create mode 100644 parse_proc_interrupts-ensure-that-buffer-is-long-eno.patch create mode 100644 procinterrupts-check-xen-dyn-event-more-flexible.patch diff --git a/Don-t-leak-socket-fd-on-connection-error.patch b/Don-t-leak-socket-fd-on-connection-error.patch new file mode 100644 index 0000000..b0ea204 --- /dev/null +++ b/Don-t-leak-socket-fd-on-connection-error.patch @@ -0,0 +1,53 @@ +From f2623176c2997e7803d485084fa5150556caddcf Mon Sep 17 00:00:00 2001 +From: Kairui Song +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 +--- + irqbalance.c | 7 ++++--- + ui/irqbalance-ui.c | 1 + + 2 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/irqbalance.c b/irqbalance.c +index 0946603..364ca72 100644 +--- a/irqbalance.c ++++ b/irqbalance.c +@@ -376,7 +376,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri + } + if ((recv_size = recvmsg(sock, &msg, 0)) < 0) { + log(TO_ALL, LOG_WARNING, "Error while receiving data.\n"); +- goto out; ++ goto out_close; + } + cmsg = CMSG_FIRSTHDR(&msg); + if ((cmsg->cmsg_level == SOL_SOCKET) && +@@ -388,7 +388,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri + } + if (!valid_user) { + log(TO_ALL, LOG_INFO, "Permission denied for user to connect to socket.\n"); +- goto out; ++ goto out_close; + } + + if (!strncmp(buff, "stats", strlen("stats"))) { +@@ -421,7 +421,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri + need_rescan = 1; + if (!strncmp(irq_string, "NONE", strlen("NONE"))) { + free(irq_string); +- goto out; ++ goto out_close; + } + int irq = strtoul(irq_string, &end, 10); + do { +@@ -457,6 +457,7 @@ gboolean sock_handle(gint fd, GIOCondition condition, gpointer user_data __attri + free(setup); + } + ++out_close: + close(sock); + } + +-- +1.8.3.1 + diff --git a/Fix-ambiguous-parsing-of-node-entries-in-sys.patch b/Fix-ambiguous-parsing-of-node-entries-in-sys.patch new file mode 100644 index 0000000..eb68d23 --- /dev/null +++ b/Fix-ambiguous-parsing-of-node-entries-in-sys.patch @@ -0,0 +1,73 @@ +From 721460664afad79e2d96bbcb173eda68eed9743b Mon Sep 17 00:00:00 2001 +From: Gerd Rausch +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 +--- + 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 + #include + #include ++#include + #include + #include + +@@ -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 + diff --git a/Fix-an-possible-overflow-error.patch b/Fix-an-possible-overflow-error.patch new file mode 100644 index 0000000..2a56e3a --- /dev/null +++ b/Fix-an-possible-overflow-error.patch @@ -0,0 +1,34 @@ +From 702cab67df2bafd9735a753387eae7febd74263b Mon Sep 17 00:00:00 2001 +From: Kairui Song +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 + diff --git a/Fix-several-memleak-problems-found-by-covscan.patch b/Fix-several-memleak-problems-found-by-covscan.patch new file mode 100644 index 0000000..91c4d0b --- /dev/null +++ b/Fix-several-memleak-problems-found-by-covscan.patch @@ -0,0 +1,253 @@ +From 85d37098a551034061d4b77be275d664e109c3fb Mon Sep 17 00:00:00 2001 +From: Kairui Song +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 + diff --git a/Fix-some-string-copy-limitations.patch b/Fix-some-string-copy-limitations.patch new file mode 100644 index 0000000..852d5c9 --- /dev/null +++ b/Fix-some-string-copy-limitations.patch @@ -0,0 +1,58 @@ +From d6abbe898baa111207e1e9316dde75c38d555325 Mon Sep 17 00:00:00 2001 +From: Neil Horman +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 +--- + 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 + diff --git a/Fix-string-truncation-issues-detected-by-GCC-8.patch b/Fix-string-truncation-issues-detected-by-GCC-8.patch new file mode 100644 index 0000000..c07ad53 --- /dev/null +++ b/Fix-string-truncation-issues-detected-by-GCC-8.patch @@ -0,0 +1,37 @@ +From 8adbe9aacb93c5a160f3ecfc00adc10a64d27c14 Mon Sep 17 00:00:00 2001 +From: Sekhar Nori +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 +--- + irqbalance.c | 2 +- + ui/irqbalance-ui.c | 5 ++--- + 2 files changed, 3 insertions(+), 4 deletions(-) + +diff --git a/irqbalance.c b/irqbalance.c +index 60d8a5e..c1a0e15 100644 +--- a/irqbalance.c ++++ b/irqbalance.c +@@ -482,7 +482,7 @@ int init_socket() + */ + addr.sun_family = AF_UNIX; + snprintf(socket_name, 64, "%s/%s%d.sock", SOCKET_TMPFS, SOCKET_PATH, getpid()); +- strncpy(addr.sun_path, socket_name, strlen(socket_name)); ++ strncpy(addr.sun_path, socket_name, sizeof(addr.sun_path)); + if (bind(socket_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + log(TO_ALL, LOG_WARNING, "Daemon couldn't be bound to the file-based socket.\n"); + +-- +1.8.3.1 + diff --git a/add-a-catchall-guessing-mechanis.patch b/add-a-catchall-guessing-mechanis.patch new file mode 100644 index 0000000..f989c57 --- /dev/null +++ b/add-a-catchall-guessing-mechanis.patch @@ -0,0 +1,52 @@ +From 0906c9dcf1754bb2f32f9247608cc937650d2a0e Mon Sep 17 00:00:00 2001 +From: Neil Horman +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 +--- + 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 + diff --git a/bugfix-fgets-will-get-a-redundant-new-line.patch b/bugfix-fgets-will-get-a-redundant-new-line.patch new file mode 100644 index 0000000..ec6e270 --- /dev/null +++ b/bugfix-fgets-will-get-a-redundant-new-line.patch @@ -0,0 +1,50 @@ +From 0c8ecab9e6f5fae5860e7fbc795e988c112edede Mon Sep 17 00:00:00 2001 +From: xiashuang +Date: Thu, 25 Jul 2019 22:38:32 -0400 +Subject: [PATCH] fix fgets will get a redundant new line + +this patch fix a bug introduced by bugfix-force-irq-into-rebalance-list-when-irq-removed-and-reinserted.patch. +the previous patch use fgets to get a directory name from buffer. but fgets will get a redundant newline, +so the directory name are always invalid, this patch just remove the '\n'. +--- + classify.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/classify.c b/classify.c +index e61c39b..440576f 100644 +--- a/classify.c ++++ b/classify.c +@@ -747,6 +747,7 @@ void find_irq_dev_path(int irq, char *dirname, int length) + char path[PATH_MAX]; + char buffer[128]; + char *brc = NULL; ++ size_t dirlen; + + memset(dirname, 0, length); + /* Return defaults if irq is 0 */ +@@ -762,8 +763,10 @@ void find_irq_dev_path(int irq, char *dirname, int length) + } + + brc = fgets(buffer, 128, output); +- if (brc) { ++ /* fgets will get a redundant \n */ ++ if (brc && (dirlen = strcspn(brc, "\n")) > 0) { + log(TO_CONSOLE, LOG_INFO, "msi_irqs IRQ %d dirname is %s\n", irq, brc); ++ brc[dirlen] = '\0'; + strncpy(dirname, brc, length); + pclose(output); + return; +@@ -779,8 +782,9 @@ void find_irq_dev_path(int irq, char *dirname, int length) + } + + brc = fgets(buffer, 128, output); +- if (brc) { ++ if (brc && (dirlen = strcspn(brc, "\n")) > 0) { + log(TO_CONSOLE, LOG_INFO, "IRQ %d dirname is %s\n", irq, brc); ++ brc[dirlen] = '\0'; + strncpy(dirname, brc, length); + pclose(output); + return; +-- +1.8.3.1 + diff --git a/bugfix-fix-a-hole-that-flees-hotplug-event.patch b/bugfix-fix-a-hole-that-flees-hotplug-event.patch new file mode 100644 index 0000000..9429bef --- /dev/null +++ b/bugfix-fix-a-hole-that-flees-hotplug-event.patch @@ -0,0 +1,30 @@ +From 2c040ddc5869635598e4fbf5c63217f60fdef5f1 Mon Sep 17 00:00:00 2001 +From: xiashuang +Date: Sun, 17 Mar 2019 18:59:09 -0400 +Subject: [PATCH 2/4] huawei bugfix fix a hole that flees hotplug event + +from 1.0.9, original infoformation is missing +--- + irqbalance.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/irqbalance.c b/irqbalance.c +index 6412447..2f699b8 100644 +--- a/irqbalance.c ++++ b/irqbalance.c +@@ -284,9 +284,9 @@ gboolean scan(gpointer data) + for_each_irq(NULL, force_rebalance_irq, NULL); + parse_proc_interrupts(); + parse_proc_stat(); +- sleep_approx(sleep_interval); +- clear_work_stats(); +- parse_proc_interrupts(); ++ ++ /* Still need to check hotplugged or not next round */ ++ return TRUE; + } + + parse_proc_stat(); +-- +1.8.3.1 + diff --git a/bugfix-fix-two-same-irq-insert-to-list.patch b/bugfix-fix-two-same-irq-insert-to-list.patch new file mode 100644 index 0000000..f1aa574 --- /dev/null +++ b/bugfix-fix-two-same-irq-insert-to-list.patch @@ -0,0 +1,81 @@ +From 384cdfa4ef28415c3df50d1759951a20c6f0661f Mon Sep 17 00:00:00 2001 +From: caomeng +Date: Thu, 4 Jul 2019 03:47:20 +0800 +Subject: [PATCH] bugfix-fix-two-same-irq-insert-to-list + +When the function force_rebalance_irq is executed,the same irq may be added into +rebalance_irq_list again, resulting in failed irqbalance service. Thus, a function +named irq_in_rebalance_list which is used to check if the irq is in rebalance_irq_list +will be executed before force_rebalance_irq. And this patch fixex the bug introduced +by feature-introduce-verifyhint-to-detect-hint-variation.patch. + +--- + classify.c | 11 +++++++++++ + irqbalance.h | 2 +- + procinterrupts.c | 8 ++++++-- + 3 files changed, 18 insertions(+), 3 deletions(-) + +diff --git a/classify.c b/classify.c +index 0951c72..4d699da 100644 +--- a/classify.c ++++ b/classify.c +@@ -288,6 +288,17 @@ static void add_banned_irq(int irq, GList **list) + return; + } + ++int irq_in_rebalance_list(int irq) ++{ ++ GList *entry = NULL; ++ struct irq_info find = {0}; ++ ++ find.irq = irq; ++ entry = g_list_find_custom(rebalance_irq_list, &find, compare_ints); ++ ++ return entry ? 1 : 0; ++} ++ + void add_cl_banned_irq(int irq) + { + add_banned_irq(irq, &cl_banned_irqs); +diff --git a/irqbalance.h b/irqbalance.h +index 80ec017..821de0e 100644 +--- a/irqbalance.h ++++ b/irqbalance.h +@@ -107,7 +107,7 @@ extern void free_cl_opts(void); + extern void add_cl_banned_module(char *modname); + #define irq_numa_node(irq) ((irq)->numa_node) + extern void force_rebalance_irq(struct irq_info *info, void *data __attribute__((unused))); +- ++int irq_in_rebalance_list(int irq); + /* huawei */ + extern struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list); + extern void find_irq_dev_path(int irq, char *dirname, int length); +diff --git a/procinterrupts.c b/procinterrupts.c +index fc4641a..9e38e49 100644 +--- a/procinterrupts.c ++++ b/procinterrupts.c +@@ -348,7 +348,9 @@ void parse_proc_interrupts(void) + */ + if (count < info->irq_count) { + log(TO_CONSOLE, LOG_INFO, "Removed and reinserted IRQ %d added into rebalance list\n", number); +- force_rebalance_irq(info, NULL); ++ if (!irq_in_rebalance_list(info->irq)) { ++ force_rebalance_irq(info, NULL); ++ } + } + + info->last_irq_count = info->irq_count; +@@ -602,7 +604,9 @@ void update_affinity_hint(struct irq_info *info, void *data __attribute__((unuse + cpumask_parse_user(line, len, current_affinity_hint); + if (!cpus_equal(current_affinity_hint, info->affinity_hint)) { + cpumask_copy(info->affinity_hint, current_affinity_hint); +- force_rebalance_irq(info, data); ++ if (!irq_in_rebalance_list(info->irq)) { ++ force_rebalance_irq(info, data); ++ } + log(TO_ALL, LOG_INFO, "IRQ(%d): affinity hint modified\n", info->irq); + } + } +-- +1.8.3.1 + diff --git a/bugfix-force-irq-into-rebalance-list-when-irq-removed-and-reinserted.patch b/bugfix-force-irq-into-rebalance-list-when-irq-removed-and-reinserted.patch new file mode 100644 index 0000000..cf0cc1d --- /dev/null +++ b/bugfix-force-irq-into-rebalance-list-when-irq-removed-and-reinserted.patch @@ -0,0 +1,472 @@ +From 1ca314651ddc31cd52ef67893fdd7aac43ea5201 Mon Sep 17 00:00:00 2001 +From: zhengshaoyu +Date: Thu, 22 Jun 2017 04:39:00 +0000 +Subject: [PATCH] irqbalance: bugfix popen and pclose + +[Changelog]: bugfix popen and pclose +[Author]:zhengshaoyu + +Date: Sun, 17 Mar 2019 20:07:28 -0400 + +--- + classify.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++------- + irqbalance.c | 2 +- + irqbalance.h | 5 +++ + procinterrupts.c | 112 +++++++++++++++++++++++++++++++------------------ + types.h | 1 + + 5 files changed, 190 insertions(+), 56 deletions(-) + +diff --git a/classify.c b/classify.c +index 9868633..30a8d2a 100644 +--- a/classify.c ++++ b/classify.c +@@ -66,6 +66,8 @@ struct pci_info { + #define PCI_SUB_DEVICE_EMC_0568 0x0568 + #define PCI_SUB_DEVICE_EMC_dd00 0xdd00 + ++extern void force_rebalance_irq(struct irq_info *info, void *data __attribute__((unused))); ++ + /* + * Apply software workarounds for some special devices + * +@@ -562,11 +564,13 @@ static int check_for_irq_ban(char *path __attribute__((unused)), int irq, GList + /* + * Check to see if we banned module which the irq belongs to. + */ +- entry = g_list_find_custom(proc_interrupts, &find, compare_ints); +- if (entry) { +- res = entry->data; +- if (check_for_module_ban(res->name)) +- return 1; ++ if (proc_interrupts) { ++ entry = g_list_find_custom(proc_interrupts, &find, compare_ints); ++ if (entry) { ++ res = entry->data; ++ if (check_for_module_ban(res->name)) ++ return 1; ++ } + } + + #ifdef INCLUDE_BANSCRIPT +@@ -605,13 +609,14 @@ static int check_for_irq_ban(char *path __attribute__((unused)), int irq, GList + /* + * Figures out which interrupt(s) relate to the device we"re looking at in dirname + */ +-static void build_one_dev_entry(const char *dirname, GList *tmp_irqs) ++struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list) + { + struct dirent *entry; + DIR *msidir; + FILE *fd; + int irqnum; +- struct irq_info *new, hint; ++ struct irq_info *new = NULL; ++ struct irq_info hint; + char path[PATH_MAX]; + char devpath[PATH_MAX]; + struct user_irq_policy pol; +@@ -635,7 +640,7 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs) + if (new) + continue; + get_irq_user_policy(devpath, irqnum, &pol); +- if ((pol.ban == 1) || (check_for_irq_ban(devpath, irqnum, tmp_irqs))) { ++ if ((pol.ban == 1) || (check_for_irq_ban(devpath, irqnum, tmp_list))) { + add_banned_irq(irqnum, &banned_irqs); + continue; + } +@@ -647,13 +652,13 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs) + } + } while (entry != NULL); + closedir(msidir); +- return; ++ return new; + } + + sprintf(path, "%s/%s/irq", SYSPCI_DIR, dirname); + fd = fopen(path, "r"); + if (!fd) +- return; ++ return new; + if (fscanf(fd, "%d", &irqnum) < 0) + goto done; + +@@ -670,7 +675,7 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs) + if (new) + goto done; + get_irq_user_policy(devpath, irqnum, &pol); +- if ((pol.ban == 1) || (check_for_irq_ban(path, irqnum, tmp_irqs))) { ++ if ((pol.ban == 1) || (check_for_irq_ban(path, irqnum, tmp_list))) { + add_banned_irq(irqnum, &banned_irqs); + goto done; + } +@@ -684,7 +689,56 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs) + + done: + fclose(fd); +- return; ++ return new; ++} ++ ++void find_irq_dev_path(int irq, char *dirname, int length) ++{ ++ char cmd[PATH_MAX + 128]; ++ FILE *output = NULL; ++ char path[PATH_MAX]; ++ char buffer[128]; ++ char *brc = NULL; ++ ++ memset(dirname, 0, length); ++ /* Return defaults if irq is 0 */ ++ if (!irq) ++ return; ++ ++ sprintf(path, "%s/*/msi_irqs", SYSPCI_DIR); ++ sprintf(cmd, "exec find %s -type f -name %d | awk -F '/' '{print $6}' ", path, irq); ++ output = popen(cmd, "r"); ++ if (!output) { ++ log(TO_CONSOLE, LOG_WARNING, "Unable to execute IRQ %d path %s\n", irq, path); ++ return; ++ } ++ ++ brc = fgets(buffer, 128, output); ++ if (brc) { ++ log(TO_CONSOLE, LOG_INFO, "msi_irqs IRQ %d dirname is %s\n", irq, brc); ++ strncpy(dirname, brc, length); ++ pclose(output); ++ return; ++ } ++ pclose(output); ++ ++ sprintf(path, "%s/*/irq", SYSPCI_DIR); ++ sprintf(cmd, "exec grep -w %d %s | awk -F '/' '{print $6}' ", irq, path); ++ output = popen(cmd, "r"); ++ if (!output) { ++ log(TO_CONSOLE, LOG_WARNING, "Unable to execute IRQ %d path %s\n", irq, path); ++ return; ++ } ++ ++ brc = fgets(buffer, 128, output); ++ if (brc) { ++ log(TO_CONSOLE, LOG_INFO, "IRQ %d dirname is %s\n", irq, brc); ++ strncpy(dirname, brc, length); ++ pclose(output); ++ return; ++ } ++ pclose(output); ++ + } + + static void free_irq(struct irq_info *info, void *data __attribute__((unused))) +@@ -692,6 +750,42 @@ static void free_irq(struct irq_info *info, void *data __attribute__((unused))) + free(info); + } + ++static void remove_no_existing_irq(struct irq_info *info, void *data __attribute__((unused))) ++{ ++ GList *entry = NULL; ++ ++ if (info->existing) { ++ info->existing = 0; ++ return; ++ } ++ ++ entry = g_list_find_custom(interrupts_db, info, compare_ints); ++ if (entry) ++ interrupts_db = g_list_delete_link(interrupts_db, entry); ++ ++ entry = g_list_find_custom(banned_irqs, info, compare_ints); ++ if (entry) ++ banned_irqs = g_list_delete_link(banned_irqs, entry); ++ ++ entry = g_list_find_custom(rebalance_irq_list, info, compare_ints); ++ if (entry) ++ rebalance_irq_list = g_list_delete_link(rebalance_irq_list, entry); ++ ++ if(info->assigned_obj) { ++ entry = g_list_find_custom(info->assigned_obj->interrupts, info, compare_ints); ++ if (entry) { ++ info->assigned_obj->interrupts = g_list_delete_link(info->assigned_obj->interrupts, entry); ++ } ++ } ++ log(TO_CONSOLE, LOG_INFO, "IRQ %d is removed from interrupts_db.\n", info->irq); ++ free_irq(info, NULL); ++} ++ ++void clear_no_existing_irqs(void) ++{ ++ for_each_irq(NULL, remove_no_existing_irq, NULL); ++} ++ + void free_irq_db(void) + { + for_each_irq(NULL, free_irq, NULL); +@@ -711,14 +805,14 @@ void free_cl_opts(void) + g_list_free(banned_irqs); + } + +-static void add_new_irq(int irq, struct irq_info *hint, GList *proc_interrupts) ++struct irq_info *add_new_irq(int irq, struct irq_info *hint, GList *proc_interrupts) + { +- struct irq_info *new; ++ struct irq_info *new = NULL; + struct user_irq_policy pol; + + new = get_irq_info(irq); + if (new) +- return; ++ return new; + + /* Set NULL devpath for the irq has no sysfs entries */ + get_irq_user_policy(NULL, irq, &pol); +@@ -730,6 +824,8 @@ static void add_new_irq(int irq, struct irq_info *hint, GList *proc_interrupts) + + if (!new) + log(TO_CONSOLE, LOG_WARNING, "add_new_irq: Failed to add irq %d\n", irq); ++ ++ return new; + } + + static void add_missing_irq(struct irq_info *info, void *attr) +diff --git a/irqbalance.c b/irqbalance.c +index 2f699b8..e375a1a 100644 +--- a/irqbalance.c ++++ b/irqbalance.c +@@ -238,7 +238,7 @@ static void dump_object_tree(void) + for_each_object(numa_nodes, dump_numa_node_info, NULL); + } + +-static void force_rebalance_irq(struct irq_info *info, void *data __attribute__((unused))) ++void force_rebalance_irq(struct irq_info *info, void *data __attribute__((unused))) + { + if (info->level == BALANCE_NONE) + return; +diff --git a/irqbalance.h b/irqbalance.h +index 8d5b329..73737ed 100644 +--- a/irqbalance.h ++++ b/irqbalance.h +@@ -107,6 +107,11 @@ extern void free_cl_opts(void); + extern void add_cl_banned_module(char *modname); + #define irq_numa_node(irq) ((irq)->numa_node) + ++/* huawei */ ++extern struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list); ++extern void find_irq_dev_path(int irq, char *dirname, int length); ++extern struct irq_info *add_new_irq(int irq, struct irq_info *hint, GList *proc_interrupts); ++extern void clear_no_existing_irqs(void); + + /* + * Generic object functions +diff --git a/procinterrupts.c b/procinterrupts.c +index eb84a1c..d384860 100644 +--- a/procinterrupts.c ++++ b/procinterrupts.c +@@ -142,6 +142,52 @@ static void guess_arm_irq_hints(char *name, struct irq_info *info) + + } + #endif ++static void init_irq_class_and_type(char *savedline, struct irq_info *info, int irq) { ++ char *irq_name = NULL; ++ char *irq_mod = NULL; ++ char *savedptr = NULL; ++ char *last_token = NULL; ++ char *p = NULL; ++ int is_xen_dyn = 0; ++#ifdef AARCH64 ++ char *tmp = NULL; ++#endif ++ ++ irq_name = strtok_r(savedline, " ", &savedptr); ++ if (strstr(irq_name, "xen-dyn") != NULL) ++ is_xen_dyn = 1; ++ last_token = strtok_r(NULL, " ", &savedptr); ++ while ((p = strtok_r(NULL, " ", &savedptr))) { ++ irq_name = last_token; ++ if (strstr(irq_name, "xen-dyn") != NULL) ++ is_xen_dyn = 1; ++ last_token = p; ++ } ++ ++#ifdef AARCH64 ++ /* Of course the formatting for /proc/interrupts is different on different arches */ ++ irq_name = last_token; ++ tmp = strchr(irq_name, '\n'); ++ if (tmp) ++ *tmp = 0; ++#endif ++ irq_mod = last_token; ++ info->irq = irq; ++ ++ if (strstr(irq_name, "-event") != NULL && is_xen_dyn == 1) { ++ info->type = IRQ_TYPE_VIRT_EVENT; ++ info->class = IRQ_VIRT_EVENT; ++ } else { ++#ifdef AARCH64 ++ guess_arm_irq_hints(irq_name, info); ++#else ++ info->type = IRQ_TYPE_LEGACY; ++ info->class = IRQ_OTHER; ++#endif ++ } ++ info->name = strdupa(irq_mod); ++} ++ + + GList* collect_full_irq_list() + { +@@ -149,10 +187,6 @@ GList* collect_full_irq_list() + FILE *file; + char *line = NULL; + size_t size = 0; +- char *irq_name, *irq_mod, *savedptr, *last_token, *p; +-#ifdef AARCH64 +- char *tmp; +-#endif + + file = fopen("/proc/interrupts", "r"); + if (!file) +@@ -168,7 +206,6 @@ GList* collect_full_irq_list() + + while (!feof(file)) { + int number; +- int is_xen_dyn = 0; + struct irq_info *info; + char *c; + char *savedline = NULL; +@@ -186,45 +220,13 @@ GList* collect_full_irq_list() + continue; + + savedline = strdup(line); +- irq_name = strtok_r(savedline, " ", &savedptr); +- if (strstr(irq_name, "xen-dyn") != NULL) +- is_xen_dyn = 1; +- last_token = strtok_r(NULL, " ", &savedptr); +- while ((p = strtok_r(NULL, " ", &savedptr))) { +- irq_name = last_token; +- if (strstr(irq_name, "xen-dyn") != NULL) +- is_xen_dyn = 1; +- last_token = p; +- } +- +-#ifdef AARCH64 +- /* Of course the formatting for /proc/interrupts is different on different arches */ +- irq_name = last_token; +- tmp = strchr(irq_name, '\n'); +- if (tmp) +- *tmp = 0; +-#endif +- irq_mod = last_token; +- + *c = 0; + c++; + number = strtoul(line, NULL, 10); + + info = calloc(sizeof(struct irq_info), 1); + if (info) { +- info->irq = number; +- if (strstr(irq_name, "-event") != NULL && is_xen_dyn == 1) { +- info->type = IRQ_TYPE_VIRT_EVENT; +- info->class = IRQ_VIRT_EVENT; +- } else { +-#ifdef AARCH64 +- guess_arm_irq_hints(irq_name, info); +-#else +- info->type = IRQ_TYPE_LEGACY; +- info->class = IRQ_OTHER; +-#endif +- } +- info->name = strdupa(irq_mod); ++ init_irq_class_and_type(savedline, info, number); + tmp_list = g_list_append(tmp_list, info); + } + free(savedline); +@@ -230,6 +235,14 @@ GList* collect_full_irq_list() + return tmp_list; + } + ++/* parsing /proc/interrrupts to detect whether removed and reinserted IRQ ++* device happened or not. If yes, then IRQs have to be rescanning again; ++* However, in order to keep no impact on online running IRQs performance stable, ++* removed and reinserted IRQ added back into rebalance_irq_list, ++* for irq load re-calculation instead of trigger rescanning all IRQs. ++* specially, when a new IRQ is detected, it has to be checked what devpath is, ++* then it is added into database accordingly. ++*/ + void parse_proc_interrupts(void) + { + FILE *file; +@@ -253,7 +266,9 @@ void parse_proc_interrupts(void) + uint64_t count; + char *c, *c2; + struct irq_info *info; ++ struct irq_info tmp_info; + char savedline[1024]; ++ char dirname[PATH_MAX] = {'\0'}; + + if (getline(&line, &size, file)==0) + break; +@@ -281,9 +296,24 @@ void parse_proc_interrupts(void) + + info = get_irq_info(number); + if (!info) { +- need_rescan = 1; +- break; ++ find_irq_dev_path(number, dirname, PATH_MAX); ++ if (strlen(dirname) > 0) { ++ info = build_one_dev_entry(dirname, NULL); ++ log(TO_CONSOLE, LOG_INFO, "new IRQ %d added into database, dirname %s\n", number, dirname); ++ } else { ++ init_irq_class_and_type(savedline, &tmp_info, number); ++ info = add_new_irq(number, &tmp_info, NULL); ++ } ++ ++ if (info) { ++ force_rebalance_irq(info, NULL); ++ log(TO_CONSOLE, LOG_INFO, "new IRQ %d added into rebalance list\n", number); ++ } else { ++ need_rescan = 1; ++ break; ++ } + } ++ info->existing = 1; + + count = 0; + cpunr = 0; +@@ -307,17 +337,19 @@ void parse_proc_interrupts(void) + * cause an overflow and IRQ won't be rebalanced again + */ + if (count < info->irq_count) { +- need_rescan = 1; +- break; ++ log(TO_CONSOLE, LOG_INFO, "Removed and reinserted IRQ %d added into rebalance list\n", number); ++ force_rebalance_irq(info, NULL); + } + +- info->last_irq_count = info->irq_count; ++ info->last_irq_count = info->irq_count; + info->irq_count = count; + + /* is interrupt MSI based? */ + if ((info->type == IRQ_TYPE_MSI) || (info->type == IRQ_TYPE_MSIX)) + msi_found_in_sysfs = 1; +- } ++ } ++ clear_no_existing_irqs(); ++ + if ((proc_int_has_msi) && (!msi_found_in_sysfs) && (!need_rescan)) { + log(TO_ALL, LOG_WARNING, "WARNING: MSI interrupts found in /proc/interrupts\n"); + log(TO_ALL, LOG_WARNING, "But none found in sysfs, you need to update your kernel\n"); +diff --git a/types.h b/types.h +index a01d649..9693cf4 100644 +--- a/types.h ++++ b/types.h +@@ -70,6 +70,7 @@ struct irq_info { + uint64_t last_irq_count; + uint64_t load; + int moved; ++ int existing; + struct topo_obj *assigned_obj; + char *name; + }; +-- +1.8.3.1 + diff --git a/bugfix-guess_arm_irq_hints.patch b/bugfix-guess_arm_irq_hints.patch new file mode 100644 index 0000000..59899e1 --- /dev/null +++ b/bugfix-guess_arm_irq_hints.patch @@ -0,0 +1,30 @@ +From a8ad43cc682e268c9f35633a15636222b6933649 Mon Sep 17 00:00:00 2001 +From:Xia Shuang +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 diff --git a/bugfix-irqbalance-fix-wrong-pid-value-in-pid-file.patch b/bugfix-irqbalance-fix-wrong-pid-value-in-pid-file.patch new file mode 100644 index 0000000..4cdecf2 --- /dev/null +++ b/bugfix-irqbalance-fix-wrong-pid-value-in-pid-file.patch @@ -0,0 +1,123 @@ +From d57caa98c082fb3bf746b0877aa368544e8e62dc Mon Sep 17 00:00:00 2001 +From: Zengruan Ye +Date: Mon, 15 Jul 2019 21:37:39 +0800 +Subject: [PATCH 4/6] bugfix: irqbalance: fix wrong pid value in pid file + +If irqbalance is killed by SIGKILL or SIGTERM, +after restarting irqbalance, the pid in pid file is +wrong, that's because the way we forbid starting +multiple irqbalance instances is wrong. + +Here we use fcntl to lock pid file to forbid another instance +been launched. + +Signed-off-by: zhanghailiang +--- + irqbalance.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 73 insertions(+), 8 deletions(-) + +diff --git a/irqbalance.c b/irqbalance.c +index 40ec65c..27cf2eb 100644 +--- a/irqbalance.c ++++ b/irqbalance.c +@@ -584,6 +584,77 @@ int init_socket() + return 0; + } + ++static int create_lock_pidfile(const char *lockfile) ++{ ++ struct flock lock = { 0 }; ++ char pid_s[16] = { 0 }; ++ int lf = 0; ++ int err = -1; ++ ++ lf = open(lockfile, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); ++ if (lf == -1) { ++ err = -errno; ++ log(TO_ALL, LOG_WARNING, "irqbalance (%u): Can't create lock file.\n", ++ getpid()); ++ return err; ++ } ++ ++retry_fcntl: ++ lock.l_type = F_WRLCK; ++ lock.l_start = 0; ++ lock.l_whence = SEEK_SET; ++ lock.l_len = 0; ++ if (fcntl (lf, F_SETLK, &lock) == -1) { ++ err = -errno; ++ switch (errno) { ++ case EINTR: ++ goto retry_fcntl; ++ case EAGAIN: ++ case EACCES: ++ log(TO_ALL, LOG_WARNING, "irqbalance (%u): Another instance is" ++ " already running, errno:%d.\n", getpid(), errno); ++ goto error_close; ++ default: ++ log(TO_ALL, LOG_WARNING, "irqbalance (%u): Can't aquire lock." ++ " errno %d.\n", getpid(), errno); ++ goto error_close; ++ } ++ } ++ ++ if (ftruncate(lf, 0) == -1) { ++ err = -errno; ++ log(TO_ALL, LOG_WARNING, "irqbalance (%u): Can't truncate lock file." ++ " errno: %d.\n", getpid(), errno); ++ goto error_close_unlink; ++ } ++ if (snprintf(pid_s, sizeof(pid_s), "%u\n", getpid()) < 0) { ++ log(TO_ALL, LOG_WARNING, "irqbalance (%u): Can't printf pid string.\n", getpid()); ++ err = -1; ++ goto error_close_unlink; ++ } ++ ++retry_write: ++ if ((size_t)write(lf, pid_s, strlen (pid_s)) != strlen (pid_s)) { ++ err = -errno; ++ if (errno == EINTR) { ++ goto retry_write; ++ } else { ++ log(TO_ALL, LOG_WARNING, "irqbalance (%u): Can't write pid to lock" ++ " file. errno %d\n", getpid(), errno); ++ goto error_close_unlink; ++ } ++ } ++ ++ return 0; ++ ++error_close_unlink: ++ (void) unlink(lockfile); ++ ++error_close: ++ close(lf); ++ return err; ++} ++ + int main(int argc, char** argv) + { + struct sigaction action, hupaction; +@@ -676,17 +747,11 @@ int main(int argc, char** argv) + } + + if (!foreground_mode) { +- int pidfd = -1; + if (daemon(0,0)) + exit(EXIT_FAILURE); + /* Write pidfile */ +- if (pidfile && (pidfd = open(pidfile, +- O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, +- S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) >= 0) { +- char str[16]; +- snprintf(str, sizeof(str), "%u\n", getpid()); +- write(pidfd, str, strlen(str)); +- close(pidfd); ++ if (pidfile && create_lock_pidfile(pidfile) < 0) { ++ exit(EXIT_FAILURE); + } + } + +-- +1.8.3.1 + diff --git a/bugfix-prevent-inserting-a-duplicate-entry-to-avoid-list-ch.patch b/bugfix-prevent-inserting-a-duplicate-entry-to-avoid-list-ch.patch new file mode 100644 index 0000000..b493353 --- /dev/null +++ b/bugfix-prevent-inserting-a-duplicate-entry-to-avoid-list-ch.patch @@ -0,0 +1,108 @@ +From 3eab5a9cee8a3641988778b676caa4cf9dcb14ab Mon Sep 17 00:00:00 2001 +From: xiashuang +Date: Sun, 11 Aug 2019 23:48:50 -0400 +Subject: [PATCH] Prevent inserting a duplicate entry to avoid list chaos + +Introduced by huawei-bugfix-force-irq-into-rebalance-list-when-irq-removed-and-reinserted.patch +and huawei-feature-introduce-verifyhint-to-detect-hint-variation.patch, irq may want be inserted to +rebalance list more then once, and we need to prevent this. we developped a solution in +huawei-bugfix-fix-two-same-irq-insert-to-list.patch, but we are likely to call irq_in_rebalance_list. + +this patch remove the code in huawei-bugfix-fix-two-same-irq-insert-to-list.patch and add protection +in force_rebalance_irq instead. +--- + classify.c | 13 +------------ + irqbalance.c | 4 ++++ + irqbalance.h | 3 ++- + procinterrupts.c | 8 ++------ + 4 files changed, 9 insertions(+), 19 deletions(-) + +diff --git a/classify.c b/classify.c +index 34a2e9f..65aeae2 100644 +--- a/classify.c ++++ b/classify.c +@@ -260,7 +260,7 @@ static int get_irq_class(const char *devpath) + return irq_class; + } + +-static gint compare_ints(gconstpointer a, gconstpointer b) ++gint compare_ints(gconstpointer a, gconstpointer b) + { + const struct irq_info *ai = a; + const struct irq_info *bi = b; +@@ -293,17 +293,6 @@ static void add_banned_irq(int irq, GList **list, int extra_flag) + return; + } + +-int irq_in_rebalance_list(int irq) +-{ +- GList *entry = NULL; +- struct irq_info find = {0}; +- +- find.irq = irq; +- entry = g_list_find_custom(rebalance_irq_list, &find, compare_ints); +- +- return entry ? 1 : 0; +-} +- + #ifdef AARCH64 + void add_banned_list_irq(int irq) + { +diff --git a/irqbalance.c b/irqbalance.c +index 6e9de88..fd72d44 100644 +--- a/irqbalance.c ++++ b/irqbalance.c +@@ -314,6 +314,10 @@ void force_rebalance_irq(struct irq_info *info, void *data __attribute__((unused + if (info->level == BALANCE_NONE) + return; + ++ /* Prevent inserting a duplicate entry to avoid list chaos */ ++ if (g_list_find_custom(rebalance_irq_list, info, compare_ints)) ++ return; ++ + if (info->assigned_obj == NULL) + rebalance_irq_list = g_list_append(rebalance_irq_list, info); + else +diff --git a/irqbalance.h b/irqbalance.h +index b6bdebd..120bc9b 100644 +--- a/irqbalance.h ++++ b/irqbalance.h +@@ -114,7 +114,8 @@ extern void free_cl_opts(void); + extern void add_cl_banned_module(char *modname); + #define irq_numa_node(irq) ((irq)->numa_node) + extern void force_rebalance_irq(struct irq_info *info, void *data __attribute__((unused))); +-int irq_in_rebalance_list(int irq); ++extern gint compare_ints(gconstpointer a, gconstpointer b); ++ + /* huawei */ + extern struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list); + extern void find_irq_dev_path(int irq, char *dirname, int length); +diff --git a/procinterrupts.c b/procinterrupts.c +index 6b25fef..4bc68d7 100644 +--- a/procinterrupts.c ++++ b/procinterrupts.c +@@ -446,9 +446,7 @@ void parse_proc_interrupts(void) + */ + if (count < info->irq_count) { + log(TO_CONSOLE, LOG_INFO, "Removed and reinserted IRQ %d added into rebalance list\n", number); +- if (!irq_in_rebalance_list(info->irq)) { +- force_rebalance_irq(info, NULL); +- } ++ force_rebalance_irq(info, NULL); + } + + info->last_irq_count = info->irq_count; +@@ -702,9 +700,7 @@ void update_affinity_hint(struct irq_info *info, void *data __attribute__((unuse + cpumask_parse_user(line, len, current_affinity_hint); + if (!cpus_equal(current_affinity_hint, info->affinity_hint)) { + cpumask_copy(info->affinity_hint, current_affinity_hint); +- if (!irq_in_rebalance_list(info->irq)) { +- force_rebalance_irq(info, data); +- } ++ force_rebalance_irq(info, data); + log(TO_ALL, LOG_INFO, "IRQ(%d): affinity hint modified\n", info->irq); + } + } +-- +1.8.3.1 + diff --git a/bugfix-use-policy-prior-to-the-default-values.patch b/bugfix-use-policy-prior-to-the-default-values.patch new file mode 100644 index 0000000..b51865a --- /dev/null +++ b/bugfix-use-policy-prior-to-the-default-values.patch @@ -0,0 +1,151 @@ +From 21b69dd5d3212026881825901442a51eeecd3dad Mon Sep 17 00:00:00 2001 +From: Yun Wu +Date: Tue, 25 Aug 2015 19:47:58 +0800 +Subject: [PATCH] use policy prior to the default values + +Currently user-defined policies against non-PCI devices' interrupts +are not working properly. + +For example, when trying to set "balance_level=core" for a non-PCI +device interrupt which is classified as "other", will result in +the level of "package" because overrided in add_new_irq(). + +This patch fixes this by restricting irq info initializations in +add_one_irq_to_db(), which requires a change on its parameters. + +Signed-off-by: Yun Wu +--- + classify.c | 49 +++++++++++++++++++++---------------------------- + 1 file changed, 21 insertions(+), 28 deletions(-) + +diff --git a/classify.c b/classify.c +index df8a89b..9868633 100644 +--- a/classify.c ++++ b/classify.c +@@ -342,10 +342,10 @@ void add_cl_banned_module(char *modname) + * related device. NULL devpath means no sysfs entries for + * this irq. + */ +-static struct irq_info *add_one_irq_to_db(const char *devpath, int irq, struct user_irq_policy *pol) ++static struct irq_info *add_one_irq_to_db(const char *devpath, struct irq_info *hint, struct user_irq_policy *pol) + { +- int irq_class = IRQ_OTHER; +- struct irq_info *new, find; ++ int irq = hint->irq; ++ struct irq_info *new; + int numa_node; + char path[PATH_MAX]; + FILE *fd; +@@ -357,8 +357,7 @@ static struct irq_info *add_one_irq_to_db(const char *devpath, int irq, struct u + /* + * First check to make sure this isn't a duplicate entry + */ +- find.irq = irq; +- entry = g_list_find_custom(interrupts_db, &find, compare_ints); ++ entry = g_list_find_custom(interrupts_db, hint, compare_ints); + if (entry) { + log(TO_CONSOLE, LOG_INFO, "DROPPING DUPLICATE ENTRY FOR IRQ %d on path %s\n", irq, devpath); + return NULL; +@@ -374,23 +373,24 @@ static struct irq_info *add_one_irq_to_db(const char *devpath, int irq, struct u + return NULL; + + new->irq = irq; +- new->class = IRQ_OTHER; ++ new->type = hint->type; ++ new->class = hint->class; + + interrupts_db = g_list_append(interrupts_db, new); + + /* Some special irqs have NULL devpath */ + if (devpath != NULL) { + /* Map PCI class code to irq class */ +- irq_class = get_irq_class(devpath); ++ int irq_class = get_irq_class(devpath); + if (irq_class < 0) + goto get_numa_node; ++ new->class = irq_class; + } + +- new->class = irq_class; + if (pol->level >= 0) + new->level = pol->level; + else +- new->level = map_class_to_level[irq_class]; ++ new->level = map_class_to_level[new->class]; + + get_numa_node: + numa_node = -1; +@@ -611,13 +611,16 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs) + DIR *msidir; + FILE *fd; + int irqnum; +- struct irq_info *new; ++ struct irq_info *new, hint; + char path[PATH_MAX]; + char devpath[PATH_MAX]; + struct user_irq_policy pol; + + sprintf(path, "%s/%s/msi_irqs", SYSPCI_DIR, dirname); + sprintf(devpath, "%s/%s", SYSPCI_DIR, dirname); ++ ++ /* Needs to be further classified */ ++ hint.class = IRQ_OTHER; + + msidir = opendir(path); + +@@ -636,10 +639,11 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs) + add_banned_irq(irqnum, &banned_irqs); + continue; + } +- new = add_one_irq_to_db(devpath, irqnum, &pol); ++ hint.irq = irqnum; ++ hint.type = IRQ_TYPE_MSIX; ++ new = add_one_irq_to_db(devpath, &hint, &pol); + if (!new) + continue; +- new->type = IRQ_TYPE_MSIX; + } + } while (entry != NULL); + closedir(msidir); +@@ -671,10 +675,11 @@ static void build_one_dev_entry(const char *dirname, GList *tmp_irqs) + goto done; + } + +- new = add_one_irq_to_db(devpath, irqnum, &pol); ++ hint.irq = irqnum; ++ hint.type = IRQ_TYPE_LEGACY; ++ new = add_one_irq_to_db(devpath, &hint, &pol); + if (!new) + goto done; +- new->type = IRQ_TYPE_LEGACY; + } + + done: +@@ -721,22 +726,10 @@ static void add_new_irq(int irq, struct irq_info *hint, GList *proc_interrupts) + add_banned_irq(irq, &banned_irqs); + new = get_irq_info(irq); + } else +- new = add_one_irq_to_db(NULL, irq, &pol); ++ new = add_one_irq_to_db(NULL, hint, &pol); + +- if (!new) { ++ if (!new) + log(TO_CONSOLE, LOG_WARNING, "add_new_irq: Failed to add irq %d\n", irq); +- return; +- } +- +- /* +- * Override some of the new irq defaults here +- */ +- if (hint) { +- new->type = hint->type; +- new->class = hint->class; +- } +- +- new->level = map_class_to_level[new->class]; + } + + static void add_missing_irq(struct irq_info *info, void *attr) +-- +1.8.3.1 + diff --git a/classify-remove-unused-label.patch b/classify-remove-unused-label.patch new file mode 100644 index 0000000..7f2b1ea --- /dev/null +++ b/classify-remove-unused-label.patch @@ -0,0 +1,28 @@ +From ff28f445a0808677c983d85a3b8331e4c090d70d Mon Sep 17 00:00:00 2001 +From: Neil Horman +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 +--- + 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 + diff --git a/cputree-adjust-snprintf-sizes-to-avoid-gcc-warnings.patch b/cputree-adjust-snprintf-sizes-to-avoid-gcc-warnings.patch new file mode 100644 index 0000000..e2cafbc --- /dev/null +++ b/cputree-adjust-snprintf-sizes-to-avoid-gcc-warnings.patch @@ -0,0 +1,91 @@ +From 0605850acfce6f2ae23759618604f02f946026c2 Mon Sep 17 00:00:00 2001 +From: Neil Horman +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 +--- + 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 + diff --git a/feature-add-new-user-irq-policy-config-rule.patch b/feature-add-new-user-irq-policy-config-rule.patch new file mode 100644 index 0000000..c3ec319 --- /dev/null +++ b/feature-add-new-user-irq-policy-config-rule.patch @@ -0,0 +1,476 @@ +From 0406d202af914881af1a6caf5247e7ac40564366 Mon Sep 17 00:00:00 2001 +From: hejingxian +Date: Tue, 17 Sep 2019 23:32:54 +0800 +Subject: [PATCH] add new user irq policy config rule + +When there is many irqs, the old user irq policy script will cost too much time. +Therefore, we introduce a new user irq policy config rule which avoid policy script running +for every irq. +--- + Makefile.am | 2 +- + classify.c | 32 +++++++-- + irqbalance.c | 31 +++++---- + irqbalance.h | 2 +- + misc/irqbalance.service | 2 +- + placement.c | 3 +- + procinterrupts.c | 3 +- + rules_config.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++ + rules_config.h | 38 +++++++++++ + 9 files changed, 260 insertions(+), 23 deletions(-) + create mode 100644 rules_config.c + create mode 100644 rules_config.h + +diff --git a/Makefile.am b/Makefile.am +index 62ac482..9276bfb 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -38,7 +38,7 @@ sbin_PROGRAMS += irqbalance-ui + endif + + irqbalance_SOURCES = activate.c bitmap.c classify.c cputree.c irqbalance.c \ +- irqlist.c numa.c placement.c procinterrupts.c sockapi.c ++ irqlist.c numa.c placement.c procinterrupts.c sockapi.c rules_config.c + irqbalance_LDADD = $(LIBCAP_NG_LIBS) $(GLIB2_LIBS) -lpthread + if IRQBALANCEUI + irqbalance_ui_SOURCES = $(UI_DIR)/helpers.c $(UI_DIR)/irqbalance-ui.c \ +diff --git a/classify.c b/classify.c +index 65aeae2..7c97d47 100644 +--- a/classify.c ++++ b/classify.c +@@ -663,7 +663,7 @@ struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list) + + sprintf(path, "%s/%s/msi_irqs", SYSPCI_DIR, dirname); + sprintf(devpath, "%s/%s", SYSPCI_DIR, dirname); +- ++ memset(&pol, -1, sizeof(struct user_irq_policy)); + /* Needs to be further classified */ + hint.class = IRQ_OTHER; + +@@ -679,7 +679,9 @@ struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list) + new = get_irq_info(irqnum); + if (new) + continue; +- get_irq_user_policy(devpath, irqnum, &pol); ++ if (user_policy_list == NULL) { ++ get_irq_user_policy(devpath, irqnum, &pol); ++ } + if ((pol.ban == 1) || (check_for_irq_ban(devpath, irqnum, tmp_list))) { + add_banned_irq(irqnum, &banned_irqs, 0); + continue; +@@ -714,7 +716,9 @@ struct irq_info *build_one_dev_entry(const char *dirname, GList *tmp_list) + new = get_irq_info(irqnum); + if (new) + goto done; +- get_irq_user_policy(devpath, irqnum, &pol); ++ if (user_policy_list == NULL) { ++ get_irq_user_policy(devpath, irqnum, &pol); ++ } + if ((pol.ban == 1) || (check_for_irq_ban(path, irqnum, tmp_list))) { + add_banned_irq(irqnum, &banned_irqs, 0); + goto done; +@@ -855,18 +859,24 @@ struct irq_info *add_new_irq(int irq, struct irq_info *hint, GList *proc_interru + struct irq_info *new = NULL; + struct user_irq_policy pol; + ++ memset(&pol, -1, sizeof(struct user_irq_policy)); + new = get_irq_info(irq); + if (new) + return new; + + /* Set NULL devpath for the irq has no sysfs entries */ +- get_irq_user_policy(NULL, irq, &pol); ++ if (user_policy_list == NULL) { ++ get_irq_user_policy(NULL, irq, &pol); ++ } + if ((pol.ban == 1) || check_for_irq_ban(NULL, irq, proc_interrupts)) { /*FIXME*/ + add_banned_irq(irq, &banned_irqs, 0); + new = get_irq_info(irq); +- } else ++ } else { + new = add_one_irq_to_db(NULL, hint, &pol); +- ++ if ((new != NULL) && (user_policy_list != NULL)) { ++ set_usr_irq_policy(hint->name, new); ++ } ++ } + if (!new) + log(TO_CONSOLE, LOG_WARNING, "add_new_irq: Failed to add irq %d\n", irq); + +@@ -880,6 +890,16 @@ static void add_missing_irq(struct irq_info *info, void *attr) + + if (!lookup) + add_new_irq(info->irq, info, proc_interrupts); ++ else { ++ if (user_policy_list != NULL) { ++ set_usr_irq_policy(info->name, lookup); ++ } ++ } ++ if (info->name) { ++ free(info->name); ++ info->name = NULL; ++ } ++ + } + + +diff --git a/irqbalance.c b/irqbalance.c +index 21d578a..d41753c 100644 +--- a/irqbalance.c ++++ b/irqbalance.c +@@ -148,6 +148,7 @@ struct option lopts[] = { + {"interval", 1 , NULL, 't'}, + {"version", 0, NULL, 'V'}, + {"verifyhint", 1, NULL, 'v'}, ++ {"rulesconfig", 1, NULL, 'r'}, + {0, 0, 0, 0} + }; + +@@ -155,7 +156,7 @@ static void usage(void) + { + log(TO_CONSOLE, LOG_INFO, "irqbalance [--oneshot | -o] [--debug | -d] [--foreground | -f] [--journal | -j] [--hintpolicy | -h ]\n"); + log(TO_CONSOLE, LOG_INFO, " [--powerthresh= | -p | ] [--banirq= | -i ] [--banmod= | -m ] [--policyscript= | -l