mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-01 23:03:54 -06:00
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. Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> Message-Id: <20170921085110.25598-3-aik@ozlabs.ru> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
e76bb18f7e
commit
9a62e24f45
4 changed files with 21 additions and 32 deletions
27
exec.c
27
exec.c
|
@ -1347,9 +1347,8 @@ static void register_multipage(AddressSpaceDispatch *d,
|
||||||
phys_page_set(d, start_addr >> TARGET_PAGE_BITS, num_pages, section_index);
|
phys_page_set(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;
|
AddressSpaceDispatch *d = as->next_dispatch;
|
||||||
MemoryRegionSection now = *section, remain = *section;
|
MemoryRegionSection now = *section, remain = *section;
|
||||||
Int128 page_size = int128_make64(TARGET_PAGE_SIZE);
|
Int128 page_size = int128_make64(TARGET_PAGE_SIZE);
|
||||||
|
@ -2673,9 +2672,8 @@ static void io_mem_init(void)
|
||||||
NULL, UINT64_MAX);
|
NULL, UINT64_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
AddressSpaceDispatch *d = g_new0(AddressSpaceDispatch, 1);
|
||||||
uint16_t n;
|
uint16_t n;
|
||||||
|
|
||||||
|
@ -2699,9 +2697,8 @@ static void address_space_dispatch_free(AddressSpaceDispatch *d)
|
||||||
g_free(d);
|
g_free(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 *cur = as->dispatch;
|
||||||
AddressSpaceDispatch *next = as->next_dispatch;
|
AddressSpaceDispatch *next = as->next_dispatch;
|
||||||
|
|
||||||
|
@ -2731,24 +2728,6 @@ static void tcg_commit(MemoryListener *listener)
|
||||||
tlb_flush(cpuas->cpu);
|
tlb_flush(cpuas->cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
void address_space_init_dispatch(AddressSpace *as)
|
|
||||||
{
|
|
||||||
as->dispatch = NULL;
|
|
||||||
as->dispatch_listener = (MemoryListener) {
|
|
||||||
.begin = mem_begin,
|
|
||||||
.commit = mem_commit,
|
|
||||||
.region_add = mem_add,
|
|
||||||
.region_nop = mem_add,
|
|
||||||
.priority = 0,
|
|
||||||
};
|
|
||||||
memory_listener_register(&as->dispatch_listener, as);
|
|
||||||
}
|
|
||||||
|
|
||||||
void address_space_unregister(AddressSpace *as)
|
|
||||||
{
|
|
||||||
memory_listener_unregister(&as->dispatch_listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
void address_space_destroy_dispatch(AddressSpace *as)
|
void address_space_destroy_dispatch(AddressSpace *as)
|
||||||
{
|
{
|
||||||
AddressSpaceDispatch *d = as->dispatch;
|
AddressSpaceDispatch *d = as->dispatch;
|
||||||
|
|
|
@ -22,8 +22,6 @@
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
typedef struct AddressSpaceDispatch AddressSpaceDispatch;
|
typedef struct AddressSpaceDispatch AddressSpaceDispatch;
|
||||||
|
|
||||||
void address_space_init_dispatch(AddressSpace *as);
|
|
||||||
void address_space_unregister(AddressSpace *as);
|
|
||||||
void address_space_destroy_dispatch(AddressSpace *as);
|
void address_space_destroy_dispatch(AddressSpace *as);
|
||||||
|
|
||||||
extern const MemoryRegionOps unassigned_mem_ops;
|
extern const MemoryRegionOps unassigned_mem_ops;
|
||||||
|
@ -31,5 +29,9 @@ extern const MemoryRegionOps unassigned_mem_ops;
|
||||||
bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr,
|
bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr,
|
||||||
unsigned size, bool is_write);
|
unsigned size, bool is_write);
|
||||||
|
|
||||||
|
void mem_add(AddressSpace *as, MemoryRegionSection *section);
|
||||||
|
void mem_begin(AddressSpace *as);
|
||||||
|
void mem_commit(AddressSpace *as);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -318,7 +318,6 @@ struct AddressSpace {
|
||||||
struct MemoryRegionIoeventfd *ioeventfds;
|
struct MemoryRegionIoeventfd *ioeventfds;
|
||||||
struct AddressSpaceDispatch *dispatch;
|
struct AddressSpaceDispatch *dispatch;
|
||||||
struct AddressSpaceDispatch *next_dispatch;
|
struct AddressSpaceDispatch *next_dispatch;
|
||||||
MemoryListener dispatch_listener;
|
|
||||||
QTAILQ_HEAD(memory_listeners_as, MemoryListener) listeners;
|
QTAILQ_HEAD(memory_listeners_as, MemoryListener) listeners;
|
||||||
QTAILQ_ENTRY(AddressSpace) address_spaces_link;
|
QTAILQ_ENTRY(AddressSpace) address_spaces_link;
|
||||||
};
|
};
|
||||||
|
|
19
memory.c
19
memory.c
|
@ -884,14 +884,24 @@ static void address_space_update_topology_pass(AddressSpace *as,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void address_space_update_topology(AddressSpace *as)
|
static void address_space_update_topology(AddressSpace *as)
|
||||||
{
|
{
|
||||||
FlatView *old_view = address_space_get_flatview(as);
|
FlatView *old_view = address_space_get_flatview(as);
|
||||||
FlatView *new_view = generate_memory_topology(as->root);
|
FlatView *new_view = generate_memory_topology(as->root);
|
||||||
|
int i;
|
||||||
|
|
||||||
address_space_update_topology_pass(as, old_view, new_view, false);
|
mem_begin(as);
|
||||||
address_space_update_topology_pass(as, old_view, new_view, true);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
/* Writes are protected by the BQL. */
|
/* Writes are protected by the BQL. */
|
||||||
atomic_rcu_set(&as->current_map, new_view);
|
atomic_rcu_set(&as->current_map, new_view);
|
||||||
|
@ -2626,7 +2636,7 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name)
|
||||||
QTAILQ_INIT(&as->listeners);
|
QTAILQ_INIT(&as->listeners);
|
||||||
QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link);
|
QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link);
|
||||||
as->name = g_strdup(name ? name : "anonymous");
|
as->name = g_strdup(name ? name : "anonymous");
|
||||||
address_space_init_dispatch(as);
|
as->dispatch = NULL;
|
||||||
memory_region_update_pending |= root->enabled;
|
memory_region_update_pending |= root->enabled;
|
||||||
memory_region_transaction_commit();
|
memory_region_transaction_commit();
|
||||||
}
|
}
|
||||||
|
@ -2677,7 +2687,6 @@ void address_space_destroy(AddressSpace *as)
|
||||||
as->root = NULL;
|
as->root = NULL;
|
||||||
memory_region_transaction_commit();
|
memory_region_transaction_commit();
|
||||||
QTAILQ_REMOVE(&address_spaces, as, address_spaces_link);
|
QTAILQ_REMOVE(&address_spaces, as, address_spaces_link);
|
||||||
address_space_unregister(as);
|
|
||||||
|
|
||||||
/* At this point, as->dispatch and as->current_map are dummy
|
/* At this point, as->dispatch and as->current_map are dummy
|
||||||
* entries that the guest should never use. Wait for the old
|
* entries that the guest should never use. Wait for the old
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue