From patchwork Wed Jun 10 04:27:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Michael S. Tsirkin" X-Patchwork-Id: 280969 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.9 required=3.0 tests=DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CAEB6C433E0 for ; Wed, 10 Jun 2020 04:58:19 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 900F62072E for ; Wed, 10 Jun 2020 04:58:19 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="aaF6TjyO" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 900F62072E Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:58302 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jisoc-0003SK-Rq for qemu-devel@archiver.kernel.org; Wed, 10 Jun 2020 00:58:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:34758) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jisOF-0004e7-Vs for qemu-devel@nongnu.org; Wed, 10 Jun 2020 00:31:04 -0400 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:27644 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1jisOE-0000gR-S9 for qemu-devel@nongnu.org; Wed, 10 Jun 2020 00:31:03 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1591763462; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=oiR6m9EPqvRwON04zA+EzVpgAt3vN6EqBTJGhjucyNs=; b=aaF6TjyOV0GZLKD3BOcMzJWTCKlT5q3b6H+oHOV4NIyfBWmMFrioxTEU/2Ydl9lw2Dug5a dXdXtA+WSmFDuGeTfM72XtPZIBNgemYqiKPwmWUAdJL89YXVB0NT4DJEfW9TtPFtdXnioz lt4vhrIcD/Q82F9mFZAg6duqwvEXPfo= Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-295-96wZOBQXMneCbH_PwvvjAA-1; Wed, 10 Jun 2020 00:27:34 -0400 X-MC-Unique: 96wZOBQXMneCbH_PwvvjAA-1 Received: by mail-wr1-f70.google.com with SMTP id z10so518436wrs.2 for ; Tue, 09 Jun 2020 21:27:34 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=oiR6m9EPqvRwON04zA+EzVpgAt3vN6EqBTJGhjucyNs=; b=b5u6OlORyZuOc3auvru+2Q2mzl4ldQN2ccsRMndEBtOsuIjG564Zy09f1gKqwlxk3z BnAU+lCR/3PEXqsOl69XJvSm4ProyL7LWbBNPBjQtA4igNkvfPm0sVIBT9XoJsKs9rKG qU/9TpsW0WpGCs9RXNwce9wUvbbmE/kpZQ0xcOJ9UsmyxJaaDIKmyPUSAqSzyKU+QiAA sCH9uPU58k6mIK4JX5zuunsZolf/ifQIqzqH6jH9KTEHSPjXIQCw8yJ3DlD+69D8xrHd 6ax8Xf92Svq9bEMYB3CmLG20Bg+w7FfWXRH4h45Cu/8i04w0w/gQDg9X2/bYNFByCjoP V6rw== X-Gm-Message-State: AOAM531C0yjCL3qPB3czQkfZtEQjmP1yMoQrJmKqg6A8oOaBcS8aoV0C p26ZenxfQlnXKzm5Uvq6utp+gWE47FB+wJEIYkek8qY7M+PnH7jQBLMTT/DScE/ZdYWrsb3JmZS B52piMD7Jzi2fUvw= X-Received: by 2002:adf:dfcf:: with SMTP id q15mr1245722wrn.373.1591763252985; Tue, 09 Jun 2020 21:27:32 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxa4dk+l/1Ch+m+1RkcjcKiCA9aEwSc5XmXyewBcZfD5nYVBRxlcYvuDcOlofsyzuE/pJoBtA== X-Received: by 2002:adf:dfcf:: with SMTP id q15mr1245710wrn.373.1591763252768; Tue, 09 Jun 2020 21:27:32 -0700 (PDT) Received: from redhat.com (bzq-79-181-55-232.red.bezeqint.net. [79.181.55.232]) by smtp.gmail.com with ESMTPSA id 23sm5098468wmg.10.2020.06.09.21.27.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Jun 2020 21:27:32 -0700 (PDT) Date: Wed, 10 Jun 2020 00:27:31 -0400 From: "Michael S. Tsirkin" To: qemu-devel@nongnu.org Subject: [PULL 26/56] virtio-balloon: Provide an interface for free page reporting Message-ID: <20200610042613.1459309-27-mst@redhat.com> References: <20200610042613.1459309-1-mst@redhat.com> MIME-Version: 1.0 In-Reply-To: <20200610042613.1459309-1-mst@redhat.com> X-Mailer: git-send-email 2.24.1.751.gd10ce2899c X-Mutt-Fcc: =sent X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline Received-SPF: pass client-ip=207.211.31.120; envelope-from=mst@redhat.com; helo=us-smtp-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/09 21:17:20 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -30 X-Spam_score: -3.1 X-Spam_bar: --- X-Spam_report: (-3.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Maydell , Alexander Duyck , David Hildenbrand Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Alexander Duyck Add support for free page reporting. 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 provides a new way of letting the guest proactively report free pages to the hypervisor, so the hypervisor can reuse them. In contrast to inflate/deflate that is triggered via the hypervisor explicitly. Acked-by: David Hildenbrand Signed-off-by: Alexander Duyck Message-Id: <20200527041407.12700.73735.stgit@localhost.localdomain> --- include/hw/virtio/virtio-balloon.h | 2 +- hw/virtio/virtio-balloon.c | 72 ++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/include/hw/virtio/virtio-balloon.h b/include/hw/virtio/virtio-balloon.h index 7fe78e5c14..d49fef00ce 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, *reporting_vq; uint32_t free_page_report_status; uint32_t num_pages; uint32_t actual; diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index 31d3c88482..10507b2a43 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -321,6 +321,67 @@ 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; + + /* + * When we discard the page it has the effect of removing the page + * from the hypervisor itself and causing it to be zeroed when it + * is returned to us. So we must not discard the page if it is + * accessible by another device or process, or if the guest is + * expecting it to retain a non-zero value. + */ + if (qemu_balloon_is_inhibited() || dev->poison_val) { + goto skip_element; + } + + 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; + RAMBlock *rb; + + /* + * There is no need to check the memory section to see if + * it is ram/readonly/romd like there is for handle_output + * below. If the region is not meant to be written to then + * address_space_map will have allocated a bounce buffer + * and it will be freed in address_space_unmap and trigger + * and unassigned_mem_write before failing to copy over the + * buffer. If more than one bad descriptor is provided it + * will return NULL after the first bounce buffer and fail + * to map any resources. + */ + rb = qemu_ram_block_from_host(addr, false, &ram_offset); + if (!rb) { + trace_virtio_balloon_bad_addr(elem->in_addr[i]); + continue; + } + + /* + * For now we will simply ignore unaligned memory regions, or + * regions that overrun the end of the RAMBlock. + */ + if (!QEMU_IS_ALIGNED(ram_offset | size, qemu_ram_pagesize(rb)) || + (ram_offset + size) > qemu_ram_get_used_length(rb)) { + continue; + } + + ram_block_discard_range(rb, ram_offset, size); + } + +skip_element: + 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); @@ -835,6 +896,12 @@ static void virtio_balloon_device_realize(DeviceState *dev, Error **errp) s->free_page_bh = aio_bh_new(iothread_get_aio_context(s->iothread), virtio_ballloon_get_free_page_hints, s); } + + if (virtio_has_feature(s->host_features, VIRTIO_BALLOON_F_REPORTING)) { + s->reporting_vq = virtio_add_queue(vdev, 32, + virtio_balloon_handle_report); + } + reset_stats(s); } @@ -858,6 +925,9 @@ static void virtio_balloon_device_unrealize(DeviceState *dev) if (s->free_page_vq) { virtio_delete_queue(s->free_page_vq); } + if (s->reporting_vq) { + virtio_delete_queue(s->reporting_vq); + } virtio_cleanup(vdev); } @@ -945,6 +1015,8 @@ static Property virtio_balloon_properties[] = { VIRTIO_BALLOON_F_FREE_PAGE_HINT, false), DEFINE_PROP_BIT("page-poison", VirtIOBalloon, host_features, VIRTIO_BALLOON_F_PAGE_POISON, true), + DEFINE_PROP_BIT("free-page-reporting", VirtIOBalloon, host_features, + VIRTIO_BALLOON_F_REPORTING, false), /* QEMU 4.0 accidentally changed the config size even when free-page-hint * is disabled, resulting in QEMU 3.1 migration incompatibility. This * property retains this quirk for QEMU 4.1 machine types.