All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chenyi Qiang <chenyi.qiang@intel.com>
To: <marcandre.lureau@redhat.com>, <qemu-devel@nongnu.org>
Cc: "Ben Chaney" <bchaney@akamai.com>,
	"Michael S. Tsirkin" <mst@redhat.com>,
	"Cédric Le Goater" <clg@redhat.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Alex Williamson" <alex@shazbot.org>,
	"Fabiano Rosas" <farosas@suse.de>,
	"David Hildenbrand" <david@kernel.org>,
	"Philippe Mathieu-Daudé" <philmd@linaro.org>,
	"Peter Xu" <peterx@redhat.com>,
	kvm@vger.kernel.org, "Mark Kanda" <mark.kanda@oracle.com>
Subject: Re: [PATCH v3 06/15] system/memory: split RamDiscardManager into source and manager
Date: Wed, 4 Mar 2026 17:51:43 +0800	[thread overview]
Message-ID: <02381fd6-dd40-45e7-bd7c-f97de5618df1@intel.com> (raw)
In-Reply-To: <20260226140001.3622334-7-marcandre.lureau@redhat.com>



On 2/26/2026 9:59 PM, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
> 
> 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).
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>  include/hw/virtio/virtio-mem.h |   3 -
>  include/system/memory.h        | 197 ++++++++++++++++-------------
>  include/system/ramblock.h      |   3 +-
>  hw/virtio/virtio-mem.c         | 163 +++++-------------------
>  system/memory.c                | 218 +++++++++++++++++++++++++++++----
>  system/ram-block-attributes.c  | 171 ++++++++------------------
>  6 files changed, 386 insertions(+), 369 deletions(-)
> 

[...]

> diff --git a/system/memory.c b/system/memory.c
> index c51d0798a84..3e7fd759692 100644
> --- a/system/memory.c
> +++ b/system/memory.c
> @@ -2105,34 +2105,88 @@ RamDiscardManager *memory_region_get_ram_discard_manager(MemoryRegion *mr)
>      return mr->rdm;
>  }
>  
> -int memory_region_set_ram_discard_manager(MemoryRegion *mr,
> -                                          RamDiscardManager *rdm)
> +static RamDiscardManager *ram_discard_manager_new(MemoryRegion *mr,
> +                                                  RamDiscardSource *rds)
> +{
> +    RamDiscardManager *rdm = RAM_DISCARD_MANAGER(object_new(TYPE_RAM_DISCARD_MANAGER));
> +
> +    rdm->rds = rds;
> +    rdm->mr = mr;
> +    QLIST_INIT(&rdm->rdl_list);

Is this QLIST_INIT() redundant since it is already called in ram_discard_manager_initfn()?

> +    return rdm;
> +}
> +

[...]

