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>
This commit is contained in:
Paolo Bonzini 2013-05-17 12:40:44 +02:00
parent 374f2981d1
commit 2b647668c9

View file

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