diff mbox

[PULL,17/50] memory: optimize memory_region_sync_dirty_bitmap

Message ID 1477316855-42218-18-git-send-email-pbonzini@redhat.com
State New
Headers show

Commit Message

Paolo Bonzini Oct. 24, 2016, 1:47 p.m. UTC
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 <pbonzini@redhat.com>
---
 memory.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)
diff mbox

Patch

diff --git a/memory.c b/memory.c
index c857722..edbc701 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);