aboutsummaryrefslogtreecommitdiff
path: root/include/exec
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2014-12-02 11:23:18 +0000
committerPaolo Bonzini <pbonzini@redhat.com>2015-06-05 17:10:00 +0200
commit03eebc9e3246b9b3f5925aa41f7dfd7c1e467875 (patch)
tree74641e34056f1169770c48aa604477315210d6be /include/exec
parent20015f72bda7d2f356c43580a5542a659afedf83 (diff)
downloadqemu-03eebc9e3246b9b3f5925aa41f7dfd7c1e467875.zip
qemu-03eebc9e3246b9b3f5925aa41f7dfd7c1e467875.tar.gz
qemu-03eebc9e3246b9b3f5925aa41f7dfd7c1e467875.tar.bz2
memory: replace cpu_physical_memory_reset_dirty() with test-and-clear
The cpu_physical_memory_reset_dirty() function is sometimes used together with cpu_physical_memory_get_dirty(). This is not atomic since two separate accesses to the dirty memory bitmap are made. Turn cpu_physical_memory_reset_dirty() and cpu_physical_memory_clear_dirty_range_type() into the atomic cpu_physical_memory_test_and_clear_dirty(). Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Message-Id: <1417519399-3166-6-git-send-email-stefanha@redhat.com> Reviewed-by: Fam Zheng <famz@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'include/exec')
-rw-r--r--include/exec/ram_addr.h33
1 files changed, 10 insertions, 23 deletions
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index 63db371..a2beea7 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -194,30 +194,19 @@ static inline void cpu_physical_memory_set_dirty_lebitmap(unsigned long *bitmap,
}
#endif /* not _WIN32 */
-static inline void cpu_physical_memory_clear_dirty_range_type(ram_addr_t start,
- ram_addr_t length,
- unsigned client)
-{
- unsigned long end, page;
-
- assert(client < DIRTY_MEMORY_NUM);
- end = TARGET_PAGE_ALIGN(start + length) >> TARGET_PAGE_BITS;
- page = start >> TARGET_PAGE_BITS;
- bitmap_clear(ram_list.dirty_memory[client], page, end - page);
-}
+bool cpu_physical_memory_test_and_clear_dirty(ram_addr_t start,
+ ram_addr_t length,
+ unsigned client);
static inline void cpu_physical_memory_clear_dirty_range(ram_addr_t start,
ram_addr_t length)
{
- cpu_physical_memory_clear_dirty_range_type(start, length, DIRTY_MEMORY_MIGRATION);
- cpu_physical_memory_clear_dirty_range_type(start, length, DIRTY_MEMORY_VGA);
- cpu_physical_memory_clear_dirty_range_type(start, length, DIRTY_MEMORY_CODE);
+ cpu_physical_memory_test_and_clear_dirty(start, length, DIRTY_MEMORY_MIGRATION);
+ cpu_physical_memory_test_and_clear_dirty(start, length, DIRTY_MEMORY_VGA);
+ cpu_physical_memory_test_and_clear_dirty(start, length, DIRTY_MEMORY_CODE);
}
-void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t length,
- unsigned client);
-
static inline
uint64_t cpu_physical_memory_sync_dirty_bitmap(unsigned long *dest,
ram_addr_t start,
@@ -245,16 +234,14 @@ uint64_t cpu_physical_memory_sync_dirty_bitmap(unsigned long *dest,
}
} else {
for (addr = 0; addr < length; addr += TARGET_PAGE_SIZE) {
- if (cpu_physical_memory_get_dirty(start + addr,
- TARGET_PAGE_SIZE,
- DIRTY_MEMORY_MIGRATION)) {
+ if (cpu_physical_memory_test_and_clear_dirty(
+ start + addr,
+ TARGET_PAGE_SIZE,
+ DIRTY_MEMORY_MIGRATION)) {
long k = (start + addr) >> TARGET_PAGE_BITS;
if (!test_and_set_bit(k, dest)) {
num_dirty++;
}
- cpu_physical_memory_reset_dirty(start + addr,
- TARGET_PAGE_SIZE,
- DIRTY_MEMORY_MIGRATION);
}
}
}