kvm balloon guest driver (v2)
Subsystems (2)
PATCH 1/1 kvm balloon guest driver (v2)
Updated balloon driver.
Changes from last version:
- Get rid of global variables/structure
- Use page->lru to link ballooned pages
- Use dev_dbg/dev_printk
- Proper kthread_should_stop handling
- Move shared definitions to separate header
- Use ->config_changed method for notification
This depends on Rusty's config_changed patch.
drivers/virtio/Kconfig +9 -0
@@ -23,3 +23,12 @@ config VIRTIO_PCI If unsure, say M. +config KVM_BALLOON + tristate "KVM balloon driver (EXPERIMENTAL)" + depends on VIRTIO_PCI + ---help--- + This driver provides support for ballooning memory in/out of a + KVM paravirt guest. + + If unsure, say M. +
drivers/virtio/Makefile +1 -0
@@ -1,3 +1,4 @@ obj-$(CONFIG_VIRTIO) += virtio.o obj-$(CONFIG_VIRTIO_RING) += virtio_ring.o obj-$(CONFIG_VIRTIO_PCI) += virtio_pci.o +obj-$(CONFIG_KVM_BALLOON) += kvm_balloon.o
drivers/virtio/kvm_balloon.c new file +537 -0
537 lines not on this page · raw message
drivers/virtio/virtio_pci.c +1 -0
@@ -67,6 +67,7 @@ static struct pci_device_id virtio_pci_i { 0x1AF4, 0x1000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Dummy entry */ { 0x1AF4, 0x1001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Dummy entry */ { 0x1AF4, 0x1002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Dummy entry */ + { 0x1AF4, 0x1003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Balloon */ { 0 }, };
include/linux/virtio_balloon.h new file +20 -0
@@ -0,0 +1,20 @@ +#ifndef _LINUX_VIRTIO_BALLOON_H +#define _LINUX_VIRTIO_BALLOON_H +#include <linux/virtio_config.h> + +#define VIRTIO_ID_BALLOON 3 + +#define CMD_BALLOON_INFLATE 0x1 +#define CMD_BALLOON_DEFLATE 0x2 + +struct virtio_balloon_hdr { +uint8_t cmd; +uint8_t status; +}; + +struct virtio_balloon_config +{ +uint32_t target_nrpages; +}; + +#endif /* _LINUX_VIRTIO_BALLOON_H */
-------------------------------------------------------------------------
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
Hi, Marcelo
Quoted 12 lines
+struct
balloon_buf*alloc_balloon_buf(structvirtio_device*vdev,gfp_tflags)drivers/virtio/kvm_balloon.c new file +10
-0+{ +struct balloon_buf *buf; + + buf =kzalloc (sizeof (struct balloon_buf ), flags); +if (!buf) +dev_printk (KERN_ERR , &vdev->dev,"%s: alloc fail\n" , __func__); + +return buf; +} +
[snip..]
drivers/virtio/kvm_balloon.c line 118
Quoted 10 lines
drivers/virtio/kvm_balloon.c new file +10
-0+static int kvm_balloon_inflate (struct virtballoon *v,int32_t npages) +{ +LIST_HEAD (tmp_list); +struct page *page, *tmp; +struct balloon_buf *buf; +u32 *pfn; +int allocated =0 ; +int i, r = -ENOMEM ; + + buf =alloc_balloon_buf (v->vdev,GFP_KERNEL );
When does balloon driver free the buf?
Quoted 37 lines
drivers/virtio/kvm_balloon.c new file +37
-0+if (!buf) +return r; + + pfn = (u32 *)&buf->data; + *pfn++ = (u32 )npages; + +for (i =0 ; i < npages; i++) { + page =alloc_page (GFP_HIGHUSER | __GFP_NORETRY); +if (!page) + goto out_free; +list_add (&page->lru, &tmp_list); + allocated++; + *pfn =page_to_pfn (page); + pfn++; + } + + r =send_balloon_buf (v,CMD_BALLOON_INFLATE , buf); +if (r) + goto out_free; + +spin_lock (&v->plist_lock); +list_splice (&tmp_list, &v->balloon_plist); + v->balloon_size += allocated; + totalram_pages -= allocated; +dprintk (&v->vdev->dev,"%s: current balloon size=%d\n" , __func__, + v->balloon_size); +spin_unlock (&v->plist_lock); +return allocated; + +out_free: +list_for_each_entry_safe (page, tmp, &tmp_list, lru) { +list_del (&page->lru); +__free_page (page); + } +return r; +} +
drivers/virtio/kvm_balloon.c line 165
Quoted 10 lines
drivers/virtio/kvm_balloon.c new file +10
-0+static int kvm_balloon_deflate (struct virtballoon *v,int32_t npages) +{ +LIST_HEAD (tmp_list); +struct page *page, *tmp; +struct balloon_buf *buf; +u32 *pfn; +int deallocated =0 ; +int r =0 ; + + buf =alloc_balloon_buf (v->vdev,GFP_KERNEL );
ditto.
Quoted 39 lines
drivers/virtio/kvm_balloon.c new file +39
-0+if (!buf) +return r; + +spin_lock (&v->plist_lock); + +if (v->balloon_size < npages) { +dev_printk (KERN_INFO , &v->vdev->dev, +"%s: balloon=%d with deflate rq=%d\n" , + __func__, v->balloon_size, npages); + npages = v->balloon_size; +if (!npages) + goto out; + } + + pfn = (u32 *)&buf->data; + *pfn++ = (u32)-npages; + +/* +* Move the balloon pages to tmp list before issuing +* the virtio buffer +*/ +list_for_each_entry_safe (page, tmp, &v->balloon_plist, lru) { + *pfn++ =page_to_pfn (page); +list_move (&page->lru, &tmp_list); +if (++deallocated == npages) +break ; + } + + r =send_balloon_buf (v,CMD_BALLOON_DEFLATE , buf); +if (r) + goto out; + +list_for_each_entry_safe (page, tmp, &tmp_list, lru) +list_del_init (&page->lru); + + v->balloon_size -= npages; + totalram_pages += npages; +dprintk (&v->vdev->dev,"%s: current balloon size=%d\n" , __func__, + v->balloon_size);
drivers/virtio/kvm_balloon.c line 214
Quoted 10 lines
drivers/virtio/kvm_balloon.c new file +10
-0+ +spin_unlock (&v->plist_lock); +return deallocated; + +out: +list_splice (&tmp_list, &v->balloon_plist); +spin_unlock (&v->plist_lock); +return r; +} +
Best Regards,
Akio Takebe
-------------------------------------------------------------------------
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
A message that is not in the archive (sent off-list or not yet received): F1C85358126773takebe_akio-+CUm20s59erQFUHtdCDX3A@public.gmane.org
Quoted 15 lines · Akio Takebe
Hi, Marcelo
Quoted 12 lines
+struct
balloon_buf*alloc_balloon_buf(structvirtio_device*vdev,gfp_tflags)drivers/virtio/kvm_balloon.c new file +10
-0+{ +struct balloon_buf *buf; + + buf =kzalloc (sizeof (struct balloon_buf ), flags); +if (!buf) +dev_printk (KERN_ERR , &vdev->dev,"%s: alloc fail\n" , __func__); + +return buf; +} +[snip..]
Quoted 11 lines
drivers/virtio/kvm_balloon.c line 118
Quoted 10 lines
drivers/virtio/kvm_balloon.c new file +10
-0+static int kvm_balloon_inflate (struct virtballoon *v,int32_t npages) +{ +LIST_HEAD (tmp_list); +struct page *page, *tmp; +struct balloon_buf *buf; +u32 *pfn; +int allocated =0 ; +int i, r = -ENOMEM ; + + buf =alloc_balloon_buf (v->vdev,GFP_KERNEL );When does balloon driver free the buf?
Hi Akio,
The buffers are passed from the virtio handling routine to the balloon_thread through the balloon_work list, and then freed here:
+ spin_lock_irq(&v->queue_lock);
+ while (!list_empty(&v->balloon_work)) {
+ struct balloon_work *work;
+ struct balloon_buf *buf;
+
+ work = list_entry(v->balloon_work.next,
+ struct balloon_work, list);
+ list_del(&work->list); + spin_unlock_irq(&v->queue_lock); + buf = work->buf; + kfree(work);
+
+ switch(buf->hdr.cmd) {
+ case CMD_BALLOON_DEFLATE:
+ deflate_done(v, buf);
+ break;
+ case CMD_BALLOON_INFLATE:
+ inflate_done(v, buf);
+ break;
+ default:
+ printk("%s: unknown cmd 0x%x\n", __func__,
+ buf->hdr.cmd);
+ }
+ kfree(buf);
-------------------------------------------------------------------------
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
Hi, Marcelo
Quoted 31 lines
Quoted 11 lines
drivers/virtio/kvm_balloon.c line 118
Quoted 10 lines
drivers/virtio/kvm_balloon.c new file +10
-0+static int kvm_balloon_inflate (struct virtballoon *v,int32_t npages) +{ +LIST_HEAD (tmp_list); +struct page *page, *tmp; +struct balloon_buf *buf; +u32 *pfn; +int allocated =0 ; +int i, r = -ENOMEM ; + + buf =alloc_balloon_buf (v->vdev,GFP_KERNEL );When does balloon driver free the buf?
Hi Akio,
The buffers are passed from the virtio handling routine to the
balloon_threadthrough theballoon_worklist, and then freed here:drivers/virtio/kvm_balloon.c new file +14
-0+spin_lock_irq (&v->queue_lock); +while (!list_empty (&v->balloon_work)) { +struct balloon_work *work; +struct balloon_buf *buf; + + work =list_entry (v->balloon_work.next, + struct balloon_work, list); +list_del (&work->list); +spin_unlock_irq (&v->queue_lock); + buf = work->buf; +kfree (work); + +switch (buf->hdr.cmd) { +case CMD_BALLOON_DEFLATE :
drivers/virtio/kvm_balloon.c line 380
Quoted 10 lines
drivers/virtio/kvm_balloon.c new file +10
-0+deflate_done (v, buf); +break ; +case CMD_BALLOON_INFLATE : +inflate_done (v, buf); +break ; +default : +printk ("%s: unknown cmd 0x%x\n" , __func__, + buf->hdr.cmd); + } +kfree (buf);
Thank you for your exlanation.
Does balloon free the buf when kvm_balloon_xflate() retrun -ENOMEM?
Best Regards,
Akio Takebe
-------------------------------------------------------------------------
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
A message that is not in the archive (sent off-list or not yet received): F7C853842F97FDtakebe_akio-+CUm20s59erQFUHtdCDX3A@public.gmane.org
Quoted 37 lines · Akio Takebe
Hi, Marcelo
Quoted 35 lines
Quoted 11 lines
drivers/virtio/kvm_balloon.c line 118
Quoted 10 lines
drivers/virtio/kvm_balloon.c new file +10
-0+static int kvm_balloon_inflate (struct virtballoon *v,int32_t npages) +{ +LIST_HEAD (tmp_list); +struct page *page, *tmp; +struct balloon_buf *buf; +u32 *pfn; +int allocated =0 ; +int i, r = -ENOMEM ; + + buf =alloc_balloon_buf (v->vdev,GFP_KERNEL );When does balloon driver free the buf?
Hi Akio,
The buffers are passed from the virtio handling routine to the
balloon_threadthrough theballoon_worklist, and then freed here:drivers/virtio/kvm_balloon.c new file +18
-0+spin_lock_irq (&v->queue_lock); +while (!list_empty (&v->balloon_work)) { +struct balloon_work *work; +struct balloon_buf *buf; + + work =list_entry (v->balloon_work.next, + struct balloon_work, list); +list_del (&work->list); +spin_unlock_irq (&v->queue_lock); + buf = work->buf; +kfree (work); + +switch (buf->hdr.cmd) { +case CMD_BALLOON_DEFLATE : +deflate_done (v, buf); +break ; +case CMD_BALLOON_INFLATE : +inflate_done (v, buf);
Quoted 8 lines
drivers/virtio/kvm_balloon.c line 380
Quoted 6 lines
drivers/virtio/kvm_balloon.c new file +6
-0+break ; +default : +printk ("%s: unknown cmd 0x%x\n" , __func__, + buf->hdr.cmd); + } +kfree (buf);Thank you for your exlanation.
Does balloon free the buf whenkvm_balloon_xflate()retrun-ENOMEM?
It return -ENOMEM only when kvm_balloon_inflate fails.
We just need to handle this case a little better - there is no leak but the xflate function or the balloon thread need to check the value and update the host that it failed to reach the requested balloon size.
Quoted 12 lines
Akio Takebe
-------------------------------------------------------------------------
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
_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel
-------------------------------------------------------------------------
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