All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] kvm tools: Add 'kvm memstat' command
@ 2011-08-15 11:53 Sasha Levin
  2011-08-15 11:56 ` Pekka Enberg
  0 siblings, 1 reply; 6+ messages in thread
From: Sasha Levin @ 2011-08-15 11:53 UTC (permalink / raw)
  To: penberg; +Cc: mingo, asias.hejun, prasadjoshi124, gorcunov, kvm, Sasha Levin

This patch adds 'kvm memstat' command that allows retrieving memory statistics out of
a running guest using the virtio-balloon stats vq interface.

Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
 tools/kvm/Documentation/kvm-memstat.txt |   16 +++++
 tools/kvm/Makefile                      |    1 +
 tools/kvm/builtin-memstat.c             |   69 ++++++++++++++++++++
 tools/kvm/command-list.txt              |    1 +
 tools/kvm/include/kvm/builtin-memstat.h |    7 ++
 tools/kvm/include/kvm/kvm.h             |    1 +
 tools/kvm/kvm-cmd.c                     |    2 +
 tools/kvm/virtio/balloon.c              |  108 +++++++++++++++++++++++++++++-
 8 files changed, 201 insertions(+), 4 deletions(-)
 create mode 100644 tools/kvm/Documentation/kvm-memstat.txt
 create mode 100644 tools/kvm/builtin-memstat.c
 create mode 100644 tools/kvm/include/kvm/builtin-memstat.h

diff --git a/tools/kvm/Documentation/kvm-memstat.txt b/tools/kvm/Documentation/kvm-memstat.txt
new file mode 100644
index 0000000..0562d33
--- /dev/null
+++ b/tools/kvm/Documentation/kvm-memstat.txt
@@ -0,0 +1,16 @@
+kvm-memstat(1)
+================
+
+NAME
+----
+kvm-memstat - Print memory statistics about a running instance
+
+SYNOPSIS
+--------
+[verse]
+'kvm memstat [-n instance] [-p instance pid] [--all]'
+
+DESCRIPTION
+-----------
+The command prints memory statistics about a running instance.
+For a list of running instances see 'kvm list'.
diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index 3a06e10..ce68b8c 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -24,6 +24,7 @@ OBJS	+= builtin-balloon.o
 OBJS	+= builtin-debug.o
 OBJS	+= builtin-help.o
 OBJS	+= builtin-list.o
+OBJS	+= builtin-memstat.o
 OBJS	+= builtin-pause.o
 OBJS	+= builtin-resume.o
 OBJS	+= builtin-run.o
diff --git a/tools/kvm/builtin-memstat.c b/tools/kvm/builtin-memstat.c
new file mode 100644
index 0000000..d32d97a
--- /dev/null
+++ b/tools/kvm/builtin-memstat.c
@@ -0,0 +1,69 @@
+#include <kvm/util.h>
+#include <kvm/kvm-cmd.h>
+#include <kvm/builtin-memstat.h>
+#include <kvm/kvm.h>
+#include <kvm/parse-options.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+
+static bool all;
+static u64 instance_pid;
+static const char *instance_name;
+
+static const char * const memstat_usage[] = {
+	"kvm memstat [--all] [-n name] [-p pid]",
+	NULL
+};
+
+static const struct option memstat_options[] = {
+	OPT_GROUP("General options:"),
+	OPT_BOOLEAN('a', "all", &all, "Memstat all instances"),
+	OPT_STRING('n', "name", &instance_name, "name", "Instance name"),
+	OPT_U64('p', "pid", &instance_pid, "Instance pid"),
+	OPT_END()
+};
+
+static void parse_memstat_options(int argc, const char **argv)
+{
+	while (argc != 0) {
+		argc = parse_options(argc, argv, memstat_options, memstat_usage,
+				PARSE_OPT_STOP_AT_NON_OPTION);
+		if (argc != 0)
+			kvm_memstat_help();
+	}
+}
+
+void kvm_memstat_help(void)
+{
+	usage_with_options(memstat_usage, memstat_options);
+}
+
+static int do_memstat(const char *name, int pid)
+{
+	printf("Sending memstat command to %s, output should be on the targets' terminal.\n", name);
+	return kill(pid, SIGKVMMEMSTAT);
+}
+
+int kvm_cmd_memstat(int argc, const char **argv, const char *prefix)
+{
+	parse_memstat_options(argc, argv);
+
+	if (all)
+		return kvm__enumerate_instances(do_memstat);
+
+	if (instance_name == NULL &&
+	    instance_pid == 0)
+		kvm_memstat_help();
+
+	if (instance_name)
+		instance_pid = kvm__get_pid_by_instance(instance_name);
+
+	if (instance_pid <= 0)
+		die("Failed locating instance");
+
+	printf("Sending memstat command to designated instance, output should be on the targets' terminal.\n");
+
+	return kill(instance_pid, SIGKVMMEMSTAT);
+}
diff --git a/tools/kvm/command-list.txt b/tools/kvm/command-list.txt
index 6a49d0a..78f2dcf 100644
--- a/tools/kvm/command-list.txt
+++ b/tools/kvm/command-list.txt
@@ -10,3 +10,4 @@ kvm-list			common
 kvm-debug			common
 kvm-balloon			common
 kvm-stop			common
+kvm-memstat			common
diff --git a/tools/kvm/include/kvm/builtin-memstat.h b/tools/kvm/include/kvm/builtin-memstat.h
new file mode 100644
index 0000000..eb355ee
--- /dev/null
+++ b/tools/kvm/include/kvm/builtin-memstat.h
@@ -0,0 +1,7 @@
+#ifndef KVM__MEMSTAT_H
+#define KVM__MEMSTAT_H
+
+int kvm_cmd_memstat(int argc, const char **argv, const char *prefix);
+void kvm_memstat_help(void);
+
+#endif
diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h
index d4fe2a1..c2d815c 100644
--- a/tools/kvm/include/kvm/kvm.h
+++ b/tools/kvm/include/kvm/kvm.h
@@ -22,6 +22,7 @@
 #define SIGKVMDELMEM		(SIGRTMIN + 3)
 #define SIGKVMSTOP		(SIGRTMIN + 4)
 #define SIGKVMRESUME		(SIGRTMIN + 5)
+#define SIGKVMMEMSTAT		(SIGRTMIN + 6)
 
 struct kvm {
 	int			sys_fd;		/* For system ioctls(), i.e. /dev/kvm */
diff --git a/tools/kvm/kvm-cmd.c b/tools/kvm/kvm-cmd.c
index 4e3ea22..09e1825 100644
--- a/tools/kvm/kvm-cmd.c
+++ b/tools/kvm/kvm-cmd.c
@@ -12,6 +12,7 @@
 #include "kvm/builtin-list.h"
 #include "kvm/builtin-version.h"
 #include "kvm/builtin-stop.h"
+#include "kvm/builtin-memstat.h"
 #include "kvm/builtin-help.h"
 #include "kvm/kvm-cmd.h"
 #include "kvm/builtin-run.h"
@@ -26,6 +27,7 @@ struct cmd_struct kvm_commands[] = {
 	{ "version",	kvm_cmd_version,	NULL,			0 },
 	{ "--version",	kvm_cmd_version,	NULL,			0 },
 	{ "stop",	kvm_cmd_stop,		kvm_stop_help,		0 },
+	{ "memstat",	kvm_cmd_memstat,	kvm_memstat_help,	0 },
 	{ "help",	kvm_cmd_help,		NULL,			0 },
 	{ "run",	kvm_cmd_run,		kvm_run_help,		0 },
 	{ NULL,		NULL,			NULL,			0 },
diff --git a/tools/kvm/virtio/balloon.c b/tools/kvm/virtio/balloon.c
index 983a114..c5853a5 100644
--- a/tools/kvm/virtio/balloon.c
+++ b/tools/kvm/virtio/balloon.c
@@ -21,10 +21,11 @@
 #include <sys/stat.h>
 #include <pthread.h>
 
-#define NUM_VIRT_QUEUES		2
+#define NUM_VIRT_QUEUES		3
 #define VIRTIO_BLN_QUEUE_SIZE	128
 #define VIRTIO_BLN_INFLATE	0
 #define VIRTIO_BLN_DEFLATE	1
+#define VIRTIO_BLN_STATS	2
 
 struct bln_dev {
 	struct pci_device_header pci_hdr;
@@ -41,6 +42,12 @@ struct bln_dev {
 	struct virt_queue	vqs[NUM_VIRT_QUEUES];
 	struct thread_pool__job	jobs[NUM_VIRT_QUEUES];
 
+	struct virtio_balloon_stat stats[VIRTIO_BALLOON_S_NR];
+	struct virtio_balloon_stat *cur_stat;
+	u32			cur_stat_head;
+	u16			stat_count;
+	int			stat_waitfd;
+
 	struct virtio_balloon_config config;
 };
 
@@ -127,7 +134,7 @@ static bool virtio_bln_do_io_request(struct kvm *kvm, struct bln_dev *bdev, stru
 		if (queue == &bdev->vqs[VIRTIO_BLN_INFLATE]) {
 			madvise(guest_ptr, 1 << VIRTIO_BALLOON_PFN_SHIFT, MADV_DONTNEED);
 			bdev->config.actual++;
-		} else {
+		} else if (queue == &bdev->vqs[VIRTIO_BLN_DEFLATE]) {
 			bdev->config.actual--;
 		}
 	}
@@ -137,10 +144,46 @@ static bool virtio_bln_do_io_request(struct kvm *kvm, struct bln_dev *bdev, stru
 	return true;
 }
 
+static bool virtio_bln_do_stat_request(struct kvm *kvm, struct bln_dev *bdev, struct virt_queue *queue)
+{
+	struct iovec iov[VIRTIO_BLN_QUEUE_SIZE];
+	u16 out, in, head;
+	struct virtio_balloon_stat *stat;
+	u64 wait_val = 1;
+
+	head = virt_queue__get_iov(queue, iov, &out, &in, kvm);
+	stat = iov[0].iov_base;
+
+	/* Initial empty stat buffer */
+	if (bdev->cur_stat == NULL) {
+		bdev->cur_stat = stat;
+		bdev->cur_stat_head = head;
+
+		return true;
+	}
+
+	memcpy(bdev->stats, stat, iov[0].iov_len);
+
+	bdev->stat_count = iov[0].iov_len / sizeof(struct virtio_balloon_stat);
+	bdev->cur_stat = stat;
+	bdev->cur_stat_head = head;
+
+	if (write(bdev->stat_waitfd, &wait_val, sizeof(wait_val)) <= 0)
+		return -EFAULT;
+
+	return 1;
+}
+
 static void virtio_bln_do_io(struct kvm *kvm, void *param)
 {
 	struct virt_queue *vq = param;
 
+	if (vq == &bdev.vqs[VIRTIO_BLN_STATS]) {
+		virtio_bln_do_stat_request(kvm, &bdev, vq);
+		virt_queue__trigger_irq(vq, bdev.pci_hdr.irq_line, &bdev.isr, kvm);
+		return;
+	}
+
 	while (virt_queue__available(vq)) {
 		virtio_bln_do_io_request(kvm, &bdev, vq);
 		virt_queue__trigger_irq(vq, bdev.pci_hdr.irq_line, &bdev.isr, kvm);
@@ -218,15 +261,70 @@ static struct ioport_operations virtio_bln_io_ops = {
 	.io_out				= virtio_bln_pci_io_out,
 };
 
+static int virtio_bln__collect_stats(void)
+{
+	u64 tmp;
+
+	virt_queue__set_used_elem(&bdev.vqs[VIRTIO_BLN_STATS], bdev.cur_stat_head,
+				  sizeof(struct virtio_balloon_stat));
+	virt_queue__trigger_irq(&bdev.vqs[VIRTIO_BLN_STATS], bdev.pci_hdr.irq_line,
+				&bdev.isr, kvm);
+
+	if (read(bdev.stat_waitfd, &tmp, sizeof(tmp)) <= 0)
+		return -EFAULT;
+
+	return 0;
+}
+
+static int virtio_bln__print_stats(void)
+{
+	u16 i;
+
+	if (virtio_bln__collect_stats() < 0)
+		return -EFAULT;
+
+	printf("\n\n\t*** Guest memory statistics ***\n\n");
+	for (i = 0; i < bdev.stat_count; i++) {
+		switch (bdev.stats[i].tag) {
+		case VIRTIO_BALLOON_S_SWAP_IN:
+			printf("The amount of memory that has been swapped in (in bytes):");
+			break;
+		case VIRTIO_BALLOON_S_SWAP_OUT:
+			printf("The amount of memory that has been swapped out to disk (in bytes):");
+			break;
+		case VIRTIO_BALLOON_S_MAJFLT:
+			printf("The number of major page faults that have occurred:");
+			break;
+		case VIRTIO_BALLOON_S_MINFLT:
+			printf("The number of minor page faults that have occurred:");
+			break;
+		case VIRTIO_BALLOON_S_MEMFREE:
+			printf("The amount of memory not being used for any purpose (in bytes):");
+			break;
+		case VIRTIO_BALLOON_S_MEMTOT:
+			printf("The total amount of memory available (in bytes):");
+			break;
+		}
+		printf("%llu\n", bdev.stats[i].val);
+	}
+	printf("\n");
+
+	return 0;
+}
+
 static void handle_sigmem(int sig)
 {
 	if (sig == SIGKVMADDMEM) {
 		bdev.config.num_pages += 256;
-	} else {
+	} else if (sig == SIGKVMDELMEM) {
 		if (bdev.config.num_pages < 256)
 			return;
 
 		bdev.config.num_pages -= 256;
+	} else if (sig == SIGKVMMEMSTAT) {
+		virtio_bln__print_stats();
+
+		return;
 	}
 
 	/* Notify that the configuration space has changed */
@@ -241,6 +339,7 @@ void virtio_bln__init(struct kvm *kvm)
 
 	signal(SIGKVMADDMEM, handle_sigmem);
 	signal(SIGKVMDELMEM, handle_sigmem);
+	signal(SIGKVMMEMSTAT, handle_sigmem);
 
 	bdev_base_addr = ioport__register(IOPORT_EMPTY, &virtio_bln_io_ops, IOPORT_SIZE, &bdev);
 
@@ -262,7 +361,8 @@ void virtio_bln__init(struct kvm *kvm)
 
 	bdev.pci_hdr.irq_pin	= pin;
 	bdev.pci_hdr.irq_line	= line;
-	bdev.host_features	= 0;
+	bdev.host_features	= 1 << VIRTIO_BALLOON_F_STATS_VQ;
+	bdev.stat_waitfd	= eventfd(0, 0);
 	memset(&bdev.config, 0, sizeof(struct virtio_balloon_config));
 
 	pci__register(&bdev.pci_hdr, dev);
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] kvm tools: Add 'kvm memstat' command
  2011-08-15 11:53 [PATCH] kvm tools: Add 'kvm memstat' command Sasha Levin
@ 2011-08-15 11:56 ` Pekka Enberg
  2011-08-15 12:02   ` Sasha Levin
  0 siblings, 1 reply; 6+ messages in thread
From: Pekka Enberg @ 2011-08-15 11:56 UTC (permalink / raw)
  To: Sasha Levin; +Cc: mingo, asias.hejun, prasadjoshi124, gorcunov, kvm

On 8/15/11 2:53 PM, Sasha Levin wrote:
> This patch adds 'kvm memstat' command that allows retrieving memory statistics out of
> a running guest using the virtio-balloon stats vq interface.
>
> Signed-off-by: Sasha Levin<levinsasha928@gmail.com>

Shouldn't we just call this "kvm stat"? We can print out all statistics 
by default and
add command line options like "--mem" to display individual stats?

                         Pekka

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] kvm tools: Add 'kvm memstat' command
  2011-08-15 11:56 ` Pekka Enberg
