]> git.proxmox.com Git - pve-qemu-kvm.git/commitdiff
re-enable balloon stats
authorDietmar Maurer <dietmar@proxmox.com>
Tue, 11 Dec 2012 11:49:17 +0000 (12:49 +0100)
committerDietmar Maurer <dietmar@proxmox.com>
Wed, 12 Dec 2012 13:18:34 +0000 (14:18 +0100)
Makefile
debian/changelog
debian/patches/series
debian/patches/virtio-balloon-document-stats.patch [new file with mode: 0644]
debian/patches/virtio-balloon-drop-old-stats-code.patch [new file with mode: 0644]
debian/patches/virtio-balloon-pvefixes.patch [new file with mode: 0644]
debian/patches/virtio-balloon-re-enable-balloon-stats.patch [new file with mode: 0644]

index 6751eef8085bf0ff5112cf72c468971b12908358..9d4fb408371eb05f3d2115ab9ff5eb00e9f175ee 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ RELEASE=2.2
 
 # also update debian/changelog
 KVMVER=1.3
-KVMPKGREL=7
+KVMPKGREL=8
 
 KVMPACKAGE=pve-qemu-kvm
 KVMDIR=qemu-kvm
index 2f386d8431eef5b9c31876a72e9bfe880ccbf72f..8469aa389a7c09e30711624b846d1392b120b72a 100644 (file)
@@ -1,3 +1,9 @@
+pve-qemu-kvm (1.3-8) unstable; urgency=low
+
+  * re-enable balloon stats
+
+ -- Proxmox Support Team <support@proxmox.com>  Tue, 11 Dec 2012 12:48:26 +0100
+
 pve-qemu-kvm (1.3-7) unstable; urgency=low
 
   * update seabios to e8a76b0f225bba5ba9d63ab227e0a37b3beb1059
index 8331b3163678e17f29aa4fcf092a1e28cb33e85b..d2972972e7ac956f711731452e936e4135f44776 100644 (file)
@@ -18,3 +18,7 @@ enable-kvm-by-default.patch
 0004-introduce-new-vma-archive-format.patch
 0005-add-regression-tests-for-backup.patch
 0006-add-vm-state-to-backups.patch
