From e723b8dd49031c317ff1a6180ec72ffb8a50dffe Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Sun, 4 Mar 2018 02:02:41 -0500 Subject: [PATCH] memory: Open code FlatView rendering We are going to share FlatView's between AddressSpace's and per-AS memory listeners won't suit the purpose anymore so open code the dispatch tree rendering. Since there is a good chance that dispatch_listener was the only listener, this avoids address_space_update_topology_pass() if there is no registered listeners; this should improve starting time. This should cause no behavioural change. Backports commit 1b04a1580917d9e41fd37ca62cbff9b4bf061e96 from qemu --- qemu/exec.c | 30 +++-------------------------- qemu/include/exec/memory-internal.h | 5 +++-- qemu/include/exec/memory.h | 1 - qemu/memory.c | 18 +++++++++++++---- 4 files changed, 20 insertions(+), 34 deletions(-) diff --git a/qemu/exec.c b/qemu/exec.c index 4e0e3283..98706ecd 100644 --- a/qemu/exec.c +++ b/qemu/exec.c @@ -1080,9 +1080,8 @@ static void register_multipage(struct uc_struct *uc, phys_page_set(uc, d, start_addr >> TARGET_PAGE_BITS, num_pages, section_index); } -static void mem_add(MemoryListener *listener, MemoryRegionSection *section) +void mem_add(AddressSpace *as, MemoryRegionSection *section) { - AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener); AddressSpaceDispatch *d = as->next_dispatch; MemoryRegionSection now = *section, remain = *section; Int128 page_size = int128_make64(TARGET_PAGE_SIZE); @@ -1845,9 +1844,8 @@ void phys_mem_clean(AddressSpace *as) g_free(d->map.sections); } -static void mem_begin(MemoryListener *listener) +void mem_begin(AddressSpace *as) { - AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener); AddressSpaceDispatch *d = g_new0(AddressSpaceDispatch, 1); uint16_t n; PhysPageEntry ppe = { 1, PHYS_MAP_NODE_NIL }; @@ -1867,9 +1865,8 @@ static void mem_begin(MemoryListener *listener) as->next_dispatch = d; } -static void mem_commit(MemoryListener *listener) +void mem_commit(AddressSpace *as) { - AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener); AddressSpaceDispatch *cur = as->dispatch; AddressSpaceDispatch *next = as->next_dispatch; @@ -1903,31 +1900,10 @@ static void tcg_commit(MemoryListener *listener) tlb_flush(cpuas->cpu); } -void address_space_init_dispatch(AddressSpace *as) -{ - MemoryListener ml = { 0 }; - - ml.begin = mem_begin; - ml.commit = mem_commit; - ml.region_add = mem_add; - ml.region_nop = mem_add; - ml.priority = 0; - - as->dispatch = NULL; - as->dispatch_listener = ml; - memory_listener_register(as->uc, &as->dispatch_listener, as); -} - -void address_space_unregister(AddressSpace *as) -{ - memory_listener_unregister(as->uc, &as->dispatch_listener); -} - void address_space_destroy_dispatch(AddressSpace *as) { AddressSpaceDispatch *d = as->dispatch; - memory_listener_unregister(as->uc, &as->dispatch_listener); g_free(d->map.nodes); g_free(d); diff --git a/qemu/include/exec/memory-internal.h b/qemu/include/exec/memory-internal.h index d3546d29..9abde2f1 100644 --- a/qemu/include/exec/memory-internal.h +++ b/qemu/include/exec/memory-internal.h @@ -22,7 +22,6 @@ #ifndef CONFIG_USER_ONLY typedef struct AddressSpaceDispatch AddressSpaceDispatch; -void address_space_init_dispatch(AddressSpace *as); void address_space_destroy_dispatch(AddressSpace *as); extern const MemoryRegionOps unassigned_mem_ops; @@ -30,7 +29,9 @@ extern const MemoryRegionOps unassigned_mem_ops; bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr, unsigned size, bool is_write); -void address_space_unregister(AddressSpace *as); +void mem_add(AddressSpace *as, MemoryRegionSection *section); +void mem_begin(AddressSpace *as); +void mem_commit(AddressSpace *as); #endif #endif diff --git a/qemu/include/exec/memory.h b/qemu/include/exec/memory.h index c416fd4a..df3ee44e 100644 --- a/qemu/include/exec/memory.h +++ b/qemu/include/exec/memory.h @@ -236,7 +236,6 @@ struct AddressSpace { struct FlatView *current_map; struct AddressSpaceDispatch *dispatch; struct AddressSpaceDispatch *next_dispatch; - MemoryListener dispatch_listener; struct uc_struct* uc; QTAILQ_HEAD(memory_listeners_as, MemoryListener) listeners; diff --git a/qemu/memory.c b/qemu/memory.c index f7d13719..820638e8 100644 --- a/qemu/memory.c +++ b/qemu/memory.c @@ -757,9 +757,20 @@ static void address_space_update_topology(AddressSpace *as) { FlatView *old_view = address_space_get_flatview(as); FlatView *new_view = generate_memory_topology(as->root); + int i; - address_space_update_topology_pass(as, old_view, new_view, false); - address_space_update_topology_pass(as, old_view, new_view, true); + mem_begin(as); + for (i = 0; i < new_view->nr; i++) { + MemoryRegionSection mrs = + section_from_flat_range(&new_view->ranges[i], as); + mem_add(as, &mrs); + } + mem_commit(as); + + if (!QTAILQ_EMPTY(&as->listeners)) { + address_space_update_topology_pass(as, old_view, new_view, false); + address_space_update_topology_pass(as, old_view, new_view, true); + } flatview_unref(as->current_map); as->current_map = new_view; @@ -1798,7 +1809,7 @@ void address_space_init(struct uc_struct *uc, AddressSpace *as, MemoryRegion *ro QTAILQ_INIT(&as->listeners); QTAILQ_INSERT_TAIL(&uc->address_spaces, as, address_spaces_link); as->name = g_strdup(name ? name : "anonymous"); - address_space_init_dispatch(as); + as->dispatch = NULL; uc->memory_region_update_pending |= root->enabled; memory_region_transaction_commit(uc); } @@ -1856,7 +1867,6 @@ void address_space_destroy(AddressSpace *as) as->root = NULL; memory_region_transaction_commit(as->uc); QTAILQ_REMOVE(&as->uc->address_spaces, as, address_spaces_link); - address_space_unregister(as); /* At this point, as->dispatch and as->current_map are dummy * entries that the guest should never use. Wait for the old