> +}
> +
> +static void ram_discard_manager_initfn(Object *obj)
> +{
> +    RamDiscardManager *rdm = RAM_DISCARD_MANAGER(obj);
> +
> +    QLIST_INIT(&rdm->rdl_list);
> +}
> +
> +static void ram_discard_manager_finalize(Object *obj)
> +{
> +    RamDiscardManager *rdm = RAM_DISCARD_MANAGER(obj);
>  
> -    g_assert(rdmc->replay_discarded);
> -    return rdmc->replay_discarded(rdm, section, replay_fn, opaque);
> +    g_assert(QLIST_EMPTY(&rdm->rdl_list));
> +}
> +
> +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) {
> +        /* 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;
> +}
> +

[...]

>  
>  static int
>  ram_block_attributes_notify_populate(RamBlockAttributes *attr,
>                                       uint64_t offset, uint64_t size)
>  {
> -    RamDiscardListener *rdl;
> -    int ret = 0;
> -
> -    QLIST_FOREACH(rdl, &attr->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;
> -        }
> -    }
> +    RamDiscardManager *rdm = memory_region_get_ram_discard_manager(attr->ram_block->mr);
>  
> -    return ret;
> +    return ram_discard_manager_notify_populate(rdm, offset, size);
>  }

This change introduces a slight difference, as it will perform a rollback if ->notify_populate() fails.
I believe this is acceptable since, currently, memory conversion failures result in QEMU terminating
rather than resuming the guest or retrying the operation. And this rollback is necessary if we plan to support
retry operations in the future. Therefore, we can retain this modification.


  parent reply	other threads:[~2026-03-04  9:51 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-26 13:59 [PATCH v3 00/15] Make RamDiscardManager work with multiple sources marcandre.lureau
2026-02-26 13:59 ` [PATCH v3 01/15] system/rba: use DIV_ROUND_UP marcandre.lureau
2026-03-03 18:57   ` Peter Xu
2026-02-26 13:59 ` [PATCH v3 02/15] memory: drop RamDiscardListener::double_discard_supported marcandre.lureau
2026-02-26 15:58   ` David Hildenbrand
2026-03-03 18:57   ` Peter Xu
2026-02-26 13:59 ` [PATCH v3 03/15] virtio-mem: use warn_report_err_once() marcandre.lureau
2026-02-26 15:57   ` David Hildenbrand
2026-03-03 18:58   ` Peter Xu
2026-02-26 13:59 ` [PATCH v3 04/15] system/memory: minor doc fix marcandre.lureau
2026-02-26 15:58   ` David Hildenbrand
2026-03-03 18:59   ` Peter Xu
2026-02-26 13:59 ` [PATCH v3 05/15] kvm: replace RamDicardManager by the RamBlockAttribute marcandre.lureau
2026-03-03 18:59   ` Peter Xu
2026-03-04  9:09   ` Chenyi Qiang
2026-02-26 13:59 ` [PATCH v3 06/15] system/memory: split RamDiscardManager into source and manager marcandre.lureau
2026-03-03 19:45   ` Peter Xu
2026-03-04  9:51   ` Chenyi Qiang [this message]
2026-02-26 13:59 ` [PATCH v3 07/15] system/memory: move RamDiscardManager to separate compilation unit marcandre.lureau
2026-03-03 19:47   ` Peter Xu
2026-02-26 13:59 ` [PATCH v3 08/15] system/memory: constify section arguments marcandre.lureau
2026-03-03 19:48   ` Peter Xu
2026-02-26 13:59 ` [PATCH v3 09/15] system/ram-discard-manager: implement replay via is_populated iteration marcandre.lureau
2026-02-26 16:01   ` David Hildenbrand
2026-03-03 10:47     ` Marc-André Lureau
2026-03-03 20:27       ` Peter Xu
2026-02-26 13:59 ` [PATCH v3 10/15] virtio-mem: remove replay_populated/replay_discarded implementation marcandre.lureau
2026-02-26 13:59 ` [PATCH v3 11/15] system/ram-discard-manager: drop replay from source interface marcandre.lureau
2026-02-26 13:59 ` [PATCH v3 12/15] system/memory: implement RamDiscardManager multi-source aggregation marcandre.lureau
2026-03-03 21:16   ` Peter Xu
2026-02-26 13:59 ` [PATCH v3 13/15] system/physmem: destroy ram block attributes before RCU-deferred reclaim marcandre.lureau
2026-03-03 21:31   ` Peter Xu
2026-02-26 13:59 ` [PATCH v3 14/15] system/memory: add RamDiscardManager reference counting and cleanup marcandre.lureau
2026-03-03 21:33   ` Peter Xu
2026-02-26 14:00 ` [PATCH v3 15/15] tests: add unit tests for RamDiscardManager multi-source aggregation marcandre.lureau
2026-03-03 21:28 ` [PATCH v3 00/15] Make RamDiscardManager work with multiple sources Peter Xu
2026-03-03 22:33   ` Marc-André Lureau
2026-03-09 18:25 ` Peter Xu
2026-03-10  2:35 ` Chenyi Qiang
2026-03-10 16:09   ` Marc-André Lureau
2026-03-11  7:17     ` Chenyi Qiang
2026-03-11 14:12       ` Marc-André Lureau

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=02381fd6-dd40-45e7-bd7c-f97de5618df1@intel.com \
    --to=chenyi.qiang@intel.com \
    --cc=alex@shazbot.org \
    --cc=bchaney@akamai.com \
    --cc=clg@redhat.com \
    --cc=david@kernel.org \
    --cc=farosas@suse.de \
    --cc=kvm@vger.kernel.org \
    --cc=marcandre.lureau@redhat.com \
    --cc=mark.kanda@oracle.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peterx@redhat.com \
    --cc=philmd@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /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.