COMPREPLY=( $(compgen -W "auto enable disable" -- $cur) )
return 0
;;
+ '-C'|'--cpu-list')
+ return 0
+ ;;
'-d'|'--delay')
COMPREPLY=( $(compgen -W "secs" -- $cur) )
return 0
;;
esac
OPTS=" --cpu-stat
+ --cpu-list
--delay
--sort
--output
#include <errno.h>
#include <limits.h>
#include <locale.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
return str;
}
+static bool cpu_in_list(int cpu, size_t setsize, cpu_set_t *cpuset)
+{
+ /* no -C/--cpu-list specified, use all the CPUs */
+ if (!cpuset)
+ return true;
+
+ return CPU_ISSET_S(cpu, setsize, cpuset);
+}
+
/*
* irqinfo - parse the system's interrupts
*/
-static struct irq_stat *get_irqinfo(int softirq)
+static struct irq_stat *get_irqinfo(int softirq, size_t setsize, cpu_set_t *cpuset)
{
FILE *irqfile;
char *line = NULL, *tmp;
if (sscanf(tmp, " %10lu", &count) != 1)
continue;
- curr->total += count;
- cpu->total += count;
- stat->total_irq += count;
+ if (cpu_in_list(index, setsize, cpuset)) {
+ curr->total += count;
+ cpu->total += count;
+ stat->total_irq += count;
+ }
tmp += 11;
}
struct libscols_table *get_scols_cpus_table(struct irq_output *out,
struct irq_stat *prev,
- struct irq_stat *curr)
+ struct irq_stat *curr,
+ size_t setsize,
+ cpu_set_t *cpuset)
{
struct libscols_table *table;
struct libscols_column *cl;
struct libscols_line *ln;
char colname[sizeof(stringify_value(LONG_MAX))];
- size_t i;
+ size_t i, j;
if (prev) {
for (i = 0; i < curr->nr_active_cpu; i++) {
scols_table_new_column(table, "", 0, SCOLS_FL_RIGHT);
for (i = 0; i < curr->nr_active_cpu; i++) {
+ if (!cpu_in_list(i, setsize, cpuset))
+ continue;
snprintf(colname, sizeof(colname), "cpu%zu", i);
cl = scols_table_new_column(table, colname, 0, SCOLS_FL_RIGHT);
if (cl == NULL) {
if (!ln || (!out->json && scols_line_set_data(ln, 0, "%irq:") != 0))
goto err;
- for (i = 0; i < curr->nr_active_cpu; i++) {
+ for (i = 0, j = 0; i < curr->nr_active_cpu; i++) {
struct irq_cpu *cpu = &curr->cpus[i];
char *str;
+ if (!cpu_in_list(i, setsize, cpuset))
+ continue;
xasprintf(&str, "%0.1f", (double)((long double) cpu->total / (long double) curr->total_irq * 100.0));
- if (str && scols_line_refer_data(ln, i + 1, str) != 0)
+ if (str && scols_line_refer_data(ln, ++j, str) != 0)
goto err;
}
if (!ln || (!out->json && scols_line_set_data(ln, 0, _("%delta:")) != 0))
goto err;
- for (i = 0; i < curr->nr_active_cpu; i++) {
+ for (i = 0, j = 0; i < curr->nr_active_cpu; i++) {
struct irq_cpu *cpu = &curr->cpus[i];
char *str;
+ if (!cpu_in_list(i, setsize, cpuset))
+ continue;
if (!curr->delta_irq)
continue;
xasprintf(&str, "%0.1f", (double)((long double) cpu->delta / (long double) curr->delta_irq * 100.0));
- if (str && scols_line_refer_data(ln, i + 1, str) != 0)
+ if (str && scols_line_refer_data(ln, ++j, str) != 0)
goto err;
}
struct libscols_table *get_scols_table(struct irq_output *out,
struct irq_stat *prev,
struct irq_stat **xstat,
- int softirq)
+ int softirq,
+ size_t setsize,
+ cpu_set_t *cpuset)
{
struct libscols_table *table;
struct irq_info *result;
size_t i;
/* the stats */
- stat = get_irqinfo(softirq);
+ stat = get_irqinfo(softirq, setsize, cpuset);
if (!stat)
return NULL;
#include "c.h"
#include "nls.h"
+#include "cpuset.h"
/* supported columns */
enum {
struct libscols_table *get_scols_table(struct irq_output *out,
struct irq_stat *prev,
struct irq_stat **xstat,
- int softirq);
+ int softirq,
+ size_t setsize,
+ cpu_set_t *cpuset);
struct libscols_table *get_scols_cpus_table(struct irq_output *out,
struct irq_stat *prev,
- struct irq_stat *curr);
+ struct irq_stat *curr,
+ size_t setsize,
+ cpu_set_t *cpuset);
#endif /* UTIL_LINUX_H_IRQ_COMMON */
*-c*, *--cpu-stat* _mode_::
Show per-cpu statistics by specified mode. Available modes are: *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.
+*-C*, *--cpu-list* _list_::
+Specify cpus in list format to show.
+
*-d*, *--delay* _seconds_::
Update interrupt output every _seconds_ intervals.
#include <libsmartcols.h>
#include "closestream.h"
+#include "cpuset.h"
#include "monotonic.h"
#include "pathnames.h"
#include "strutils.h"
struct itimerspec timer;
struct irq_stat *prev_stat;
+ size_t setsize;
+ cpu_set_t *cpuset;
enum irqtop_cpustat_mode cpustat_mode;
unsigned int request_exit:1;
char timestr[64], *data, *data0, *p;
/* make irqs table */
- table = get_scols_table(out, ctl->prev_stat, &stat, ctl->softirq);
+ table = get_scols_table(out, ctl->prev_stat, &stat, ctl->softirq, ctl->setsize,
+ ctl->cpuset);
if (!table) {
ctl->request_exit = 1;
return 1;
/* make cpus table */
if (ctl->cpustat_mode != IRQTOP_CPUSTAT_DISABLE) {
- cpus = get_scols_cpus_table(out, ctl->prev_stat, stat);
+ cpus = get_scols_cpus_table(out, ctl->prev_stat, stat, ctl->setsize,
+ ctl->cpuset);
scols_table_reduce_termwidth(cpus, 1);
if (ctl->cpustat_mode == IRQTOP_CPUSTAT_AUTO)
scols_table_enable_nowrap(cpus, 1);
fputs(USAGE_OPTIONS, stdout);
fputs(_(" -c, --cpu-stat <mode> show per-cpu stat (auto, enable, disable)\n"), stdout);
+ fputs(_(" -C, --cpu-list <list> specify cpus in list format\n"), stdout);
fputs(_(" -d, --delay <secs> delay updates\n"), stdout);
fputs(_(" -o, --output <list> define which output columns to use\n"), stdout);
fputs(_(" -s, --sort <column> specify sort column\n"), stdout);
const char *outarg = NULL;
static const struct option longopts[] = {
{"cpu-stat", required_argument, NULL, 'c'},
+ {"cpu-list", required_argument, NULL, 'C'},
{"delay", required_argument, NULL, 'd'},
{"sort", required_argument, NULL, 's'},
{"output", required_argument, NULL, 'o'},
};
int o;
- while ((o = getopt_long(argc, argv, "c:d:o:s:ShV", longopts, NULL)) != -1) {
+ while ((o = getopt_long(argc, argv, "c:C:d:o:s:ShV", longopts, NULL)) != -1) {
switch (o) {
case 'c':
if (!strcmp(optarg, "auto"))
else
errx(EXIT_FAILURE, _("unsupported mode '%s'"), optarg);
break;
+ case 'C':
+ {
+ int ncpus = get_max_number_of_cpus();
+ if (ncpus <= 0)
+ errx(EXIT_FAILURE, _("cannot determine NR_CPUS; aborting"));
+
+ ctl->cpuset = cpuset_alloc(ncpus, &ctl->setsize, NULL);
+ if (!ctl->cpuset)
+ err(EXIT_FAILURE, _("cpuset_alloc failed"));
+
+ if (cpulist_parse(optarg, ctl->cpuset, ctl->setsize, 0))
+ errx(EXIT_FAILURE, _("failed to parse CPU list: %s"),
+ optarg);
+ }
+ break;
case 'd':
{
struct timeval delay;
free_irqstat(ctl.prev_stat);
free(ctl.hostname);
+ cpuset_free(ctl.cpuset);
if (is_tty)
tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_tty);
{
struct libscols_table *table;
- table = get_scols_table(out, NULL, NULL, softirq);
+ table = get_scols_table(out, NULL, NULL, softirq, 0, NULL);
if (!table)
return -1;