memory: avoid ref/unref in memory_region_find
authorPaolo Bonzini <pbonzini@redhat.com>
Fri, 17 May 2013 10:40:44 +0000 (12:40 +0200)
committerPaolo Bonzini <pbonzini@redhat.com>
Mon, 2 Feb 2015 15:55:10 +0000 (16:55 +0100)
Do the entire lookup under RCU, which avoids atomic operations
in flatview_ref and flatview_unref.

Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
memory.c

index a844ced..9b91243 100644 (file)
--- a/memory.c
+++ b/memory.c
@@ -1828,11 +1828,11 @@ MemoryRegionSection memory_region_find(MemoryRegion *mr,
     }
     range = addrrange_make(int128_make64(addr), int128_make64(size));
 
-    view = address_space_get_flatview(as);
+    rcu_read_lock();
+    view = atomic_rcu_read(&as->current_map);
     fr = flatview_lookup(view, range);
     if (!fr) {
-        flatview_unref(view);
-        return ret;
+        goto out;
     }
 
     while (fr > view->ranges && addrrange_intersects(fr[-1].addr, range)) {
@@ -1849,8 +1849,8 @@ MemoryRegionSection memory_region_find(MemoryRegion *mr,
     ret.offset_within_address_space = int128_get64(range.start);
     ret.readonly = fr->readonly;
     memory_region_ref(ret.mr);
-
-    flatview_unref(view);
+out:
+    rcu_read_unlock();
     return ret;
 }