qemu-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-commits] [COMMIT 151f774] kvm: Rework dirty bitmap synchronization


From: Anthony Liguori
Subject: [Qemu-commits] [COMMIT 151f774] kvm: Rework dirty bitmap synchronization
Date: Fri, 22 May 2009 15:52:50 -0000

From: Jan Kiszka <address@hidden>

Extend kvm_physical_sync_dirty_bitmap() so that is can sync across
multiple slots. Useful for updating the whole dirty log during
migration. Moreover, properly pass down errors the whole call chain.

Signed-off-by: Jan Kiszka <address@hidden>
Signed-off-by: Anthony Liguori <address@hidden>

diff --git a/cpu-all.h b/cpu-all.h
index b23be60..dc9b034 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -901,7 +901,8 @@ int cpu_physical_memory_set_dirty_tracking(int enable);
 
 int cpu_physical_memory_get_dirty_tracking(void);
 
-void cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr, 
target_phys_addr_t end_addr);
+int cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
+                                   target_phys_addr_t end_addr);
 
 void dump_exec_info(FILE *f,
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
diff --git a/exec.c b/exec.c
index c5c9280..544fb43 100644
--- a/exec.c
+++ b/exec.c
@@ -1931,10 +1931,14 @@ int cpu_physical_memory_get_dirty_tracking(void)
     return in_migration;
 }
 
-void cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr, 
target_phys_addr_t end_addr)
+int cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
+                                   target_phys_addr_t end_addr)
 {
+    int ret = 0;
+
     if (kvm_enabled())
-        kvm_physical_sync_dirty_bitmap(start_addr, end_addr);
+        ret = kvm_physical_sync_dirty_bitmap(start_addr, end_addr);
+    return ret;
 }
 
 static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry)
diff --git a/kvm-all.c b/kvm-all.c
index 3b6b5ed..eb4b9ea 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -272,47 +272,58 @@ int kvm_set_migration_log(int enable)
  * @start_add: start of logged region.
  * @end_addr: end of logged region.
  */
-void kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
-                                    target_phys_addr_t end_addr)
+int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
+                                   target_phys_addr_t end_addr)
 {
     KVMState *s = kvm_state;
-    KVMDirtyLog d;
-    KVMSlot *mem = kvm_lookup_matching_slot(s, start_addr, end_addr);
-    unsigned long alloc_size;
+    unsigned long size, allocated_size = 0;
+    target_phys_addr_t phys_addr;
     ram_addr_t addr;
-    target_phys_addr_t phys_addr = start_addr;
+    KVMDirtyLog d;
+    KVMSlot *mem;
+    int ret = 0;
 
-    dprintf("sync addr: " TARGET_FMT_lx " into %lx\n", start_addr,
-            mem->phys_offset);
-    if (mem == NULL) {
-            fprintf(stderr, "BUG: %s: invalid parameters " TARGET_FMT_plx "-"
-                    TARGET_FMT_plx "\n", __func__, phys_addr, end_addr - 1);
-            return;
-    }
+    d.dirty_bitmap = NULL;
+    while (start_addr < end_addr) {
+        mem = kvm_lookup_overlapping_slot(s, start_addr, end_addr);
+        if (mem == NULL) {
+            break;
+        }
 
-    alloc_size = ((mem->memory_size >> TARGET_PAGE_BITS) + 7) / 8;
-    d.dirty_bitmap = qemu_mallocz(alloc_size);
+        size = ((mem->memory_size >> TARGET_PAGE_BITS) + 7) / 8;
+        if (!d.dirty_bitmap) {
+            d.dirty_bitmap = qemu_malloc(size);
+        } else if (size > allocated_size) {
+            d.dirty_bitmap = qemu_realloc(d.dirty_bitmap, size);
+        }
+        allocated_size = size;
+        memset(d.dirty_bitmap, 0, allocated_size);
 
-    d.slot = mem->slot;
-    dprintf("slot %d, phys_addr %llx, uaddr: %llx\n",
-            d.slot, mem->start_addr, mem->phys_offset);
+        d.slot = mem->slot;
 
-    if (kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d) == -1) {
-        dprintf("ioctl failed %d\n", errno);
-        goto out;
-    }
+        if (kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d) == -1) {
+            dprintf("ioctl failed %d\n", errno);
+            ret = -1;
+            break;
+        }
+
+        for (phys_addr = mem->start_addr, addr = mem->phys_offset;
+             phys_addr < mem->start_addr + mem->memory_size;
+             phys_addr += TARGET_PAGE_SIZE, addr += TARGET_PAGE_SIZE) {
+            unsigned long *bitmap = (unsigned long *)d.dirty_bitmap;
+            unsigned nr = (phys_addr - mem->start_addr) >> TARGET_PAGE_BITS;
+            unsigned word = nr / (sizeof(*bitmap) * 8);
+            unsigned bit = nr % (sizeof(*bitmap) * 8);
 
-    phys_addr = start_addr;
-    for (addr = mem->phys_offset; phys_addr < end_addr; phys_addr+= 
TARGET_PAGE_SIZE, addr += TARGET_PAGE_SIZE) {
-        unsigned long *bitmap = (unsigned long *)d.dirty_bitmap;
-        unsigned nr = (phys_addr - start_addr) >> TARGET_PAGE_BITS;
-        unsigned word = nr / (sizeof(*bitmap) * 8);
-        unsigned bit = nr % (sizeof(*bitmap) * 8);
-        if ((bitmap[word] >> bit) & 1)
-            cpu_physical_memory_set_dirty(addr);
+            if ((bitmap[word] >> bit) & 1) {
+                cpu_physical_memory_set_dirty(addr);
+            }
+        }
+        start_addr = phys_addr;
     }
-out:
     qemu_free(d.dirty_bitmap);
+
+    return ret;
 }
 
 int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
diff --git a/kvm.h b/kvm.h
index 1d247e0..d0738f5 100644
--- a/kvm.h
+++ b/kvm.h
@@ -40,8 +40,8 @@ void kvm_set_phys_mem(target_phys_addr_t start_addr,
                       ram_addr_t size,
                       ram_addr_t phys_offset);
 
-void kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
-                                    target_phys_addr_t end_addr);
+int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
+                                   target_phys_addr_t end_addr);
 
 int kvm_log_start(target_phys_addr_t phys_addr, ram_addr_t size);
 int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t size);




reply via email to

[Prev in Thread] Current Thread [Next in Thread]