Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1433663 > unrolled thread
| Started by | Liang Li <liang.z.li@intel.com> |
|---|---|
| First post | 2016-06-29 12:50 +0200 |
| Last post | 2016-07-06 02:50 +0200 |
| Articles | 4 — 2 participants |
Back to article view | Back to linux.kernel
[PATCH v2 kernel 0/7] Extend virtio-balloon for fast (de)inflating & fast live migration Liang Li <liang.z.li@intel.com> - 2016-06-29 12:50 +0200
[PATCH v2 kernel 7/7] virtio-balloon: tell host vm's free page info Liang Li <liang.z.li@intel.com> - 2016-06-29 12:50 +0200
[PATCH v2 kernel 6/7] mm: add the related functions to get free page info Liang Li <liang.z.li@intel.com> - 2016-06-29 12:50 +0200
RE: [PATCH v2 kernel 0/7] Extend virtio-balloon for fast (de)inflating & fast live migration "Li, Liang Z" <liang.z.li@intel.com> - 2016-07-06 02:50 +0200
| From | Liang Li <liang.z.li@intel.com> |
|---|---|
| Date | 2016-06-29 12:50 +0200 |
| Subject | [PATCH v2 kernel 0/7] Extend virtio-balloon for fast (de)inflating & fast live migration |
| Message-ID | <rPle9-36J-3@gated-at.bofh.it> |
This patch set contains two parts of changes to the virtio-balloon.
One is the change for speeding up the inflating & deflating process,
the main idea of this optimization is to use bitmap to send the page
information to host instead of the PFNs, to reduce the overhead of
virtio data transmission, address translation and madvise(). This can
help to improve the performance by about 85%.
Another change is for speeding up live migration. By skipping process
guest's free pages in the first round of data copy, to reduce needless
data processing, this can help to save quite a lot of CPU cycles and
network bandwidth. We put guest's free page information in bitmap and
send it to host with the virt queue of virtio-balloon. For an idle 8GB
guest, this can help to shorten the total live migration time from 2Sec
to about 500ms in the 10Gbps network environment.
Changes from v1 to v2:
* Abandon the patch for dropping page cache.
* Put some structures to uapi head file.
* Use a new way to determine the page bitmap size.
* Use a unified way to send the free page information with the bitmap
* Address the issues referred in MST's comments
Liang Li (7):
virtio-balloon: rework deflate to add page to a list
virtio-balloon: define new feature bit and page bitmap head
mm: add a function to get the max pfn
virtio-balloon: speed up inflate/deflate process
virtio-balloon: define feature bit and head for misc virt queue
mm: add the related functions to get free page info
virtio-balloon: tell host vm's free page info
drivers/virtio/virtio_balloon.c | 306 +++++++++++++++++++++++++++++++-----
include/uapi/linux/virtio_balloon.h | 41 +++++
mm/page_alloc.c | 52 ++++++
3 files changed, 359 insertions(+), 40 deletions(-)
--
1.8.3.1
[toc] | [next] | [standalone]
| From | Liang Li <liang.z.li@intel.com> |
|---|---|
| Date | 2016-06-29 12:50 +0200 |
| Subject | [PATCH v2 kernel 7/7] virtio-balloon: tell host vm's free page info |
| Message-ID | <rPlea-36J-27@gated-at.bofh.it> |
| In reply to | #1433663 |
Support the request for vm's free page information, response with
a page bitmap. QEMU can make use of this free page bitmap to speed
up live migration process by skipping process the free pages.
Signed-off-by: Liang Li <liang.z.li@intel.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: Amit Shah <amit.shah@redhat.com>
---
drivers/virtio/virtio_balloon.c | 104 +++++++++++++++++++++++++++++++++++++---
1 file changed, 98 insertions(+), 6 deletions(-)
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 2d18ff6..5ca4ad3 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -62,10 +62,13 @@ module_param(oom_pages, int, S_IRUSR | S_IWUSR);
MODULE_PARM_DESC(oom_pages, "pages to free on OOM");
extern unsigned long get_max_pfn(void);
+extern int get_free_pages(unsigned long start_pfn, unsigned long end_pfn,
+ unsigned long *bitmap, unsigned long len);
+
struct virtio_balloon {
struct virtio_device *vdev;
- struct virtqueue *inflate_vq, *deflate_vq, *stats_vq;
+ struct virtqueue *inflate_vq, *deflate_vq, *stats_vq, *misc_vq;
/* The balloon servicing is delegated to a freezable workqueue. */
struct work_struct update_balloon_stats_work;
@@ -89,6 +92,8 @@ struct virtio_balloon {
unsigned long pfn_limit;
/* Used to record the processed pfn range */
unsigned long min_pfn, max_pfn, start_pfn, end_pfn;
+ /* Request header */
+ struct balloon_req_hdr req_hdr;
/*
* The pages we've told the Host we're not using are enqueued
* at vb_dev_info->pages list.
@@ -373,6 +378,49 @@ static void update_balloon_stats(struct virtio_balloon *vb)
pages_to_bytes(available));
}
+static void update_free_pages_stats(struct virtio_balloon *vb,
+ unsigned long req_id)
+{
+ struct scatterlist sg_in, sg_out;
+ unsigned long pfn = 0, bmap_len, max_pfn;
+ struct virtqueue *vq = vb->misc_vq;
+ struct balloon_bmap_hdr *hdr = vb->bmap_hdr;
+ int ret = 1;
+
+ max_pfn = get_max_pfn();
+ mutex_lock(&vb->balloon_lock);
+ while (pfn < max_pfn) {
+ memset(vb->page_bitmap, 0, vb->bmap_len);
+ ret = get_free_pages(pfn, pfn + vb->pfn_limit,
+ vb->page_bitmap, vb->bmap_len * BITS_PER_BYTE);
+ hdr->cmd = cpu_to_virtio16(vb->vdev, BALLOON_GET_FREE_PAGES);
+ hdr->page_shift = cpu_to_virtio16(vb->vdev, PAGE_SHIFT);
+ hdr->req_id = cpu_to_virtio64(vb->vdev, req_id);
+ hdr->start_pfn = cpu_to_virtio64(vb->vdev, pfn);
+ bmap_len = vb->pfn_limit / BITS_PER_BYTE;
+ if (!ret) {
+ hdr->flag = cpu_to_virtio16(vb->vdev,
+ BALLOON_FLAG_DONE);
+ if (pfn + vb->pfn_limit > max_pfn)
+ bmap_len = (max_pfn - pfn) / BITS_PER_BYTE;
+ } else
+ hdr->flag = cpu_to_virtio16(vb->vdev,
+ BALLOON_FLAG_CONT);
+ hdr->bmap_len = cpu_to_virtio64(vb->vdev, bmap_len);
+ sg_init_one(&sg_out, hdr,
+ sizeof(struct balloon_bmap_hdr) + bmap_len);
+
+ virtqueue_add_outbuf(vq, &sg_out, 1, vb, GFP_KERNEL);
+ virtqueue_kick(vq);
+ pfn += vb->pfn_limit;
+ }
+
+ sg_init_one(&sg_in, &vb->req_hdr, sizeof(vb->req_hdr));
+ virtqueue_add_inbuf(vq, &sg_in, 1, &vb->req_hdr, GFP_KERNEL);
+ virtqueue_kick(vq);
+ mutex_unlock(&vb->balloon_lock);
+}
+
/*
* While most virtqueues communicate guest-initiated requests to the hypervisor,
* the stats queue operates in reverse. The driver initializes the virtqueue
@@ -511,18 +559,49 @@ static void update_balloon_size_func(struct work_struct *work)
queue_work(system_freezable_wq, work);
}
+static void misc_handle_rq(struct virtio_balloon *vb)
+{
+ struct balloon_req_hdr *ptr_hdr;
+ unsigned int len;
+
+ ptr_hdr = virtqueue_get_buf(vb->misc_vq, &len);
+ if (!ptr_hdr || len != sizeof(vb->req_hdr))
+ return;
+
+ switch (ptr_hdr->cmd) {
+ case BALLOON_GET_FREE_PAGES:
+ update_free_pages_stats(vb, ptr_hdr->param);
+ break;
+ default:
+ break;
+ }
+}
+
+static void misc_request(struct virtqueue *vq)
+{
+ struct virtio_balloon *vb = vq->vdev->priv;
+
+ misc_handle_rq(vb);
+}
+
static int init_vqs(struct virtio_balloon *vb)
{
- struct virtqueue *vqs[3];
- vq_callback_t *callbacks[] = { balloon_ack, balloon_ack, stats_request };
- static const char * const names[] = { "inflate", "deflate", "stats" };
+ struct virtqueue *vqs[4];
+ vq_callback_t *callbacks[] = { balloon_ack, balloon_ack,
+ stats_request, misc_request };
+ static const char * const names[] = { "inflate", "deflate", "stats",
+ "misc" };
int err, nvqs;
/*
* We expect two virtqueues: inflate and deflate, and
* optionally stat.
*/
- nvqs = virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_STATS_VQ) ? 3 : 2;
+ if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_MISC_VQ))
+ nvqs = 4;
+ else
+ nvqs = virtio_has_feature(vb->vdev,
+ VIRTIO_BALLOON_F_STATS_VQ) ? 3 : 2;
err = vb->vdev->config->find_vqs(vb->vdev, nvqs, vqs, callbacks, names);
if (err)
return err;
@@ -543,6 +622,16 @@ static int init_vqs(struct virtio_balloon *vb)
BUG();
virtqueue_kick(vb->stats_vq);
}
+ if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_MISC_VQ)) {
+ struct scatterlist sg_in;
+
+ vb->misc_vq = vqs[3];
+ sg_init_one(&sg_in, &vb->req_hdr, sizeof(vb->req_hdr));
+ if (virtqueue_add_inbuf(vb->misc_vq, &sg_in, 1,
+ &vb->req_hdr, GFP_KERNEL) < 0)
+ BUG();
+ virtqueue_kick(vb->misc_vq);
+ }
return 0;
}
@@ -639,8 +728,10 @@ static int virtballoon_probe(struct virtio_device *vdev)
vb->bmap_hdr = kzalloc(hdr_len + vb->bmap_len, GFP_KERNEL);
/* Clear the feature bit if memory allocation fails */
- if (!vb->bmap_hdr)
+ if (!vb->bmap_hdr) {
__virtio_clear_bit(vdev, VIRTIO_BALLOON_F_PAGE_BITMAP);
+ __virtio_clear_bit(vdev, VIRTIO_BALLOON_F_MISC_VQ);
+ }
else
vb->page_bitmap = vb->bmap_hdr + hdr_len;
mutex_init(&vb->balloon_lock);
@@ -743,6 +834,7 @@ static unsigned int features[] = {
VIRTIO_BALLOON_F_STATS_VQ,
VIRTIO_BALLOON_F_DEFLATE_ON_OOM,
VIRTIO_BALLOON_F_PAGE_BITMAP,
+ VIRTIO_BALLOON_F_MISC_VQ,
};
static struct virtio_driver virtio_balloon_driver = {
--
1.8.3.1
[toc] | [prev] | [next] | [standalone]
| From | Liang Li <liang.z.li@intel.com> |
|---|---|
| Date | 2016-06-29 12:50 +0200 |
| Subject | [PATCH v2 kernel 6/7] mm: add the related functions to get free page info |
| Message-ID | <rPlea-36J-33@gated-at.bofh.it> |
| In reply to | #1433663 |
Save the free page info into a page bitmap, will be used in virtio
balloon device driver.
Signed-off-by: Liang Li <liang.z.li@intel.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Mel Gorman <mgorman@techsingularity.net>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: Amit Shah <amit.shah@redhat.com>
---
mm/page_alloc.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 2083b40..c2a6669 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -4521,6 +4521,52 @@ unsigned long get_max_pfn(void)
}
EXPORT_SYMBOL(get_max_pfn);
+static void mark_free_pages_bitmap(struct zone *zone, unsigned long start_pfn,
+ unsigned long end_pfn, unsigned long *bitmap, unsigned long len)
+{
+ unsigned long pfn, flags, page_num;
+ unsigned int order, t;
+ struct list_head *curr;
+
+ if (zone_is_empty(zone))
+ return;
+ end_pfn = min(start_pfn + len, end_pfn);
+ spin_lock_irqsave(&zone->lock, flags);
+
+ for_each_migratetype_order(order, t) {
+ list_for_each(curr, &zone->free_area[order].free_list[t]) {
+ pfn = page_to_pfn(list_entry(curr, struct page, lru));
+ if (pfn >= start_pfn && pfn <= end_pfn) {
+ page_num = 1UL << order;
+ if (pfn + page_num > end_pfn)
+ page_num = end_pfn - pfn;
+ bitmap_set(bitmap, pfn - start_pfn, page_num);
+ }
+ }
+ }
+
+ spin_unlock_irqrestore(&zone->lock, flags);
+}
+
+int get_free_pages(unsigned long start_pfn, unsigned long end_pfn,
+ unsigned long *bitmap, unsigned long len)
+{
+ struct zone *zone;
+ int ret = 0;
+
+ if (bitmap == NULL || start_pfn > end_pfn || start_pfn >= max_pfn)
+ return 0;
+ if (end_pfn < max_pfn)
+ ret = 1;
+ if (end_pfn >= max_pfn)
+ ret = 0;
+
+ for_each_populated_zone(zone)
+ mark_free_pages_bitmap(zone, start_pfn, end_pfn, bitmap, len);
+ return ret;
+}
+EXPORT_SYMBOL(get_free_pages);
+
static void zoneref_set_zone(struct zone *zone, struct zoneref *zoneref)
{
zoneref->zone = zone;
--
1.8.3.1
[toc] | [prev] | [next] | [standalone]
| From | "Li, Liang Z" <liang.z.li@intel.com> |
|---|---|
| Date | 2016-07-06 02:50 +0200 |
| Subject | RE: [PATCH v2 kernel 0/7] Extend virtio-balloon for fast (de)inflating & fast live migration |
| Message-ID | <rRJcl-1UL-1@gated-at.bofh.it> |
| In reply to | #1433663 |
Ping ... Liang > -----Original Message----- > From: Li, Liang Z > Sent: Wednesday, June 29, 2016 6:32 PM > To: mst@redhat.com > Cc: linux-kernel@vger.kernel.org; virtualization@lists.linux-foundation.org; > kvm@vger.kernel.org; qemu-devel@nongnu.org; virtio-dev@lists.oasis- > open.org; dgilbert@redhat.com; quintela@redhat.com; Li, Liang Z > Subject: [PATCH v2 kernel 0/7] Extend virtio-balloon for fast (de)inflating & > fast live migration > > This patch set contains two parts of changes to the virtio-balloon. > > One is the change for speeding up the inflating & deflating process, the main > idea of this optimization is to use bitmap to send the page information to > host instead of the PFNs, to reduce the overhead of virtio data transmission, > address translation and madvise(). This can help to improve the performance > by about 85%. > > Another change is for speeding up live migration. By skipping process guest's > free pages in the first round of data copy, to reduce needless data processing, > this can help to save quite a lot of CPU cycles and network bandwidth. We > put guest's free page information in bitmap and send it to host with the virt > queue of virtio-balloon. For an idle 8GB guest, this can help to shorten the > total live migration time from 2Sec to about 500ms in the 10Gbps network > environment. > > > Changes from v1 to v2: > * Abandon the patch for dropping page cache. > * Put some structures to uapi head file. > * Use a new way to determine the page bitmap size. > * Use a unified way to send the free page information with the bitmap > * Address the issues referred in MST's comments > > Liang Li (7): > virtio-balloon: rework deflate to add page to a list > virtio-balloon: define new feature bit and page bitmap head > mm: add a function to get the max pfn > virtio-balloon: speed up inflate/deflate process > virtio-balloon: define feature bit and head for misc virt queue > mm: add the related functions to get free page info > virtio-balloon: tell host vm's free page info > > drivers/virtio/virtio_balloon.c | 306 > +++++++++++++++++++++++++++++++----- > include/uapi/linux/virtio_balloon.h | 41 +++++ > mm/page_alloc.c | 52 ++++++ > 3 files changed, 359 insertions(+), 40 deletions(-) > > -- > 1.8.3.1
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web