All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] vm-stat utility
@ 2007-02-15 16:29 Andrew Theurer
  0 siblings, 0 replies; only message in thread
From: Andrew Theurer @ 2007-02-15 16:29 UTC (permalink / raw)
  To: xen-devel

Below is a utility which outputs utilization CPU by domain and by phys 
CPU.  We used this for some OLS work last year, and we have received 
some requests for the patch.  We needed this utility because we wanted 
to know which and how much of a phys CPU a domain was consuming, and we 
wanted output to be easily redirected to a text file, to be processed 
later. 

This patch is quite old (and very rough on the edges), but it should 
still apply to current xen-unstable.  It was originally based off xentop 
code (I am certain there are many lines in there, originally for xentop, 
which are not even needed for vm-stat).  I should also state that its 
ability to attribute a domain's vCPU time to a pCPU is not very accurate 
anymore with the addition of credit scheduler and load balancing.  When 
we did not load balance, it was pretty easy to assume a vCPU's time was 
all spent on one pCPU -not the case anymore.  If you want accurate 
vCPU->pCPU usage, I think we would need some additional data in vcpu 
struct, or just pin vCPUs to pCPUS for your tests.

I am not sure if this utility is of any use to anyone these days, but I 
wanted to make it available just in case.  I am not asking to have this 
included in xen, but if someone else finds it useful and wants to clean 
it up, have fun!

-Andrew

<signed-off-by: Andrew Theurer habanero@us.ibm.com>

