[PATCH 00/16] memory: Stop piggybacking on memory region owners

Akihiko Odaki posted 16 patches 3 weeks, 6 days ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20250901-mr-v1-0-dd7cb6b1480b@rsg.ci.i.u-tokyo.ac.jp
Maintainers: Richard Henderson <richard.henderson@linaro.org>, Helge Deller <deller@gmx.de>, "Marc-André Lureau" <marcandre.lureau@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>, "Michael S. Tsirkin" <mst@redhat.com>, "Daniel P. Berrangé" <berrange@redhat.com>, Eduardo Habkost <eduardo@habkost.net>, Gerd Hoffmann <kraxel@redhat.com>, John Snow <jsnow@redhat.com>, Keith Busch <kbusch@kernel.org>, Klaus Jensen <its@irrelevant.dk>, Jesper Devantier <foss@defmacro.it>, Marcel Apfelbaum <marcel.apfelbaum@gmail.com>, Nicholas Piggin <npiggin@gmail.com>, Harsh Prateek Bora <harshpb@linux.ibm.com>, John Levon <john.levon@nutanix.com>, Thanos Makatos <thanos.makatos@nutanix.com>, "Cédric Le Goater" <clg@redhat.com>, Alex Williamson <alex.williamson@redhat.com>, Peter Xu <peterx@redhat.com>, David Hildenbrand <david@redhat.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>
MAINTAINERS                |  1 +
docs/devel/memory.rst      | 45 +++++++++++++++++-----------------------
include/hw/qdev-core.h     |  2 ++
include/system/memory.h    | 51 +++++++++++++++++++++++-----------------------
hw/char/diva-gsp.c         |  1 -
hw/char/serial-pci-multi.c |  1 -
hw/core/qdev.c             | 29 ++++++++++++++++++++++++++
hw/display/vga-pci.c       |  8 --------
hw/ide/cmd646.c            | 12 -----------
hw/ide/piix.c              | 13 ------------
hw/ide/via.c               | 12 -----------
hw/nvme/ctrl.c             |  2 --
hw/pci/pci.c               | 20 ------------------
hw/ppc/spapr_pci.c         | 22 --------------------
hw/usb/hcd-ehci.c          |  4 ----
hw/usb/hcd-xhci.c          | 10 ---------
hw/vfio-user/pci.c         |  6 ------
hw/vfio/pci.c              |  4 ----
stubs/memory.c             |  9 ++++++++
system/memory.c            | 11 +++-------
stubs/meson.build          |  1 +
21 files changed, 89 insertions(+), 175 deletions(-)
[PATCH 00/16] memory: Stop piggybacking on memory region owners
Posted by Akihiko Odaki 3 weeks, 6 days ago
Supersedes: https://lore.kernel.org/qemu-devel/20250828-san-v9-0-c0dff4b8a487@rsg.ci.i.u-tokyo.ac.jp/
("[PATCH v9 0/2] Fix check-qtest-ppc64 sanitizer errors")

MemoryRegions used to "piggyback" on their owners instead of using their
reference counters due to the circular dependencies between them, which
caused memory leak.

I tried to fix it with "[PATCH v9 0/2] Fix check-qtest-ppc64 sanitizer
errors" but it resulted in a lengthy discussion; ultimately it is
attributed to the fact that "piggybacking" is hard to understand and
forces us design trade-offs. It was also insufficient because it only
deals with the container-subregion pattern and did not deal with DMA.

With this series, I remove the "piggyback" hack altogather.
The key insight here is that the owners explicitly call
memory_region_del_subregion() to stop accepting new accesses to
its MemoryRegions when they are no longer needed. I code the fact by 
calling object_unparent() along with it.

While I could write a function like memory_region_unparent() and replace
such memory_region_del_subregion() calls, I used a few other insights to
simplify the code:
- Deletable MemoryRegions are of hotpluggable devices.
- Devices do no longer accept new accesses after unrealization.

So I made the common qdev code call memory_region_del_subregion() and
object_unparent(). In the end, this series makes the code simpler and
semantically robust, and kills the entire class of memory leak.

Patch [1, 2] removes object_unparent() calls in instance_finalize(),
which are incorrect.

Patch 3 makes the qdev code automatically call
memory_region_del_subregion().

