From 077ffc3bd57e4563ef7811fa3132a2b66f66aa50 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Sat, 17 Feb 2018 20:09:58 -0500 Subject: [PATCH] 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. Backports commit 612263cf33062f7441a5d0e3b37c65991fdc3210 from qemu --- qemu/include/exec/memory.h | 1 + qemu/memory.c | 30 +++++++++++++----------------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/qemu/include/exec/memory.h b/qemu/include/exec/memory.h index 87fb74be..aaab4d7d 100644 --- a/qemu/include/exec/memory.h +++ b/qemu/include/exec/memory.h @@ -162,6 +162,7 @@ struct MemoryRegion { uint8_t dirty_log_mask; ram_addr_t ram_addr; const MemoryRegionIOMMUOps *iommu_ops; + Object *owner; const MemoryRegionOps *ops; void *opaque; diff --git a/qemu/memory.c b/qemu/memory.c index e0d63742..111919c9 100644 --- a/qemu/memory.c +++ b/qemu/memory.c @@ -861,11 +861,6 @@ void memory_region_init(struct uc_struct *uc, MemoryRegion *mr, const char *name, uint64_t size) { - if (!owner) { - owner = qdev_get_machine(uc); - uc->owner = owner; - } - object_initialize(uc, mr, sizeof(*mr), TYPE_MEMORY_REGION); mr->uc = uc; mr->size = int128_make64(size); @@ -873,10 +868,17 @@ void memory_region_init(struct uc_struct *uc, MemoryRegion *mr, 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 = qdev_get_machine(uc); + uc->owner = owner; + } + object_property_add_child(owner, name_array, OBJECT(mr), &error_abort); object_unref(uc, OBJECT(mr)); g_free(name_array); @@ -1260,24 +1262,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(mr->uc, obj->parent); - } else { - object_unref(mr->uc, obj); + if (mr && mr->owner) { + object_unref(mr->uc, mr->owner); } }