All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: Eduardo Habkost <ehabkost@redhat.com>,
	David Hildenbrand <david@redhat.com>,
	Markus Armbruster <armbru@redhat.com>,
	Peter Xu <peterx@redhat.com>, Igor Mammedov <imammedo@redhat.com>,
	Eric Blake <eblake@redhat.com>
Subject: [PULL 27/45] hostmem: Wire up RAM_NORESERVE via "reserve" property
Date: Thu, 17 Jun 2021 11:31:16 +0200	[thread overview]
Message-ID: <20210617093134.900014-28-pbonzini@redhat.com> (raw)
In-Reply-To: <20210617093134.900014-1-pbonzini@redhat.com>

From: David Hildenbrand <david@redhat.com>

Let's provide a way to control the use of RAM_NORESERVE via memory
backends using the "reserve" property which defaults to true (old
behavior).

Only Linux currently supports clearing the flag (and support is checked at
runtime, depending on the setting of "/proc/sys/vm/overcommit_memory").
Windows and other POSIX systems will bail out with "reserve=false".

The target use case is virtio-mem, which dynamically exposes memory
inside a large, sparse memory area to the VM. This essentially allows
avoiding to set "/proc/sys/vm/overcommit_memory == 0") when using
virtio-mem and also supporting hugetlbfs in the future.

As really only Linux implements RAM_NORESERVE right now, let's expose
the property only with CONFIG_LINUX. Setting the property to "false"
will then only fail in corner cases -- for example on very old kernels
or when memory overcommit was completely disabled by the admin.

Reviewed-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Eduardo Habkost <ehabkost@redhat.com> for memory backend and machine core
Cc: Markus Armbruster <armbru@redhat.com>
Cc: Eric Blake <eblake@redhat.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20210510114328.21835-11-david@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 backends/hostmem-file.c  | 11 ++++++-----
 backends/hostmem-memfd.c |  1 +
 backends/hostmem-ram.c   |  1 +
 backends/hostmem.c       | 36 ++++++++++++++++++++++++++++++++++++
 include/sysemu/hostmem.h |  2 +-
 qapi/qom.json            | 10 ++++++++++
 6 files changed, 55 insertions(+), 6 deletions(-)

diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index 9b1b9f0a56..cd038024fa 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -39,6 +39,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
                object_get_typename(OBJECT(backend)));
 #else
     HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(backend);
+    uint32_t ram_flags;
     gchar *name;
 
     if (!backend->size) {
@@ -51,11 +52,11 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
     }
 
     name = host_memory_backend_get_name(backend);
-    memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
-                                     name,
-                                     backend->size, fb->align,
-                                     (backend->share ? RAM_SHARED : 0) |
-                                     (fb->is_pmem ? RAM_PMEM : 0),
+    ram_flags = backend->share ? RAM_SHARED : 0;
+    ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
+    ram_flags |= fb->is_pmem ? RAM_PMEM : 0;
+    memory_region_init_ram_from_file(&backend->mr, OBJECT(backend), name,
+                                     backend->size, fb->align, ram_flags,
                                      fb->mem_path, fb->readonly, errp);
     g_free(name);
 #endif
diff --git a/backends/hostmem-memfd.c b/backends/hostmem-memfd.c
index 3076da146d..3fc85c3db8 100644
--- a/backends/hostmem-memfd.c
+++ b/backends/hostmem-memfd.c
@@ -54,6 +54,7 @@ memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
 
     name = host_memory_backend_get_name(backend);
     ram_flags = backend->share ? RAM_SHARED : 0;
+    ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
     memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend), name,
                                    backend->size, ram_flags, fd, 0, errp);
     g_free(name);
diff --git a/backends/hostmem-ram.c b/backends/hostmem-ram.c
index 741e701062..b8e55cdbd0 100644
--- a/backends/hostmem-ram.c
+++ b/backends/hostmem-ram.c
@@ -29,6 +29,7 @@ ram_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
 
     name = host_memory_backend_get_name(backend);
     ram_flags = backend->share ? RAM_SHARED : 0;