+virtio-balloon-drop-old-stats-code.patch
+virtio-balloon-re-enable-balloon-stats.patch
+virtio-balloon-document-stats.patch
+virtio-balloon-pvefixes.patch
diff --git a/debian/patches/virtio-balloon-document-stats.patch b/debian/patches/virtio-balloon-document-stats.patch
new file mode 100644 (file)
index 0000000..b4a460f
--- /dev/null
@@ -0,0 +1,108 @@
+From: Luiz Capitulino <lcapitulino@redhat.com>
+Subject: [Qemu-devel] [PATCH 3/3] docs: document virtio-balloon stats
+
+Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
+---
+ docs/virtio-balloon-stats.txt | 87 +++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 87 insertions(+)
+ create mode 100644 docs/virtio-balloon-stats.txt
+
+diff --git a/docs/virtio-balloon-stats.txt b/docs/virtio-balloon-stats.txt
+new file mode 100644
+index 0000000..139e74d
+--- /dev/null
++++ b/docs/virtio-balloon-stats.txt
+@@ -0,0 +1,87 @@
++virtio balloon memory statistics
++================================
++
++The virtio balloon driver supports guest memory statistics reporting. These
++statistics are available to QEMU users as QOM (QEMU Object Model) device
++properties via a polling mechanism.
++
++Basically, clients first have to enable polling, then they can query the
++available statistics.
++
++There are two control properties and six memory statistics properties.
++
++The control properties are:
++
++ o stats-polling-interval: polling time interval in seconds, it can be:
++
++   > 0  enables polling in the specified interval. If polling is already
++        enabled, the polling time interval will be changed to the new value
++
++   0    disables polling. Previous polled statistics are still valid and
++        can be queried.
++
++ o stats-last-update: last stats update timestamp, in seconds
++
++The following statistics are available, all values are in bytes:
++
++ o stat-swap-in
++ o stat-swap-out
++ o stat-major-faults
++ o stat-minor-faults
++ o stat-free-memory
++ o stat-total-memory
++
++Also, please note the following:
++
++ - If a statistic is queried before the timer is enabled or if the guest
++   doesn't support a particular statistic, an error will be returned
++
++ - Previously polled statistics remain available even if the timer is
++   later disabled
++
++ - The polling timer is only re-armed when the guest answers to the
++   statistics request. This means that if the guest takes too long to
++   respond (say, a few seconds) this delay will end up being added to the
++   poll interval. Also, if a (buggy) guest doesn't ever respond, the
++   statistics won't get updated and the timer disarmed
++
++Here are a few examples. The virtio-balloon device is assumed to be in the
++'/machine/peripheral-anon/device[1]' QOM path.
++
++Enable polling with 2 seconds interval:
++
++{ "execute": "qom-set",
++             "arguments": { "path": "/machine/peripheral-anon/device[1]",
++                       "property": "stats-polling-interval", "value": 2 } }
++
++{ "return": {} }
++
++Change polling to 10 seconds:
++
++{ "execute": "qom-set",
++             "arguments": { "path": "/machine/peripheral-anon/device[1]",
++                       "property": "stats-polling-interval", "value": 10 } }
++
++{ "return": {} }
++
++Get last update timestamp and free memory stat:
++
++{ "execute": "qom-get",
++  "arguments": { "path": "/machine/peripheral-anon/device[1]",
++  "property": "stats-last-update" } }
++
++{ "return": 1354629634 }
++
++{ "execute": "qom-get",
++  "arguments": { "path": "/machine/peripheral-anon/device[1]",
++  "property": "stat-free-memory" } }
++
++{ "return": 845115392 }
++
++Disable polling:
++
++{ "execute": "qom-set",
++             "arguments": { "path": "/machine/peripheral-anon/device[1]",
++                       "property": "stats-polling-interval", "value": 0 } }
++
++{ "return": {} }
+-- 
+1.8.0
+
+
+
+
diff --git a/debian/patches/virtio-balloon-drop-old-stats-code.patch b/debian/patches/virtio-balloon-drop-old-stats-code.patch
new file mode 100644 (file)
index 0000000..cf606fe
--- /dev/null
@@ -0,0 +1,50 @@
+From: Luiz Capitulino <lcapitulino@redhat.com>
+Subject: [Qemu-devel] [PATCH 1/3] virtio-balloon: drop old stats code
+
+Next commit will re-enable balloon stats with a different interface, but
+this old code conflicts with it. Drop it.
+
+Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
+---
+ hw/virtio-balloon.c | 22 ----------------------
+ 1 file changed, 22 deletions(-)
+
+diff --git a/hw/virtio-balloon.c b/hw/virtio-balloon.c
+index dd1a650..4398025 100644
+--- a/hw/virtio-balloon.c
++++ b/hw/virtio-balloon.c
+@@ -164,28 +164,6 @@ static uint32_t virtio_balloon_get_features(VirtIODevice *vdev, uint32_t f)
+ static void virtio_balloon_stat(void *opaque, BalloonInfo *info)
+ {
+     VirtIOBalloon *dev = opaque;
+-
+-#if 0
+-    /* Disable guest-provided stats for now. For more details please check:
+-     * https://bugzilla.redhat.com/show_bug.cgi?id=623903
+-     *
+-     * If you do enable it (which is probably not going to happen as we
+-     * need a new command for it), remember that you also need to fill the
+-     * appropriate members of the BalloonInfo structure so that the stats
+-     * are returned to the client.
+-     */
+-    if (dev->vdev.guest_features & (1 << VIRTIO_BALLOON_F_STATS_VQ)) {
+-        virtqueue_push(dev->svq, &dev->stats_vq_elem, dev->stats_vq_offset);
+-        virtio_notify(&dev->vdev, dev->svq);
+-        return;
+-    }
+-#endif
+-
+-    /* Stats are not supported.  Clear out any stale values that might
+-     * have been set by a more featureful guest kernel.
+-     */
+-    reset_stats(dev);
+-
+     info->actual = ram_size - ((uint64_t) dev->actual <<
+                                VIRTIO_BALLOON_PFN_SHIFT);
+ }
+-- 
+1.8.0
+
+
+
+
diff --git a/debian/patches/virtio-balloon-pvefixes.patch b/debian/patches/virtio-balloon-pvefixes.patch
new file mode 100644 (file)
index 0000000..4621e62
--- /dev/null
@@ -0,0 +1,27 @@
+Index: new/hw/virtio-balloon.c
+===================================================================
+--- new.orig/hw/virtio-balloon.c       2012-12-12 14:05:56.000000000 +0100
++++ new/hw/virtio-balloon.c    2012-12-12 14:07:43.000000000 +0100
+@@ -111,6 +111,10 @@
+ {
+     VirtIOBalloon *s = opaque;
++    if (!balloon_stats_supported(s) || !runstate_is_running()) {
++        return;
++    }
++
+     virtqueue_push(s->svq, &s->stats_vq_elem, s->stats_vq_offset);
+     virtio_notify(&s->vdev, s->svq);
+ }
+@@ -164,11 +168,6 @@
+     VirtIOBalloon *s = opaque;
+     int64_t value;
+-    if (!balloon_stats_supported(s)) {
+-        error_setg(errp, "guest doesn\'t support balloon stats");
+-        return;
+-    }
+-
+     visit_type_int(v, &value, name, errp);
+     if (error_is_set(errp)) {
+         return;
diff --git a/debian/patches/virtio-balloon-re-enable-balloon-stats.patch b/debian/patches/virtio-balloon-re-enable-balloon-stats.patch
new file mode 100644 (file)
index 0000000..c980b05
--- /dev/null
@@ -0,0 +1,275 @@
+From: Luiz Capitulino <lcapitulino@redhat.com>
+Subject: [Qemu-devel] [PATCH 2/3] virtio-balloon: re-enable balloon stats
+
+The statistics are now available through device properties via a
+polling mechanism. First a client has to enable polling, then it
+can query each stat individually.
+
+The following control properties are introduced:
+
+ o stats-polling-interval: a value greater than zero enables polling
+   in the specified interval (in seconds). When value equals zero,
+   polling is disabled. If polling is already enabled and a value
+   greater than zero is written, the polling interval time is changed
+
+ o stats-last-update: last stats update timestamp, in seconds.
+
+The following stats properties are introduced, all values are in bytes:
+
+ o stat-swap-in
+ o stat-swap-out
+ o stat-major-faults
+ o stat-minor-faults
+ o stat-free-memory
+ o stat-total-memory
+
+Please, refer to the documentation introduced by the next commit for
+more information and examples.
+
+Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
+---
+ hw/virtio-balloon.c | 167 +++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 165 insertions(+), 2 deletions(-)
+
+diff --git a/hw/virtio-balloon.c b/hw/virtio-balloon.c
+index 4398025..4bab2ae 100644
+--- a/hw/virtio-balloon.c
++++ b/hw/virtio-balloon.c
+@@ -22,6 +22,8 @@
+ #include "virtio-balloon.h"
+ #include "kvm.h"
+ #include "exec-memory.h"
++#include "qemu-timer.h"
++#include "qapi/qapi-visit-core.h"
+ #if defined(__linux__)
+ #include <sys/mman.h>
+@@ -36,6 +38,9 @@ typedef struct VirtIOBalloon
+     uint64_t stats[VIRTIO_BALLOON_S_NR];
+     VirtQueueElement stats_vq_elem;
+     size_t stats_vq_offset;
++    QEMUTimer *stats_timer;
++    int64_t stats_last_update;
++    int64_t stats_poll_interval;
+     DeviceState *qdev;
+ } VirtIOBalloon;
+@@ -53,6 +58,16 @@ static void balloon_page(void *addr, int deflate)
+ #endif
+ }
++static const char *balloon_stat_names[] = {
++   [VIRTIO_BALLOON_S_SWAP_IN] = "stat-swap-in", 
++   [VIRTIO_BALLOON_S_SWAP_OUT] = "stat-swap-out",
++   [VIRTIO_BALLOON_S_MAJFLT] = "stat-major-faults",
++   [VIRTIO_BALLOON_S_MINFLT] = "stat-minor-faults",
++   [VIRTIO_BALLOON_S_MEMFREE] = "stat-free-memory",
++   [VIRTIO_BALLOON_S_MEMTOT] = "stat-total-memory",
++   [VIRTIO_BALLOON_S_NR] = NULL
++};
++
+ /*
+  * reset_stats - Mark all items in the stats array as unset
+  *
+@@ -67,6 +82,127 @@ static inline void reset_stats(VirtIOBalloon *dev)
+     for (i = 0; i < VIRTIO_BALLOON_S_NR; dev->stats[i++] = -1);
+ }
++static bool balloon_stats_supported(const VirtIOBalloon *s)
++{
++    return s->vdev.guest_features & (1 << VIRTIO_BALLOON_F_STATS_VQ);
++}
++
++static bool balloon_stats_enabled(const VirtIOBalloon *s)
++{
++    return s->stats_poll_interval > 0;
++}
++
++static void balloon_stats_destroy_timer(VirtIOBalloon *s)
++{
++    if (balloon_stats_enabled(s)) {
++        qemu_del_timer(s->stats_timer);
++        qemu_free_timer(s->stats_timer);
++        s->stats_timer = NULL;
++        s->stats_poll_interval = 0;
++    }
++}
++
++static void balloon_stats_change_timer(VirtIOBalloon *s, int secs)
++{
++    qemu_mod_timer(s->stats_timer, qemu_get_clock_ms(vm_clock) + secs * 1000);
++}
++
++static void balloon_stats_poll_cb(void *opaque)
++{
++    VirtIOBalloon *s = opaque;
++
++    virtqueue_push(s->svq, &s->stats_vq_elem, s->stats_vq_offset);
++    virtio_notify(&s->vdev, s->svq);
++}
++
++static void balloon_stats_get_last_update(Object *obj, struct Visitor *v,
++                                          void *opaque, const char *name,
++                                          Error **errp)
++{
++    VirtIOBalloon *s = opaque;
++    visit_type_int(v, &s->stats_last_update, name, errp);
++}
++
++static void balloon_stats_get_stat(Object *obj, struct Visitor *v,
++                                   void *opaque, const char *name, Error **errp)
++{
++    VirtIOBalloon *s = opaque;
++    int i;
++
++    for (i = 0; i < VIRTIO_BALLOON_S_NR; i++) {
++        if (!strcmp(balloon_stat_names[i], name)) {
++            break;
++        }
++    }
++
++    if (i == VIRTIO_BALLOON_S_NR) {
++        error_setg(errp, "invalid stat name '%s'", name);
++        return;
++    }
++
++    if (s->stats[i] == -1) {
++        error_setg(errp,
++            "timer hasn't been enabled or guest doesn't support '%s'", name);
++        return;
++    }
++
++    visit_type_int(v, (int64_t *) &s->stats[i], name, errp);
++}
++
++static void balloon_stats_get_poll_interval(Object *obj, struct Visitor *v,
++                                            void *opaque, const char *name,
++                                            Error **errp)
++{
++    VirtIOBalloon *s = opaque;
++    visit_type_int(v, &s->stats_poll_interval, name, errp);
++}
++
++static void balloon_stats_set_poll_interval(Object *obj, struct Visitor *v,
++                                            void *opaque, const char *name,
++                                            Error **errp)
++{
++    VirtIOBalloon *s = opaque;
++    int64_t value;
++
++    if (!balloon_stats_supported(s)) {
++        error_setg(errp, "guest doesn\'t support balloon stats");
++        return;
++    }
++
++    visit_type_int(v, &value, name, errp);
++    if (error_is_set(errp)) {
++        return;
++    }
++
++    if (value < 0) {
++        error_setg(errp, "timer value must be positive");
++        return;
++    }
++
++    if (value == s->stats_poll_interval) {
++        return;
++    }
++
++    if (value == 0) {
++        /* timer=0 disables the timer */
++        balloon_stats_destroy_timer(s);
++        return;
++    }
++
++    if (balloon_stats_enabled(s)) {
++        /* timer interval change */
++        s->stats_poll_interval = value;
++        balloon_stats_change_timer(s, value);
++        return;
++    }
++
++    /* create a new timer */
++    g_assert(s->stats_timer == NULL);
++    s->stats_timer = qemu_new_timer_ms(vm_clock, balloon_stats_poll_cb, s);
++    s->stats_poll_interval = value;
++    balloon_stats_change_timer(s, 0);
++}
++
+ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq)
+ {
+     VirtIOBalloon *s = to_virtio_balloon(vdev);
+@@ -107,9 +243,10 @@ static void virtio_balloon_receive_stats(VirtIODevice *vdev, VirtQueue *vq)
+     VirtQueueElement *elem = &s->stats_vq_elem;
+     VirtIOBalloonStat stat;
+     size_t offset = 0;
++    qemu_timeval tv;
+     if (!virtqueue_pop(vq, elem)) {
+-        return;
++        goto out;
+     }
+     /* Initialize the stats to get rid of any stale values.  This is only
+@@ -128,6 +265,18 @@ static void virtio_balloon_receive_stats(VirtIODevice *vdev, VirtQueue *vq)
+             s->stats[tag] = val;
+     }
+     s->stats_vq_offset = offset;
++
++    if (qemu_gettimeofday(&tv) < 0) {
++        fprintf(stderr, "warning: %s: failed to get time of day\n", __func__);
++        goto out;
++    }
++
++    s->stats_last_update = tv.tv_sec;
++
++out:
++    if (balloon_stats_enabled(s)) {
++        balloon_stats_change_timer(s, s->stats_poll_interval);
++    }
+ }
+ static void virtio_balloon_get_config(VirtIODevice *vdev, uint8_t *config_data)
+@@ -212,7 +361,7 @@ static int virtio_balloon_load(QEMUFile *f, void *opaque, int version_id)
+ VirtIODevice *virtio_balloon_init(DeviceState *dev)
+ {
+     VirtIOBalloon *s;
+-    int ret;
++    int i, ret;
+     s = (VirtIOBalloon *)virtio_common_init("virtio-balloon",
+                                             VIRTIO_ID_BALLOON,
+@@ -239,6 +388,19 @@ VirtIODevice *virtio_balloon_init(DeviceState *dev)
+     register_savevm(dev, "virtio-balloon", -1, 1,
+                     virtio_balloon_save, virtio_balloon_load, s);
++    for (i = 0; i < VIRTIO_BALLOON_S_NR; i++) {
++        object_property_add(OBJECT(dev), balloon_stat_names[i], "int",
++                            balloon_stats_get_stat, NULL, NULL, s, NULL);
++    }
++
++    object_property_add(OBJECT(dev), "stats-last-update", "int",
++                        balloon_stats_get_last_update, NULL, NULL, s, NULL);
++
++    object_property_add(OBJECT(dev), "stats-polling-interval", "int",
++                        balloon_stats_get_poll_interval,
++                        balloon_stats_set_poll_interval,
++                        NULL, s, NULL);
++
+     return &s->vdev;
+ }
+@@ -246,6 +408,7 @@ void virtio_balloon_exit(VirtIODevice *vdev)
+ {
+     VirtIOBalloon *s = DO_UPCAST(VirtIOBalloon, vdev, vdev);
++    balloon_stats_destroy_timer(s);
+     qemu_remove_balloon_handler(s);
+     unregister_savevm(s->qdev, "virtio-balloon", s);
+     virtio_cleanup(vdev);
+-- 
+1.8.0
+
+
+
+