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
This commit is contained in:
Alexey Kardashevskiy 2018-03-04 02:02:41 -05:00 committed by Lioncash
parent f74fcb194f
commit e723b8dd49
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
4 changed files with 20 additions and 34 deletions

View file

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

View file

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

View file

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

View file

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