Skip to contentSkip to conversation

QEMU KVM balloon support

PATCH In review Marcelo Tosatti 4 participants 5 messages Jan 8, 2008 1 message not in the archive

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 QEMU KVM balloon support

Add QEMU support for the KVM balloon driver.

Memory hinting is performed via madvise().

libkvm/libkvm.c +11 -0
Index: kvm-userspace/libkvm/libkvm.c
===================================================================
@@ -886,6 +886,17 @@ int kvm_is_ready_for_interrupt_injection
 	return run->ready_for_interrupt_injection;
 }
 
+int kvm_sync_shadow_with_user(kvm_context_t kvm)
+{
+        int r = 0;
+#ifdef KVM_CAP_SYNC_SHADOW_WITH_USER
+        r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_SYNC_SHADOW_WITH_USER);
+        if (r > 0)
+		r = ioctl(kvm->vm_fd, KVM_SYNC_SHADOW_WITH_USER);
+#endif
+	return r;
+}
+
 int kvm_run(kvm_context_t kvm, int vcpu)
 {
 	int r;
libkvm/libkvm.h +2 -0
Index: kvm-userspace/libkvm/libkvm.h
===================================================================
@@ -423,6 +423,8 @@ int kvm_get_dirty_pages_range(kvm_contex
 			      int (*cb)(unsigned long start, unsigned long len,
 					void*bitmap, void *opaque));
 
+int kvm_sync_shadow_with_user(kvm_context_t kvm);
+
 /*!
  * \brief Create a memory alias
  *
qemu/Makefile.target +1 -1
Index: kvm-userspace/qemu/Makefile.target
===================================================================
@@ -464,7 +464,7 @@ VL_OBJS += rtl8139.o
 VL_OBJS+= hypercall.o
 
 # virtio devices
-VL_OBJS += virtio.o virtio-net.o virtio-blk.o
+VL_OBJS += virtio.o virtio-net.o virtio-blk.o virtio-balloon.o
 
 ifeq ($(TARGET_BASE_ARCH), i386)
 # Hardware support
qemu/hw/pc.c +2 -0
Index: kvm-userspace/qemu/hw/pc.c
===================================================================
@@ -1029,6 +1029,8 @@ static void pc_init1(ram_addr_t ram_size
         }
     }
 
+    virtio_balloon_init(pci_bus);
+
 #define USE_HYPERCALL
 #ifdef USE_HYPERCALL
     pci_hypercall_init(pci_bus);
qemu/hw/pc.h +3 -0
Index: kvm-userspace/qemu/hw/pc.h
===================================================================
@@ -155,4 +155,7 @@ void *virtio_blk_init(PCIBus *bus, uint1
 
 void extboot_init(BlockDriverState *bs, int cmd);
 
+/* virtio-balloon.c */
+void *virtio_balloon_init(PCIBus *bus);
+
 #endif
qemu/hw/virtio-balloon.c new file +103 -0

103 lines not on this page · raw message

qemu/migration.c +4 -0
Index: kvm-userspace/qemu/migration.c
===================================================================
@@ -34,6 +34,7 @@
 #endif
 
 #include <sys/wait.h>
+#include <sys/mman.h>
 
 #define MIN_FINALIZE_SIZE	(200 << 10)
 #define MAX_ITERATIONS           30
@@ -765,6 +766,9 @@ static void migrate_incoming_homogeneous
 
     for (i=0; i<n; i++)
         p[i] = v;
+
+    if (v == 0)
+        madvise(phys_ram_base + addr, TARGET_PAGE_SIZE, MADV_DONTNEED);
 }
 
 static int migrate_incoming_page(QEMUFile *f, uint32_t addr)
qemu/monitor.c +2 -0
Index: kvm-userspace/qemu/monitor.c
===================================================================
@@ -1339,6 +1339,8 @@ static term_cmd_t term_cmds[] = {
       "", "cancel the current VM migration" },
     { "migrate_set_speed", "s", do_migrate_set_speed,
       "value", "set maximum speed (in bytes) for migrations" },
+    { "setmem", "s", do_setmemory, "value", 
+      "set memory for the guest (in bytes)" },
     { NULL, NULL, },
 };
 
qemu/qemu-kvm.c +94 -1

