278 lines
12 KiB
Diff
278 lines
12 KiB
Diff
From a0a6a0d1131461f2695f28a673f410bbb33262ef Mon Sep 17 00:00:00 2001
|
|
From: Paolo Bonzini <pbonzini@redhat.com>
|
|
Date: Fri, 18 Jul 2025 18:11:28 +0200
|
|
Subject: [PATCH 113/115] memory: Unify the definiton of ReplayRamPopulate()
|
|
and ReplayRamDiscard()
|
|
|
|
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: [113/115] 8ad320473d66f2956d701a4625f815d2fcd8ae4b (bonzini/rhel-qemu-kvm)
|
|
|
|
Update ReplayRamDiscard() function to return the result and unify the
|
|
ReplayRamPopulate() and ReplayRamDiscard() to ReplayRamDiscardState() at
|
|
the same time due to their identical definitions. This unification
|
|
simplifies related structures, such as VirtIOMEMReplayData, which makes
|
|
it cleaner.
|
|
|
|
Reviewed-by: David Hildenbrand <david@redhat.com>
|
|
Reviewed-by: Pankaj Gupta <pankaj.gupta@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-4-chenyi.qiang@intel.com
|
|
Signed-off-by: Peter Xu <peterx@redhat.com>
|
|
(cherry picked from commit 2205b8466733f8c6e3306c964f31c5a7cac69dfa)
|
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
---
|
|
hw/virtio/virtio-mem.c | 21 ++++++------
|
|
include/exec/memory.h | 74 ++++++++++++++++++++++++++++++++----------
|
|
migration/ram.c | 5 +--
|
|
system/memory.c | 12 +++----
|
|
4 files changed, 76 insertions(+), 36 deletions(-)
|
|
|
|
diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
|
|
index 6284539243..32af43852a 100644
|
|
--- a/hw/virtio/virtio-mem.c
|
|
+++ b/hw/virtio/virtio-mem.c
|
|
@@ -1736,7 +1736,7 @@ static bool virtio_mem_rdm_is_populated(const RamDiscardManager *rdm,
|
|
}
|
|
|
|
struct VirtIOMEMReplayData {
|
|
- void *fn;
|
|
+ ReplayRamDiscardState fn;
|
|
void *opaque;
|
|
};
|
|
|
|
@@ -1744,12 +1744,12 @@ static int virtio_mem_rdm_replay_populated_cb(MemoryRegionSection *s, void *arg)
|
|
{
|
|
struct VirtIOMEMReplayData *data = arg;
|
|
|
|
- return ((ReplayRamPopulate)data->fn)(s, data->opaque);
|
|
+ return data->fn(s, data->opaque);
|
|
}
|
|
|
|
static int virtio_mem_rdm_replay_populated(const RamDiscardManager *rdm,
|
|
MemoryRegionSection *s,
|
|
- ReplayRamPopulate replay_fn,
|
|
+ ReplayRamDiscardState replay_fn,
|
|
void *opaque)
|
|
{
|
|
const VirtIOMEM *vmem = VIRTIO_MEM(rdm);
|
|
@@ -1768,14 +1768,13 @@ static int virtio_mem_rdm_replay_discarded_cb(MemoryRegionSection *s,
|
|
{
|
|
struct VirtIOMEMReplayData *data = arg;
|
|
|
|
- ((ReplayRamDiscard)data->fn)(s, data->opaque);
|
|
- return 0;
|
|
+ return data->fn(s, data->opaque);
|
|
}
|
|
|
|
-static void virtio_mem_rdm_replay_discarded(const RamDiscardManager *rdm,
|
|
- MemoryRegionSection *s,
|
|
- ReplayRamDiscard replay_fn,
|
|
- void *opaque)
|
|
+static int virtio_mem_rdm_replay_discarded(const RamDiscardManager *rdm,
|
|
+ MemoryRegionSection *s,
|
|
+ ReplayRamDiscardState replay_fn,
|
|
+ void *opaque)
|
|
{
|
|
const VirtIOMEM *vmem = VIRTIO_MEM(rdm);
|
|
struct VirtIOMEMReplayData data = {
|
|
@@ -1784,8 +1783,8 @@ static void virtio_mem_rdm_replay_discarded(const RamDiscardManager *rdm,
|
|
};
|
|
|
|
g_assert(s->mr == &vmem->memdev->mr);
|
|
- virtio_mem_for_each_unplugged_section(vmem, s, &data,
|
|
- virtio_mem_rdm_replay_discarded_cb);
|
|
+ return virtio_mem_for_each_unplugged_section(vmem, s, &data,
|
|
+ virtio_mem_rdm_replay_discarded_cb);
|
|
}
|
|
|
|
static void virtio_mem_rdm_register_listener(RamDiscardManager *rdm,
|
|
diff --git a/include/exec/memory.h b/include/exec/memory.h
|
|
index 7cfbe203f4..563353eab6 100644
|
|
--- a/include/exec/memory.h
|
|
+++ b/include/exec/memory.h
|
|
@@ -566,8 +566,20 @@ static inline void ram_discard_listener_init(RamDiscardListener *rdl,
|
|
rdl->double_discard_supported = double_discard_supported;
|
|
}
|
|
|
|
-typedef int (*ReplayRamPopulate)(MemoryRegionSection *section, void *opaque);
|
|
-typedef void (*ReplayRamDiscard)(MemoryRegionSection *section, void *opaque);
|
|
+/**
|
|
+ * typedef ReplayRamDiscardState:
|
|
+ *
|
|
+ * The callback handler for #RamDiscardManagerClass.replay_populated/
|
|
+ * #RamDiscardManagerClass.replay_discarded to invoke on populated/discarded
|
|
+ * parts.
|
|
+ *
|
|
+ * @section: the #MemoryRegionSection of populated/discarded part
|
|
+ * @opaque: pointer to forward to the callback
|
|
+ *
|
|
+ * Returns 0 on success, or a negative error if failed.
|
|
+ */
|
|
+typedef int (*ReplayRamDiscardState)(MemoryRegionSection *section,
|
|
+ void *opaque);
|
|
|
|
/*
|
|
* RamDiscardManagerClass:
|
|
@@ -641,36 +653,38 @@ struct RamDiscardManagerClass {
|
|
/**
|
|
* @replay_populated:
|
|
*
|
|
- * Call the #ReplayRamPopulate callback for all populated parts within the
|
|
- * #MemoryRegionSection via the #RamDiscardManager.
|
|
+ * Call the #ReplayRamDiscardState callback for all populated parts within
|
|
+ * the #MemoryRegionSection via the #RamDiscardManager.
|
|
*
|
|
* In case any call fails, no further calls are made.
|
|
*
|
|
* @rdm: the #RamDiscardManager
|
|
* @section: the #MemoryRegionSection
|
|
- * @replay_fn: the #ReplayRamPopulate callback
|
|
+ * @replay_fn: the #ReplayRamDiscardState callback
|
|
* @opaque: pointer to forward to the callback
|
|
*
|
|
* Returns 0 on success, or a negative error if any notification failed.
|
|
*/
|
|
int (*replay_populated)(const RamDiscardManager *rdm,
|
|
MemoryRegionSection *section,
|
|
- ReplayRamPopulate replay_fn, void *opaque);
|
|
+ ReplayRamDiscardState replay_fn, void *opaque);
|
|
|
|
/**
|
|
* @replay_discarded:
|
|
*
|
|
- * Call the #ReplayRamDiscard callback for all discarded parts within the
|
|
- * #MemoryRegionSection via the #RamDiscardManager.
|
|
+ * Call the #ReplayRamDiscardState callback for all discarded parts within
|
|
+ * the #MemoryRegionSection via the #RamDiscardManager.
|
|
*
|
|
* @rdm: the #RamDiscardManager
|
|
* @section: the #MemoryRegionSection
|
|
- * @replay_fn: the #ReplayRamDiscard callback
|
|
+ * @replay_fn: the #ReplayRamDiscardState callback
|
|
* @opaque: pointer to forward to the callback
|
|
+ *
|
|
+ * Returns 0 on success, or a negative error if any notification failed.
|
|
*/
|
|
- void (*replay_discarded)(const RamDiscardManager *rdm,
|
|
- MemoryRegionSection *section,
|
|
- ReplayRamDiscard replay_fn, void *opaque);
|
|
+ int (*replay_discarded)(const RamDiscardManager *rdm,
|
|
+ MemoryRegionSection *section,
|
|
+ ReplayRamDiscardState replay_fn, void *opaque);
|
|
|
|
/**
|
|
* @register_listener:
|
|
@@ -711,15 +725,41 @@ uint64_t ram_discard_manager_get_min_granularity(const RamDiscardManager *rdm,
|
|
bool ram_discard_manager_is_populated(const RamDiscardManager *rdm,
|
|
const MemoryRegionSection *section);
|
|
|
|
+/**
|
|
+ * ram_discard_manager_replay_populated:
|
|
+ *
|
|
+ * A wrapper to call the #RamDiscardManagerClass.replay_populated callback
|
|
+ * of the #RamDiscardManager.
|
|
+ *
|
|
+ * @rdm: the #RamDiscardManager
|
|
+ * @section: the #MemoryRegionSection
|
|
+ * @replay_fn: the #ReplayRamDiscardState callback
|
|
+ * @opaque: pointer to forward to the callback
|
|
+ *
|
|
+ * Returns 0 on success, or a negative error if any notification failed.
|
|
+ */
|
|
int ram_discard_manager_replay_populated(const RamDiscardManager *rdm,
|
|
MemoryRegionSection *section,
|
|
- ReplayRamPopulate replay_fn,
|
|
+ ReplayRamDiscardState replay_fn,
|
|
void *opaque);
|
|
|
|
-void ram_discard_manager_replay_discarded(const RamDiscardManager *rdm,
|
|
- MemoryRegionSection *section,
|
|
- ReplayRamDiscard replay_fn,
|
|
- void *opaque);
|
|
+/**
|
|
+ * ram_discard_manager_replay_discarded:
|
|
+ *
|
|
+ * A wrapper to call the #RamDiscardManagerClass.replay_discarded callback
|
|
+ * of the #RamDiscardManager.
|
|
+ *
|
|
+ * @rdm: the #RamDiscardManager
|
|
+ * @section: the #MemoryRegionSection
|
|
+ * @replay_fn: the #ReplayRamDiscardState callback
|
|
+ * @opaque: pointer to forward to the callback
|
|
+ *
|
|
+ * Returns 0 on success, or a negative error if any notification failed.
|
|
+ */
|
|
+int ram_discard_manager_replay_discarded(const RamDiscardManager *rdm,
|
|
+ MemoryRegionSection *section,
|
|
+ ReplayRamDiscardState replay_fn,
|
|
+ void *opaque);
|
|
|
|
void ram_discard_manager_register_listener(RamDiscardManager *rdm,
|
|
RamDiscardListener *rdl,
|
|
diff --git a/migration/ram.c b/migration/ram.c
|
|
index 0803f85b8a..aaeea04546 100644
|
|
--- a/migration/ram.c
|
|
+++ b/migration/ram.c
|
|
@@ -874,8 +874,8 @@ static inline bool migration_bitmap_clear_dirty(RAMState *rs,
|
|
return ret;
|
|
}
|
|
|
|
-static void dirty_bitmap_clear_section(MemoryRegionSection *section,
|
|
- void *opaque)
|
|
+static int dirty_bitmap_clear_section(MemoryRegionSection *section,
|
|
+ void *opaque)
|
|
{
|
|
const hwaddr offset = section->offset_within_region;
|
|
const hwaddr size = int128_get64(section->size);
|
|
@@ -894,6 +894,7 @@ static void dirty_bitmap_clear_section(MemoryRegionSection *section,
|
|
}
|
|
*cleared_bits += bitmap_count_one_with_offset(rb->bmap, start, npages);
|
|
bitmap_clear(rb->bmap, start, npages);
|
|
+ return 0;
|
|
}
|
|
|
|
/*
|
|
diff --git a/system/memory.c b/system/memory.c
|
|
index 35011f731e..8c36ab17b6 100644
|
|
--- a/system/memory.c
|
|
+++ b/system/memory.c
|
|
@@ -2115,7 +2115,7 @@ bool ram_discard_manager_is_populated(const RamDiscardManager *rdm,
|
|
|
|
int ram_discard_manager_replay_populated(const RamDiscardManager *rdm,
|
|
MemoryRegionSection *section,
|
|
- ReplayRamPopulate replay_fn,
|
|
+ ReplayRamDiscardState replay_fn,
|
|
void *opaque)
|
|
{
|
|
RamDiscardManagerClass *rdmc = RAM_DISCARD_MANAGER_GET_CLASS(rdm);
|
|
@@ -2124,15 +2124,15 @@ int ram_discard_manager_replay_populated(const RamDiscardManager *rdm,
|
|
return rdmc->replay_populated(rdm, section, replay_fn, opaque);
|
|
}
|
|
|
|
-void ram_discard_manager_replay_discarded(const RamDiscardManager *rdm,
|
|
- MemoryRegionSection *section,
|
|
- ReplayRamDiscard replay_fn,
|
|
- void *opaque)
|
|
+int ram_discard_manager_replay_discarded(const RamDiscardManager *rdm,
|
|
+ MemoryRegionSection *section,
|
|
+ ReplayRamDiscardState replay_fn,
|
|
+ void *opaque)
|
|
{
|
|
RamDiscardManagerClass *rdmc = RAM_DISCARD_MANAGER_GET_CLASS(rdm);
|
|
|
|
g_assert(rdmc->replay_discarded);
|
|
- rdmc->replay_discarded(rdm, section, replay_fn, opaque);
|
|
+ return rdmc->replay_discarded(rdm, section, replay_fn, opaque);
|
|
}
|
|
|
|
void ram_discard_manager_register_listener(RamDiscardManager *rdm,
|
|
--
|
|
2.50.1
|
|
|