161 lines
6.3 KiB
Diff
161 lines
6.3 KiB
Diff
From 9e0c4adad755988ea9f94f57a87e000dd7045962 Mon Sep 17 00:00:00 2001
|
|
From: Paolo Bonzini <pbonzini@redhat.com>
|
|
Date: Fri, 18 Jul 2025 18:11:27 +0200
|
|
Subject: [PATCH 112/115] memory: Change
|
|
memory_region_set_ram_discard_manager() to return the result
|
|
|
|
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
|
|
RH-MergeRequest: 391: TDX support, including attestation and device assignment
|
|
RH-Jira: RHEL-15710 RHEL-20798 RHEL-49728
|
|
RH-Acked-by: Yash Mankad <None>
|
|
RH-Acked-by: Peter Xu <peterx@redhat.com>
|
|
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
|
RH-Commit: [112/115] 43deb5763dfabf964b55c7a6bb4363b96a5020cc (bonzini/rhel-qemu-kvm)
|
|
|
|
Modify memory_region_set_ram_discard_manager() to return -EBUSY if a
|
|
RamDiscardManager is already set in the MemoryRegion. The caller must
|
|
handle this failure, such as having virtio-mem undo its actions and fail
|
|
the realize() process. Opportunistically move the call earlier to avoid
|
|
complex error handling.
|
|
|
|
This change is beneficial when introducing a new RamDiscardManager
|
|
instance besides virtio-mem. After
|
|
ram_block_coordinated_discard_require(true) unlocks all
|
|
RamDiscardManager instances, only one instance is allowed to be set for
|
|
one MemoryRegion at present.
|
|
|
|
Suggested-by: David Hildenbrand <david@redhat.com>
|
|
Reviewed-by: David Hildenbrand <david@redhat.com>
|
|
Reviewed-by: Pankaj Gupta <pankaj.gupta@amd.com>
|
|
Tested-by: Alexey Kardashevskiy <aik@amd.com>
|
|
Reviewed-by: Alexey Kardashevskiy <aik@amd.com>
|
|
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
|
|
Signed-off-by: Chenyi Qiang <chenyi.qiang@intel.com>
|
|
Link: https://lore.kernel.org/r/20250612082747.51539-3-chenyi.qiang@intel.com
|
|
Signed-off-by: Peter Xu <peterx@redhat.com>
|
|
(cherry picked from commit ff1211154c45c9f7f82116ae9a8c72a848e4a8b5)
|
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
---
|
|
hw/virtio/virtio-mem.c | 30 +++++++++++++++++-------------
|
|
include/exec/memory.h | 6 +++---
|
|
system/memory.c | 10 +++++++---
|
|
3 files changed, 27 insertions(+), 19 deletions(-)
|
|
|
|
diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
|
|
index ae26133f58..6284539243 100644
|
|
--- a/hw/virtio/virtio-mem.c
|
|
+++ b/hw/virtio/virtio-mem.c
|
|
@@ -1049,6 +1049,17 @@ static void virtio_mem_device_realize(DeviceState *dev, Error **errp)
|
|
return;
|
|
}
|
|
|
|
+ /*
|
|
+ * Set ourselves as RamDiscardManager before the plug handler maps the
|
|
+ * memory region and exposes it via an address space.
|
|
+ */
|
|
+ if (memory_region_set_ram_discard_manager(&vmem->memdev->mr,
|
|
+ RAM_DISCARD_MANAGER(vmem))) {
|
|
+ error_setg(errp, "Failed to set RamDiscardManager");
|
|
+ ram_block_coordinated_discard_require(false);
|
|
+ return;
|
|
+ }
|
|
+
|
|
/*
|
|
* We don't know at this point whether shared RAM is migrated using
|
|
* QEMU or migrated using the file content. "x-ignore-shared" will be
|
|
@@ -1063,6 +1074,7 @@ static void virtio_mem_device_realize(DeviceState *dev, Error **errp)
|
|
ret = ram_block_discard_range(rb, 0, qemu_ram_get_used_length(rb));
|
|
if (ret) {
|
|
error_setg_errno(errp, -ret, "Unexpected error discarding RAM");
|
|
+ memory_region_set_ram_discard_manager(&vmem->memdev->mr, NULL);
|
|
ram_block_coordinated_discard_require(false);
|
|
return;
|
|
}
|
|
@@ -1124,13 +1136,6 @@ static void virtio_mem_device_realize(DeviceState *dev, Error **errp)
|
|
vmem->system_reset = VIRTIO_MEM_SYSTEM_RESET(obj);
|
|
vmem->system_reset->vmem = vmem;
|
|
qemu_register_resettable(obj);
|
|
-
|
|
- /*
|
|
- * Set ourselves as RamDiscardManager before the plug handler maps the
|
|
- * memory region and exposes it via an address space.
|
|
- */
|
|
- memory_region_set_ram_discard_manager(&vmem->memdev->mr,
|
|
- RAM_DISCARD_MANAGER(vmem));
|
|
}
|
|
|
|
static void virtio_mem_device_unrealize(DeviceState *dev)
|
|
@@ -1138,12 +1143,6 @@ static void virtio_mem_device_unrealize(DeviceState *dev)
|
|
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
|
|
VirtIOMEM *vmem = VIRTIO_MEM(dev);
|
|
|
|
- /*
|
|
- * The unplug handler unmapped the memory region, it cannot be
|
|
- * found via an address space anymore. Unset ourselves.
|
|
- */
|
|
- memory_region_set_ram_discard_manager(&vmem->memdev->mr, NULL);
|
|
-
|
|
qemu_unregister_resettable(OBJECT(vmem->system_reset));
|
|
object_unref(OBJECT(vmem->system_reset));
|
|
|
|
@@ -1156,6 +1155,11 @@ static void virtio_mem_device_unrealize(DeviceState *dev)
|
|
virtio_del_queue(vdev, 0);
|
|
virtio_cleanup(vdev);
|
|
g_free(vmem->bitmap);
|
|
+ /*
|
|
+ * The unplug handler unmapped the memory region, it cannot be
|
|
+ * found via an address space anymore. Unset ourselves.
|
|
+ */
|
|
+ memory_region_set_ram_discard_manager(&vmem->memdev->mr, NULL);
|
|
ram_block_coordinated_discard_require(false);
|
|
}
|
|
|
|
diff --git a/include/exec/memory.h b/include/exec/memory.h
|
|
index 71b4a411cc..7cfbe203f4 100644
|
|
--- a/include/exec/memory.h
|
|
+++ b/include/exec/memory.h
|
|
@@ -2488,13 +2488,13 @@ static inline bool memory_region_has_ram_discard_manager(MemoryRegion *mr)
|
|
*
|
|
* This function must not be called for a mapped #MemoryRegion, a #MemoryRegion
|
|
* that does not cover RAM, or a #MemoryRegion that already has a
|
|
- * #RamDiscardManager assigned.
|
|
+ * #RamDiscardManager assigned. Return 0 if the rdm is set successfully.
|
|
*
|
|
* @mr: the #MemoryRegion
|
|
* @rdm: #RamDiscardManager to set
|
|
*/
|
|
-void memory_region_set_ram_discard_manager(MemoryRegion *mr,
|
|
- RamDiscardManager *rdm);
|
|
+int memory_region_set_ram_discard_manager(MemoryRegion *mr,
|
|
+ RamDiscardManager *rdm);
|
|
|
|
/**
|
|
* memory_region_find: translate an address/size relative to a
|
|
diff --git a/system/memory.c b/system/memory.c
|
|
index 5e6eb459d5..35011f731e 100644
|
|
--- a/system/memory.c
|
|
+++ b/system/memory.c
|
|
@@ -2083,12 +2083,16 @@ RamDiscardManager *memory_region_get_ram_discard_manager(MemoryRegion *mr)
|
|
return mr->rdm;
|
|
}
|
|
|
|
-void memory_region_set_ram_discard_manager(MemoryRegion *mr,
|
|
- RamDiscardManager *rdm)
|
|
+int memory_region_set_ram_discard_manager(MemoryRegion *mr,
|
|
+ RamDiscardManager *rdm)
|
|
{
|
|
g_assert(memory_region_is_ram(mr));
|
|
- g_assert(!rdm || !mr->rdm);
|
|
+ if (mr->rdm && rdm) {
|
|
+ return -EBUSY;
|
|
+ }
|
|
+
|
|
mr->rdm = rdm;
|
|
+ return 0;
|
|
}
|
|
|
|
uint64_t ram_discard_manager_get_min_granularity(const RamDiscardManager *rdm,
|
|
--
|
|
2.50.1
|
|
|