+    ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
     memory_region_init_ram_flags_nomigrate(&backend->mr, OBJECT(backend), name,
                                            backend->size, ram_flags, errp);
     g_free(name);
diff --git a/backends/hostmem.c b/backends/hostmem.c
index aab3de8408..4c05862ed5 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -216,6 +216,11 @@ static void host_memory_backend_set_prealloc(Object *obj, bool value,
     Error *local_err = NULL;
     HostMemoryBackend *backend = MEMORY_BACKEND(obj);
 
+    if (!backend->reserve && value) {
+        error_setg(errp, "'prealloc=on' and 'reserve=off' are incompatible");
+        return;
+    }
+
     if (!host_memory_backend_mr_inited(backend)) {
         backend->prealloc = value;
         return;
@@ -267,6 +272,7 @@ static void host_memory_backend_init(Object *obj)
     /* TODO: convert access to globals to compat properties */
     backend->merge = machine_mem_merge(machine);
     backend->dump = machine_dump_guest_core(machine);
+    backend->reserve = true;
     backend->prealloc_threads = 1;
 }
 
@@ -425,6 +431,30 @@ static void host_memory_backend_set_share(Object *o, bool value, Error **errp)
     backend->share = value;
 }
 
+#ifdef CONFIG_LINUX
+static bool host_memory_backend_get_reserve(Object *o, Error **errp)
+{
+    HostMemoryBackend *backend = MEMORY_BACKEND(o);
+
+    return backend->reserve;
+}
+
+static void host_memory_backend_set_reserve(Object *o, bool value, Error **errp)
+{
+    HostMemoryBackend *backend = MEMORY_BACKEND(o);
+
+    if (host_memory_backend_mr_inited(backend)) {
+        error_setg(errp, "cannot change property value");
+        return;
+    }
+    if (backend->prealloc && !value) {
+        error_setg(errp, "'prealloc=on' and 'reserve=off' are incompatible");
+        return;
+    }
+    backend->reserve = value;
+}
+#endif /* CONFIG_LINUX */
+
 static bool
 host_memory_backend_get_use_canonical_path(Object *obj, Error **errp)
 {
@@ -493,6 +523,12 @@ host_memory_backend_class_init(ObjectClass *oc, void *data)
         host_memory_backend_get_share, host_memory_backend_set_share);
     object_class_property_set_description(oc, "share",
         "Mark the memory as private to QEMU or shared");
+#ifdef CONFIG_LINUX
+    object_class_property_add_bool(oc, "reserve",
+        host_memory_backend_get_reserve, host_memory_backend_set_reserve);
+    object_class_property_set_description(oc, "reserve",
+        "Reserve swap space (or huge pages) if applicable");
+#endif /* CONFIG_LINUX */
     /*
      * Do not delete/rename option. This option must be considered stable
      * (as if it didn't have the 'x-' prefix including deprecation period) as
diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h
index df5644723a..9ff5c16963 100644
--- a/include/sysemu/hostmem.h
+++ b/include/sysemu/hostmem.h
@@ -64,7 +64,7 @@ struct HostMemoryBackend {
     /* protected */
     uint64_t size;
     bool merge, dump, use_canonical_path;
-    bool prealloc, is_mapped, share;
+    bool prealloc, is_mapped, share, reserve;
     uint32_t prealloc_threads;
     DECLARE_BITMAP(host_nodes, MAX_NODES + 1);
     HostMemPolicy policy;
diff --git a/qapi/qom.json b/qapi/qom.json
index f7ef30f940..652be317b8 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -545,6 +545,9 @@
 # @share: if false, the memory is private to QEMU; if true, it is shared
 #         (default: false)
 #
