From 17f7caa45105f0cbf8bf9b562468fba2c5d4a549 Mon Sep 17 00:00:00 2001 From: zhenwei pi Date: Wed, 10 Nov 2021 11:16:42 +0800 Subject: [PATCH] irqtop: add -c/--cpu-stat option Since a23aecc1bf("irqtop: add per-cpu stats"), irqtop always shows per-cpu stats. Test on a modern AMD server with 2 socket(256 CPU), irqtop shows messy output with too many columns. In this patch, add -c/--cpu-stat option to enable/disable per-cpu stats. And 'auto' option auto-detect window size, only show per-cpu stats if the length of per-cpu stats is shorter than the width of window. [kzak@redhat.com: - shorten the commit message - rename --cpu to --cpu-stat - use scols_table_enable_nowrap() rather than trim in irqtop.c - reduce --help for the new option] Signed-off-by: zhenwei pi Signed-off-by: Karel Zak --- bash-completion/irqtop | 7 ++++++- sys-utils/irqtop.1.adoc | 3 +++ sys-utils/irqtop.c | 41 +++++++++++++++++++++++++++++++++-------- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/bash-completion/irqtop b/bash-completion/irqtop index e34e391003..6dae28924e 100644 --- a/bash-completion/irqtop +++ b/bash-completion/irqtop @@ -5,6 +5,10 @@ _irqtop_module() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" case $prev in + '-c'|'--cpus') + COMPREPLY=( $(compgen -W "auto enable disable" -- $cur) ) + return 0 + ;; '-d'|'--delay') COMPREPLY=( $(compgen -W "secs" -- $cur) ) return 0 @@ -30,7 +34,8 @@ _irqtop_module() return 0 ;; esac - OPTS=" --delay + OPTS=" --cpus + --delay --sort --output --softirq diff --git a/sys-utils/irqtop.1.adoc b/sys-utils/irqtop.1.adoc index 84f826a42d..b8aae417a8 100644 --- a/sys-utils/irqtop.1.adoc +++ b/sys-utils/irqtop.1.adoc @@ -25,6 +25,9 @@ The default output is subject to change. So whenever possible, you should avoid *-o*, *--output* _list_:: Specify which output columns to print. Use *--help* to get a list of all supported columns. The default list of columns may be extended if list is specified in the format _+list_. +*-c*, *--cpu-stat* _mode_:: +Show per-cpu statistics by specified option, available options: auto, enable, disable. The default option *auto* detects the width of window, then shows the per-cpu statistics if the width of window is large enouth to show a full line of statistics. + *-d*, *--delay* _seconds_:: Update interrupt output every _seconds_ intervals. diff --git a/sys-utils/irqtop.c b/sys-utils/irqtop.c index 1a5cec0cc9..16212a223f 100644 --- a/sys-utils/irqtop.c +++ b/sys-utils/irqtop.c @@ -68,6 +68,12 @@ #define MAX_EVENTS 3 +enum irqtop_cpus_table { + irqtop_cpus_table_auto, + irqtop_cpus_table_enable, + irqtop_cpus_table_disable, +}; + /* top control struct */ struct irqtop_ctl { WINDOW *win; @@ -78,6 +84,7 @@ struct irqtop_ctl { struct itimerspec timer; struct irq_stat *prev_stat; + enum irqtop_cpus_table cpus; unsigned int request_exit:1; unsigned int softirq:1; }; @@ -98,7 +105,7 @@ static void parse_input(struct irqtop_ctl *ctl, struct irq_output *out, char c) static int update_screen(struct irqtop_ctl *ctl, struct irq_output *out) { - struct libscols_table *table, *cpus; + struct libscols_table *table, *cpus = NULL; struct irq_stat *stat; time_t now = time(NULL); char timestr[64], *data, *data0, *p; @@ -114,8 +121,12 @@ static int update_screen(struct irqtop_ctl *ctl, struct irq_output *out) scols_table_reduce_termwidth(table, 1); /* make cpus table */ - cpus = get_scols_cpus_table(out, ctl->prev_stat, stat); - scols_table_reduce_termwidth(cpus, 1); + if (ctl->cpus != irqtop_cpus_table_disable) { + cpus = get_scols_cpus_table(out, ctl->prev_stat, stat); + scols_table_reduce_termwidth(cpus, 1); + if (ctl->cpus == irqtop_cpus_table_auto) + scols_table_enable_nowrap(cpus, 1); + } /* print header */ move(0, 0); @@ -123,10 +134,12 @@ static int update_screen(struct irqtop_ctl *ctl, struct irq_output *out) wprintw(ctl->win, _("irqtop | total: %ld delta: %ld | %s | %s\n\n"), stat->total_irq, stat->delta_irq, ctl->hostname, timestr); - /* print cpus table */ - scols_print_table_to_string(cpus, &data); - wprintw(ctl->win, "%s\n\n", data); - free(data); + /* print cpus table or not by -c option */ + if (cpus) { + scols_print_table_to_string(cpus, &data); + wprintw(ctl->win, "%s\n\n", data); + free(data); + } /* print irqs table */ scols_print_table_to_string(table, &data0); @@ -247,6 +260,7 @@ static void __attribute__((__noreturn__)) usage(void) puts(_("Interactive utility to display kernel interrupt information.")); fputs(USAGE_OPTIONS, stdout); + fputs(_(" -c, --cpu-stat show per-cpu stat (auto, enable, disable)\n"), stdout); fputs(_(" -d, --delay delay updates\n"), stdout); fputs(_(" -o, --output define which output columns to use\n"), stdout); fputs(_(" -s, --sort specify sort column\n"), stdout); @@ -275,6 +289,7 @@ static void parse_args( struct irqtop_ctl *ctl, { const char *outarg = NULL; static const struct option longopts[] = { + {"cpus", required_argument, NULL, 'c'}, {"delay", required_argument, NULL, 'd'}, {"sort", required_argument, NULL, 's'}, {"output", required_argument, NULL, 'o'}, @@ -285,8 +300,18 @@ static void parse_args( struct irqtop_ctl *ctl, }; int o; - while ((o = getopt_long(argc, argv, "d:o:s:ShV", longopts, NULL)) != -1) { + while ((o = getopt_long(argc, argv, "c:d:o:s:ShV", longopts, NULL)) != -1) { switch (o) { + case 'c': + if (!strcmp(optarg, "auto")) + ctl->cpus = irqtop_cpus_table_auto; + else if (!strcmp(optarg, "enable")) + ctl->cpus = irqtop_cpus_table_enable; + else if (!strcmp(optarg, "disable")) + ctl->cpus = irqtop_cpus_table_disable; + else + errx(EXIT_FAILURE, _("unsupported mode '%s'"), optarg); + break; case 'd': { struct timeval delay; -- 2.47.3