Re: [PATCH v5 01/12] system/memory: split RamDiscardManager into source and manager
Philippe Mathieu-Daudé <[email protected]> Thu, 18 Jun 2026 22:51:34 +0200
| Newsgroups | org.nongnu.qemu-rust,org.kernel.vger.kvm,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
On 4/6/26 15:43, Marc-André Lureau wrote:
> Refactor the RamDiscardManager interface into two distinct components:
> - RamDiscardSource: An interface that state providers (virtio-mem,
> RamBlockAttributes) implement to provide discard state information
> (granularity, populated/discarded ranges, replay callbacks).
> - RamDiscardManager: A concrete QOM object that wraps a source, owns
> the listener list, and handles listener registration/unregistration
> and notifications.
>
> This separation moves the listener management logic from individual
> source implementations into the central RamDiscardManager, reducing
> code duplication between virtio-mem and RamBlockAttributes.
>
> The change prepares for future work where a RamDiscardManager could
> aggregate multiple sources.
>
> Note, the original virtio-mem code had conditions before discard:
> if (vmem->size) {
> rdl->notify_discard(rdl, rdl->section);
> }
> however, the new code calls discard unconditionally. This is considered
> safe, since the populate/discard of sections are already asymmetrical
> (unplug & unregister all listener section unconditionally).
>
> Reviewed-by: Peter Xu <[email protected]>
> Acked-by: David Hildenbrand <[email protected]>
> Signed-off-by: Marc-André Lureau <[email protected]>
> ---
> include/hw/virtio/virtio-mem.h | 3 -
> include/system/memory.h | 197 +++++++++++++++++++++----------------
> include/system/ramblock.h | 2 -
> hw/virtio/virtio-mem.c | 163 ++++++------------------------
> system/memory.c | 218 ++++++++++++++++++++++++++++++++++++-----
> system/ram-block-attributes.c | 171 ++++++++++----------------------
> 6 files changed, 385 insertions(+), 369 deletions(-)
> +int ram_discard_manager_notify_populate(RamDiscardManager *rdm,
> + uint64_t offset, uint64_t size)
> +{
> + RamDiscardListener *rdl, *rdl2;
> + int ret = 0;
> +
> + QLIST_FOREACH(rdl, &rdm->rdl_list, next) {
> + MemoryRegionSection tmp = *rdl->section;
> +
> + if (!memory_region_section_intersect_range(&tmp, offset, size)) {
> + continue;
> + }
> + ret = rdl->notify_populate(rdl, &tmp);
> + if (ret) {
> + break;
> + }
> + }
> +
> + if (ret) {
(Pre-existing, reduce scope?)
RamDiscardListener *rdl2;
> + /* Notify all already-notified listeners about discard. */
> + QLIST_FOREACH(rdl2, &rdm->rdl_list, next) {
> + MemoryRegionSection tmp = *rdl2->section;
> +
> + if (rdl2 == rdl) {
> + break;
> + }
> + if (!memory_region_section_intersect_range(&tmp, offset, size)) {
> + continue;
> + }
> + rdl2->notify_discard(rdl2, &tmp);
> + }
> + }
> + return ret;
> +}
> void ram_discard_manager_register_listener(RamDiscardManager *rdm,
> RamDiscardListener *rdl,
> MemoryRegionSection *section)
> {
> - RamDiscardManagerClass *rdmc = RAM_DISCARD_MANAGER_GET_CLASS(rdm);
> + int ret;
> +
> + g_assert(section->mr == rdm->mr);
> +
> + rdl->section = memory_region_section_new_copy(section);
> + QLIST_INSERT_HEAD(&rdm->rdl_list, rdl, next);
>
> - g_assert(rdmc->register_listener);
> - rdmc->register_listener(rdm, rdl, section);
> + ret = ram_discard_source_replay_populated(rdm->rds, rdl->section,
> + rdm_populate_cb, rdl);
> + if (ret) {
> + error_report("%s: Replaying populated ranges failed: %s", __func__,
> + strerror(-ret));
Pre-existing, should ram_discard_manager_register_listener propagate
Error*? For example the current caller provides an errp
(vfio_ram_discard_register_listener). Can be improved on top of course.
Reviewed-by: Philippe Mathieu-Daudé <[email protected]>
> + }
> }