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
This commit is contained in:
Paolo Bonzini 2018-02-17 20:09:58 -05:00 committed by Lioncash
parent e6b25279f8
commit 077ffc3bd5
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
2 changed files with 14 additions and 17 deletions

View file

@ -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;

View file

@ -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);
}
}