Integrate physical CPU usage statistics into xentop. This patch adds: - a new command-line option (-p, --pcpus) - display of per-CPU usage statistics - cleanup of pcpu resources on exit
This allows users to monitor host physical CPU utilization alongside existing domain metrics. Signed-off-by: Jahan Murudi <jahan.murudi...@renesas.com> --- tools/xentop/xentop.c | 79 +++++++++++++++++++++++++++++++++---------- 1 file changed, 61 insertions(+), 18 deletions(-) diff --git a/tools/xentop/xentop.c b/tools/xentop/xentop.c index f5d6c19cf9..addb1c70c9 100644 --- a/tools/xentop/xentop.c +++ b/tools/xentop/xentop.c @@ -37,6 +37,7 @@ #endif #include <xenstat.h> +#include "pcpu.h" #define XENTOP_VERSION "1.0" @@ -205,6 +206,7 @@ field_id sort_field = FIELD_DOMID; unsigned int first_domain_index = 0; unsigned int delay = 3; unsigned int batch = 0; +static unsigned int show_pcpus = 0; unsigned int loop = 1; unsigned int iterations = 0; int show_vcpus = 0; @@ -230,22 +232,23 @@ static WINDOW *cwin; /* Print usage message, using given program name */ static void usage(const char *program) { - printf("Usage: %s [OPTION]\n" - "Displays ongoing information about xen vm resources \n\n" - "-h, --help display this help and exit\n" - "-V, --version output version information and exit\n" - "-d, --delay=SECONDS seconds between updates (default 3)\n" - "-n, --networks output vif network data\n" - "-x, --vbds output vbd block device data\n" - "-r, --repeat-header repeat table header before each domain\n" - "-v, --vcpus output vcpu data\n" - "-b, --batch output in batch mode, no user input accepted\n" - "-i, --iterations number of iterations before exiting\n" - "-f, --full-name output the full domain name (not truncated)\n" - "-z, --dom0-first display dom0 first (ignore sorting)\n" - "\n" XENTOP_BUGSTO, - program); - return; + printf("Usage: %s [OPTION]\n" + "Displays ongoing information about xen vm resources \n\n" + "-h, --help display this help and exit\n" + "-V, --version output version information and exit\n" + "-d, --delay=SECONDS seconds between updates (default 3)\n" + "-n, --networks output vif network data\n" + "-x, --vbds output vbd block device data\n" + "-r, --repeat-header repeat table header before each domain\n" + "-v, --vcpus output vcpu data\n" + "-b, --batch output in batch mode, no user input accepted\n" + "-p, --pcpus show physical CPU stats\n" + "-i, --iterations number of iterations before exiting\n" + "-f, --full-name output the full domain name (not truncated)\n" + "-z, --dom0-first display dom0 first (ignore sorting)\n" + "\n" XENTOP_BUGSTO, + program); + return; } /* Print program version information */ @@ -267,6 +270,8 @@ static void cleanup(void) xenstat_free_node(cur_node); if(xhandle != NULL) xenstat_uninit(xhandle); + + free_pcpu_stats(); } /* Display the given message and gracefully exit */ @@ -313,6 +318,32 @@ static void print(const char *fmt, ...) } } +/* PCPU statistics display function */ +static void print_pcpu_stats_display(void) +{ + int i; + int num_cpus; + + if (!has_pcpu_data()) { + print("\nNo PCPU data available\n"); + return; + } + + num_cpus = get_pcpu_count(); + + /* Use the existing print() function which handles cursor bounds */ + print("\nPhysical CPU Usage:\n"); + print("+-------+--------+\n"); + print("| Core | Usage |\n"); + print("+-------+--------+\n"); + + for (i = 0; i < num_cpus; i++) { + print("| %-5d | %5.1f%% |\n", i, get_pcpu_usage(i)); + } + + print("+-------+--------+\n"); +} + static void xentop_attron(int attr) { if (!batch) @@ -1245,6 +1276,14 @@ static void top(void) do_vbd(domains[i]); } + if (show_pcpus) { + if (update_pcpu_stats(&curtime, delay) == 0) { + print_pcpu_stats_display(); + } else { + fail("Error getting PCPU stats\n"); + } + } + if (!batch) do_bottom_line(); @@ -1271,13 +1310,14 @@ int main(int argc, char **argv) { "repeat-header", no_argument, NULL, 'r' }, { "vcpus", no_argument, NULL, 'v' }, { "delay", required_argument, NULL, 'd' }, - { "batch", no_argument, NULL, 'b' }, + { "batch", no_argument, NULL, 'b' }, + { "pcpus", no_argument, NULL, 'p' }, { "iterations", required_argument, NULL, 'i' }, { "full-name", no_argument, NULL, 'f' }, { "dom0-first", no_argument, NULL, 'z' }, { 0, 0, 0, 0 }, }; - const char *sopts = "hVnxrvd:bi:fz"; + const char *sopts = "hVnxrvd:bpi:fz"; if (atexit(cleanup) != 0) fail("Failed to install cleanup handler.\n"); @@ -1312,6 +1352,9 @@ int main(int argc, char **argv) case 'b': batch = 1; break; + case 'p': + show_pcpus = 1; + break; case 'i': iterations = atoi(optarg); loop = 0; -- 2.34.1