diff -Naurp 1/tools/xenstat/libxenstat/src/xenstat.c 2/tools/xenstat/libxenstat/src/xenstat.c
--- 1/tools/xenstat/libxenstat/src/xenstat.c	2005-10-26 11:07:15.000000000 -0500
+++ 2/tools/xenstat/libxenstat/src/xenstat.c	2005-10-26 14:30:41.000000000 -0500
@@ -63,6 +63,7 @@ struct xenstat_domain {
 struct xenstat_vcpu {
 	unsigned int online;
 	unsigned long long ns;
+	int phys_cpu;
 };
 
 struct xenstat_network {
@@ -451,6 +452,7 @@ static int xenstat_collect_vcpus(xenstat
 
 			node->domains[i].vcpus[vcpu].online = info.online;
 			node->domains[i].vcpus[vcpu].ns = info.cpu_time;
+			node->domains[i].vcpus[vcpu].phys_cpu = info.cpu;
 		}
 	}
 	return 1;
@@ -475,6 +477,12 @@ unsigned int xenstat_vcpu_online(xenstat
 	return vcpu->online;
 }
 
+/* Get VCPU to PHYSCPU mapping */
+int xenstat_vcpu_physcpu(xenstat_vcpu * vcpu)
+{
+	return vcpu->phys_cpu;
+}
+
 /* Get VCPU usage */
 unsigned long long xenstat_vcpu_ns(xenstat_vcpu * vcpu)
 {
diff -Naurp 1/tools/xenstat/libxenstat/src/xenstat.h 2/tools/xenstat/libxenstat/src/xenstat.h
--- 1/tools/xenstat/libxenstat/src/xenstat.h	2005-10-26 11:07:15.000000000 -0500
+++ 2/tools/xenstat/libxenstat/src/xenstat.h	2005-10-26 11:08:46.000000000 -0500
@@ -118,6 +118,9 @@ xenstat_network *xenstat_domain_network(
  * VCPU functions - extract information from a xenstat_vcpu
  */
 
+/* Get VCPU to PHYSCPU mapping */
+int xenstat_vcpu_physcpu(xenstat_vcpu * vcpu);
+
 /* Get VCPU usage */
 unsigned int xenstat_vcpu_online(xenstat_vcpu * vcpu);
 unsigned long long xenstat_vcpu_ns(xenstat_vcpu * vcpu);
diff -Naurp 1/tools/xenstat/Makefile 2/tools/xenstat/Makefile
--- 1/tools/xenstat/Makefile	2005-10-26 15:05:50.000000000 -0500
+++ 2/tools/xenstat/Makefile	2005-10-26 11:08:46.000000000 -0500
@@ -6,7 +6,7 @@ SUBDIRS += libxenstat
 
 # This doesn't cross-compile (cross-compile environments rarely have curses)
 ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH))
-SUBDIRS += xentop
+SUBDIRS += xentop vm-stat
 endif
 
 .PHONY: all install clean
diff -Naurp 1/tools/xenstat/vm-stat/Makefile 2/tools/xenstat/vm-stat/Makefile
--- 1/tools/xenstat/vm-stat/Makefile	1969-12-31 18:00:00.000000000 -0600
+++ 2/tools/xenstat/vm-stat/Makefile	2005-10-26 11:08:46.000000000 -0500
@@ -0,0 +1,43 @@
+# Copyright (C) International Business Machines Corp., 2005
+# Author: Josh Triplett <josht@us.ibm.com>
+# 
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; under version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+XEN_ROOT=../../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+ifneq ($(XENSTAT_XENTOP),y)
+all install vm-stat:
+else
+
+INSTALL         = install
+INSTALL_PROG    = $(INSTALL) -m0755 -D
+INSTALL_DATA    = $(INSTALL) -m0644 -D
+
+prefix=/usr
+mandir=$(prefix)/share/man
+man1dir=$(mandir)/man1
+sbindir=$(prefix)/sbin
+
+CFLAGS += -DGCC_PRINTF -Wall -Werror -I$(XEN_LIBXENSTAT)
+LDFLAGS += -L$(XEN_LIBXENSTAT)
+LDLIBS += -lxenstat -lncurses
+
+all:  vm-stat
+
+vm-stat: vm-stat.o
+
+install: vm-stat
+	$(INSTALL_PROG) vm-stat $(DESTDIR)$(sbindir)/vm-stat
+
+endif
+
+clean:
+	rm -f vm-stat vm-stat.o
diff -Naurp 1/tools/xenstat/vm-stat/vm-stat.c 2/tools/xenstat/vm-stat/vm-stat.c
--- 1/tools/xenstat/vm-stat/vm-stat.c	1969-12-31 18:00:00.000000000 -0600
+++ 2/tools/xenstat/vm-stat/vm-stat.c	2005-10-26 11:08:46.000000000 -0500
@@ -0,0 +1,164 @@
+/*
+ *  Copyright (C) International Business Machines  Corp., 2005
+ *  Author(s): Judy Fischbach <jfisch@us.ibm.com>
+ *             David Hendricks <dhendrix@us.ibm.com>
+ *             Josh Triplett <josht@us.ibm.com>
+ *    based on code from Anthony Liguori <aliguori@us.ibm.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; under version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <curses.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+#include <xenstat.h>
+
+#define KEY_ESCAPE '\x1B'
+
+/*
+ * Function prototypes
+ */
+/* Utility functions */
+static void cleanup(void);
+static void fail(const char *);
+
+/* Section printing functions */
+static void top(void);
+
+
+/* Globals */
+struct timeval curtime, oldtime;
+xenstat_handle *xhandle = NULL;
+xenstat_node *prev_node = NULL;
+xenstat_node *cur_node = NULL;
+unsigned int delay = 3;
+
+/* Clean up any open resources */
+static void cleanup(void)
+{
+	if(prev_node != NULL)
+		xenstat_free_node(prev_node);
+	if(cur_node != NULL)
+		xenstat_free_node(cur_node);
+	if(xhandle != NULL)
+		xenstat_uninit(xhandle);
+}
+
+/* Display the given message and gracefully exit */
+static void fail(const char *str)
+{
+	fprintf(stderr, str);
+	exit(1);
+}
+
+static void top(void)
+{
+	xenstat_domain *cur_domain, *prev_domain;
+	unsigned int i, j, phys_cpu, num_domains = 0, num_vcpus;
+	xenstat_vcpu *prev_vcpu, *cur_vcpu;
+	unsigned long long vcpu_ns;
+	double us_elapsed;
+	typedef struct {
+		unsigned long long ns;
+		char detail[320];
+		int len;
+	} phys_cpu_t;
+
+	phys_cpu_t cpu[64];
+
+	double vcpu_pct;
+
+	for (i = 0; i < 64; i++) {
+		cpu[i].ns = 0;
+		cpu[i].len = 0;
+	}
+
+	prev_node = cur_node;
+	cur_node = xenstat_get_node(xhandle, XENSTAT_ALL);
+	if (cur_node == NULL)
+		fail("Failed to retrieve statistics from libxenstat\n");
+
+	/* Wait until we have 2 samples */
+	if (prev_node == NULL)
+		return;
+
+	printf("\nCPU  Total Pct   Virtual CPUs\n");
+	/* Count the number of domains for which to report data */
+	num_domains = xenstat_node_num_domains(cur_node);
+
+        us_elapsed = ((curtime.tv_sec-oldtime.tv_sec)*1000000.0
+		+ (curtime.tv_usec - oldtime.tv_usec));
+
+	for (i=0; i < num_domains; i++) {
+		cur_domain = xenstat_node_domain_by_index(cur_node, i);
+		prev_domain = xenstat_node_domain_by_index(prev_node, i);
+
+		if (prev_domain && cur_domain) {
+			unsigned int dom_id;
+			dom_id = xenstat_domain_id(cur_domain);
+			num_vcpus = xenstat_domain_num_vcpus(cur_domain);
+			for (j = 0; j < num_vcpus; j++) {
+				cur_vcpu = xenstat_domain_vcpu(cur_domain, j);
+				prev_vcpu = xenstat_domain_vcpu(prev_domain, j);
+				if (cur_vcpu >= 0 && prev_vcpu >= 0) {
+					phys_cpu = xenstat_vcpu_physcpu(cur_vcpu);
+					vcpu_ns = xenstat_vcpu_ns(cur_vcpu) - xenstat_vcpu_ns(prev_vcpu);
+					vcpu_pct = vcpu_ns / 10.0 / us_elapsed;
+					cpu[phys_cpu].ns += vcpu_ns;
+					cpu[phys_cpu].len += sprintf(&cpu[phys_cpu].detail[cpu[phys_cpu].len], " d%u-%u[%05.1f]", dom_id, j, vcpu_pct);
+
+				}
+			}
+		}
+	}
+	for (i = 0; i < 64; i++) {
+		double pct;
+		if (cpu[i].ns > 0) {
+
+			pct = cpu[i].ns / 10.0 / us_elapsed;
+			printf("%3i  [%05.1f]    %s\n", i, pct, cpu[i].detail);
+			fflush(NULL);
+		}
+	}
+}
+
+int main(int argc, char **argv)
+{
+	if (argc >= 2) {
+		delay = atoi(argv[1]);
+	}
+	if (atexit(cleanup) != 0)
+		fail("Failed to install cleanup handler.\n");
+
+	/* Get xenstat handle */
+	xhandle = xenstat_init();
+	if (xhandle == NULL)
+		fail("Failed to initialize xenstat library\n");
+
+	do {
+		gettimeofday(&curtime, NULL);
+		top();
+		oldtime = curtime;
+		sleep(delay);
+	} while (0 == 0);
+
+	/* Cleanup occurs in cleanup(), so no work to do here. */
+
+	return 0;
+}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2007-02-15 16:29 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-02-15 16:29 [PATCH] vm-stat utility Andrew Theurer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.