@ 2011-08-15 12:02   ` Sasha Levin
  2011-08-15 12:06     ` Pekka Enberg
  0 siblings, 1 reply; 6+ messages in thread
From: Sasha Levin @ 2011-08-15 12:02 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: mingo, asias.hejun, prasadjoshi124, gorcunov, kvm

On Mon, 2011-08-15 at 14:56 +0300, Pekka Enberg wrote:
> On 8/15/11 2:53 PM, Sasha Levin wrote:
> > This patch adds 'kvm memstat' command that allows retrieving memory statistics out of
> > a running guest using the virtio-balloon stats vq interface.
> >
> > Signed-off-by: Sasha Levin<levinsasha928@gmail.com>
> 
> Shouldn't we just call this "kvm stat"? We can print out all statistics 
> by default and
> add command line options like "--mem" to display individual stats?

Do we have any other statistics to print out at the moment?

-- 

Sasha.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] kvm tools: Add 'kvm memstat' command
  2011-08-15 12:02   ` Sasha Levin
@ 2011-08-15 12:06     ` Pekka Enberg
  2011-08-16  5:01       ` Asias He
  0 siblings, 1 reply; 6+ messages in thread
From: Pekka Enberg @ 2011-08-15 12:06 UTC (permalink / raw)
  To: Sasha Levin; +Cc: mingo, asias.hejun, prasadjoshi124, gorcunov, kvm

On 8/15/11 3:02 PM, Sasha Levin wrote:
> On Mon, 2011-08-15 at 14:56 +0300, Pekka Enberg wrote:
>> On 8/15/11 2:53 PM, Sasha Levin wrote:
>>> This patch adds 'kvm memstat' command that allows retrieving memory statistics out of
>>> a running guest using the virtio-balloon stats vq interface.
>>>
>>> Signed-off-by: Sasha Levin<levinsasha928@gmail.com>
>> Shouldn't we just call this "kvm stat"? We can print out all statistics
>> by default and
>> add command line options like "--mem" to display individual stats?
> Do we have any other statistics to print out at the moment?

Not right now but IIRC Asias talked about networking statistics. The
'kvm memstat' feels too specific to justify a separate builtin as
opposed to an command line option in a 'kvm stat' command.

                         Pekka

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] kvm tools: Add 'kvm memstat' command
  2011-08-15 12:06     ` Pekka Enberg
