From bd67801a53bbc658025cfde3e37ea733465a753a Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Mon, 13 Jun 2022 09:27:25 -0400 Subject: [PATCH 1/5] Enable static building of irqbalance openwrt would find it useful to have a statically linked version of irqbalance for better link-time optimization. --- Makefile.am | 4 ++++ configure.ac | 25 +++++++++++++++++-------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/Makefile.am b/Makefile.am index 84e7d46..9eb0dbd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -37,6 +37,10 @@ if IRQBALANCEUI sbin_PROGRAMS += irqbalance-ui endif +if STATICBUILD +irqbalance_LDFLAGS = -Wl,-Bstatic +endif + irqbalance_SOURCES = activate.c bitmap.c classify.c cputree.c irqbalance.c \ irqlist.c numa.c placement.c procinterrupts.c irqbalance_LDADD = $(LIBCAP_NG_LIBS) $(GLIB2_LIBS) $(NUMA_LIBS) diff --git a/configure.ac b/configure.ac index 9eef01b..dab5d8a 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ AC_INIT(irqbalance,1.9.0) -AC_PREREQ(2.12)dnl -AM_CONFIG_HEADER(config.h) +AC_PREREQ(2.69)dnl +AC_CONFIG_HEADERS(config.h) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([foreign] [subdir-objects]) @@ -11,18 +11,27 @@ AC_PROG_CC AC_PROG_INSTALL AC_PROG_AWK +AC_HEADER_STDC +AC_CHECK_HEADERS([numa.h]) + +AC_CHECK_FUNCS(getopt_long) + +AC_ARG_ENABLE([staticbuild], + AS_HELP_STRING([--enable-staticbuild], [enable static builds(default disabled)])) + +AM_CONDITIONAL([STATICBUILD], [test "x$enable_staticbuild" = "xyes"]) + +# If we requested static building, enable that in pkg-config +AS_IF([test "x$enable_staticbuild" = "xyes"], [ + PKG_CONFIG="$PKG_CONFIG --static"],[]) + + AC_ARG_ENABLE([numa], AS_HELP_STRING([--disable-numa], [enable numa support (default is auto)])) AS_IF([test "$enable_numa" = "no"],[ ac_cv_header_numa_h=no ac_cv_lib_numa_numa_available=no ]) - -AC_HEADER_STDC -AC_CHECK_HEADERS([numa.h]) - -AC_CHECK_FUNCS(getopt_long) - PKG_CHECK_MODULES([NUMA], [numa], [has_numa=yes], [AC_CHECK_LIB(numa, numa_available)]) AC_CHECK_LIB(m, floor) From c8d1fff0f16ad906cca153a22faac11516ccc0dd Mon Sep 17 00:00:00 2001 From: Liu Chao Date: Mon, 18 Jul 2022 16:54:53 +0800 Subject: [PATCH 2/5] irqbalance-ui: skip ',' in parse_setup to avoid coredump When processing the ',' in hex_to_bitmap, it returns '0000\ 0' directly. The return value will be freed in parse_setup, but it is not requested through malloc. Fixes: 85d37098a551 ("Fix several memleak problems found by covscan") And it treat ',' as "0000", which cause irqbalance-ui will display wrong Banned CPU numbers. For example: # IRQBALANCE_BANNED_CPUS="00000002,00000000,00000000" ./irqbalance or # IRQBALANCE_BANNED_CPULIST="65" ./irqbalance # ./irqbalance-ui Banned CPU numbers: 73 Fixes: 76d1c9d73935 ("Add main user interface files") Signed-off-by: Liu Chao --- ui/irqbalance-ui.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ui/irqbalance-ui.c b/ui/irqbalance-ui.c index 47b6c88..b7f9b62 100644 --- a/ui/irqbalance-ui.c +++ b/ui/irqbalance-ui.c @@ -142,7 +142,7 @@ try_again: void parse_setup(char *setup_data) { char *token, *ptr; - int i,j; + int i,j, cpu = 0; char *copy; irq_t *new_irq = NULL; if((setup_data == NULL) || (strlen(setup_data) == 0)) return; @@ -179,14 +179,17 @@ void parse_setup(char *setup_data) if(strncmp(token, "BANNED", strlen("BANNED"))) goto out; token = strtok_r(NULL, " ", &ptr); for(i = strlen(token) - 1; i >= 0; i--) { + if (token[i] == ',') + continue; char *map = hex_to_bitmap(token[i]); for(j = 3; j >= 0; j--) { if(map[j] == '1') { uint64_t *banned_cpu = malloc(sizeof(uint64_t)); - *banned_cpu = (4 * (strlen(token) - (i + 1)) + (4 - (j + 1))); + *banned_cpu = cpu; setup.banned_cpus = g_list_append(setup.banned_cpus, banned_cpu); } + cpu++; } free(map); From d48eaf61c2fa61cf5ab5dc0ade18ece911ea6e02 Mon Sep 17 00:00:00 2001 From: Liu Chao Date: Mon, 18 Jul 2022 19:19:31 +0800 Subject: [PATCH 3/5] irqbalance: use endptr to check whether the input parameter is empty Signed-off-by: Liu Chao --- irqbalance.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/irqbalance.c b/irqbalance.c index 5eae5b6..2c9e3f3 100644 --- a/irqbalance.c +++ b/irqbalance.c @@ -124,6 +124,7 @@ static void parse_command_line(int argc, char **argv) int opt; int longind; unsigned long val; + char *endptr; while ((opt = getopt_long(argc, argv, "odfjVi:p:s:c:l:m:t:e:", @@ -139,8 +140,8 @@ static void parse_command_line(int argc, char **argv) exit(1); break; case 'c': - deepest_cache = strtoul(optarg, NULL, 10); - if (deepest_cache == ULONG_MAX || deepest_cache < 1) { + deepest_cache = strtoul(optarg, &endptr, 10); + if (optarg == endptr || deepest_cache == ULONG_MAX || deepest_cache < 1) { usage(); exit(1); } @@ -153,8 +154,8 @@ static void parse_command_line(int argc, char **argv) foreground_mode=1; break; case 'i': - val = strtoull(optarg, NULL, 10); - if (val == ULONG_MAX) { + val = strtoull(optarg, &endptr, 10); + if (optarg == endptr || val == ULONG_MAX) { usage(); exit(1); } @@ -171,8 +172,8 @@ static void parse_command_line(int argc, char **argv) if (!strncmp(optarg, "off", strlen(optarg))) power_thresh = ULONG_MAX; else { - power_thresh = strtoull(optarg, NULL, 10); - if (power_thresh == ULONG_MAX) { + power_thresh = strtoull(optarg, &endptr, 10); + if (optarg == endptr || power_thresh == ULONG_MAX) { usage(); exit(1); } @@ -189,14 +190,18 @@ static void parse_command_line(int argc, char **argv) foreground_mode=1; break; case 't': - sleep_interval = strtol(optarg, NULL, 10); - if (sleep_interval < 1) { + sleep_interval = strtol(optarg, &endptr, 10); + if (optarg == endptr || sleep_interval < 1) { usage(); exit(1); } break; case 'e': - migrate_ratio = strtoul(optarg, NULL, 10); + migrate_ratio = strtoul(optarg, &endptr, 10); + if (optarg == endptr) { + usage(); + exit(1); + } break; } } From 402ca1b7a0a719401370ba1e25797dccc47500ff Mon Sep 17 00:00:00 2001 From: Liu Chao Date: Thu, 14 Jul 2022 16:10:01 +0800 Subject: [PATCH 4/5] irqbalance-ui: display irq name in SETUP IRQS get irq name from /proc/interrupts Signed-off-by: Liu Chao --- ui/ui.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/ui/ui.c b/ui/ui.c index f1490d5..897371b 100644 --- a/ui/ui.c +++ b/ui/ui.c @@ -9,6 +9,8 @@ int max_offset; GList *all_cpus = NULL; GList *all_irqs = NULL; +static char **irq_name; + char *IRQ_CLASS_TO_STR[] = { "Other", "Legacy", @@ -392,6 +394,38 @@ void print_assigned_objects_string(irq_t *irq, int *line_offset) mvprintw(*line_offset, 68, "%s ", assigned_to); } +void get_irq_name(int end) +{ + int i, cpunr, len; + FILE *output; + char *cmd; + char buffer[128]; + + if (irq_name == NULL) { + irq_name = malloc(sizeof(char *) * LINES); + for (i = 4; i < LINES; i++) { + irq_name[i] = malloc(sizeof(char) * 50); + memset(irq_name[i], 0, sizeof(char) * 50); + } + } + + output = popen("cat /proc/interrupts | head -1 | awk '{print NF}'", "r"); + if (!output) + return; + fscanf(output, "%d", &cpunr); + pclose(output); + + len = snprintf(NULL, 0, "cat /proc/interrupts | awk '{for (i=%d;i<=NF;i++)printf(\"%%s \", $i);print \"\"}' | cut -c-49", cpunr + 2); + cmd = alloca(sizeof(char) * (len + 1)); + snprintf(cmd, len + 1, "cat /proc/interrupts | awk '{for (i=%d;i<=NF;i++)printf(\"%%s \", $i);print \"\"}' | cut -c-49", cpunr + 2); + output = popen(cmd, "r"); + for (i = 0; i <= offset; i++) + fgets(buffer, 50, output); + for (i = 4; i < end; i++) + fgets(irq_name[i], 50, output); + pclose(output); +} + void print_tmp_irq_line(irq_t *irq, void *data __attribute__((unused))) { int line = max_offset - offset + 4; @@ -428,6 +462,7 @@ void print_tmp_irq_line(irq_t *irq, void *data __attribute__((unused))) mvprintw(line, 36, "%s ", irq->class < 0 ? "Unknown" : IRQ_CLASS_TO_STR[irq->class]); print_assigned_objects_string(irq, &line); + mvprintw(line, 120, "%s", irq_name[line]); } void print_irq_line(irq_t *irq, void *data __attribute__((unused))) @@ -466,6 +501,7 @@ void print_irq_line(irq_t *irq, void *data __attribute__((unused))) mvprintw(line, 36, "%s ", irq->class < 0 ? "Unknown" : IRQ_CLASS_TO_STR[irq->class]); print_assigned_objects_string(irq, &line); + mvprintw(line, 120, "%s", irq_name[line]); } void print_all_irqs() @@ -474,7 +510,8 @@ void print_all_irqs() attrset(COLOR_PAIR(0)); mvprintw(2, 3, "NUMBER IS BANNED CLASS \ - ASSIGNED TO CPUS"); + ASSIGNED TO CPUS IRQ NAME"); + get_irq_name(LINES - 2); for_each_irq(all_irqs, print_irq_line, NULL); max_offset -= LINES - 6; if (max_offset < 0) @@ -545,6 +582,7 @@ void handle_irq_banning() } else if (offset > 0) { offset--; max_offset = 0; + get_irq_name(LINES - 3); for_each_irq(tmp, print_tmp_irq_line, NULL); max_offset -= LINES - 7; if (max_offset < 0) @@ -561,6 +599,7 @@ void handle_irq_banning() } else if (offset < max_offset) { offset++; max_offset = 0; + get_irq_name(LINES - 3); for_each_irq(tmp, print_tmp_irq_line, NULL); max_offset -= LINES - 7; if (max_offset < 0) From 911bd62cc2f77c4c700ce77a64c470c31aff2a0b Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Tue, 13 Sep 2022 12:39:49 -0400 Subject: [PATCH 5/5] [DMN] placement: packing policy --- placement.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/placement.c b/placement.c index 9fde8cb..73d87c7 100644 --- a/placement.c +++ b/placement.c @@ -70,6 +70,21 @@ static void find_best_object(struct topo_obj *d, void *data) } } +static void find_best_object_packing(GList *objs, struct irq_info *info, struct obj_placement *place) +{ + GList *entry; + entry = g_list_first(objs); + while (entry) { + struct topo_obj *d = entry->data; + if (d->load + info->load < 0.9e9) { + place->best = d; + place->best_cost = d->load + info->load; + return; + } + entry = g_list_next(entry); + } +} + static void find_best_object_for_irq(struct irq_info *info, void *data) { struct obj_placement place; @@ -105,7 +120,11 @@ static void find_best_object_for_irq(struct irq_info *info, void *data) place.best = NULL; place.best_cost = ULLONG_MAX; - for_each_object(d->children, find_best_object, &place); + if (info->level != BALANCE_CORE) { + for_each_object(d->children, find_best_object, &place); + } else { + find_best_object_packing(d->children, info, &place); + } asign = place.best;