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: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Paolo Bonzini 2015-12-09 11:44:25 +01:00
parent a676854f34
commit 612263cf33
2 changed files with 13 additions and 16 deletions

View File

@ -172,6 +172,7 @@ struct MemoryRegion {
bool global_locking; bool global_locking;
uint8_t dirty_log_mask; uint8_t dirty_log_mask;
ram_addr_t ram_addr; ram_addr_t ram_addr;
Object *owner;
const MemoryRegionIOMMUOps *iommu_ops; const MemoryRegionIOMMUOps *iommu_ops;
const MemoryRegionOps *ops; const MemoryRegionOps *ops;

View File

@ -905,20 +905,22 @@ void memory_region_init(MemoryRegion *mr,
const char *name, const char *name,
uint64_t size) uint64_t size)
{ {
if (!owner) {
owner = container_get(qdev_get_machine(), "/unattached");
}
object_initialize(mr, sizeof(*mr), TYPE_MEMORY_REGION); object_initialize(mr, sizeof(*mr), TYPE_MEMORY_REGION);
mr->size = int128_make64(size); mr->size = int128_make64(size);
if (size == UINT64_MAX) { if (size == UINT64_MAX) {
mr->size = int128_2_64(); mr->size = int128_2_64();
} }
mr->name = g_strdup(name); mr->name = g_strdup(name);
mr->owner = owner;
if (name) { if (name) {
char *escaped_name = memory_region_escape_name(name); char *escaped_name = memory_region_escape_name(name);
char *name_array = g_strdup_printf("%s[*]", escaped_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_property_add_child(owner, name_array, OBJECT(mr), &error_abort);
object_unref(OBJECT(mr)); object_unref(OBJECT(mr));
g_free(name_array); 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 * The memory region is a child of its owner. As long as the
* owner doesn't call unparent itself on the memory region, * owner doesn't call unparent itself on the memory region,
* ref-ing the owner will also keep the memory region alive. * ref-ing the owner will also keep the memory region alive.
* Memory regions without an owner are supposed to never go away, * Memory regions without an owner are supposed to never go away;
* but we still ref/unref them for debugging purposes. * we do not ref/unref them because it slows down DMA sensibly.
*/ */
Object *obj = OBJECT(mr); if (mr && mr->owner) {
if (obj && obj->parent) { object_ref(mr->owner);
object_ref(obj->parent);
} else {
object_ref(obj);
} }
} }
void memory_region_unref(MemoryRegion *mr) void memory_region_unref(MemoryRegion *mr)
{ {
Object *obj = OBJECT(mr); if (mr && mr->owner) {
if (obj && obj->parent) { object_unref(mr->owner);
object_unref(obj->parent);
} else {
object_unref(obj);
} }
} }