Patch [4, 15] removes memory_region_del_subregion() calls that are
obviously no longer needed, demonstrating the benefit of automatic
automatic subregion deletion.

Patch 16 adds the object_unparent() call and stop piggybacking.

Signed-off-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
---
Akihiko Odaki (16):
      docs/devel: Do not unparent in instance_finalize
      vfio/pci: Do not unparent in instance_finalize
      qdev: Automatically delete memory subregions
      hw/char/diva-gsp: Do not delete the subregion
      hw/char/serial-pci-multi: Do not delete the subregion
      secondary-vga: Do not delete the subregions
      cmd646: Do not delete the subregions
      hw/ide/piix: Do not delete the subregions
      hw/ide/via: Do not delete the subregions
      hw/nvme: Do not delete the subregion
      pci: Do not delete the subregions
      hw/ppc/spapr_pci: Do not delete the subregions
      hw/usb/hcd-ehci: Do not delete the subregions
      hw/usb/hcd-xhci: Do not delete the subregions
      vfio-user: Do not delete the subregion
      memory: Stop piggybacking on memory region owners

 MAINTAINERS                |  1 +
 docs/devel/memory.rst      | 45 +++++++++++++++++-----------------------
 include/hw/qdev-core.h     |  2 ++
 include/system/memory.h    | 51 +++++++++++++++++++++++-----------------------
 hw/char/diva-gsp.c         |  1 -
 hw/char/serial-pci-multi.c |  1 -
 hw/core/qdev.c             | 29 ++++++++++++++++++++++++++
 hw/display/vga-pci.c       |  8 --------
 hw/ide/cmd646.c            | 12 -----------
 hw/ide/piix.c              | 13 ------------
 hw/ide/via.c               | 12 -----------
 hw/nvme/ctrl.c             |  2 --
 hw/pci/pci.c               | 20 ------------------
 hw/ppc/spapr_pci.c         | 22 --------------------
 hw/usb/hcd-ehci.c          |  4 ----
 hw/usb/hcd-xhci.c          | 10 ---------
 hw/vfio-user/pci.c         |  6 ------
 hw/vfio/pci.c              |  4 ----
 stubs/memory.c             |  9 ++++++++
 system/memory.c            | 11 +++-------
 stubs/meson.build          |  1 +
 21 files changed, 89 insertions(+), 175 deletions(-)
---
base-commit: e101d33792530093fa0b0a6e5f43e4d8cfe4581e
change-id: 20250831-mr-d0dc495bad11

Best regards,
-- 
Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Re: [PATCH 00/16] memory: Stop piggybacking on memory region owners
Posted by Peter Maydell 3 weeks, 6 days ago
On Mon, 1 Sept 2025 at 07:11, Akihiko Odaki
<odaki@rsg.ci.i.u-tokyo.ac.jp> wrote:
>
> Supersedes: https://lore.kernel.org/qemu-devel/20250828-san-v9-0-c0dff4b8a487@rsg.ci.i.u-tokyo.ac.jp/
> ("[PATCH v9 0/2] Fix check-qtest-ppc64 sanitizer errors")
>
> MemoryRegions used to "piggyback" on their owners instead of using their
> reference counters due to the circular dependencies between them, which
> caused memory leak.
>
> I tried to fix it with "[PATCH v9 0/2] Fix check-qtest-ppc64 sanitizer
> errors" but it resulted in a lengthy discussion; ultimately it is
> attributed to the fact that "piggybacking" is hard to understand and
> forces us design trade-offs. It was also insufficient because it only
> deals with the container-subregion pattern and did not deal with DMA.

Unlike Peter Xu's proposed patch and your v9 patch you reference
above, with this series I still see leaks doing a 'make check'
on an ASAN build of the Arm targets. Here's a sample leak
detected during the device-introspect-test:

==3769612==ERROR: LeakSanitizer: detected memory leaks

Too many leaks! Only the first 5000 leaks encountered will be reported.
Direct leak of 120 byte(s) in 8 object(s) allocated from:
    #0 0x61e094196de3 in malloc
(/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/qemu-system-arm+0x21f2de3)
(BuildId: 9b33a0e2d440e084929ae6a2821eacb977772688)
    #1 0x79c9d0e06b09 in g_malloc
