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;
|
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;
|
||||||
|
|
28
memory.c
28
memory.c
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue