From 0a752eeea810a1c37f5de4edba355c35cfa42524 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 23 Sep 2016 11:08:54 +0200 Subject: memory: optimize memory_region_sync_dirty_bitmap Avoid walking the FlatView of all address spaces. Most of the address spaces will have no log_sync callback on their listeners. Signed-off-by: Paolo Bonzini --- memory.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/memory.c b/memory.c index c857722f86..edbc7012b6 100644 --- a/memory.c +++ b/memory.c @@ -1642,14 +1642,26 @@ bool memory_region_test_and_clear_dirty(MemoryRegion *mr, hwaddr addr, void memory_region_sync_dirty_bitmap(MemoryRegion *mr) { + MemoryListener *listener; AddressSpace *as; + FlatView *view; FlatRange *fr; - QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) { - FlatView *view = address_space_get_flatview(as); + /* If the same address space has multiple log_sync listeners, we + * visit that address space's FlatView multiple times. But because + * log_sync listeners are rare, it's still cheaper than walking each + * address space once. + */ + QTAILQ_FOREACH(listener, &memory_listeners, link) { + if (!listener->log_sync) { + continue; + } + as = listener->address_space; + view = address_space_get_flatview(as); FOR_EACH_FLAT_RANGE(fr, view) { if (fr->mr == mr) { - MEMORY_LISTENER_UPDATE_REGION(fr, as, Forward, log_sync); + MemoryRegionSection mrs = section_from_flat_range(fr, as); + listener->log_sync(listener, &mrs); } } flatview_unref(view); -- cgit v1.2.3