On Wed, 29 Oct 2025, Akihiko Odaki wrote:
On 2025/10/29 6:28, BALATON Zoltan wrote:
On Wed, 29 Oct 2025, Akihiko Odaki wrote:
On 2025/10/28 21:59, BALATON Zoltan wrote:
On Tue, 28 Oct 2025, Philippe Mathieu-Daudé wrote:
On 27/10/25 20:47, BALATON Zoltan wrote:
On Mon, 27 Oct 2025, Philippe Mathieu-Daudé wrote:
On 25/10/25 01:31, BALATON Zoltan wrote:
These memory windows are a result of the address decoding in the
Articia S north bridge so better model it there and not in board code.

Suggested-by: Philippe Mathieu-Daudé <[email protected]>
Signed-off-by: BALATON Zoltan <[email protected]>
---
  hw/pci-host/articia.c | 15 ++++++++++++++-
  hw/ppc/amigaone.c     | 28 +++++-----------------------
  hw/ppc/pegasos2.c     | 13 -------------
  3 files changed, 19 insertions(+), 37 deletions(-)


@@ -169,6 +174,7 @@ static void articia_realize(DeviceState *dev, Error **errp)
  {
      ArticiaState *s = ARTICIA(dev);
      PCIHostState *h = PCI_HOST_BRIDGE(dev);
+    MemoryRegion *mr;
      PCIDevice *pdev;
        bitbang_i2c_init(&s->smbus, i2c_init_bus(dev, "smbus"));
@@ -180,6 +186,14 @@ static void articia_realize(DeviceState *dev, Error **errp)
      memory_region_init_io(&s->reg, OBJECT(s), &articia_reg_ops, s,
                            TYPE_ARTICIA, 0x1000000);
      memory_region_add_subregion_overlap(&s->reg, 0, &s->io, 1);
+    mr = g_new(MemoryRegion, 1);

Won't Coverity or other analysis tools complain about the leak?
(this is why we usually keep a reference in the device state, here
ArticiaState). Otherwise:

According to https://www.qemu.org/docs/master/devel/ memory.html#region- lifecycle there should be no leak and keeping a reference should not be necessary as the lifetime is managed by attaching it to the owner object so no need to keep a reference when it's not needed otherwise. Not littering the state struct with unneded references makes it easier to comprehend so I'd only keep things there that are necessary.

IIUC this doc is about what happens within the allocated MemoryRegion,
regardless of where it is allocated.

That doc explicitely says:

"Destruction of a memory region happens automatically when the owner object dies. When there are multiple memory regions under the same owner object, the memory API will guarantee all memory regions will be properly detached and finalized one by one. The order in which memory regions will be finalized is not guaranteed."

Destruction in this context does not imply freeing the storage.

The documentation describes destruction in QOM. QOM performs the following steps during destruction:
1. Delete properties
2. Call finalization callbacks
3. Free the storage

However, 3 will not happen in this case since you allocate the storage by yourself and it is not managed by QOM.

Please also note that the documentation also says:
If however the memory region is part of a dynamically allocated data
structure, you should free the memory region in the instance_finalize
callback.  For an example see VFIOMSIXInfo and VFIOQuirk in
hw/vfio/pci.c.

So the problem is probably using g_new() to allocate it. Maybe this should be object_new() instead? I was trying to figure out how this should work but not sure I understand everything. It looks like as long as the mr has a name, memory_region_init() will add the mr as a child property to the owner and unref it so the reference will be passed to the owner which will own this mr after that. On destructing the owner it will delete all its properties which should dereference the memory region so it would be freed then if it had a free function set but it seems allocating with g_new and init-ing the region with memory_region_init() won't set the free function. Only way to set that seems to be object_new() but that also inits the object so maybe using it would double init the mr or add an extra reference so that may also not work. The extra ref could be solved by unref'ing after memory_region_init() but double init seems to be unnecessary. Maybe we need a memory_region_new_* set of functions or simpler than that an object_alloc() that allocates the object without init it that could be used in this case when init is done by other function like memory_region_init in this case?

memory_region_new_* will work, but I don't think removing unnecessary but harmless fields from a device state structure does not sufficiently motivates adding them.

I haven't given up on this yet, that's why I alternatively proposed

object_alloc (same as object_new without object_initialize)
memory_region_init

which is just a small change but should also work without adding memory_region_new convenience functions. Then only object_alloc needs to be added.

(and these pci-host objects are created once at machine init and never die so the question seems quite theoretical). I'd like to keep object state simple and not keep around references in it that nothing uses and should be managed automatically. I'd only add fields to the state struct that other methods need.

It is indeed theoretical. That said, I prefer the memory region to be embedded into the device state struct as it will clarify that the lifetime of the memory region is bound to the device.

But that way a lot of otherwise not needed fields would make the state struct more crowded and harder to see what's actually used there. Maybe this could be remedied by grouping these at the end below a comment but if ref counting worked as the docs state it this should not be necessary.

Before my cleanup the state strcut in raven.c looked like this:

struct PRePPCIState {
     PCIHostState parent_obj;

     OrIRQState *or_irq;
     qemu_irq pci_irqs[PCI_NUM_PINS];
     PCIBus pci_bus;
     AddressSpace pci_io_as;
     MemoryRegion pci_io;
     MemoryRegion pci_io_non_contiguous;
     MemoryRegion pci_memory;
     MemoryRegion pci_intack;
     MemoryRegion bm;
     MemoryRegion bm_ram_alias;
     MemoryRegion bm_pci_memory_alias;
     AddressSpace bm_as;
     RavenPCIState pci_dev;

     int contiguous_map;
};

which would become this after this series:

struct PREPPCIState {
     PCIHostState parent_obj;

     qemu_irq irq;
     MemoryRegion pci_io;
     MemoryRegion pci_discontiguous_io;
     MemoryRegion pci_memory;
     MemoryRegion pci_intack;
     AddressSpace bm_as;
};

if we don't have to keep regions we don't use after realize so those can be managed by QOM which is much more readable and comprehensible to me.

It still requires a trade-off that obscures the duration of MemoryRegion and may confuse Coverity or other tools. I also prefer the fields present in the state as I can be immediately sure they do not leak even without checking that the device is not hotpluggable.

What I don't like is that it blows up the object state and makes it look more complex than needed. Memory regions are often created at realize then never used again. The documentation also says that these should be managed automatically and when memory_region_init'ing it adds a reference to the owner that should be enough to manage the lifetime of the mr. Also when using sysbus_init_mmio it also stores a pointer to the mr so actually no need to store those MemoryRegions in the object state for SysBusDevices. Then most simple devices could do without a subclass or only a few fields in their state that they add to their superclass but now we have these full of these memory regions unnecessarily.

I don't think it needs comments. It is a common pattern that MemoryRegions are directly referenced only at initialization and uninitialization. The presence of MemoryRegions in a device state structure only tells that they are alive as long as the device is alive, and does not imply that it is directly referenced later.

But this makes the device more difficult to comprehend. As in the raven device above we had a lot of memory regions plus an unneeded init method that we could do without to make the device simpler and easier to understand what actual functionality it adds. Having additional fields in the state struct just distracts from that.

It looks like we won't be able to come to an agreement before the freeze and I don't have time now to change this patch but don't want to miss the release with this series that finishes pegasos renaming because of this. So for this patch I'd say since this is already how it is now and it does not make it worse and this object is not user creatable anyway so cannot leak please take it as it is and we'll do a clean up later after we finish discussion.

Regards,
BALATON Zoltan

Reply via email to