(/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x62b09) (BuildId:
1eb6131419edb83b2178b682829a6913cf682d75)
    #2 0x79c9d0e1c4d8 in g_strdup
(/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x784d8) (BuildId:
1eb6131419edb83b2178b682829a6913cf682d75)
    #3 0x61e0958b6749 in g_strdup_inline
/usr/include/glib-2.0/glib/gstrfuncs.h:321:10
    #4 0x61e0958b6749 in memory_region_do_init
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../system/memory.c:1224:16
    #5 0x61e0958b6551 in memory_region_init
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../system/memory.c:1250:5
    #6 0x61e0958bc097 in memory_region_init_io
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../system/memory.c:1568:5
    #7 0x61e09494b6d0 in stm32l4x5_gpio_init
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../hw/gpio/stm32l4x5_gpio.c:402:5
    #8 0x61e096a36371 in object_init_with_type
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:428:9
    #9 0x61e096a1d8db in object_initialize_with_type
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:570:5
    #10 0x61e096a1d220 in object_initialize
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:578:5
    #11 0x61e096a1dbdc in object_initialize_child_with_propsv
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:608:5
    #12 0x61e096a1dab7 in object_initialize_child_with_props
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:591:10
    #13 0x61e096a1e607 in object_initialize_child_internal
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:645:5
    #14 0x61e0962c7f9a in stm32l4x5_soc_initfn
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../hw/arm/stm32l4x5_soc.c:150:9
    #15 0x61e096a36371 in object_init_with_type
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:428:9
    #16 0x61e096a36242 in object_init_with_type
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:424:9
    #17 0x61e096a1d8db in object_initialize_with_type
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:570:5
    #18 0x61e096a1f1fd in object_new_with_type
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:774:5
    #19 0x61e096a1efc9 in object_new_with_class
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:782:12
    #20 0x61e09709cec5 in qmp_device_list_properties
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/qom-qmp-cmds.c:206:11
    #21 0x61e09594492c in qdev_device_help
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../system/qdev-monitor.c:313:17
    #22 0x61e09594ac2c in hmp_device_add
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../system/qdev-monitor.c:989:9
    #23 0x61e095b17b2d in handle_hmp_command_exec
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../monitor/hmp.c:1106:9
    #24 0x61e095b12035 in handle_hmp_command
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../monitor/hmp.c:1158:9
    #25 0x61e095b2549d in qmp_human_monitor_command
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../monitor/qmp-cmds.c:179:5
    #26 0x61e09720c44a in qmp_marshal_human_monitor_command
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/qapi/qapi-commands-misc.c:347:14
    #27 0x61e0973140f1 in do_qmp_dispatch_bh
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qapi/qmp-dispatch.c:128:5
    #28 0x61e0973f01ad in aio_bh_call
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../util/async.c:172:5
    #29 0x61e0973f0ee6 in aio_bh_poll
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../util/async.c:219:13
    #30 0x61e09735c8b8 in aio_dispatch
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../util/aio-posix.c:436:5

(there are many more after this one)

