mpstat \- Report processors related statistics.
.SH SYNOPSIS
-.B mpstat [ -A ] [ --dec={ 0 | 1 | 2 } ] [ -n ] [ -u ] [ -T ] [ -V ] [ -I {
+.B mpstat [ -A ] [ --dec={ 0 | 1 | 2 } ] [ -n ] [ -u ] [ -T ] [ -V ] [ -H ] [ -I {
.IB "keyword" "[,...] | ALL } ] [ -N { " "node_list " "| ALL } ] [ -o JSON ] [ -P {"
.IB "cpu_list " "| ALL } ] [ " "interval " "[ " "count " "] ]"
.B --dec={ 0 | 1 | 2 }
Specify the number of decimal places to use (0 to 2, default value is 2).
.TP
+.B -H
+Detect and Display stats of physically hotplugged vCPUs also
.BI "-I { " "keyword" "[,...] | ALL }"
Report interrupts statistics.
.RI "Possible " "keywords " "are"
/*
* mpstat: per-processor statistics
* (C) 2000-2022 by Sebastien GODARD (sysstat <at> orange.fr)
+ * Copyright (c) 2022, Oracle and/or its affiliates.
*
***************************************************************************
* This program is free software; you can redistribute it and/or modify it *
progname);
fprintf(stderr, _("Options are:\n"
- "[ -A ] [ -n ] [ -T ] [ -u ] [ -V ]\n"
+ "[ -A ] [ -n ] [ -T ] [ -u ] [ -V ] [ -H ]\n"
"[ -I { SUM | CPU | SCPU | ALL } ] [ -N { <node_list> | ALL } ]\n"
"[ --dec={ 0 | 1 | 2 } ] [ -o JSON ] [ -P { <cpu_list> | ALL } ]\n"));
exit(1);
* IN:
* @dis_hdr Set to TRUE if the header line must always be printed.
* @rows Number of rows of screen.
+ *
+ * OUT:
+ * @new_cpu_nr Return 0 as default.
+ * Return new_cpu_nr (!=0) if physical vCPU hotplug occured.
***************************************************************************
*/
-void rw_mpstat_loop(int dis_hdr, int rows)
+int rw_mpstat_loop(int dis_hdr, int rows)
{
struct stats_cpu *scc;
int i;
int curr = 1, dis = 1;
+ int new_cpu_nr = 0;
unsigned long lines = rows;
/* Read system uptime and CPU stats */
if (sigint_caught)
/* SIGINT signal caught during first interval: Exit immediately */
- return;
+ return 0;
do {
/*
curr ^= 1;
}
}
+
+ /* -H option is given and vCPU physical hotplug occured */
+ if (USE_OPTION_H(flags)) {
+ new_cpu_nr = get_cpu_nr(~0, TRUE);
+ if (new_cpu_nr > cpu_nr) {
+ return new_cpu_nr;
+ }
+ }
}
while (count);
else {
write_stats_avg(curr, dis_hdr);
}
+ return 0;
+}
+
+/*
+ ***************************************************************************
+ * Detect physical vCPU hotplug and call rw_mpstat_loop to display stats
+ *
+ * IN:
+ * @dis_hdr Set to TRUE if the header line must always be printed.
+ * @rows Number of rows of screen.
+ ***************************************************************************
+ */
+void mpstat_loop(int dis_hdr, int rows)
+{
+ int new_cpu_nr = 0;
+
+ while (1) {
+ /* Main loop for reading-writing stats */
+ new_cpu_nr = rw_mpstat_loop(dis_hdr, rows);
+
+ /* Handle vCPU physical hotplug */
+ if (new_cpu_nr == 0) {
+ return;
+ }
+ else {
+ /* Update the highest processor number */
+ cpu_nr = new_cpu_nr;
+
+ /* Recalculate number of interrupts per processor */
+ irqcpu_nr = get_irqcpu_nr(INTERRUPTS, NR_IRQS, cpu_nr) +
+ NR_IRQCPU_PREALLOC;
+ /* Recalculate number of soft interrupts per processor */
+ softirqcpu_nr = get_irqcpu_nr(SOFTIRQS, NR_IRQS, cpu_nr) +
+ NR_IRQCPU_PREALLOC;
+
+ /*
+ * Reallocate cpu stats structs :
+ * global, proc0, proc1, ..., proc$(prev_cpu_nr-1).
+ * global, proc0, proc1, ..., proc$(prev_cpu_nr-1), ..., proc$(cpu_nr-1).
+ */
+ salloc_mp_struct(cpu_nr + 1, FALSE);
+
+ /* Get NUMA node placement */
+ node_nr = get_node_placement(cpu_nr, cpu_per_node, cpu2node);
+ }
+ }
}
/*
print_version();
break;
+ case 'H':
+ /* Display physically hotplugged vCPU also */
+ flags |= F_OPTION_H;
+ break;
+
default:
usage(argv[0]);
}
DISPLAY_JSON_OUTPUT(flags));
/* Main loop */
- rw_mpstat_loop(dis_hdr, rows);
+ mpstat_loop(dis_hdr, rows);
/* Free structures */
sfree_mp_struct();