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>,
"Stefan Hajnoczi" <stefanha@redhat.com>,
"Maciej S . Szmigiero" <mail@maciej.szmigiero.name>,
kvm@vger.kernel.org
Subject: [PATCH v2 08/16] memory-device: Track required and actually used memslots in DeviceMemoryState
Date: Fri, 25 Aug 2023 15:21:41 +0200 [thread overview]
Message-ID: <20230825132149.366064-9-david@redhat.com> (raw)
In-Reply-To: <20230825132149.366064-1-david@redhat.com>
Let's track how many memslots are required by plugged memory devices and
how many are currently actually getting used by plugged memory
devices.
"required - used" is the number of reserved memslots. For now, the number
of used and required memslots is always equal, and there are no
reservations. This is a preparation for memory devices that want to
dynamically consume memslots after initially specifying how many they
require -- where we'll end up with reserved memslots.
To track the number of used memslots, create a new address space for
our device memory and register a memory listener (add/remove) for that
address space.
Signed-off-by: David Hildenbrand <david@redhat.com>
---
hw/mem/memory-device.c | 54 ++++++++++++++++++++++++++++++++++++++++++
include/hw/boards.h | 10 +++++++-
2 files changed, 63 insertions(+), 1 deletion(-)
diff --git a/hw/mem/memory-device.c b/hw/mem/memory-device.c
index 4613a15e1f..ee77f9d290 100644
--- a/hw/mem/memory-device.c
+++ b/hw/mem/memory-device.c
@@ -286,6 +286,7 @@ void memory_device_plug(MemoryDeviceState *md, MachineState *ms)
g_assert(ms->device_memory);
ms->device_memory->used_region_size += memory_region_size(mr);
+ ms->device_memory->required_memslots += memory_device_get_memslots(md);
memory_region_add_subregion(&ms->device_memory->mr,
addr - ms->device_memory->base, mr);
trace_memory_device_plug(DEVICE(md)->id ? DEVICE(md)->id : "", addr);
@@ -305,6 +306,7 @@ void memory_device_unplug(MemoryDeviceState *md, MachineState *ms)
memory_region_del_subregion(&ms->device_memory->mr, mr);
ms->device_memory->used_region_size -= memory_region_size(mr);
+ ms->device_memory->required_memslots -= memory_device_get_memslots(md);
trace_memory_device_unplug(DEVICE(md)->id ? DEVICE(md)->id : "",
mdc->get_addr(md));
}
@@ -324,6 +326,50 @@ uint64_t memory_device_get_region_size(const MemoryDeviceState *md,
return memory_region_size(mr);
}
+static void memory_devices_region_mod(MemoryListener *listener,
+ MemoryRegionSection *mrs, bool add)
+{
+ DeviceMemoryState *dms = container_of(listener, DeviceMemoryState,
+ listener);
+
+ if (!memory_region_is_ram(mrs->mr)) {
+ warn_report("Unexpected memory region mapped into device memory region.");
+ return;
+ }
+
+ /*
+ * The expectation is that each distinct RAM memory region section in
+ * our region for memory devices consumes exactly one memslot in KVM
+ * and in vhost. For vhost, this is true, except:
+ * * ROM memory regions don't consume a memslot. These get used very
+ * rarely for memory devices (R/O NVDIMMs).
+ * * Memslots without a fd (memory-backend-ram) don't necessarily
+ * consume a memslot. Such setups are quite rare and possibly bogus:
+ * the memory would be inaccessible by such vhost devices.
+ *
+ * So for vhost, in corner cases we might over-estimate the number of
+ * memslots that are currently used or that might still be reserved
+ * (required - used).
+ */
+ dms->used_memslots += add ? 1 : -1;
+
+ if (dms->used_memslots > dms->required_memslots) {
+ warn_report("Memory devices use more memory slots than indicated as required.");
+ }
+}
+
+static void memory_devices_region_add(MemoryListener *listener,
+ MemoryRegionSection *mrs)
+{
+ return memory_devices_region_mod(listener, mrs, true);
+}
+
+static void memory_devices_region_del(MemoryListener *listener,
+ MemoryRegionSection *mrs)
+{
+ return memory_devices_region_mod(listener, mrs, false);
+}
+
void machine_memory_devices_init(MachineState *ms, hwaddr base, uint64_t size)
{
g_assert(size);
@@ -333,8 +379,16 @@ void machine_memory_devices_init(MachineState *ms, hwaddr base, uint64_t size)
memory_region_init(&ms->device_memory->mr, OBJECT(ms), "device-memory",
size);
+ address_space_init(&ms->device_memory->as, &ms->device_memory->mr,
+ "device-memory");
memory_region_add_subregion(get_system_memory(), ms->device_memory->base,
&ms->device_memory->mr);
+
+ /* Track the number of memslots used by memory devices. */
+ ms->device_memory->listener.region_add = memory_devices_region_add;
+ ms->device_memory->listener.region_del = memory_devices_region_del;
+ memory_listener_register(&ms->device_memory->listener,
+ &ms->device_memory->as);
}
static const TypeInfo memory_device_info = {
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 3b541ffd24..e344ded607 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -296,15 +296,23 @@ struct MachineClass {
* DeviceMemoryState:
* @base: address in guest physical address space where the memory
* address space for memory devices starts
- * @mr: address space container for memory devices
+ * @mr: memory region container for memory devices
+ * @as: address space for memory devices
+ * @listener: memory listener used to track used memslots in the address space
* @dimm_size: the sum of plugged DIMMs' sizes
* @used_region_size: the part of @mr already used by memory devices
+ * @required_memslots: the number of memslots required by memory devices
+ * @used_memslots: the number of memslots currently used by memory devices
*/
typedef struct DeviceMemoryState {
hwaddr base;
MemoryRegion mr;
+ AddressSpace as;
+ MemoryListener listener;
uint64_t dimm_size;
uint64_t used_region_size;
+ unsigned int required_memslots;
+ unsigned int used_memslots;
} DeviceMemoryState;
/**
--
2.41.0
next prev parent reply other threads:[~2023-08-25 13:23 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-25 13:21 [PATCH v2 00/16] virtio-mem: Expose device memory through multiple memslots David Hildenbrand
2023-08-25 13:21 ` [PATCH v2 01/16] vhost: Rework memslot filtering and fix "used_memslot" tracking David Hildenbrand
2023-08-25 13:21 ` [PATCH v2 02/16] vhost: Remove vhost_backend_can_merge() callback David Hildenbrand
2023-08-25 13:21 ` [PATCH v2 03/16] softmmu/physmem: Fixup qemu_ram_block_from_host() documentation David Hildenbrand
2023-08-25 13:21 ` [PATCH v2 04/16] kvm: Return number of free memslots David Hildenbrand
2023-08-28 22:26 ` Philippe Mathieu-Daudé
2023-09-06 14:14 ` David Hildenbrand
2023-09-06 14:37 ` David Hildenbrand
2023-08-25 13:21 ` [PATCH v2 05/16] vhost: " David Hildenbrand
2023-08-25 13:21 ` [PATCH v2 06/16] memory-device: Support memory devices with multiple memslots David Hildenbrand
2023-08-25 13:21 ` [PATCH v2 07/16] stubs: Rename qmp_memory_device.c to memory_device.c David Hildenbrand
2023-08-25 13:21 ` David Hildenbrand [this message]
2023-08-25 13:21 ` [PATCH v2 09/16] memory-device, vhost: Support memory devices that dynamically consume memslots David Hildenbrand
2023-08-25 13:21 ` [PATCH v2 10/16] kvm: Add stub for kvm_get_max_memslots() David Hildenbrand
2023-08-25 13:21 ` [PATCH v2 11/16] vhost: Add vhost_get_max_memslots() David Hildenbrand
2023-08-25 13:21 ` [PATCH v2 12/16] memory-device, vhost: Support automatic decision on the number of memslots David Hildenbrand
2023-08-25 13:21 ` [PATCH v2 13/16] memory: Clarify mapping requirements for RamDiscardManager David Hildenbrand
2023-08-25 13:21 ` [PATCH v2 14/16] virtio-mem: Expose device memory via multiple memslots if enabled David Hildenbrand
2023-08-25 13:21 ` [PATCH v2 15/16] memory, vhost: Allow for marking memory device memory regions unmergeable David Hildenbrand
2023-08-28 22:43 ` [PATCH v2 15/16] memory,vhost: " Philippe Mathieu-Daudé
2023-08-25 13:21 ` [PATCH v2 16/16] virtio-mem: Mark memslot alias " David Hildenbrand
2023-08-28 22:44 ` Philippe Mathieu-Daudé
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=20230825132149.366064-9-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=mail@maciej.szmigiero.name \
--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=stefanha@redhat.com \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).