thanks
-- PMM
Re: [PATCH 00/16] memory: Stop piggybacking on memory region owners
Posted by Akihiko Odaki 3 weeks, 6 days ago
On 2025/09/01 21:35, Peter Maydell wrote:
> On Mon, 1 Sept 2025 at 07:11, Akihiko Odaki
> <odaki@rsg.ci.i.u-tokyo.ac.jp> wrote:
>>
>> Supersedes: https://lore.kernel.org/qemu-devel/20250828-san-v9-0-c0dff4b8a487@rsg.ci.i.u-tokyo.ac.jp/
>> ("[PATCH v9 0/2] Fix check-qtest-ppc64 sanitizer errors")
>>
>> MemoryRegions used to "piggyback" on their owners instead of using their
>> reference counters due to the circular dependencies between them, which
>> caused memory leak.
>>
>> I tried to fix it with "[PATCH v9 0/2] Fix check-qtest-ppc64 sanitizer
>> errors" but it resulted in a lengthy discussion; ultimately it is
>> attributed to the fact that "piggybacking" is hard to understand and
>> forces us design trade-offs. It was also insufficient because it only
>> deals with the container-subregion pattern and did not deal with DMA.
> 
> Unlike Peter Xu's proposed patch and your v9 patch you reference
> above, with this series I still see leaks doing a 'make check'
> on an ASAN build of the Arm targets. Here's a sample leak
> detected during the device-introspect-test:
> 
> ==3769612==ERROR: LeakSanitizer: detected memory leaks
> 
> Too many leaks! Only the first 5000 leaks encountered will be reported.
> Direct leak of 120 byte(s) in 8 object(s) allocated from:
>      #0 0x61e094196de3 in malloc
> (/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/qemu-system-arm+0x21f2de3)
> (BuildId: 9b33a0e2d440e084929ae6a2821eacb977772688)
>      #1 0x79c9d0e06b09 in g_malloc
> (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x62b09) (BuildId:
> 1eb6131419edb83b2178b682829a6913cf682d75)
>      #2 0x79c9d0e1c4d8 in g_strdup
> (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x784d8) (BuildId:
> 1eb6131419edb83b2178b682829a6913cf682d75)
>      #3 0x61e0958b6749 in g_strdup_inline
> /usr/include/glib-2.0/glib/gstrfuncs.h:321:10
>      #4 0x61e0958b6749 in memory_region_do_init
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../system/memory.c:1224:16
>      #5 0x61e0958b6551 in memory_region_init
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../system/memory.c:1250:5
>      #6 0x61e0958bc097 in memory_region_init_io
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../system/memory.c:1568:5
>      #7 0x61e09494b6d0 in stm32l4x5_gpio_init
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../hw/gpio/stm32l4x5_gpio.c:402:5
>      #8 0x61e096a36371 in object_init_with_type
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:428:9
>      #9 0x61e096a1d8db in object_initialize_with_type
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:570:5
>      #10 0x61e096a1d220 in object_initialize
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:578:5
>      #11 0x61e096a1dbdc in object_initialize_child_with_propsv
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:608:5
>      #12 0x61e096a1dab7 in object_initialize_child_with_props
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:591:10
>      #13 0x61e096a1e607 in object_initialize_child_internal
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:645:5
>      #14 0x61e0962c7f9a in stm32l4x5_soc_initfn
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../hw/arm/stm32l4x5_soc.c:150:9
>      #15 0x61e096a36371 in object_init_with_type
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:428:9
>      #16 0x61e096a36242 in object_init_with_type
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:424:9
>      #17 0x61e096a1d8db in object_initialize_with_type
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:570:5
>      #18 0x61e096a1f1fd in object_new_with_type
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:774:5
>      #19 0x61e096a1efc9 in object_new_with_class
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:782:12
>      #20 0x61e09709cec5 in qmp_device_list_properties
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/qom-qmp-cmds.c:206:11
>      #21 0x61e09594492c in qdev_device_help
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../system/qdev-monitor.c:313:17
>      #22 0x61e09594ac2c in hmp_device_add
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../system/qdev-monitor.c:989:9
>      #23 0x61e095b17b2d in handle_hmp_command_exec
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../monitor/hmp.c:1106:9
>      #24 0x61e095b12035 in handle_hmp_command
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../monitor/hmp.c:1158:9
>      #25 0x61e095b2549d in qmp_human_monitor_command
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../monitor/qmp-cmds.c:179:5
>      #26 0x61e09720c44a in qmp_marshal_human_monitor_command
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/qapi/qapi-commands-misc.c:347:14
>      #27 0x61e0973140f1 in do_qmp_dispatch_bh
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qapi/qmp-dispatch.c:128:5
>      #28 0x61e0973f01ad in aio_bh_call
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../util/async.c:172:5
>      #29 0x61e0973f0ee6 in aio_bh_poll
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../util/async.c:219:13
>      #30 0x61e09735c8b8 in aio_dispatch
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../util/aio-posix.c:436:5
> 
> (there are many more after this one)

This approach is clearly not working. The problem here is that there are 
devices that never get realized (so never get unrealized either).

I'm thinking of a solution that fixes all possible circular references 
originated from owners without breaking anything else, but I don't have 
one for now.

