Commit 612263cf authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

memory: avoid unnecessary object_ref/unref



For the common case of DMA into non-hotplugged RAM, it is unnecessary
but expensive to do object_ref/unref.  Add back an owner field to
MemoryRegion, so that these memory regions can skip the reference
counting.

Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent a676854f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -172,6 +172,7 @@ struct MemoryRegion {
    bool global_locking;
    uint8_t dirty_log_mask;
    ram_addr_t ram_addr;
    Object *owner;
    const MemoryRegionIOMMUOps *iommu_ops;

    const MemoryRegionOps *ops;
+12 −16
Original line number Diff line number Diff line
@@ -905,20 +905,22 @@ void memory_region_init(MemoryRegion *mr,
                        const char *name,
                        uint64_t size)
{
    if (!owner) {
        owner = container_get(qdev_get_machine(), "/unattached");
    }

    object_initialize(mr, sizeof(*mr), TYPE_MEMORY_REGION);
    mr->size = int128_make64(size);
    if (size == UINT64_MAX) {
        mr->size = int128_2_64();
    }
    mr->name = g_strdup(name);
    mr->owner = owner;

    if (name) {
        char *escaped_name = memory_region_escape_name(name);
        char *name_array = g_strdup_printf("%s[*]", escaped_name);

        if (!owner) {
            owner = container_get(qdev_get_machine(), "/unattached");
        }

        object_property_add_child(owner, name_array, OBJECT(mr), &error_abort);
        object_unref(OBJECT(mr));
        g_free(name_array);
@@ -1369,24 +1371,18 @@ void memory_region_ref(MemoryRegion *mr)
     * The memory region is a child of its owner.  As long as the
     * owner doesn't call unparent itself on the memory region,
     * ref-ing the owner will also keep the memory region alive.
     * Memory regions without an owner are supposed to never go away,
     * but we still ref/unref them for debugging purposes.
     * Memory regions without an owner are supposed to never go away;
     * we do not ref/unref them because it slows down DMA sensibly.
     */
    Object *obj = OBJECT(mr);
    if (obj && obj->parent) {
        object_ref(obj->parent);
    } else {
        object_ref(obj);
    if (mr && mr->owner) {
        object_ref(mr->owner);
    }
}

void memory_region_unref(MemoryRegion *mr)
{
    Object *obj = OBJECT(mr);
    if (obj && obj->parent) {
        object_unref(obj->parent);
    } else {
        object_unref(obj);
    if (mr && mr->owner) {
        object_unref(mr->owner);
    }
}