diff options
author | OHMURA Kei <ohmura.kei@lab.ntt.co.jp> | 2010-02-15 15:12:21 +0900 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-02-17 11:46:04 +0200 |
commit | f0f8f0ef270f81bf38eb5d81a0205c8ba49e1eee (patch) | |
tree | 604990e3abe1e7029c857eea510897f06cc1f35c /qemu-kvm.c | |
parent | 229005e09edc348c7679c8fe85bab2042d384098 (diff) |
qemu-kvm: Speed up of the dirty-bitmap-traveling
dirty-bitmap-traveling is carried out by byte size in qemu-kvm.c.
But We think that dirty-bitmap-traveling by long size is faster than by byte
size especially when most of memory is not dirty.
Signed-off-by: OHMURA Kei <ohmura.kei@lab.ntt.co.jp>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'qemu-kvm.c')
-rw-r--r-- | qemu-kvm.c | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/qemu-kvm.c b/qemu-kvm.c index 7ddf36a43..c83273052 100644 --- a/qemu-kvm.c +++ b/qemu-kvm.c @@ -2443,31 +2443,32 @@ int kvm_physical_memory_set_dirty_tracking(int enable) /* get kvm's dirty pages bitmap and update qemu's */ static int kvm_get_dirty_pages_log_range(unsigned long start_addr, - unsigned char *bitmap, + unsigned long *bitmap, unsigned long offset, unsigned long mem_size) { - unsigned int i, j, n = 0; - unsigned char c; - unsigned long page_number, addr, addr1; + unsigned int i, j; + unsigned long page_number, addr, addr1, c; ram_addr_t ram_addr; - unsigned int len = ((mem_size / TARGET_PAGE_SIZE) + 7) / 8; + unsigned int len = ((mem_size / TARGET_PAGE_SIZE) + HOST_LONG_BITS - 1) / + HOST_LONG_BITS; /* * bitmap-traveling is faster than memory-traveling (for addr...) * especially when most of the memory is not dirty. */ for (i = 0; i < len; i++) { - c = bitmap[i]; - while (c > 0) { - j = ffsl(c) - 1; - c &= ~(1u << j); - page_number = i * 8 + j; - addr1 = page_number * TARGET_PAGE_SIZE; - addr = offset + addr1; - ram_addr = cpu_get_physical_page_desc(addr); - cpu_physical_memory_set_dirty(ram_addr); - n++; + if (bitmap[i] != 0) { + c = leul_to_cpu(bitmap[i]); + do { + j = ffsl(c) - 1; + c &= ~(1ul << j); + page_number = i * HOST_LONG_BITS + j; + addr1 = page_number * TARGET_PAGE_SIZE; + addr = offset + addr1; + ram_addr = cpu_get_physical_page_desc(addr); + cpu_physical_memory_set_dirty(ram_addr); + } while (c != 0); } } return 0; |