113 lines not on this page · raw message

qemu/qemu-kvm.h +3 -0
Index: kvm-userspace/qemu/qemu-kvm.h
===================================================================
@@ -39,6 +39,9 @@ void kvm_arch_post_kvm_run(void *opaque,
 int kvm_arch_has_work(CPUState *env);
 int kvm_arch_try_push_interrupts(void *opaque);
 void kvm_arch_update_regs_for_sipi(CPUState *env);
+int kvm_handle_ballooning_call(void *data, size_t len);
+
+void do_setmemory(const char *value);
 
 extern int kvm_allowed;
 extern int kvm_irqchip;
qemu/vl.c +27 -0
Index: kvm-userspace/qemu/vl.c
===================================================================
@@ -7216,6 +7216,30 @@ static void ram_decompress_close(RamDeco
     inflateEnd(&s->zstream);
 }
 
+#ifdef USE_KVM
+extern int64_t target_ramsize; /* qemu/hw/virtio-balloon.c */
+static void balloon_save(QEMUFile *f, void *opaque)
+{
+    qemu_put_be64(f, target_ramsize);
+}
+
+static int balloon_load(QEMUFile *f, void *opaque, int version_id)
+{
+    int64_t target;
+
+    if (version_id != 1)
+        return -EINVAL;
+
+    target = qemu_get_be64(f);
+    if (!target)
+        return -EINVAL;
+
+    balloon_update_target(target);
+
+    return 0;
+}
+#endif
+
 static void ram_save_live(QEMUFile *f, void *opaque)
 {
     target_ulong addr;
@@ -9378,6 +9402,9 @@ int main(int argc, char **argv)
 
     register_savevm("timer", 0, 2, timer_save, timer_load, NULL);
     register_savevm("ram", 0, 3, ram_save, ram_load, NULL);
+    if (kvm_allowed)
+        register_savevm("balloon", 0, 1, balloon_save, balloon_load, NULL);
+
 
     init_ioports();
 

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace

#1 lore raw
Quoted 12 lines · Marcelo Tosatti

Index: kvm-userspace/qemu/monitor.c
===================================================================

qemu/monitor.c +2 -0
@@ -1339,6 +1339,8 @@ static term_cmd_t term_cmds[] = {
       "", "cancel the current VM migration" },
     { "migrate_set_speed", "s", do_migrate_set_speed,
       "value", "set maximum speed (in bytes) for migrations" },
+    { "setmem", "s", do_setmemory, "value", 
+      "set memory for the guest (in bytes)" },
     { NULL, NULL, },
 };

[snip]

Quoted 14 lines
qemu/monitor.c +14 -0
+void do_setmemory(const char *value)
+{
+	int target_ramsize;
+	char *ptr;
+
+	target_ramsize = strtol(value, &ptr, 10);
+	switch (*ptr) {
+	case 'G': case 'g':
+		target_ramsize *= 1024;
+	case 'M': case 'm':
+		target_ramsize *= 1024;
+	case 'K': case 'k':
+		target_ramsize *= 1024;
+	default:

qemu/monitor.c

Quoted 10 lines
qemu/monitor.c +10 -0
+		break;
+	}
+
+	if (target_ramsize > ram_size) {
+		term_printf("Invalid RAM size, maximum: %d\n", ram_size);
+		return;
+	}
+	
+	balloon_update_target(target_ramsize);
+}

Shouldn't this use int64, and strtoll(), otherwise you'll wrap at the 2 GB mark ?

Regards,
Dan.

Signature · 10 lines
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
#5 lore raw
In reply to Marcelo Tosatti
Quoted 12 lines · Marcelo Tosatti

Index: kvm-userspace/qemu/monitor.c
===================================================================

qemu/monitor.c +2 -0
@@ -1339,6 +1339,8 @@ static term_cmd_t term_cmds[] = {
       "", "cancel the current VM migration" },
     { "migrate_set_speed", "s", do_migrate_set_speed,
       "value", "set maximum speed (in bytes) for migrations" },
+    { "setmem", "s", do_setmemory, "value", 
+      "set memory for the guest (in bytes)" },
     { NULL, NULL, },
 };

[snip]