@ 2011-08-16  5:01       ` Asias He
  2011-08-19  0:46         ` Neo Jia
  0 siblings, 1 reply; 6+ messages in thread
From: Asias He @ 2011-08-16  5:01 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Sasha Levin, mingo, prasadjoshi124, gorcunov, kvm

On 08/15/2011 08:06 PM, Pekka Enberg wrote:
> On 8/15/11 3:02 PM, Sasha Levin wrote:
>> On Mon, 2011-08-15 at 14:56 +0300, Pekka Enberg wrote:
>>> On 8/15/11 2:53 PM, Sasha Levin wrote:
>>>> This patch adds 'kvm memstat' command that allows retrieving memory
>>>> statistics out of
>>>> a running guest using the virtio-balloon stats vq interface.
>>>>
>>>> Signed-off-by: Sasha Levin<levinsasha928@gmail.com>
>>> Shouldn't we just call this "kvm stat"? We can print out all statistics
>>> by default and
>>> add command line options like "--mem" to display individual stats?
>> Do we have any other statistics to print out at the moment?
> 
> Not right now but IIRC Asias talked about networking statistics. The
> 'kvm memstat' feels too specific to justify a separate builtin as
> opposed to an command line option in a 'kvm stat' command.

Yes. the command I am proposing is 'kvm info'. We can have a lot of
thing in 'kvm info', like register info, network info ,disk info. mem
info. Actually, Pekka suggested to have kvm info for all the infos and
if we are getting too much, we can split kvm info into sub command, like
kvm info mem, kvm info reg.

