From patchwork Thu Jan 6 13:17:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Michael S. Tsirkin" X-Patchwork-Id: 1576124 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=TFgihAcL; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 bilbo.ozlabs.org (Postfix) with ESMTPS id 4JV7PP1qq8z9sSs for ; Fri, 7 Jan 2022 01:03:53 +1100 (AEDT) Received: from localhost ([::1]:56422 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n5TMt-00059o-2b for incoming@patchwork.ozlabs.org; Thu, 06 Jan 2022 09:03:51 -0500 Received: from eggs.gnu.org ([209.51.188.92]:42176) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n5Sei-0005HZ-Vc for qemu-devel@nongnu.org; Thu, 06 Jan 2022 08:18:13 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:31944) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n5Seg-0000z9-0K for qemu-devel@nongnu.org; Thu, 06 Jan 2022 08:18:12 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1641475084; 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=E8cVuTw3WnQz2PCB6BKnsgn/gSst2XbDgCGG/3vh9UE=; b=TFgihAcLUNcvMrQKwwkd3/C316hKPGpM3aHHUo+itgTrzoPY8uaCFg8IetNMhNfJ2mkjUS bFZ/W985hnjhZErmRWh9rdpGS2VSAK9gdPnQowNceVei42oisaFdSj/g5RjNcLeebjtKMe OM+nqz+/JP+23m3NX6eIbPVBtjhLkjE= Received: from mail-ed1-f69.google.com (mail-ed1-f69.google.com [209.85.208.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-269-uEGEdwzeO-2HTgphdNYYTw-1; Thu, 06 Jan 2022 08:18:03 -0500 X-MC-Unique: uEGEdwzeO-2HTgphdNYYTw-1 Received: by mail-ed1-f69.google.com with SMTP id g11-20020a056402090b00b003f8fd1ac475so1950479edz.1 for ; Thu, 06 Jan 2022 05:18:03 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=E8cVuTw3WnQz2PCB6BKnsgn/gSst2XbDgCGG/3vh9UE=; b=QxZKjdeyHOAzBUnkmNN3B/7AohLfDA1FwkT/KY4L/fRHKn8F7S5r84uki8dWVu/F+N 75j1pmsqbRmWzAjpD8NpZugmtCGVtJCHfgQ16XuwYjrrZOZUf70DJy9oR/KPokwf4fQV EUvpVRhvtSIFBJ4axdfOdwxqNpNsWiu8+Inr9i9I06SUqR487XLRbL00QmVJtr2m/UAj 4gwlNJY3TYzqrr3Dbj+SpMYveoCWdpQbKhEALF3EEdHk4zWeYBA4JNkscTv0ra8ya74l 14jgkLUDsIxUf/3AXO1ZeffGoeXpo7oICwL6NqJ2+tX+7/O4CeKA6QBHTnAy7C/UpqEf iP5g== X-Gm-Message-State: AOAM530x1lbtFOX/dMGKs7vTO8NW6tLPMMYewKoxzcqE/RSqCJjZjhJq xdSgG+RshKLWpRNc5mxeCySGTAyoSb6IMwD8TlL/WYUYgIoG+Yox+Xl7/jvAgYPQwhA1q5+SvpW Qjiw17KB67/7zsWCIySeEq9x+dbluff6FnTVIthRlnbIvN1vnuvSk4xgQE8tD X-Received: by 2002:a17:907:9810:: with SMTP id ji16mr44576245ejc.601.1641475081879; Thu, 06 Jan 2022 05:18:01 -0800 (PST) X-Google-Smtp-Source: ABdhPJwv/1mrShMtoH/JqlZzcUU6mgtQxhF+LCX8o5t9HQMs1Rs5GUac7JtM7HaSfWSIHqOjEfh5ow== X-Received: by 2002:a17:907:9810:: with SMTP id ji16mr44576229ejc.601.1641475081622; Thu, 06 Jan 2022 05:18:01 -0800 (PST) Received: from redhat.com ([2a03:c5c0:207e:991b:6857:5652:b903:a63b]) by smtp.gmail.com with ESMTPSA id q18sm23146eds.11.2022.01.06.05.18.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Jan 2022 05:18:01 -0800 (PST) Date: Thu, 6 Jan 2022 08:17:59 -0500 From: "Michael S. Tsirkin" To: qemu-devel@nongnu.org Subject: [PULL 36/52] virtio-mem: Support "prealloc=on" option Message-ID: <20220106131534.423671-37-mst@redhat.com> References: <20220106131534.423671-1-mst@redhat.com> MIME-Version: 1.0 In-Reply-To: <20220106131534.423671-1-mst@redhat.com> X-Mailer: git-send-email 2.27.0.106.g8ac3dc51b1 X-Mutt-Fcc: =sent Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=mst@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline Received-SPF: pass client-ip=170.10.129.124; envelope-from=mst@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -31 X-Spam_score: -3.2 X-Spam_bar: --- X-Spam_report: (-3.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.372, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Michal Privoznik , Peter Maydell , David Hildenbrand Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: David Hildenbrand For scarce memory resources, such as hugetlb, we want to be able to prealloc such memory resources in order to not crash later on access. On simple user errors we could otherwise easily run out of memory resources an crash the VM -- pretty much undesired. For ordinary memory devices, such as DIMMs, we preallocate memory via the memory backend for such use cases; however, with virtio-mem we're dealing with sparse memory backends; preallocating the whole memory backend destroys the whole purpose of virtio-mem. Instead, we want to preallocate memory when actually exposing memory to the VM dynamically, and fail plugging memory gracefully + warn the user in case preallocation fails. A common use case for hugetlb will be using "reserve=off,prealloc=off" for the memory backend and "prealloc=on" for the virtio-mem device. This way, no huge pages will be reserved for the process, but we can recover if there are no actual huge pages when plugging memory. Libvirt is already prepared for this. Note that preallocation cannot protect from the OOM killer -- which holds true for any kind of preallocation in QEMU. It's primarily useful only for scarce memory resources such as hugetlb, or shared file-backed memory. It's of little use for ordinary anonymous memory that can be swapped, KSM merged, ... but we won't forbid it. Reviewed-by: Michal Privoznik Signed-off-by: David Hildenbrand Message-Id: <20211217134611.31172-9-david@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/virtio/virtio-mem.h | 4 ++++ hw/virtio/virtio-mem.c | 39 ++++++++++++++++++++++++++++++---- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/include/hw/virtio/virtio-mem.h b/include/hw/virtio/virtio-mem.h index a5dd6a493b..0ac7bcb3b6 100644 --- a/include/hw/virtio/virtio-mem.h +++ b/include/hw/virtio/virtio-mem.h @@ -30,6 +30,7 @@ OBJECT_DECLARE_TYPE(VirtIOMEM, VirtIOMEMClass, #define VIRTIO_MEM_REQUESTED_SIZE_PROP "requested-size" #define VIRTIO_MEM_BLOCK_SIZE_PROP "block-size" #define VIRTIO_MEM_ADDR_PROP "memaddr" +#define VIRTIO_MEM_PREALLOC_PROP "prealloc" struct VirtIOMEM { VirtIODevice parent_obj; @@ -62,6 +63,9 @@ struct VirtIOMEM { /* block size and alignment */ uint64_t block_size; + /* whether to prealloc memory when plugging new blocks */ + bool prealloc; + /* notifiers to notify when "size" changes */ NotifierList size_change_notifiers; diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c index 341c3fa2c1..ab975ff566 100644 --- a/hw/virtio/virtio-mem.c +++ b/hw/virtio/virtio-mem.c @@ -429,10 +429,40 @@ static int virtio_mem_set_block_state(VirtIOMEM *vmem, uint64_t start_gpa, return -EBUSY; } virtio_mem_notify_unplug(vmem, offset, size); - } else if (virtio_mem_notify_plug(vmem, offset, size)) { - /* Could be a mapping attempt resulted in memory getting populated. */ - ram_block_discard_range(vmem->memdev->mr.ram_block, offset, size); - return -EBUSY; + } else { + int ret = 0; + + if (vmem->prealloc) { + void *area = memory_region_get_ram_ptr(&vmem->memdev->mr) + offset; + int fd = memory_region_get_fd(&vmem->memdev->mr); + Error *local_err = NULL; + + os_mem_prealloc(fd, area, size, 1, &local_err); + if (local_err) { + static bool warned; + + /* + * Warn only once, we don't want to fill the log with these + * warnings. + */ + if (!warned) { + warn_report_err(local_err); + warned = true; + } else { + error_free(local_err); + } + ret = -EBUSY; + } + } + if (!ret) { + ret = virtio_mem_notify_plug(vmem, offset, size); + } + + if (ret) { + /* Could be preallocation or a notifier populated memory. */ + ram_block_discard_range(vmem->memdev->mr.ram_block, offset, size); + return -EBUSY; + } } virtio_mem_set_bitmap(vmem, start_gpa, size, plug); return 0; @@ -1108,6 +1138,7 @@ static void virtio_mem_instance_init(Object *obj) static Property virtio_mem_properties[] = { DEFINE_PROP_UINT64(VIRTIO_MEM_ADDR_PROP, VirtIOMEM, addr, 0), DEFINE_PROP_UINT32(VIRTIO_MEM_NODE_PROP, VirtIOMEM, node, 0), + DEFINE_PROP_BOOL(VIRTIO_MEM_PREALLOC_PROP, VirtIOMEM, prealloc, false), DEFINE_PROP_LINK(VIRTIO_MEM_MEMDEV_PROP, VirtIOMEM, memdev, TYPE_MEMORY_BACKEND, HostMemoryBackend *), DEFINE_PROP_END_OF_LIST(),