diff mbox

kvm: Flush coalesced MMIO buffer periodly

Message ID 1264126972-29758-1-git-send-email-sheng@linux.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Sheng Yang Jan. 22, 2010, 2:22 a.m. UTC
None
diff mbox

Patch

diff --git a/qemu-kvm.c b/qemu-kvm.c
index 599c3d6..a9b5107 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -463,6 +463,12 @@  static void kvm_create_vcpu(CPUState *env, int id)
         goto err_fd;
     }
 
+#ifdef KVM_CAP_COALESCED_MMIO
+    if (kvm_state->coalesced_mmio && !kvm_state->coalesced_mmio_ring)
+        kvm_state->coalesced_mmio_ring = (void *) env->kvm_run +
+		kvm_state->coalesced_mmio * PAGE_SIZE;
+#endif
+
     return;
   err_fd:
     close(env->kvm_fd);
@@ -927,8 +933,7 @@  int kvm_run(CPUState *env)
 
 #if defined(KVM_CAP_COALESCED_MMIO)
     if (kvm_state->coalesced_mmio) {
-        struct kvm_coalesced_mmio_ring *ring =
-            (void *) run + kvm_state->coalesced_mmio * PAGE_SIZE;
+        struct kvm_coalesced_mmio_ring *ring = kvm_state->coalesced_mmio_ring;
         while (ring->first != ring->last) {
             cpu_physical_memory_rw(ring->coalesced_mmio[ring->first].phys_addr,
                            &ring->coalesced_mmio[ring->first].data[0],
@@ -2073,6 +2078,23 @@  static void io_thread_wakeup(void *opaque)
     }
 }
 
+#ifdef KVM_CAP_COALESCED_MMIO
+void kvm_flush_coalesced_mmio_buffer(void)
+{
+    if (kvm_state->coalesced_mmio_ring) {
+        struct kvm_coalesced_mmio_ring *ring =
+            kvm_state->coalesced_mmio_ring;
+        while (ring->first != ring->last) {
+            cpu_physical_memory_rw(ring->coalesced_mmio[ring->first].phys_addr,
+                           &ring->coalesced_mmio[ring->first].data[0],
+                           ring->coalesced_mmio[ring->first].len, 1);
+            smp_wmb();
+            ring->first = (ring->first + 1) % KVM_COALESCED_MMIO_MAX;
+        }
+    }
+}
+#endif
+
 int kvm_main_loop(void)
 {
     int fds[2];
diff --git a/qemu-kvm.h b/qemu-kvm.h
index 6b3e5a1..8188ff6 100644
--- a/qemu-kvm.h
+++ b/qemu-kvm.h
@@ -1125,6 +1125,11 @@  static inline int kvm_set_migration_log(int enable)
     return kvm_physical_memory_set_dirty_tracking(enable);
 }
 
+#ifdef KVM_CAP_COALESCED_MMIO
+void kvm_flush_coalesced_mmio_buffer(void);
+#else
+void kvm_flush_coalesced_mmio_buffer(void) {}
+#endif
 
 int kvm_irqchip_in_kernel(void);
 #ifdef CONFIG_KVM
@@ -1144,6 +1149,7 @@  typedef struct KVMState {
     int fd;
     int vmfd;
     int coalesced_mmio;
+    struct kvm_coalesced_mmio_ring *coalesced_mmio_ring;
     int broken_set_mem_region;
     int migration_log;
     int vcpu_events;
diff --git a/vl.c b/vl.c
index 9edea10..64902f2 100644
--- a/vl.c
+++ b/vl.c
@@ -3235,6 +3235,7 @@  static void gui_update(void *opaque)
             interval = dcl->gui_timer_interval;
         dcl = dcl->next;
     }
+    kvm_flush_coalesced_mmio_buffer();
     qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock(rt_clock));
 }
 
@@ -3242,6 +3243,7 @@  static void nographic_update(void *opaque)
 {
     uint64_t interval = GUI_REFRESH_INTERVAL;
 
+    kvm_flush_coalesced_mmio_buffer();
     qemu_mod_timer(nographic_timer, interval + qemu_get_clock(rt_clock));
 }