From patchwork Tue Nov 19 21:54:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Duyck X-Patchwork-Id: 11252739 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 631A76C1 for ; Tue, 19 Nov 2019 21:55:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3B44922461 for ; Tue, 19 Nov 2019 21:55:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="dx7Blc0Y" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727427AbfKSVzB (ORCPT ); Tue, 19 Nov 2019 16:55:01 -0500 Received: from mail-pf1-f193.google.com ([209.85.210.193]:45712 "EHLO mail-pf1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727007AbfKSVzB (ORCPT ); Tue, 19 Nov 2019 16:55:01 -0500 Received: by mail-pf1-f193.google.com with SMTP id z4so12997090pfn.12; Tue, 19 Nov 2019 13:55:00 -0800 (PST) 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=dx7Blc0Yj3Rx/RjrgJKyI/MPW54vzQaHCiPgTU2lJYHzw713Y8tJjzISyVbISg+82W q0xpJJIwYAJJNWbud3SnhHwP6hSpvbfRTFqZwDH1PiAuCuIpIozQszjMjMh39e01JtVP T+VdM8A33zHH1LTbsDV2P7me2fEBOzOA2hMAKGfUCIG8d4I2nKAKtRviUBzbqckjV6WT bNGOq7nC1xpYfZ3RsSfb4ZgA1gb68/Cd4xlSICl7EpKQDYwkBTzExQfCqY74vb3Q2zAo 82oRpNw/6gmeSvLsedxttdirYaSfrSVS+ikkQZ0R5eFwaHgpUiv0dgJDkdju6Q+TZ4XC i1Ug== 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=aWTmyhYkzVSdAs4ASeufbp2ecPhSeq0Jdq2EvHVwgl3JuO8EFVL7Y15X+jEhtuDhyQ fbcc5LeUY2C58uPy3DX6a03q55Vv4PeHIT3YWnbkMY+nHjq1Pe4yWFCOVtVks5bYiWam WfXwOUqRWiBHlDekVdhoCjf8eQPH1LkNm/VYO2nItsw0Aj3thGl2LPU8EI4v+i27cBms oo+jNS6Y6EqbdEk/d8uwfUQ66skGXvxHgbKLpHSZtPsovsfc138p5oIRXifBUkzDB8au CATmY+LEdFO9u0eKKNTczjD2wkpe/kmIjuumw5F6uBAZxjPgmz10HOYvZvNm08KO1R4v VrsA== X-Gm-Message-State: APjAAAWU7xDRnTuLkw7Qd8h7jkzRNg/KDlSGMgMlE6sewdvHiZxw789P Dz1G0uHKcFSQqI4ExfgI34QHVytq X-Google-Smtp-Source: APXvYqyJ92owA+lmtlUVzaa1BakWv9kc2YzTjdx3YCCnhnqzx2X0AmPtiG72ZQbCkuKqiG8LXkVQ3Q== X-Received: by 2002:a63:225f:: with SMTP id t31mr8119549pgm.358.1574200500065; Tue, 19 Nov 2019 13:55:00 -0800 (PST) Received: from localhost.localdomain ([2001:470:b:9c3:9e5c:8eff:fe4f:f2d0]) by smtp.gmail.com with ESMTPSA id n72sm4683355pjc.4.2019.11.19.13.54.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Nov 2019 13:54:59 -0800 (PST) Subject: [PATCH v14 QEMU 3/3] virtio-balloon: Provide a interface for unused page reporting From: Alexander Duyck To: kvm@vger.kernel.org, mst@redhat.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 Cc: yang.zhang.wz@gmail.com, nitesh@redhat.com, konrad.wilk@oracle.com, david@redhat.com, pagupta@redhat.com, riel@surriel.com, lcapitulino@redhat.com, dave.hansen@intel.com, wei.w.wang@intel.com, aarcange@redhat.com, pbonzini@redhat.com, dan.j.williams@intel.com, alexander.h.duyck@linux.intel.com, osalvador@suse.de Date: Tue, 19 Nov 2019 13:54:58 -0800 Message-ID: <20191119215458.25688.33379.stgit@localhost.localdomain> In-Reply-To: <20191119214454.24996.66289.stgit@localhost.localdomain> References: <20191119214454.24996.66289.stgit@localhost.localdomain> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@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;