From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965226AbcFMJxr (ORCPT ); Mon, 13 Jun 2016 05:53:47 -0400 Received: from mga02.intel.com ([134.134.136.20]:6778 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1161105AbcFMJxn (ORCPT ); Mon, 13 Jun 2016 05:53:43 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.26,466,1459839600"; d="scan'208";a="120844432" From: Liang Li To: kvm@vger.kernel.org Cc: virtio-dev@lists.oasis-open.org, qemu-devel@nongun.org, linux-kernel@vger.kernel.org, mst@redhat.com, Liang Li , Paolo Bonzini , Cornelia Huck , Amit Shah Subject: [PATCH 6/6] virtio-balloon: tell host vm's free page info Date: Mon, 13 Jun 2016 17:47:13 +0800 Message-Id: <1465811233-21136-7-git-send-email-liang.z.li@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1465811233-21136-1-git-send-email-liang.z.li@intel.com> References: <1465811233-21136-1-git-send-email-liang.z.li@intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Support the new request for vm's free page information, response with a page bitmap. QEMU can make use of this free page bitmap to speed up the live migration process by skipping process the free pages. Signed-off-by: Liang Li Cc: Michael S. Tsirkin Cc: Paolo Bonzini Cc: Cornelia Huck Cc: Amit Shah --- drivers/virtio/virtio_balloon.c | 64 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 5a30ca0..5237d50 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c @@ -46,8 +46,12 @@ static int oom_pages = OOM_VBALLOON_DEFAULT_PAGES; module_param(oom_pages, int, S_IRUSR | S_IWUSR); MODULE_PARM_DESC(oom_pages, "pages to free on OOM"); +extern void get_free_pages(unsigned long *free_page_bitmap, unsigned long len); +extern unsigned long get_max_pfn(void); + enum balloon_req_id { BALLOON_DROP_CACHE, + BALLOON_GET_FREE_PAGES, }; struct balloon_req_hdr { @@ -85,6 +89,9 @@ struct virtio_balloon { /* Used to record the processed pfn range */ unsigned long min_pfn, max_pfn, start_pfn, end_pfn; struct balloon_req_hdr req_hdr; + /* Free page bitmap and length to tell the host */ + unsigned long *free_pages; + unsigned long free_bmap_len; /* * The pages we've told the Host we're not using are enqueued * at vb_dev_info->pages list. @@ -370,6 +377,41 @@ static void update_balloon_stats(struct virtio_balloon *vb) pages_to_bytes(available)); } +static int reset_free_page_bmap(struct virtio_balloon *vb, + unsigned long *max_pfn) +{ + int err = 0; + unsigned long bitmap_bytes; + + *max_pfn = get_max_pfn(); + bitmap_bytes = ALIGN(*max_pfn, BITS_PER_LONG) / BITS_PER_BYTE; + + if (bitmap_bytes < vb->free_bmap_len) + memset(vb->free_pages, 0, bitmap_bytes); + else { + kfree(vb->free_pages); + vb->free_bmap_len = bitmap_bytes; + vb->free_pages = kzalloc(bitmap_bytes, GFP_KERNEL); + } + + if (!vb->free_pages) { + err = -ENOMEM; + vb->free_bmap_len = 0; + } + + return err; +} + +static void update_free_pages_stats(struct virtio_balloon *vb) +{ + unsigned long max_pfn; + + if (!reset_free_page_bmap(vb, &max_pfn)) + get_free_pages(vb->free_pages, max_pfn); + else + dev_err(&vb->vdev->dev, "%s failure: No memory!\n", __func__); +} + /* * While most virtqueues communicate guest-initiated requests to the hypervisor, * the stats queue operates in reverse. The driver initializes the virtqueue @@ -511,10 +553,11 @@ static void update_balloon_size_func(struct work_struct *work) static void misc_handle_rq(struct virtio_balloon *vb) { struct virtqueue *vq; - struct scatterlist sg_out; + struct scatterlist sg_out, sg[2]; unsigned int len; struct balloon_req_hdr *ptr_hdr; struct scatterlist sg_in; + struct balloon_bmap_hdr hdr; vq = vb->misc_vq; ptr_hdr = virtqueue_get_buf(vq, &len); @@ -532,6 +575,18 @@ static void misc_handle_rq(struct virtio_balloon *vb) sg_init_one(&sg_in, &vb->req_hdr, sizeof(vb->req_hdr)); virtqueue_add_inbuf(vq, &sg_in, 1, &vb->req_hdr, GFP_KERNEL); break; + case BALLOON_GET_FREE_PAGES: + update_free_pages_stats(vb); + sg_init_table(sg, 2); + + hdr.id = cpu_to_virtio32(vb->vdev, BALLOON_GET_FREE_PAGES); + hdr.page_shift = cpu_to_virtio32(vb->vdev, PAGE_SHIFT); + hdr.start_pfn = cpu_to_virtio64(vb->vdev, 0); + hdr.bmap_len = cpu_to_virtio64(vb->vdev, vb->free_bmap_len); + sg_set_buf(&sg[0], &hdr, sizeof(hdr)); + sg_set_buf(&sg[1], vb->free_pages, vb->free_bmap_len); + virtqueue_add_outbuf(vq, &sg[0], 2, vb, GFP_KERNEL); + break; default: break; } @@ -689,6 +744,12 @@ static int virtballoon_probe(struct virtio_device *vdev) err = -ENOMEM; goto out; } + vb->free_bmap_len = ALIGN(get_max_pfn(), BITS_PER_LONG) / BITS_PER_BYTE; + vb->free_pages = kzalloc(vb->free_bmap_len, GFP_KERNEL); + if (!vb->free_pages) { + err = -ENOMEM; + goto out; + } mutex_init(&vb->balloon_lock); init_waitqueue_head(&vb->acked); vb->vdev = vdev; @@ -750,6 +811,7 @@ static void virtballoon_remove(struct virtio_device *vdev) remove_common(vb); kfree(vb->page_bitmap); + kfree(vb->free_pages); kfree(vb); } -- 1.9.1