Quoted 14 lines
qemu/monitor.c +14 -0
+void do_setmemory(const char *value)
+{
+	int target_ramsize;
+	char *ptr;
+
+	target_ramsize = strtol(value, &ptr, 10);
+	switch (*ptr) {
+	case 'G': case 'g':
+		target_ramsize *= 1024;
+	case 'M': case 'm':
+		target_ramsize *= 1024;
+	case 'K': case 'k':
+		target_ramsize *= 1024;
+	default:

qemu/monitor.c

Quoted 10 lines
qemu/monitor.c +10 -0
+		break;
+	}
+
+	if (target_ramsize > ram_size) {
+		term_printf("Invalid RAM size, maximum: %d\n", ram_size);
+		return;
+	}
+	
+	balloon_update_target(target_ramsize);
+}

Shouldn't this use int64, and strtoll(), otherwise you'll wrap at the 2 GB mark ?

Regards,
Dan.

Signature · 4 lines
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 
#3 lore raw
In reply to a message not in the archive
Quoted 35 lines · Daniel P. Berrange
Quoted 12 lines · Marcelo Tosatti

Index: kvm-userspace/qemu/monitor.c
===================================================================

qemu/monitor.c +2 -0
@@ -1339,6 +1339,8 @@ static term_cmd_t term_cmds[] = {
       "", "cancel the current VM migration" },
     { "migrate_set_speed", "s", do_migrate_set_speed,
       "value", "set maximum speed (in bytes) for migrations" },
+    { "setmem", "s", do_setmemory, "value", 
+      "set memory for the guest (in bytes)" },
     { NULL, NULL, },
 };

[snip]

Quoted 19 lines
qemu/monitor.c +19 -0
+void do_setmemory(const char *value)
+{
+	int target_ramsize;
+	char *ptr;
+
+	target_ramsize = strtol(value, &ptr, 10);
+	switch (*ptr) {
+	case 'G': case 'g':
+		target_ramsize *= 1024;
+	case 'M': case 'm':
+		target_ramsize *= 1024;
+	case 'K': case 'k':
+		target_ramsize *= 1024;
+	default:
+		break;
+	}
+
+	if (target_ramsize > ram_size) {
+		term_printf("Invalid RAM size, maximum: %d\n", ram_size);
Quoted 8 lines

qemu/monitor.c

Quoted 5 lines
qemu/monitor.c +5 -0
+		return;
+	}
+	
+	balloon_update_target(target_ramsize);
+}

Shouldn't this use int64, and strtoll(), otherwise you'll wrap at the 2 GB mark ?

Good catch, thanks.

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace

#4 lore raw
In reply to Daniel P. Berrange
Quoted 35 lines · Daniel P. Berrange
Quoted 12 lines · Marcelo Tosatti

Index: kvm-userspace/qemu/monitor.c
===================================================================

qemu/monitor.c +2 -0
@@ -1339,6 +1339,8 @@ static term_cmd_t term_cmds[] = {
       "", "cancel the current VM migration" },
     { "migrate_set_speed", "s", do_migrate_set_speed,
       "value", "set maximum speed (in bytes) for migrations" },
+    { "setmem", "s", do_setmemory, "value", 
+      "set memory for the guest (in bytes)" },
     { NULL, NULL, },
 };

[snip]

Quoted 19 lines
qemu/monitor.c +19 -0
+void do_setmemory(const char *value)
+{
+	int target_ramsize;
+	char *ptr;
+
+	target_ramsize = strtol(value, &ptr, 10);
+	switch (*ptr) {
+	case 'G': case 'g':
+		target_ramsize *= 1024;
+	case 'M': case 'm':
+		target_ramsize *= 1024;
+	case 'K': case 'k':
+		target_ramsize *= 1024;
+	default:
+		break;
+	}
+
+	if (target_ramsize > ram_size) {
+		term_printf("Invalid RAM size, maximum: %d\n", ram_size);
Quoted 8 lines

qemu/monitor.c

Quoted 5 lines
qemu/monitor.c +5 -0
+		return;
+	}
+	
+	balloon_update_target(target_ramsize);
+}

Shouldn't this use int64, and strtoll(), otherwise you'll wrap at the 2 GB mark ?

Good catch, thanks.