From: Avi Kivity <[EMAIL PROTECTED]>

as vcpu 0 receives all signals, if another vcpu waits for aio completion, it
will hang as the signal will never be received.  fix by waiting on a condition
variable, and signaling that variable from vcpu 0 when the completion signal
is received.

this fixes hangs with -smp 2 -snapshot and qcow2.

Signed-off-by: Avi Kivity <[EMAIL PROTECTED]>

diff --git a/qemu/block-raw-posix.c b/qemu/block-raw-posix.c
index b50da1f..9a72d36 100644
--- a/qemu/block-raw-posix.c
+++ b/qemu/block-raw-posix.c
@@ -23,6 +23,7 @@
  */
 #include "qemu-common.h"
 #ifndef QEMU_IMG
+#include "qemu-kvm.h"
 #include "qemu-timer.h"
 #include "exec-all.h"
 #endif
@@ -345,6 +346,12 @@ void qemu_aio_wait_start(void)
 
     if (!aio_initialized)
         qemu_aio_init();
+#ifdef USE_KVM
+    if (kvm_allowed) {
+        qemu_kvm_aio_wait_start();
+        return;
+    }
+#endif
     sigemptyset(&set);
     sigaddset(&set, aio_sig_num);
     sigprocmask(SIG_BLOCK, &set, &wait_oset);
@@ -359,6 +366,13 @@ void qemu_aio_wait(void)
     if (qemu_bh_poll())
         return;
 #endif
+#ifdef USE_KVM
+    if (kvm_allowed) {
+        qemu_kvm_aio_wait();
+        qemu_aio_poll();
+        return;
+    }
+#endif
     sigemptyset(&set);
     sigaddset(&set, aio_sig_num);
     sigwait(&set, &nb_sigs);
@@ -367,6 +381,12 @@ void qemu_aio_wait(void)
 
 void qemu_aio_wait_end(void)
 {
+#ifdef USE_KVM
+    if (kvm_allowed) {
+        qemu_kvm_aio_wait_end();
+        return;
+    }
+#endif
     sigprocmask(SIG_SETMASK, &wait_oset, NULL);
 }
 
diff --git a/qemu/qemu-kvm.c b/qemu/qemu-kvm.c
index f8a2e5c..6c8c391 100644
--- a/qemu/qemu-kvm.c
+++ b/qemu/qemu-kvm.c
@@ -29,6 +29,7 @@ kvm_context_t kvm_context;
 extern int smp_cpus;
 
 pthread_mutex_t qemu_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t qemu_aio_cond = PTHREAD_COND_INITIALIZER;
 __thread CPUState *vcpu_env;
 
 static sigset_t io_sigset, io_negsigset;
@@ -182,6 +183,8 @@ static int kvm_eat_signal(CPUState *env, int timeout)
     if (r != -1) {
        sigaction(siginfo.si_signo, NULL, &sa);
        sa.sa_handler(siginfo.si_signo);
+       if (siginfo.si_signo == SIGUSR2)
+           pthread_cond_signal(&qemu_aio_cond);
        ret = 1;
     }
     pthread_mutex_unlock(&qemu_mutex);
@@ -753,4 +756,23 @@ int kvm_set_irq(int irq, int level)
 
 #endif
 
+void qemu_kvm_aio_wait_start(void)
+{
+}
+
+void qemu_kvm_aio_wait(void)
+{
+    if (!cpu_single_env || cpu_single_env->cpu_index == 0) {
+       pthread_mutex_unlock(&qemu_mutex);
+       kvm_eat_signal(cpu_single_env, 1000);
+       pthread_mutex_lock(&qemu_mutex);
+    } else {
+       pthread_cond_wait(&qemu_aio_cond, &qemu_mutex);
+    }
+}
+
+void qemu_kvm_aio_wait_end(void)
+{
+}
+
 #endif
diff --git a/qemu/qemu-kvm.h b/qemu/qemu-kvm.h
index c4514bb..bda1c0b 100644
--- a/qemu/qemu-kvm.h
+++ b/qemu/qemu-kvm.h
@@ -40,6 +40,10 @@ int kvm_arch_has_work(CPUState *env);
 int kvm_arch_try_push_interrupts(void *opaque);
 void kvm_arch_update_regs_for_sipi(CPUState *env);
 
+void qemu_kvm_aio_wait_start(void);
+void qemu_kvm_aio_wait(void);
+void qemu_kvm_aio_wait_end(void);
+
 extern int kvm_allowed;
 extern int kvm_irqchip;
 

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
kvm-commits mailing list
kvm-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-commits

Reply via email to