[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC][PATCH 3/3] QEmu changes to provide balloon hint
From: |
Balbir Singh |
Subject: |
[Qemu-devel] [RFC][PATCH 3/3] QEmu changes to provide balloon hint |
Date: |
Fri, 29 Oct 2010 04:10:19 +0530 |
Provide memory hint during ballooning
From: Balbir Singh <address@hidden>
This patch adds an optional hint to the qemu monitor balloon
command. The hint tells the guest operating system to consider
a class of memory during reclaim. Currently the supported
hint is cached memory. The design is generic and can be extended
to provide other hints in the future if required.
Signed-off-by: Balbir Singh <address@hidden>
---
balloon.c | 18 ++++++++++++++----
balloon.h | 4 +++-
hmp-commands.hx | 7 +++++--
hw/virtio-balloon.c | 15 +++++++++++----
hw/virtio-balloon.h | 3 +++
qmp-commands.hx | 7 ++++---
6 files changed, 40 insertions(+), 14 deletions(-)
diff --git a/balloon.c b/balloon.c
index 0021fef..b2bdda5 100644
--- a/balloon.c
+++ b/balloon.c
@@ -41,11 +41,13 @@ void qemu_add_balloon_handler(QEMUBalloonEvent *func, void
*opaque)
qemu_balloon_event_opaque = opaque;
}
-int qemu_balloon(ram_addr_t target, MonitorCompletion cb, void *opaque)
+int qemu_balloon(ram_addr_t target, bool reclaim_cache_first,
+ MonitorCompletion cb, void *opaque)
{
if (qemu_balloon_event) {
trace_balloon_event(qemu_balloon_event_opaque, target);
- qemu_balloon_event(qemu_balloon_event_opaque, target, cb, opaque);
+ qemu_balloon_event(qemu_balloon_event_opaque, target,
+ reclaim_cache_first, cb, opaque);
return 1;
} else {
return 0;
@@ -55,7 +57,7 @@ int qemu_balloon(ram_addr_t target, MonitorCompletion cb,
void *opaque)
int qemu_balloon_status(MonitorCompletion cb, void *opaque)
{
if (qemu_balloon_event) {
- qemu_balloon_event(qemu_balloon_event_opaque, 0, cb, opaque);
+ qemu_balloon_event(qemu_balloon_event_opaque, 0, 0, cb, opaque);
return 1;
} else {
return 0;
@@ -131,13 +133,21 @@ int do_balloon(Monitor *mon, const QDict *params,
MonitorCompletion cb, void *opaque)
{
int ret;
+ int val;
+ const char *cache_hint;
+ int reclaim_cache_first = 0;
if (kvm_enabled() && !kvm_has_sync_mmu()) {
qerror_report(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
return -1;
}
- ret = qemu_balloon(qdict_get_int(params, "value"), cb, opaque);
+ val = qdict_get_int(params, "value");
+ cache_hint = qdict_get_try_str(params, "hint");
+ if (cache_hint)
+ reclaim_cache_first = 1;
+
+ ret = qemu_balloon(val, reclaim_cache_first, cb, opaque);
if (ret == 0) {
qerror_report(QERR_DEVICE_NOT_ACTIVE, "balloon");
return -1;
diff --git a/balloon.h b/balloon.h
index d478e28..65d68c1 100644
--- a/balloon.h
+++ b/balloon.h
@@ -17,11 +17,13 @@
#include "monitor.h"
typedef void (QEMUBalloonEvent)(void *opaque, ram_addr_t target,
+ bool reclaim_cache_first,
MonitorCompletion cb, void *cb_data);
void qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque);
-int qemu_balloon(ram_addr_t target, MonitorCompletion cb, void *opaque);
+int qemu_balloon(ram_addr_t target, bool reclaim_cache_first,
+ MonitorCompletion cb, void *opaque);
int qemu_balloon_status(MonitorCompletion cb, void *opaque);
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 81999aa..80e42aa 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -925,8 +925,8 @@ ETEXI
{
.name = "balloon",
- .args_type = "value:M",
- .params = "target",
+ .args_type = "value:M,hint:s?",
+ .params = "target [cache]",
.help = "request VM to change its memory allocation (in MB)",
.user_print = monitor_user_noop,
.mhandler.cmd_async = do_balloon,
@@ -937,6 +937,9 @@ STEXI
@item balloon @var{value}
@findex balloon
Request VM to change its memory allocation to @var{value} (in MB).
+An optional @var{hint} can be specified to indicate if the guest
+should reclaim from the cached memory in the guest first. The
address@hidden may be ignored by the guest.
ETEXI
{
diff --git a/hw/virtio-balloon.c b/hw/virtio-balloon.c
index 8adddea..e363507 100644
--- a/hw/virtio-balloon.c
+++ b/hw/virtio-balloon.c
@@ -44,6 +44,7 @@ typedef struct VirtIOBalloon
size_t stats_vq_offset;
MonitorCompletion *stats_callback;
void *stats_opaque_callback_data;
+ uint32_t reclaim_cache_first;
} VirtIOBalloon;
static VirtIOBalloon *to_virtio_balloon(VirtIODevice *vdev)
@@ -181,8 +182,11 @@ static void virtio_balloon_get_config(VirtIODevice *vdev,
uint8_t *config_data)
config.num_pages = cpu_to_le32(dev->num_pages);
config.actual = cpu_to_le32(dev->actual);
-
- memcpy(config_data, &config, 8);
+ if (vdev->guest_features & (1 << VIRTIO_BALLOON_F_BALLOON_HINT)) {
+ config.reclaim_cache_first = cpu_to_le32(dev->reclaim_cache_first);
+ memcpy(config_data, &config, 12);
+ } else
+ memcpy(config_data, &config, 8);
}
static void virtio_balloon_set_config(VirtIODevice *vdev,
@@ -196,11 +200,13 @@ static void virtio_balloon_set_config(VirtIODevice *vdev,
static uint32_t virtio_balloon_get_features(VirtIODevice *vdev, uint32_t f)
{
- f |= (1 << VIRTIO_BALLOON_F_STATS_VQ);
+ f |= (1 << VIRTIO_BALLOON_F_STATS_VQ) |
+ (1 << VIRTIO_BALLOON_F_BALLOON_HINT);
return f;
}
static void virtio_balloon_to_target(void *opaque, ram_addr_t target,
+ bool reclaim_cache_first,
MonitorCompletion cb, void *cb_data)
{
VirtIOBalloon *dev = opaque;
@@ -210,6 +216,7 @@ static void virtio_balloon_to_target(void *opaque,
ram_addr_t target,
if (target) {
dev->num_pages = (ram_size - target) >> VIRTIO_BALLOON_PFN_SHIFT;
+ dev->reclaim_cache_first = reclaim_cache_first;
virtio_notify_config(&dev->vdev);
} else {
/* For now, only allow one request at a time. This restriction can be
@@ -263,7 +270,7 @@ VirtIODevice *virtio_balloon_init(DeviceState *dev)
s = (VirtIOBalloon *)virtio_common_init("virtio-balloon",
VIRTIO_ID_BALLOON,
- 8, sizeof(VirtIOBalloon));
+ 12, sizeof(VirtIOBalloon));
s->vdev.get_config = virtio_balloon_get_config;
s->vdev.set_config = virtio_balloon_set_config;
diff --git a/hw/virtio-balloon.h b/hw/virtio-balloon.h
index e20cf6b..39d1b01 100644
--- a/hw/virtio-balloon.h
+++ b/hw/virtio-balloon.h
@@ -26,6 +26,7 @@
/* The feature bitmap for virtio balloon */
#define VIRTIO_BALLOON_F_MUST_TELL_HOST 0 /* Tell before reclaiming pages */
#define VIRTIO_BALLOON_F_STATS_VQ 1 /* Memory stats virtqueue */
+#define VIRTIO_BALLOON_F_BALLOON_HINT 2 /* Ballon hint */
/* Size of a PFN in the balloon interface. */
#define VIRTIO_BALLOON_PFN_SHIFT 12
@@ -36,6 +37,8 @@ struct virtio_balloon_config
uint32_t num_pages;
/* Number of pages we've actually got in balloon. */
uint32_t actual;
+ /* Hint, should we reclaim cached pages first? */
+ uint32_t reclaim_cache_first;
};
/* Memory Statistics */
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 793cf1c..1da2e65 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -605,8 +605,8 @@ EQMP
{
.name = "balloon",
- .args_type = "value:M",
- .params = "target",
+ .args_type = "value:M,hint:s?",
+ .params = "target [cache]",
.help = "request VM to change its memory allocation (in MB)",
.user_print = monitor_user_noop,
.mhandler.cmd_async = do_balloon,
@@ -622,10 +622,11 @@ Request VM to change its memory allocation (in bytes).
Arguments:
- "value": New memory allocation (json-int)
+- "hint": Optional hint (json-string, optional)
Example:
--> { "execute": "balloon", "arguments": { "value": 536870912 } }
++-> { "execute": "balloon", "arguments": { "value": 536870912, "hint":"cache"
} }
<- { "return": {} }
EQMP
--
Three Cheers,
Balbir