Forráskód Böngészése

memory-device: Track used region size in DeviceMemoryState

Let's avoid iterating over all devices and simply track it in the
DeviceMemoryState.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20230623124553.400585-11-david@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
David Hildenbrand 2 éve
szülő
commit
ac23dd2f29
2 módosított fájl, 5 hozzáadás és 19 törlés
  1. 3 19
      hw/mem/memory-device.c
  2. 2 0
      include/hw/boards.h

+ 3 - 19
hw/mem/memory-device.c

@@ -52,28 +52,11 @@ static int memory_device_build_list(Object *obj, void *opaque)
     return 0;
     return 0;
 }
 }
 
 
-static int memory_device_used_region_size(Object *obj, void *opaque)
-{
-    uint64_t *size = opaque;
-
-    if (object_dynamic_cast(obj, TYPE_MEMORY_DEVICE)) {
-        const DeviceState *dev = DEVICE(obj);
-        const MemoryDeviceState *md = MEMORY_DEVICE(obj);
-
-        if (dev->realized) {
-            *size += memory_device_get_region_size(md, &error_abort);
-        }
-    }
-
-    object_child_foreach(obj, memory_device_used_region_size, opaque);
-    return 0;
-}
-
 static void memory_device_check_addable(MachineState *ms, MemoryRegion *mr,
 static void memory_device_check_addable(MachineState *ms, MemoryRegion *mr,
                                         Error **errp)
                                         Error **errp)
 {
 {
+    const uint64_t used_region_size = ms->device_memory->used_region_size;
     const uint64_t size = memory_region_size(mr);
     const uint64_t size = memory_region_size(mr);
-    uint64_t used_region_size = 0;
 
 
     /* we will need a new memory slot for kvm and vhost */
     /* we will need a new memory slot for kvm and vhost */
     if (kvm_enabled() && !kvm_has_free_slot(ms)) {
     if (kvm_enabled() && !kvm_has_free_slot(ms)) {
@@ -86,7 +69,6 @@ static void memory_device_check_addable(MachineState *ms, MemoryRegion *mr,
     }
     }
 
 
     /* will we exceed the total amount of memory specified */
     /* will we exceed the total amount of memory specified */
-    memory_device_used_region_size(OBJECT(ms), &used_region_size);
     if (used_region_size + size < used_region_size ||
     if (used_region_size + size < used_region_size ||
         used_region_size + size > ms->maxram_size - ms->ram_size) {
         used_region_size + size > ms->maxram_size - ms->ram_size) {
         error_setg(errp, "not enough space, currently 0x%" PRIx64
         error_setg(errp, "not enough space, currently 0x%" PRIx64
@@ -292,6 +274,7 @@ void memory_device_plug(MemoryDeviceState *md, MachineState *ms)
     mr = mdc->get_memory_region(md, &error_abort);
     mr = mdc->get_memory_region(md, &error_abort);
     g_assert(ms->device_memory);
     g_assert(ms->device_memory);
 
 
+    ms->device_memory->used_region_size += memory_region_size(mr);
     memory_region_add_subregion(&ms->device_memory->mr,
     memory_region_add_subregion(&ms->device_memory->mr,
                                 addr - ms->device_memory->base, mr);
                                 addr - ms->device_memory->base, mr);
     trace_memory_device_plug(DEVICE(md)->id ? DEVICE(md)->id : "", addr);
     trace_memory_device_plug(DEVICE(md)->id ? DEVICE(md)->id : "", addr);
@@ -310,6 +293,7 @@ void memory_device_unplug(MemoryDeviceState *md, MachineState *ms)
     g_assert(ms->device_memory);
     g_assert(ms->device_memory);
 
 
     memory_region_del_subregion(&ms->device_memory->mr, mr);
     memory_region_del_subregion(&ms->device_memory->mr, mr);
+    ms->device_memory->used_region_size -= memory_region_size(mr);
     trace_memory_device_unplug(DEVICE(md)->id ? DEVICE(md)->id : "",
     trace_memory_device_unplug(DEVICE(md)->id ? DEVICE(md)->id : "",
                                mdc->get_addr(md));
                                mdc->get_addr(md));
 }
 }

+ 2 - 0
include/hw/boards.h

@@ -298,11 +298,13 @@ struct MachineClass {
  * address space for memory devices starts
  * address space for memory devices starts
  * @mr: address space container for memory devices
  * @mr: address space container for memory devices
  * @dimm_size: the sum of plugged DIMMs' sizes
  * @dimm_size: the sum of plugged DIMMs' sizes
+ * @used_region_size: the part of @mr already used by memory devices
  */
  */
 typedef struct DeviceMemoryState {
 typedef struct DeviceMemoryState {
     hwaddr base;
     hwaddr base;
     MemoryRegion mr;
     MemoryRegion mr;
     uint64_t dimm_size;
     uint64_t dimm_size;
+    uint64_t used_region_size;
 } DeviceMemoryState;
 } DeviceMemoryState;
 
 
 /**
 /**