All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Hildenbrand <david@redhat.com>
To: qemu-devel@nongnu.org
Cc: "David Hildenbrand" <david@redhat.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Igor Mammedov" <imammedo@redhat.com>,
	"Xiao Guangrong" <xiaoguangrong.eric@gmail.com>,
	"Michael S. Tsirkin" <mst@redhat.com>,
	"Peter Xu" <peterx@redhat.com>,
	"Philippe Mathieu-Daudé" <philmd@linaro.org>,
	"Eduardo Habkost" <eduardo@habkost.net>,
	"Marcel Apfelbaum" <marcel.apfelbaum@gmail.com>,
	"Yanan Wang" <wangyanan55@huawei.com>,
	"Michal Privoznik" <mprivozn@redhat.com>,
	"Daniel P . Berrangé" <berrange@redhat.com>,
	"Gavin Shan" <gshan@redhat.com>,
	"Alex Williamson" <alex.williamson@redhat.com>,
	kvm@vger.kernel.org
Subject: [PATCH v1 11/15] memory-device: Support memory-devices with auto-detection of the number of memslots
Date: Fri, 16 Jun 2023 11:26:50 +0200	[thread overview]
Message-ID: <20230616092654.175518-12-david@redhat.com> (raw)
In-Reply-To: <20230616092654.175518-1-david@redhat.com>

We want to support memory devices that detect at runtime how many
memslots they will use. The target use case is virtio-mem.

Let's suggest a memslot limit to the device, such that the device can
use that number to determine the number of memslots it wants to use.

To make a sane suggestion that doesn't cause trouble elsewhere, implement
a heuristic that considers
* The memslot soft-limit for all memory devices
* Unpopulated DIMM slots
* Actually still free and not reserved memslots
* The percentage of the remaining device memory region that memory device
  will occupy.

For example, if existing memory devices require 100 memslots, we have
>= 256 free (and not reserved) memslot and we have 28 unpopulated DIMM
slots, a device that occupies half of the device memory region would get a
suggestion of (256 - 100 - 28) * 1/2 = 64. [note that our soft-limit is
256]

Signed-off-by: David Hildenbrand <david@redhat.com>
---
 hw/mem/memory-device.c         | 66 +++++++++++++++++++++++++++++++++-
 include/hw/mem/memory-device.h | 10 ++++++
 2 files changed, 75 insertions(+), 1 deletion(-)

diff --git a/hw/mem/memory-device.c b/hw/mem/memory-device.c
index 2e6536c841..3099d346d7 100644
--- a/hw/mem/memory-device.c
+++ b/hw/mem/memory-device.c
@@ -12,6 +12,7 @@
 #include "qemu/osdep.h"
 #include "qemu/error-report.h"
 #include "hw/mem/memory-device.h"
+#include "hw/mem/pc-dimm.h"
 #include "qapi/error.h"
 #include "hw/boards.h"
 #include "qemu/range.h"
@@ -166,6 +167,16 @@ void memory_devices_notify_vhost_device_added(void)
     memory_devices_check_memslot_soft_limit(ms);
 }
 
+static void memory_device_set_suggested_memslot_limit(MemoryDeviceState *md,
+                                                      unsigned int limit)
+{
+    const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(md);
+
+    if (mdc->set_suggested_memslot_limit) {
+        mdc->set_suggested_memslot_limit(md, limit);
+    }
+}
+
 static unsigned int memory_device_get_memslots(MemoryDeviceState *md)
 {
     const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(md);
@@ -176,13 +187,58 @@ static unsigned int memory_device_get_memslots(MemoryDeviceState *md)
     return 1;
 }
 