-- 
Best Regards,
Asias He

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] kvm tools: Add 'kvm memstat' command
  2011-08-16  5:01       ` Asias He
@ 2011-08-19  0:46         ` Neo Jia
  0 siblings, 0 replies; 6+ messages in thread
From: Neo Jia @ 2011-08-19  0:46 UTC (permalink / raw)
  To: Asias He; +Cc: Pekka Enberg, Sasha Levin, mingo, prasadjoshi124, gorcunov, kvm

On Tue, Aug 16, 2011 at 01:01:34PM +0800, Asias He wrote:
> On 08/15/2011 08:06 PM, Pekka Enberg wrote:
> > On 8/15/11 3:02 PM, Sasha Levin wrote:
> >> On Mon, 2011-08-15 at 14:56 +0300, Pekka Enberg wrote:
> >>> On 8/15/11 2:53 PM, Sasha Levin wrote:
> >>>> This patch adds 'kvm memstat' command that allows retrieving memory
> >>>> statistics out of
> >>>> a running guest using the virtio-balloon stats vq interface.
> >>>>
> >>>> Signed-off-by: Sasha Levin<levinsasha928@gmail.com>
> >>> Shouldn't we just call this "kvm stat"? We can print out all statistics
> >>> by default and
> >>> add command line options like "--mem" to display individual stats?
> >> Do we have any other statistics to print out at the moment?
> > 
> > Not right now but IIRC Asias talked about networking statistics. The
> > 'kvm memstat' feels too specific to justify a separate builtin as
> > opposed to an command line option in a 'kvm stat' command.
> 
> Yes. the command I am proposing is 'kvm info'. We can have a lot of
> thing in 'kvm info', like register info, network info ,disk info. mem
> info. Actually, Pekka suggested to have kvm info for all the infos and
> if we are getting too much, we can split kvm info into sub command, like
> kvm info mem, kvm info reg.

Should we already have something similar from QEMU already such as register and
memory access?

Can we use this interface to write to guest physical address?

Thanks,
CJ


> 
> -- 
> Best Regards,
> Asias He
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2011-08-19  0:47 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-15 11:53 [PATCH] kvm tools: Add 'kvm memstat' command Sasha Levin
2011-08-15 11:56 ` Pekka Enberg
2011-08-15 12:02   ` Sasha Levin
2011-08-15 12:06     ` Pekka Enberg
2011-08-16  5:01       ` Asias He
2011-08-19  0:46         ` Neo Jia

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.