aboutsummaryrefslogtreecommitdiff
path: root/memory.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2013-05-17 12:40:44 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2015-02-02 16:55:10 +0100
commit2b647668c9092dbc26e36a2ece9647cc2f00e05b (patch)
treea3b4dce04c778c5c8a81f1063c4e2c566976e824 /memory.c
parent374f2981d1f10bc4307f250f24b2a7ddb9b14be0 (diff)
memory: avoid ref/unref in memory_region_find
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>
Diffstat (limited to 'memory.c')
-rw-r--r--memory.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/memory.c b/memory.c
index a844ced6ef..9b91243978 100644
--- 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;
}