+# @reserve: if true, reserve swap space (or huge pages) if applicable
+#           (default: true) (since 6.1)
+#
 # @size: size of the memory region in bytes
 #
 # @x-use-canonical-path-for-ramblock-id: if true, the canoncial path is used
@@ -556,6 +559,12 @@
 #                                        false generally, but true for machine
 #                                        types <= 4.0)
 #
+# Note: prealloc=true and reserve=false cannot be set at the same time. With
+#       reserve=true, the behavior depends on the operating system: for example,
+#       Linux will not reserve swap space for shared file mappings --
+#       "not applicable". In contrast, reserve=false will bail out if it cannot
+#       be configured accordingly.
+#
 # Since: 2.1
 ##
 { 'struct': 'MemoryBackendProperties',
@@ -566,6 +575,7 @@
             '*prealloc': 'bool',
             '*prealloc-threads': 'uint32',
             '*share': 'bool',
+            '*reserve': 'bool',
             'size': 'size',
             '*x-use-canonical-path-for-ramblock-id': 'bool' } }
 
-- 
2.31.1




  parent reply	other threads:[~2021-06-17  9:50 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
2021-06-17  9:30 ` [PULL 01/45] vnc: avoid deprecation warnings for SASL on OS X Paolo Bonzini
2021-06-17  9:30 ` [PULL 02/45] vl: Fix an assert failure in error path Paolo Bonzini
2021-06-17  9:30 ` [PULL 03/45] qemu-config: use qemu_opts_from_qdict Paolo Bonzini
2021-06-17  9:30 ` [PULL 04/45] block/scsi: correctly emulate the VPD block limits page Paolo Bonzini
2021-06-17  9:30 ` [PULL 05/45] runstate: Initialize Error * to NULL Paolo Bonzini
2021-06-17  9:30 ` [PULL 06/45] esp: only assert INTR_DC interrupt flag if selection fails Paolo Bonzini
2021-06-17  9:30 ` [PULL 07/45] esp: only set ESP_RSEQ at the start of the select sequence Paolo Bonzini
2021-06-17  9:30 ` [PULL 08/45] esp: allow non-DMA callback in esp_transfer_data() initial transfer Paolo Bonzini
2021-06-17  9:30 ` [PULL 09/45] esp: handle non-DMA transfers from the target one byte at a time Paolo Bonzini
2021-06-17  9:30 ` [PULL 10/45] esp: ensure PDMA write transfers are flushed from the FIFO to the target immediately Paolo Bonzini
2021-06-17  9:31 ` [PULL 11/45] esp: revert 75ef849696 "esp: correctly fill bus id with requested lun" Paolo Bonzini
2021-06-17  9:31 ` [PULL 12/45] esp: correctly accumulate extended messages for PDMA Paolo Bonzini
2021-06-17  9:31 ` [PULL 13/45] esp: fix migration version check in esp_is_version_5() Paolo Bonzini
2021-06-17  9:31 ` [PULL 14/45] esp: store lun coming from the MESSAGE OUT phase Paolo Bonzini
2021-06-17  9:31 ` [PULL 15/45] softmmu/physmem: Mark shared anonymous memory RAM_SHARED Paolo Bonzini
2021-06-17  9:31 ` [PULL 16/45] softmmu/physmem: Fix ram_block_discard_range() to handle shared anonymous memory Paolo Bonzini
2021-06-17  9:31 ` [PULL 17/45] softmmu/physmem: Fix qemu_ram_remap() " Paolo Bonzini
2021-06-17  9:31 ` [PULL 18/45] util/mmap-alloc: Factor out calculation of the pagesize for the guard page Paolo Bonzini
2021-06-17  9:31 ` [PULL 19/45] util/mmap-alloc: Factor out reserving of a memory region to mmap_reserve() Paolo Bonzini
2021-06-17  9:31 ` [PULL 20/45] util/mmap-alloc: Factor out activating of memory to mmap_activate() Paolo Bonzini
2021-06-17  9:31 ` [PULL 21/45] softmmu/memory: Pass ram_flags to qemu_ram_alloc_from_fd() Paolo Bonzini
2021-06-17  9:31 ` [PULL 22/45] softmmu/memory: Pass ram_flags to memory_region_init_ram_shared_nomigrate() Paolo Bonzini
2021-06-17  9:31 ` [PULL 23/45] softmmu/memory: Pass ram_flags to qemu_ram_alloc() and qemu_ram_alloc_internal() Paolo Bonzini
2021-06-17  9:31 ` [PULL 24/45] util/mmap-alloc: Pass flags instead of separate bools to qemu_ram_mmap() Paolo Bonzini
2021-06-17  9:31 ` [PULL 25/45] memory: Introduce RAM_NORESERVE and wire it up in qemu_ram_mmap() Paolo Bonzini
2021-06-17  9:31 ` [PULL 26/45] util/mmap-alloc: Support RAM_NORESERVE via MAP_NORESERVE under Linux Paolo Bonzini
2021-06-17  9:31 ` Paolo Bonzini [this message]
2021-06-17  9:31 ` [PULL 28/45] qmp: Clarify memory backend properties returned via query-memdev Paolo Bonzini
2021-06-17  9:31 ` [PULL 29/45] qmp: Include "share" property of memory backends Paolo Bonzini
2021-06-17  9:31 ` [PULL 30/45] hmp: Print "share" property of memory backends with "info memdev" Paolo Bonzini
2021-06-17  9:31 ` [PULL 31/45] qmp: Include "reserve" property of memory backends Paolo Bonzini
2021-06-17  9:31 ` [PULL 32/45] hmp: Print "reserve" property of memory backends with "info memdev" Paolo Bonzini
2021-06-17  9:31 ` [PULL 33/45] configure: map x32 to cpu_family x86_64 for meson Paolo Bonzini
2021-06-17  9:31 ` [PULL 34/45] target/i386: Refactored intercept checks into cpu_svm_has_intercept Paolo Bonzini
2021-06-17  9:31 ` [PULL 35/45] target/i386: Added consistency checks for VMRUN intercept and ASID Paolo Bonzini
2021-06-17  9:31 ` [PULL 36/45] target/i386: Added consistency checks for CR0 Paolo Bonzini
2021-06-17  9:31 ` [PULL 37/45] target/i386: Added Intercept CR0 writes check Paolo Bonzini
2021-06-17  9:31 ` [PULL 38/45] configure: Use -std=gnu11 Paolo Bonzini
2021-06-17  9:31 ` [PULL 39/45] softfloat: Use _Generic instead of QEMU_GENERIC Paolo Bonzini
2021-06-17  9:31 ` [PULL 40/45] util: Use real functions for thread-posix QemuRecMutex Paolo Bonzini
2021-06-17  9:31 ` [PULL 41/45] util: Pass file+line to qemu_rec_mutex_unlock_impl Paolo Bonzini
2021-06-17  9:31 ` [PULL 42/45] util: Use unique type for QemuRecMutex in thread-posix.h Paolo Bonzini
2021-06-17  9:31 ` [PULL 43/45] include/qemu/lockable: Use _Generic instead of QEMU_GENERIC Paolo Bonzini
2021-06-17  9:31 ` [PULL 44/45] qemu/compiler: Remove QEMU_GENERIC Paolo Bonzini
2021-06-17  9:31 ` [PULL 45/45] configure: Remove probe for _Static_assert Paolo Bonzini
2021-06-17 10:21 ` [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 no-reply
2021-06-18  8:53 ` Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210617093134.900014-28-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=armbru@redhat.com \
    --cc=david@redhat.com \
    --cc=eblake@redhat.com \
    --cc=ehabkost@redhat.com \
    --cc=imammedo@redhat.com \
    --cc=peterx@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.