Regards,
Akihiko Odaki
Re: [PATCH 00/16] memory: Stop piggybacking on memory region owners
Posted by Peter Maydell 3 weeks, 6 days ago
On Mon, 1 Sept 2025 at 14:28, Akihiko Odaki
<odaki@rsg.ci.i.u-tokyo.ac.jp> wrote:
> This approach is clearly not working. The problem here is that there are
> devices that never get realized (so never get unrealized either).

Yes, the "instance_init -> instance_finalize" lifecycle path
is valid: it gets used when we want to introspect a device
(e.g. find out what properties it has). device-introspect-test
does this for every device compiled into QEMU.

The instance_init -> realize -> unrealize -> instance_finalize path
on the other hand only really needs to work for pluggable devices,
because only those will get unrealized. So we have a lot of
devices where if we ever exercised this path we'd find we had
memory leaks or other bugs. (Many devices for SoC objects and
devices only used in SoC objects don't implement unrealize at all.)

> I'm thinking of a solution that fixes all possible circular references
> originated from owners without breaking anything else, but I don't have
> one for now.

I think overall I like Peter Xu's patch, with the underlying
model being "MemoryRegions are not reference counted objects
that should be considered to have a separate existence from
the device that backs them; unless they're the 'lives forever,
no owner' kind then what you want is to hold a reference to
the owning device".

-- PMM
Re: [PATCH 00/16] memory: Stop piggybacking on memory region owners
Posted by Peter Maydell 3 weeks, 6 days ago
On Mon, 1 Sept 2025 at 13:35, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> On Mon, 1 Sept 2025 at 07:11, Akihiko Odaki
> <odaki@rsg.ci.i.u-tokyo.ac.jp> wrote:
> >
> > Supersedes: https://lore.kernel.org/qemu-devel/20250828-san-v9-0-c0dff4b8a487@rsg.ci.i.u-tokyo.ac.jp/
> > ("[PATCH v9 0/2] Fix check-qtest-ppc64 sanitizer errors")
> >
> > MemoryRegions used to "piggyback" on their owners instead of using their
> > reference counters due to the circular dependencies between them, which
> > caused memory leak.
> >
> > I tried to fix it with "[PATCH v9 0/2] Fix check-qtest-ppc64 sanitizer
> > errors" but it resulted in a lengthy discussion; ultimately it is
> > attributed to the fact that "piggybacking" is hard to understand and
> > forces us design trade-offs. It was also insufficient because it only
> > deals with the container-subregion pattern and did not deal with DMA.
>
> Unlike Peter Xu's proposed patch and your v9 patch you reference
> above, with this series I still see leaks doing a 'make check'
> on an ASAN build of the Arm targets. Here's a sample leak
> detected during the device-introspect-test:

I should mention that I'm using an lsan-suppressions.txt file
with the following entries:

# This is a set of suppressions for LeakSanitizer; you can use it
# by setting
#   LSAN_OPTIONS="suppressions=/path/to/scripts/lsan-suppressions.txt"
# register_init_block API is busted
leak:register_init_block
leak:canfd_populate_regarray
# qtest-only leak, not very important
leak:qemu_irq_intercept_in
# this is maybe a leak caused by g_test_trap_subprocess():
# in the subprocess, the cleanup functions that are supposed to free
# memory don't get run for some reason.
leak:qos_traverse_graph

plus various leak fixes which I've sent out over the past week or two:

[PATCH 0/3] hw: Fix qemu_init_irq() leaks
 https://patchew.org/QEMU/20250821154053.2417090-1-peter.maydell@linaro.org/

[PATCH] hw/char/max78000_uart: Destroy FIFO on deinit
https://patchew.org/QEMU/20250821154358.2417744-1-peter.maydell@linaro.org/

[PATCH] hw/gpio/pca9554: Avoid leak in pca9554_set_pin()
https://patchew.org/QEMU/20250821154459.2417976-1-peter.maydell@linaro.org/

[PATCH 0/2] hw: fix some leaks in xlnx devices
https://patchew.org/QEMU/20250826174956.3010274-1-peter.maydell@linaro.org/

[PATCH] hw/arm/boot: Correctly free the MemoryDeviceInfoList
https://patchew.org/QEMU/20250901102214.3748011-1-peter.maydell@linaro.org/

and with those patches plus the lsan-suppressions file plus either
Peter Xu's patch or your v9 patch I get a clean 'make check' run.

thanks
-- PMM