Received: by 2002:a25:824b:0:0:0:0:0 with SMTP id d11csp8473116ybn; Tue, 1 Oct 2019 08:35:18 -0700 (PDT) X-Google-Smtp-Source: APXvYqyKWTa+iBp7DEdSsXpSK2wCXUvXyeJ7SIjvUx+Qyg59iSq/Yv/mSnYoXcHNwKYHRmzEcQEy X-Received: by 2002:a17:906:e297:: with SMTP id gg23mr24174750ejb.47.1569944118491; Tue, 01 Oct 2019 08:35:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1569944118; cv=none; d=google.com; s=arc-20160816; b=faiT2wEnqbgCtr7eOwRRKKHl2Te6mtJl2go9TQHvPPIklSGcZAdM1KEOvrllL/sXCB s2EXUiMhXYTpFFPyWIGyM76k93sEBKDlz3jeLqgLFhddNu46UE1Tf2y0OrJ3jY5RsPvY nEjx1qxj1hMWyIfck3MVph/V4DOZNSVv1gu7unpjZ5T1LLjViRJws7UiWypVPIaaWgUx jq+ab9tXD0lsxaSSsrIJUYYxv17sjEYpwXOuYTsgezpnVefkyXHqA02bWzCBD6MMEDmq 4wbIPl5u+RiK6ql0lI7I2J+jRMkFxF5e7KUtOv2fQjL5tZWig0y/6ZPmZ+/202/puNPO kpVA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:cc:to:from :subject:dkim-signature; bh=IYnIZF3ya8GRMyw0Z8v44wRFjachYcZ/Qaw0Oz7Yqys=; b=Vv7yZ5w+MtWyXCTk8lXR2o/wRRpJbKYJo5Av5NUAy2O2gWtKbuWafvmnCMOnbhQ/tt vfVZRX7UKQhMU4v936EsDARQN1vlHWOb8HPJ3um1J1N7YTmW55B4UpnMzYgfqAaB83D1 DeVHV51gbbBAIf8ik6M7t8A5Gb9R+87rddYtAu4LO7Tt1o6ZNl0KIViKQUi8bfgOLzrW ZLYEWDhwMc97FPehZyPNowYfokwSrUTyGr4hDOj+DP85BNphmM4ztx44SpmLH+I7HXfh QUnVkeUU81loJoPMGVxk3jxyyDX3MRx6h/EsJSBJqa22k0/Ytq21wdTDN5MC0CkBx7mq Cn1Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b="fFf/s9L/"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t16si9585197edd.269.2019.10.01.08.34.53; Tue, 01 Oct 2019 08:35:18 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b="fFf/s9L/"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389766AbfJAPbU (ORCPT + 99 others); Tue, 1 Oct 2019 11:31:20 -0400 Received: from mail-pg1-f195.google.com ([209.85.215.195]:37639 "EHLO mail-pg1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389757AbfJAPbU (ORCPT ); Tue, 1 Oct 2019 11:31:20 -0400 Received: by mail-pg1-f195.google.com with SMTP id c17so9907520pgg.4; Tue, 01 Oct 2019 08:31:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:from:to:cc:date:message-id:in-reply-to:references :user-agent:mime-version:content-transfer-encoding; bh=IYnIZF3ya8GRMyw0Z8v44wRFjachYcZ/Qaw0Oz7Yqys=; b=fFf/s9L/WVB7bjmw9fJPe2WCP680R1hAwuz1EqtrpqaGDESC6QFN2j2SXFOiAJg48C QnQhC/HuBLM4hw4d4aGJ9GMH+NahcRJzzAfWlDiQem/OQ6HTAv0fMd1BeY9U1lQ/GSge Me1yyZXkd7tOvHMyE79qhoufjm0W3V9RiZ4BajjbmZ2I7jx0AgLfZwuHR98ZhjI1xS6x 6wKWChettN4aTn+SOWX6b2RqdJSknjPHojz6q/AqeS0Emtu4rXj02fEx4X7/r9KZk0nq V6As+NbPDdINtRfRk95OxlyONVc8iPdBVtjmmXBl4YE4jeGWo7lhRl42+2ZHCEmSq6KA HTuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=IYnIZF3ya8GRMyw0Z8v44wRFjachYcZ/Qaw0Oz7Yqys=; b=SkC7AUxdxsQD+cbFSx+lt9Gnosm3Y++WaJTeX67LnL3xnVgk4NU6+NZCkOsdszXa7k 29Q3B2+9gW4+ssakpxbw77ltzWST2qa7ud9fY+cykjtVwVrcabq2U1Op1YW+WitN0wny 2rv+P+OcLAiW/aVlrY2u/bNQMub1tk0PTvODhwHg2vBFB0zj6/3ba2P/quSNF6RXyl0H Ss10BcSyerV2tcTBDYQHJPufU7R/da7YeitAKBc3ZOuj1+2/F0L6rVEOT1gGo8RxthSz 3pFZfbS4QYl/tCv28iNDOrA7ugqFHyDT+3GBF2T6gWi8G/3DQa6IPnVRV1KiTHOpw8jz XUTQ== X-Gm-Message-State: APjAAAXmBbBk85aDXDfxC2EE1K9PLKVTLhzhVCOmyuHcF31BKkJBfVzD 1qQPP3It48Ga6hxdhw60dIs= X-Received: by 2002:a62:d152:: with SMTP id t18mr4342674pfl.259.1569943879123; Tue, 01 Oct 2019 08:31:19 -0700 (PDT) Received: from localhost.localdomain ([2001:470:b:9c3:9e5c:8eff:fe4f:f2d0]) by smtp.gmail.com with ESMTPSA id 2sm16384053pfo.91.2019.10.01.08.31.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 01 Oct 2019 08:31:18 -0700 (PDT) Subject: [PATCH v11 QEMU 3/3] virtio-balloon: Provide a interface for unused page reporting From: Alexander Duyck To: virtio-dev@lists.oasis-open.org, kvm@vger.kernel.org, mst@redhat.com, david@redhat.com, dave.hansen@intel.com, linux-kernel@vger.kernel.org, willy@infradead.org, mhocko@kernel.org, linux-mm@kvack.org, akpm@linux-foundation.org, mgorman@techsingularity.net, vbabka@suse.cz, osalvador@suse.de Cc: yang.zhang.wz@gmail.com, pagupta@redhat.com, konrad.wilk@oracle.com, nitesh@redhat.com, riel@surriel.com, lcapitulino@redhat.com, wei.w.wang@intel.com, aarcange@redhat.com, pbonzini@redhat.com, dan.j.williams@intel.com, alexander.h.duyck@linux.intel.com Date: Tue, 01 Oct 2019 08:31:17 -0700 Message-ID: <20191001153117.4422.30512.stgit@localhost.localdomain> In-Reply-To: <20191001152441.27008.99285.stgit@localhost.localdomain> References: <20191001152441.27008.99285.stgit@localhost.localdomain> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Alexander Duyck Add support for what I am referring to as "unused page reporting". Basically the idea is to function very similar to how the balloon works in that we basically end up madvising the page as not being used. However we don't really need to bother with any deflate type logic since the page will be faulted back into the guest when it is read or written to. This is meant to be a simplification of the existing balloon interface to use for providing hints to what memory needs to be freed. I am assuming this is safe to do as the deflate logic does not actually appear to do very much other than tracking what subpages have been released and which ones haven't. Signed-off-by: Alexander Duyck --- hw/virtio/virtio-balloon.c | 46 ++++++++++++++++++++++++++++++++++-- include/hw/virtio/virtio-balloon.h | 2 +- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index 6ecfec422309..47f253d016db 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -321,6 +321,40 @@ static void balloon_stats_set_poll_interval(Object *obj, Visitor *v, balloon_stats_change_timer(s, 0); } +static void virtio_balloon_handle_report(VirtIODevice *vdev, VirtQueue *vq) +{ + VirtIOBalloon *dev = VIRTIO_BALLOON(vdev); + VirtQueueElement *elem; + + while ((elem = virtqueue_pop(vq, sizeof(VirtQueueElement)))) { + unsigned int i; + + for (i = 0; i < elem->in_num; i++) { + void *addr = elem->in_sg[i].iov_base; + size_t size = elem->in_sg[i].iov_len; + ram_addr_t ram_offset; + size_t rb_page_size; + RAMBlock *rb; + + if (qemu_balloon_is_inhibited() || dev->poison_val) + continue; + + rb = qemu_ram_block_from_host(addr, false, &ram_offset); + rb_page_size = qemu_ram_pagesize(rb); + + /* For now we will simply ignore unaligned memory regions */ + if ((ram_offset | size) & (rb_page_size - 1)) + continue; + + ram_block_discard_range(rb, ram_offset, size); + } + + virtqueue_push(vq, elem, 0); + virtio_notify(vdev, vq); + g_free(elem); + } +} + static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq) { VirtIOBalloon *s = VIRTIO_BALLOON(vdev); @@ -628,7 +662,8 @@ static size_t virtio_balloon_config_size(VirtIOBalloon *s) return sizeof(struct virtio_balloon_config); } if (virtio_has_feature(features, VIRTIO_BALLOON_F_PAGE_POISON) || - virtio_has_feature(features, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) { + virtio_has_feature(features, VIRTIO_BALLOON_F_FREE_PAGE_HINT) || + virtio_has_feature(features, VIRTIO_BALLOON_F_REPORTING)) { return sizeof(struct virtio_balloon_config); } return offsetof(struct virtio_balloon_config, free_page_report_cmd_id); @@ -716,7 +751,8 @@ static uint64_t virtio_balloon_get_features(VirtIODevice *vdev, uint64_t f, VirtIOBalloon *dev = VIRTIO_BALLOON(vdev); f |= dev->host_features; virtio_add_feature(&f, VIRTIO_BALLOON_F_STATS_VQ); - if (virtio_has_feature(f, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) { + if (virtio_has_feature(f, VIRTIO_BALLOON_F_FREE_PAGE_HINT) || + virtio_has_feature(f, VIRTIO_BALLOON_F_REPORTING)) { virtio_add_feature(&f, VIRTIO_BALLOON_F_PAGE_POISON); } @@ -806,6 +842,10 @@ static void virtio_balloon_device_realize(DeviceState *dev, Error **errp) s->dvq = virtio_add_queue(vdev, 128, virtio_balloon_handle_output); s->svq = virtio_add_queue(vdev, 128, virtio_balloon_receive_stats); + if (virtio_has_feature(s->host_features, VIRTIO_BALLOON_F_REPORTING)) { + s->rvq = virtio_add_queue(vdev, 32, virtio_balloon_handle_report); + } + if (virtio_has_feature(s->host_features, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) { s->free_page_vq = virtio_add_queue(vdev, VIRTQUEUE_MAX_SIZE, @@ -932,6 +972,8 @@ static Property virtio_balloon_properties[] = { */ DEFINE_PROP_BOOL("qemu-4-0-config-size", VirtIOBalloon, qemu_4_0_config_size, false), + DEFINE_PROP_BIT("unused-page-reporting", VirtIOBalloon, host_features, + VIRTIO_BALLOON_F_REPORTING, true), DEFINE_PROP_LINK("iothread", VirtIOBalloon, iothread, TYPE_IOTHREAD, IOThread *), DEFINE_PROP_END_OF_LIST(), diff --git a/include/hw/virtio/virtio-balloon.h b/include/hw/virtio/virtio-balloon.h index 7fe78e5c14d7..db5bf7127112 100644 --- a/include/hw/virtio/virtio-balloon.h +++ b/include/hw/virtio/virtio-balloon.h @@ -42,7 +42,7 @@ enum virtio_balloon_free_page_report_status { typedef struct VirtIOBalloon { VirtIODevice parent_obj; - VirtQueue *ivq, *dvq, *svq, *free_page_vq; + VirtQueue *ivq, *dvq, *svq, *free_page_vq, *rvq; uint32_t free_page_report_status; uint32_t num_pages; uint32_t actual;