diff --git a/Makefile.am b/Makefile.am index 9181a34..80d8fee 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 if THERMAL diff --git a/configure.ac b/configure.ac index 42ef0d6..a610db2 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) 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; } } 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; 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); 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)