irqtop/lsirq: support softirq

Add '-S' or '--softirq' for irqtop/lsirq, instead of interrupts, show
softirqs infomation. Because there is no more description of softirq,
do not show 'NAME' column by default.

Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
This commit is contained in:
zhenwei pi 2020-06-29 14:19:21 +08:00 committed by Karel Zak
parent e5ad3a6ad0
commit b6ce063b04
5 changed files with 33 additions and 13 deletions

View File

@ -188,6 +188,7 @@
/* irqtop paths */ /* irqtop paths */
#define _PATH_PROC_INTERRUPTS "/proc/interrupts" #define _PATH_PROC_INTERRUPTS "/proc/interrupts"
#define _PATH_PROC_SOFTIRQS "/proc/softirqs"
#define _PATH_PROC_UPTIME "/proc/uptime" #define _PATH_PROC_UPTIME "/proc/uptime"
/* kernel command line */ /* kernel command line */

View File

@ -195,7 +195,7 @@ static char *remove_repeated_spaces(char *str)
/* /*
* irqinfo - parse the system's interrupts * irqinfo - parse the system's interrupts
*/ */
static struct irq_stat *get_irqinfo(void) static struct irq_stat *get_irqinfo(int softirq)
{ {
FILE *irqfile; FILE *irqfile;
char *line = NULL, *tmp; char *line = NULL, *tmp;
@ -209,7 +209,10 @@ static struct irq_stat *get_irqinfo(void)
stat->irq_info = xmalloc(sizeof(*stat->irq_info) * IRQ_INFO_LEN); stat->irq_info = xmalloc(sizeof(*stat->irq_info) * IRQ_INFO_LEN);
stat->nr_irq_info = IRQ_INFO_LEN; stat->nr_irq_info = IRQ_INFO_LEN;
irqfile = fopen(_PATH_PROC_INTERRUPTS, "r"); if (softirq)
irqfile = fopen(_PATH_PROC_SOFTIRQS, "r");
else
irqfile = fopen(_PATH_PROC_INTERRUPTS, "r");
if (!irqfile) { if (!irqfile) {
warn(_("cannot open %s"), _PATH_PROC_INTERRUPTS); warn(_("cannot open %s"), _PATH_PROC_INTERRUPTS);
goto free_stat; goto free_stat;
@ -368,7 +371,8 @@ void set_sort_func_by_key(struct irq_output *out, char c)
struct libscols_table *get_scols_table(struct irq_output *out, struct libscols_table *get_scols_table(struct irq_output *out,
struct irq_stat *prev, struct irq_stat *prev,
struct irq_stat **xstat) struct irq_stat **xstat,
int softirq)
{ {
struct libscols_table *table; struct libscols_table *table;
struct irq_info *result; struct irq_info *result;
@ -377,7 +381,7 @@ struct libscols_table *get_scols_table(struct irq_output *out,
size_t i; size_t i;
/* the stats */ /* the stats */
stat = get_irqinfo(); stat = get_irqinfo(softirq);
if (!stat) if (!stat)
return NULL; return NULL;

View File

@ -56,6 +56,7 @@ void set_sort_func_by_key(struct irq_output *out, const char c);
struct libscols_table *get_scols_table(struct irq_output *out, struct libscols_table *get_scols_table(struct irq_output *out,
struct irq_stat *prev, struct irq_stat *prev,
struct irq_stat **xstat); struct irq_stat **xstat,
int softirq);
#endif /* UTIL_LINUX_H_IRQ_COMMON */ #endif /* UTIL_LINUX_H_IRQ_COMMON */

View File

@ -79,6 +79,7 @@ struct irqtop_ctl {
struct irq_stat *prev_stat; struct irq_stat *prev_stat;
unsigned int request_exit:1; unsigned int request_exit:1;
unsigned int softirq:1;
}; };
/* user's input parser */ /* user's input parser */
@ -102,7 +103,7 @@ static int update_screen(struct irqtop_ctl *ctl, struct irq_output *out)
time_t now = time(NULL); time_t now = time(NULL);
char timestr[64], *data; char timestr[64], *data;
table = get_scols_table(out, ctl->prev_stat, &stat); table = get_scols_table(out, ctl->prev_stat, &stat, ctl->softirq);
if (!table) { if (!table) {
ctl->request_exit = 1; ctl->request_exit = 1;
return 1; return 1;
@ -223,6 +224,7 @@ static void __attribute__((__noreturn__)) usage(void)
fputs(_(" -d, --delay <secs> delay updates\n"), stdout); fputs(_(" -d, --delay <secs> delay updates\n"), stdout);
fputs(_(" -o, --output <list> define which output columns to use\n"), stdout); fputs(_(" -o, --output <list> define which output columns to use\n"), stdout);
fputs(_(" -s, --sort <column> specify sort column\n"), stdout); fputs(_(" -s, --sort <column> specify sort column\n"), stdout);
fputs(_(" -S, --softirq show softirqs instead of interrupts\n"), stdout);
fputs(USAGE_SEPARATOR, stdout); fputs(USAGE_SEPARATOR, stdout);
printf(USAGE_HELP_OPTIONS(22)); printf(USAGE_HELP_OPTIONS(22));
@ -250,13 +252,14 @@ static void parse_args( struct irqtop_ctl *ctl,
{"delay", required_argument, NULL, 'd'}, {"delay", required_argument, NULL, 'd'},
{"sort", required_argument, NULL, 's'}, {"sort", required_argument, NULL, 's'},
{"output", required_argument, NULL, 'o'}, {"output", required_argument, NULL, 'o'},
{"softirq", no_argument, NULL, 'S'},
{"help", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 'V'}, {"version", no_argument, NULL, 'V'},
{NULL, 0, NULL, 0} {NULL, 0, NULL, 0}
}; };
int o; int o;
while ((o = getopt_long(argc, argv, "d:o:s:hV", longopts, NULL)) != -1) { while ((o = getopt_long(argc, argv, "d:o:s:ShV", longopts, NULL)) != -1) {
switch (o) { switch (o) {
case 'd': case 'd':
{ {
@ -274,6 +277,9 @@ static void parse_args( struct irqtop_ctl *ctl,
case 'o': case 'o':
outarg = optarg; outarg = optarg;
break; break;
case 'S':
ctl->softirq = 1;
break;
case 'V': case 'V':
print_version(EXIT_SUCCESS); print_version(EXIT_SUCCESS);
case 'h': case 'h':
@ -288,7 +294,8 @@ static void parse_args( struct irqtop_ctl *ctl,
out->columns[out->ncolumns++] = COL_IRQ; out->columns[out->ncolumns++] = COL_IRQ;
out->columns[out->ncolumns++] = COL_TOTAL; out->columns[out->ncolumns++] = COL_TOTAL;
out->columns[out->ncolumns++] = COL_DELTA; out->columns[out->ncolumns++] = COL_DELTA;
out->columns[out->ncolumns++] = COL_NAME; if (!ctl->softirq)
out->columns[out->ncolumns++] = COL_NAME;
} }
/* add -o [+]<list> to putput */ /* add -o [+]<list> to putput */

View File

@ -38,11 +38,11 @@
#include "irq-common.h" #include "irq-common.h"
static int print_irq_data(struct irq_output *out) static int print_irq_data(struct irq_output *out, int softirq)
{ {
struct libscols_table *table; struct libscols_table *table;
table = get_scols_table(out, NULL, NULL); table = get_scols_table(out, NULL, NULL, softirq);
if (!table) if (!table)
return -1; return -1;
@ -65,6 +65,7 @@ static void __attribute__((__noreturn__)) usage(void)
fputs(_(" -n, --noheadings don't print headings\n"), stdout); fputs(_(" -n, --noheadings don't print headings\n"), stdout);
fputs(_(" -o, --output <list> define which output columns to use\n"), stdout); fputs(_(" -o, --output <list> define which output columns to use\n"), stdout);
fputs(_(" -s, --sort <column> specify sort column\n"), stdout); fputs(_(" -s, --sort <column> specify sort column\n"), stdout);
fputs(_(" -S, --softirq show softirqs instead of interrupts\n"), stdout);
fputs(USAGE_SEPARATOR, stdout); fputs(USAGE_SEPARATOR, stdout);
printf(USAGE_HELP_OPTIONS(22)); printf(USAGE_HELP_OPTIONS(22));
@ -84,6 +85,7 @@ int main(int argc, char **argv)
{"sort", required_argument, NULL, 's'}, {"sort", required_argument, NULL, 's'},
{"noheadings", no_argument, NULL, 'n'}, {"noheadings", no_argument, NULL, 'n'},
{"output", required_argument, NULL, 'o'}, {"output", required_argument, NULL, 'o'},
{"softirq", no_argument, NULL, 'S'},
{"json", no_argument, NULL, 'J'}, {"json", no_argument, NULL, 'J'},
{"pairs", no_argument, NULL, 'P'}, {"pairs", no_argument, NULL, 'P'},
{"help", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'h'},
@ -97,10 +99,11 @@ int main(int argc, char **argv)
{0} {0}
}; };
int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT; int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT;
int softirq = 0;
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
while ((c = getopt_long(argc, argv, "no:s:hJPV", longopts, NULL)) != -1) { while ((c = getopt_long(argc, argv, "no:s:ShJPV", longopts, NULL)) != -1) {
err_exclusive_options(c, longopts, excl, excl_st); err_exclusive_options(c, longopts, excl, excl_st);
switch (c) { switch (c) {
@ -119,6 +122,9 @@ int main(int argc, char **argv)
case 's': case 's':
set_sort_func_by_name(&out, optarg); set_sort_func_by_name(&out, optarg);
break; break;
case 'S':
softirq = 1;
break;
case 'V': case 'V':
print_version(EXIT_SUCCESS); print_version(EXIT_SUCCESS);
case 'h': case 'h':
@ -132,7 +138,8 @@ int main(int argc, char **argv)
if (!out.ncolumns) { if (!out.ncolumns) {
out.columns[out.ncolumns++] = COL_IRQ; out.columns[out.ncolumns++] = COL_IRQ;
out.columns[out.ncolumns++] = COL_TOTAL; out.columns[out.ncolumns++] = COL_TOTAL;
out.columns[out.ncolumns++] = COL_NAME; if (!softirq)
out.columns[out.ncolumns++] = COL_NAME;
} }
/* add -o [+]<list> to putput */ /* add -o [+]<list> to putput */
@ -142,5 +149,5 @@ int main(int argc, char **argv)
irq_column_name_to_id) < 0) irq_column_name_to_id) < 0)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
return print_irq_data(&out) == 0 ? EXIT_SUCCESS : EXIT_FAILURE; return print_irq_data(&out, softirq) == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
} }