From patchwork Mon Jun 13 09:47:13 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Liang Li X-Patchwork-Id: 9172485 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 90A326086B for ; Mon, 13 Jun 2016 09:54:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 80D7A22473 for ; Mon, 13 Jun 2016 09:54:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7521227C2D; Mon, 13 Jun 2016 09:54:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D832722473 for ; Mon, 13 Jun 2016 09:54:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965198AbcFMJxp (ORCPT ); Mon, 13 Jun 2016 05:53:45 -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 Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga101.jf.intel.com with ESMTP; 13 Jun 2016 02:53:42 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.26,466,1459839600"; d="scan'208";a="120844432" Received: from ll.sh.intel.com (HELO localhost) ([10.239.13.123]) by fmsmga004.fm.intel.com with ESMTP; 13 Jun 2016 02:53:41 -0700 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: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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); }