+/*
+ * Suggested maximum number of memslots for a memory device with the given
+ * region size. Not exceeding this number will make most setups not run
+ * into the soft limit or even out of available memslots, even when multiple
+ * memory devices automatically determine the number of memslots to use.
+ */
+static unsigned int memory_device_suggested_memslot_limit(MachineState *ms,
+                                                          MemoryRegion *mr)
+{
+    const unsigned int soft_limit = memory_devices_memslot_soft_limit(ms);
+    const unsigned int free_dimm_slots = pc_dimm_get_free_slots(ms);
+    const uint64_t size = memory_region_size(mr);
+    uint64_t available_space;
+    unsigned int memslots;
+
+    /* Consider the soft-limit for all memory devices. */
+    if (soft_limit <= ms->device_memory->required_memslots) {
+        return 1;
+    }
+    memslots = soft_limit - ms->device_memory->required_memslots;
+
+    /* Consider the actually available memslots. */
+    memslots = MIN(memslots, get_available_memslots(ms));
+
+    /* It's the single memory device? We cannot plug something else. */
+    if (size == ms->maxram_size - ms->ram_size) {
+        return memslots;
+    }
+
+    /* Try setting one memmemslots for each empty DIMM slot aside. */
+    if (memslots <= free_dimm_slots) {
+        return 1;
+    }
+    memslots -= free_dimm_slots;
+
+    /*
+     * Simple heuristic: equally distribute the memslots over the space
+     * still available for memory devices.
+     */
+    available_space = ms->maxram_size - ms->ram_size -
+                      ms->device_memory->used_region_size;
+    memslots = (double)memslots * size / available_space;
+    return memslots < 1 ? 1 : memslots;
+}
+
 static void memory_device_check_addable(MachineState *ms, MemoryDeviceState *md,
                                         MemoryRegion *mr, Error **errp)
 {
     const uint64_t used_region_size = ms->device_memory->used_region_size;
     const unsigned int available_memslots = get_available_memslots(ms);
     const uint64_t size = memory_region_size(mr);
-    unsigned int required_memslots;
+    unsigned int required_memslots, suggested_memslot_limit;
 
     /* will we exceed the total amount of memory specified */
     if (used_region_size + size < used_region_size ||
@@ -193,6 +249,14 @@ static void memory_device_check_addable(MachineState *ms, MemoryDeviceState *md,
         return;
     }
 
+    /*
+     * Determine the per-device memslot limit for this device and
+     * communicate it to the device such that it can determine the number
+     * of memslots to use before we query them.
+     */
+    suggested_memslot_limit = memory_device_suggested_memslot_limit(ms, mr);
+    memory_device_set_suggested_memslot_limit(md, suggested_memslot_limit);
+
     /* ... are there still sufficient memslots available? */
     required_memslots = memory_device_get_memslots(md);
     if (available_memslots < required_memslots) {
diff --git a/include/hw/mem/memory-device.h b/include/hw/mem/memory-device.h
index 7e8e4452cb..c09a2f0a7c 100644
--- a/include/hw/mem/memory-device.h
+++ b/include/hw/mem/memory-device.h
@@ -100,6 +100,16 @@ struct MemoryDeviceClass {
      */
     MemoryRegion *(*get_memory_region)(MemoryDeviceState *md, Error **errp);
 
+    /*
+     * Optional: Set the suggested memslot limit, such that a device than
+     * can auto-detect the number of memslots to use based on this limit.
+     *
+     * Called exactly once when pre-plugging the memory device, before
+     * querying the number of memslots using @get_memslots the first time.
+     */
+    void (*set_suggested_memslot_limit)(MemoryDeviceState *md,
+                                        unsigned int limit);
+
     /*
      * Optional for memory devices that consume only a single memslot,
      * required for all other memory devices: Return the number of memslots
-- 
2.40.1


  parent reply	other threads:[~2023-06-16  9:31 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-16  9:26 [PATCH v1 00/15] virtio-mem: Expose device memory through multiple memslots David Hildenbrand
2023-06-16  9:26 ` [PATCH v1 01/15] memory-device: Track the required memslots in DeviceMemoryState David Hildenbrand
2023-06-16  9:26 ` [PATCH v1 02/15] kvm: Add stub for kvm_get_max_memslots() David Hildenbrand
2023-06-16  9:26 ` [PATCH v1 03/15] vhost: Add vhost_get_max_memslots() David Hildenbrand
2023-06-16  9:26 ` [PATCH v1 04/15] memory-device, vhost: Add a memslot soft limit for memory devices David Hildenbrand
2023-06-16  9:26   ` [PATCH v1 04/15] memory-device,vhost: " David Hildenbrand
2023-06-16  9:26 ` [PATCH v1 05/15] kvm: Return number of free memslots David Hildenbrand
2023-06-16  9:26 ` [PATCH v1 06/15] vhost: " David Hildenbrand
2023-06-16  9:26 ` [PATCH v1 07/15] memory-device: Support memory devices that statically consume multiple memslots David Hildenbrand
2023-06-16  9:26 ` [PATCH v1 08/15] memory-device: Track the actually used memslots in DeviceMemoryState David Hildenbrand
2023-06-16  9:26 ` [PATCH v1 09/15] memory-device, vhost: Support memory devices that dynamically consume multiple memslots David Hildenbrand
2023-06-16  9:26   ` [PATCH v1 09/15] memory-device,vhost: " David Hildenbrand
2023-06-16  9:26 ` [PATCH v1 10/15] pc-dimm: Provide pc_dimm_get_free_slots() to query free ram slots David Hildenbrand
2023-06-16  9:26 ` David Hildenbrand [this message]
2023-06-16  9:26 ` [PATCH v1 12/15] memory: Clarify mapping requirements for RamDiscardManager David Hildenbrand
2023-06-16  9:26 ` [PATCH v1 13/15] virtio-mem: Expose device memory via multiple memslots if enabled David Hildenbrand
2023-07-13 19:58   ` Maciej S. Szmigiero
2023-07-14 10:01     ` David Hildenbrand
2023-06-16  9:26 ` [PATCH v1 14/15] memory, vhost: Allow for marking memory device memory regions unmergeable David Hildenbrand
2023-06-16  9:26   ` [PATCH v1 14/15] memory,vhost: " David Hildenbrand
2023-06-16  9:26 ` [PATCH v1 15/15] virtio-mem: Mark memslot alias " David Hildenbrand

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=20230616092654.175518-12-david@redhat.com \
    --to=david@redhat.com \
    --cc=alex.williamson@redhat.com \
    --cc=berrange@redhat.com \
    --cc=eduardo@habkost.net \
    --cc=gshan@redhat.com \
    --cc=imammedo@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=marcel.apfelbaum@gmail.com \
    --cc=mprivozn@redhat.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peterx@redhat.com \
    --cc=philmd@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=wangyanan55@huawei.com \
    --cc=xiaoguangrong.eric@gmail.com \
    /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.