mirror of https://gitee.com/openkylin/qemu.git
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:
parent
a676854f34
commit
612263cf33
|
@ -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;
|
||||
|
|
28
memory.c
28
memory.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue