All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/22] [uq/master] Patch queue, part II
@ 2011-01-27 13:09 ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: kvm, qemu-devel, Alexander Graf, Gleb Natapov, Hidetoshi Seto,
	Huang Ying, Jin Dongming, Paolo Bonzini, Stefan Hajnoczi

This second round of patches focus on issues in cpus.c, primarily signal
related. The highlights are

 - Add missing KVM_RUN continuation after I/O exits
 - Fix for timer signal race in KVM entry code under !CONFIG_IOTHREAD
   (based on Stefan's findings)
 - MCE signal processing under !CONFIG_IOTHREAD
 - Prevent abortion on multiple VCPU kicks
 - Fixed synchronous (ie. VCPU-issued) reset request processing

Topics remaining for a third round are cleanups and refactorings of the
KVM VCPU entry/exit path, MCE rework, and a few assorted cleanups. But I
will wait at least until these bits here are ready for an upstream
merge.

CC: Alexander Graf <agraf@suse.de>
CC: Gleb Natapov <gleb@redhat.com>
CC: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
CC: Huang Ying <ying.huang@intel.com>
CC: Jin Dongming <jin.dongming@np.css.fujitsu.com>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>

Jan Kiszka (22):
  Prevent abortion on multiple VCPU kicks
  Stop current VCPU on synchronous reset requests
  Process vmstop requests in IO thread
  Leave inner main_loop faster on pending requests
  kvm: Report proper error on GET_VCPU_MMAP_SIZE failures
  kvm: Drop redundant kvm_enabled from kvm_cpu_thread_fn
  kvm: Handle kvm_init_vcpu errors
  kvm: Provide sigbus services arch-independently
  Refactor signal setup functions in cpus.c
  kvm: Set up signal mask also for !CONFIG_IOTHREAD
  kvm: Refactor qemu_kvm_eat_signals
  kvm: Call qemu_kvm_eat_signals also under !CONFIG_IOTHREAD
  Set up signalfd under !CONFIG_IOTHREAD
  kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
  kvm: Add MCE signal support for !CONFIG_IOTHREAD
  Introduce VCPU self-signaling service
  kvm: Move irqchip event processing out of inner loop
  kvm: Unconditionally reenter kernel after IO exits
  kvm: Remove static return code of kvm_handle_io
  kvm: Leave kvm_cpu_exec directly after KVM_EXIT_SHUTDOWN
  Refactor kvm&tcg function names in cpus.c
  Fix a few coding style violations in cpus.c

 Makefile.objs      |    2 +-
 cpu-defs.h         |    1 +
 cpus.c             |  639 +++++++++++++++++++++++++++++++---------------------
 cpus.h             |    1 +
 kvm-all.c          |   60 +++--
 kvm-stub.c         |    5 +
 kvm.h              |    7 +-
 qemu-common.h      |    1 +
 target-i386/kvm.c  |    4 +-
 target-ppc/kvm.c   |   10 +
 target-s390x/kvm.c |   10 +
 vl.c               |   26 +-
 12 files changed, 469 insertions(+), 297 deletions(-)


^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH 00/22] [uq/master] Patch queue, part II
@ 2011-01-27 13:09 ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: Hidetoshi Seto, kvm, Gleb Natapov, qemu-devel, Alexander Graf,
	Huang Ying, Paolo Bonzini, Stefan Hajnoczi, Jin Dongming

This second round of patches focus on issues in cpus.c, primarily signal
related. The highlights are

 - Add missing KVM_RUN continuation after I/O exits
 - Fix for timer signal race in KVM entry code under !CONFIG_IOTHREAD
   (based on Stefan's findings)
 - MCE signal processing under !CONFIG_IOTHREAD
 - Prevent abortion on multiple VCPU kicks
 - Fixed synchronous (ie. VCPU-issued) reset request processing

Topics remaining for a third round are cleanups and refactorings of the
KVM VCPU entry/exit path, MCE rework, and a few assorted cleanups. But I
will wait at least until these bits here are ready for an upstream
merge.

CC: Alexander Graf <agraf@suse.de>
CC: Gleb Natapov <gleb@redhat.com>
CC: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
CC: Huang Ying <ying.huang@intel.com>
CC: Jin Dongming <jin.dongming@np.css.fujitsu.com>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>

Jan Kiszka (22):
  Prevent abortion on multiple VCPU kicks
  Stop current VCPU on synchronous reset requests
  Process vmstop requests in IO thread
  Leave inner main_loop faster on pending requests
  kvm: Report proper error on GET_VCPU_MMAP_SIZE failures
  kvm: Drop redundant kvm_enabled from kvm_cpu_thread_fn
  kvm: Handle kvm_init_vcpu errors
  kvm: Provide sigbus services arch-independently
  Refactor signal setup functions in cpus.c
  kvm: Set up signal mask also for !CONFIG_IOTHREAD
  kvm: Refactor qemu_kvm_eat_signals
  kvm: Call qemu_kvm_eat_signals also under !CONFIG_IOTHREAD
  Set up signalfd under !CONFIG_IOTHREAD
  kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
  kvm: Add MCE signal support for !CONFIG_IOTHREAD
  Introduce VCPU self-signaling service
  kvm: Move irqchip event processing out of inner loop
  kvm: Unconditionally reenter kernel after IO exits
  kvm: Remove static return code of kvm_handle_io
  kvm: Leave kvm_cpu_exec directly after KVM_EXIT_SHUTDOWN
  Refactor kvm&tcg function names in cpus.c
  Fix a few coding style violations in cpus.c

 Makefile.objs      |    2 +-
 cpu-defs.h         |    1 +
 cpus.c             |  639 +++++++++++++++++++++++++++++++---------------------
 cpus.h             |    1 +
 kvm-all.c          |   60 +++--
 kvm-stub.c         |    5 +
 kvm.h              |    7 +-
 qemu-common.h      |    1 +
 target-i386/kvm.c  |    4 +-
 target-ppc/kvm.c   |   10 +
 target-s390x/kvm.c |   10 +
 vl.c               |   26 +-
 12 files changed, 469 insertions(+), 297 deletions(-)

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 01/22] Prevent abortion on multiple VCPU kicks
  2011-01-27 13:09 ` [Qemu-devel] " Jan Kiszka
@ 2011-01-27 13:09   ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, qemu-devel

If we call qemu_cpu_kick more than once before the target was able to
process the signal, pthread_kill will fail, and qemu will abort. Prevent
this by avoiding the redundant signal.

This logic can be found in qemu-kvm as well.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpu-defs.h |    1 +
 cpus.c     |    6 +++++-
 2 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/cpu-defs.h b/cpu-defs.h
index 8d4bf86..db809ed 100644
--- a/cpu-defs.h
+++ b/cpu-defs.h
@@ -205,6 +205,7 @@ typedef struct CPUWatchpoint {
     uint32_t stopped; /* Artificially stopped */                        \
     struct QemuThread *thread;                                          \
     struct QemuCond *halt_cond;                                         \
+    int thread_kicked;                                                  \
     struct qemu_work_item *queued_work_first, *queued_work_last;        \
     const char *cpu_model_str;                                          \
     struct KVMState *kvm_state;                                         \
diff --git a/cpus.c b/cpus.c
index 4c9928e..ab6e40e 100644
--- a/cpus.c
+++ b/cpus.c
@@ -481,6 +481,7 @@ static void qemu_wait_io_event_common(CPUState *env)
         qemu_cond_signal(&qemu_pause_cond);
     }
     flush_queued_work(env);
+    env->thread_kicked = false;
 }
 
 static void qemu_tcg_wait_io_event(void)
@@ -648,7 +649,10 @@ void qemu_cpu_kick(void *_env)
 {
     CPUState *env = _env;
     qemu_cond_broadcast(env->halt_cond);
-    qemu_thread_signal(env->thread, SIG_IPI);
+    if (!env->thread_kicked) {
+        qemu_thread_signal(env->thread, SIG_IPI);
+        env->thread_kicked = true;
+    }
 }
 
 int qemu_cpu_self(void *_env)
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH 01/22] Prevent abortion on multiple VCPU kicks
@ 2011-01-27 13:09   ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm

If we call qemu_cpu_kick more than once before the target was able to
process the signal, pthread_kill will fail, and qemu will abort. Prevent
this by avoiding the redundant signal.

This logic can be found in qemu-kvm as well.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpu-defs.h |    1 +
 cpus.c     |    6 +++++-
 2 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/cpu-defs.h b/cpu-defs.h
index 8d4bf86..db809ed 100644
--- a/cpu-defs.h
+++ b/cpu-defs.h
@@ -205,6 +205,7 @@ typedef struct CPUWatchpoint {
     uint32_t stopped; /* Artificially stopped */                        \
     struct QemuThread *thread;                                          \
     struct QemuCond *halt_cond;                                         \
+    int thread_kicked;                                                  \
     struct qemu_work_item *queued_work_first, *queued_work_last;        \
     const char *cpu_model_str;                                          \
     struct KVMState *kvm_state;                                         \
diff --git a/cpus.c b/cpus.c
index 4c9928e..ab6e40e 100644
--- a/cpus.c
+++ b/cpus.c
@@ -481,6 +481,7 @@ static void qemu_wait_io_event_common(CPUState *env)
         qemu_cond_signal(&qemu_pause_cond);
     }
     flush_queued_work(env);
+    env->thread_kicked = false;
 }
 
 static void qemu_tcg_wait_io_event(void)
@@ -648,7 +649,10 @@ void qemu_cpu_kick(void *_env)
 {
     CPUState *env = _env;
     qemu_cond_broadcast(env->halt_cond);
-    qemu_thread_signal(env->thread, SIG_IPI);
+    if (!env->thread_kicked) {
+        qemu_thread_signal(env->thread, SIG_IPI);
+        env->thread_kicked = true;
+    }
 }
 
 int qemu_cpu_self(void *_env)
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 02/22] Stop current VCPU on synchronous reset requests
  2011-01-27 13:09 ` [Qemu-devel] " Jan Kiszka
@ 2011-01-27 13:09   ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, qemu-devel

If some I/O operation ends up calling qemu_system_reset_request in VCPU
context, we record this and inform the io-thread, but we do not
terminate the VCPU loop. This can lead to fairly unexpected behavior if
the triggering reset operation is supposed to work synchronously.

Fix this for TCG (when run in deterministic I/O mode) by setting the
VCPU on stop and issuing a cpu_exit. KVM requires some more work on its
VCPU loop.

[ ported from qemu-kvm ]

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpus.c |   13 +++++++++----
 cpus.h |    1 +
 vl.c   |    1 +
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/cpus.c b/cpus.c
index ab6e40e..ceb3a83 100644
--- a/cpus.c
+++ b/cpus.c
@@ -99,6 +99,14 @@ void cpu_synchronize_all_post_init(void)
     }
 }
 
+void cpu_stop_current(void)
+{
+    if (cpu_single_env) {
+        cpu_single_env->stopped = 1;
+        cpu_exit(cpu_single_env);
+    }
+}
+
 int cpu_is_stopped(CPUState *env)
 {
     return !vm_running || env->stopped;
@@ -863,10 +871,7 @@ void vm_stop(int reason)
          * FIXME: should not return to device code in case
          * vm_stop() has been requested.
          */
-        if (cpu_single_env) {
-            cpu_exit(cpu_single_env);
-            cpu_single_env->stop = 1;
-        }
+        cpu_stop_current();
         return;
     }
     do_vm_stop(reason);
diff --git a/cpus.h b/cpus.h
index bf4d9bb..4cadb64 100644
--- a/cpus.h
+++ b/cpus.h
@@ -6,6 +6,7 @@ int qemu_init_main_loop(void);
 void qemu_main_loop_start(void);
 void resume_all_vcpus(void);
 void pause_all_vcpus(void);
+void cpu_stop_current(void);
 
 /* vl.c */
 extern int smp_cores;
diff --git a/vl.c b/vl.c
index 33f844f..db24a05 100644
--- a/vl.c
+++ b/vl.c
@@ -1278,6 +1278,7 @@ void qemu_system_reset_request(void)
     } else {
         reset_requested = 1;
     }
+    cpu_stop_current();
     qemu_notify_event();
 }
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH 02/22] Stop current VCPU on synchronous reset requests
@ 2011-01-27 13:09   ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm

If some I/O operation ends up calling qemu_system_reset_request in VCPU
context, we record this and inform the io-thread, but we do not
terminate the VCPU loop. This can lead to fairly unexpected behavior if
the triggering reset operation is supposed to work synchronously.

Fix this for TCG (when run in deterministic I/O mode) by setting the
VCPU on stop and issuing a cpu_exit. KVM requires some more work on its
VCPU loop.

[ ported from qemu-kvm ]

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpus.c |   13 +++++++++----
 cpus.h |    1 +
 vl.c   |    1 +
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/cpus.c b/cpus.c
index ab6e40e..ceb3a83 100644
--- a/cpus.c
+++ b/cpus.c
@@ -99,6 +99,14 @@ void cpu_synchronize_all_post_init(void)
     }
 }
 
+void cpu_stop_current(void)
+{
+    if (cpu_single_env) {
+        cpu_single_env->stopped = 1;
+        cpu_exit(cpu_single_env);
+    }
+}
+
 int cpu_is_stopped(CPUState *env)
 {
     return !vm_running || env->stopped;
@@ -863,10 +871,7 @@ void vm_stop(int reason)
          * FIXME: should not return to device code in case
          * vm_stop() has been requested.
          */
-        if (cpu_single_env) {
-            cpu_exit(cpu_single_env);
-            cpu_single_env->stop = 1;
-        }
+        cpu_stop_current();
         return;
     }
     do_vm_stop(reason);
diff --git a/cpus.h b/cpus.h
index bf4d9bb..4cadb64 100644
--- a/cpus.h
+++ b/cpus.h
@@ -6,6 +6,7 @@ int qemu_init_main_loop(void);
 void qemu_main_loop_start(void);
 void resume_all_vcpus(void);
 void pause_all_vcpus(void);
+void cpu_stop_current(void);
 
 /* vl.c */
 extern int smp_cores;
diff --git a/vl.c b/vl.c
index 33f844f..db24a05 100644
--- a/vl.c
+++ b/vl.c
@@ -1278,6 +1278,7 @@ void qemu_system_reset_request(void)
     } else {
         reset_requested = 1;
     }
+    cpu_stop_current();
     qemu_notify_event();
 }
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 03/22] Process vmstop requests in IO thread
  2011-01-27 13:09 ` [Qemu-devel] " Jan Kiszka
@ 2011-01-27 13:09   ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, qemu-devel

A pending vmstop request is also a reason to leave the inner main loop.
So far we ignored it, and pending stop requests issued over VCPU threads
were simply ignored.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 vl.c |   14 +++++---------
 1 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/vl.c b/vl.c
index db24a05..5fad700 100644
--- a/vl.c
+++ b/vl.c
@@ -1373,15 +1373,11 @@ void main_loop_wait(int nonblocking)
 
 static int vm_can_run(void)
 {
-    if (powerdown_requested)
-        return 0;
-    if (reset_requested)
-        return 0;
-    if (shutdown_requested)
-        return 0;
-    if (debug_requested)
-        return 0;
-    return 1;
+    return !(powerdown_requested ||
+             reset_requested ||
+             shutdown_requested ||
+             debug_requested ||
+             vmstop_requested);
 }
 
 qemu_irq qemu_system_powerdown;
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH 03/22] Process vmstop requests in IO thread
@ 2011-01-27 13:09   ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm

A pending vmstop request is also a reason to leave the inner main loop.
So far we ignored it, and pending stop requests issued over VCPU threads
were simply ignored.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 vl.c |   14 +++++---------
 1 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/vl.c b/vl.c
index db24a05..5fad700 100644
--- a/vl.c
+++ b/vl.c
@@ -1373,15 +1373,11 @@ void main_loop_wait(int nonblocking)
 
 static int vm_can_run(void)
 {
-    if (powerdown_requested)
-        return 0;
-    if (reset_requested)
-        return 0;
-    if (shutdown_requested)
-        return 0;
-    if (debug_requested)
-        return 0;
-    return 1;
+    return !(powerdown_requested ||
+             reset_requested ||
+             shutdown_requested ||
+             debug_requested ||
+             vmstop_requested);
 }
 
 qemu_irq qemu_system_powerdown;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 04/22] Leave inner main_loop faster on pending requests
  2011-01-27 13:09 ` [Qemu-devel] " Jan Kiszka
@ 2011-01-27 13:09   ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, qemu-devel

If there is any pending request that requires us to leave the inner loop
if main_loop, makes sure we do this as soon as possible by enforcing
non-blocking IO processing.

At this change, move variable definitions out of the inner loop to
improve readability.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 vl.c |   11 +++++++----
 1 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/vl.c b/vl.c
index 5fad700..2ebc55b 100644
--- a/vl.c
+++ b/vl.c
@@ -1384,18 +1384,21 @@ qemu_irq qemu_system_powerdown;
 
 static void main_loop(void)
 {
+    bool nonblocking = false;
+#ifdef CONFIG_PROFILER
+    int64_t ti;
+#endif
     int r;
 
     qemu_main_loop_start();
 
     for (;;) {
         do {
-            bool nonblocking = false;
-#ifdef CONFIG_PROFILER
-            int64_t ti;
-#endif
 #ifndef CONFIG_IOTHREAD
             nonblocking = cpu_exec_all();
+            if (!vm_can_run()) {
+                nonblocking = true;
+            }
 #endif
 #ifdef CONFIG_PROFILER
             ti = profile_getclock();
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH 04/22] Leave inner main_loop faster on pending requests
@ 2011-01-27 13:09   ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm

If there is any pending request that requires us to leave the inner loop
if main_loop, makes sure we do this as soon as possible by enforcing
non-blocking IO processing.

At this change, move variable definitions out of the inner loop to
improve readability.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 vl.c |   11 +++++++----
 1 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/vl.c b/vl.c
index 5fad700..2ebc55b 100644
--- a/vl.c
+++ b/vl.c
@@ -1384,18 +1384,21 @@ qemu_irq qemu_system_powerdown;
 
 static void main_loop(void)
 {
+    bool nonblocking = false;
+#ifdef CONFIG_PROFILER
+    int64_t ti;
+#endif
     int r;
 
     qemu_main_loop_start();
 
     for (;;) {
         do {
-            bool nonblocking = false;
-#ifdef CONFIG_PROFILER
-            int64_t ti;
-#endif
 #ifndef CONFIG_IOTHREAD
             nonblocking = cpu_exec_all();
+            if (!vm_can_run()) {
+                nonblocking = true;
+            }
 #endif
 #ifdef CONFIG_PROFILER
             ti = profile_getclock();
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 05/22] kvm: Report proper error on GET_VCPU_MMAP_SIZE failures
  2011-01-27 13:09 ` [Qemu-devel] " Jan Kiszka
@ 2011-01-27 13:09   ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, qemu-devel

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kvm-all.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 9976762..1a55a10 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -219,6 +219,7 @@ int kvm_init_vcpu(CPUState *env)
 
     mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0);
     if (mmap_size < 0) {
+        ret = mmap_size;
         DPRINTF("KVM_GET_VCPU_MMAP_SIZE failed\n");
         goto err;
     }
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH 05/22] kvm: Report proper error on GET_VCPU_MMAP_SIZE failures
@ 2011-01-27 13:09   ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kvm-all.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 9976762..1a55a10 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -219,6 +219,7 @@ int kvm_init_vcpu(CPUState *env)
 
     mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0);
     if (mmap_size < 0) {
+        ret = mmap_size;
         DPRINTF("KVM_GET_VCPU_MMAP_SIZE failed\n");
         goto err;
     }
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 06/22] kvm: Drop redundant kvm_enabled from kvm_cpu_thread_fn
  2011-01-27 13:09 ` [Qemu-devel] " Jan Kiszka
@ 2011-01-27 13:09   ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, qemu-devel

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpus.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/cpus.c b/cpus.c
index ceb3a83..cd3f89b 100644
--- a/cpus.c
+++ b/cpus.c
@@ -606,8 +606,8 @@ static void *kvm_cpu_thread_fn(void *arg)
 
     qemu_mutex_lock(&qemu_global_mutex);
     qemu_thread_self(env->thread);
-    if (kvm_enabled())
-        kvm_init_vcpu(env);
+
+    kvm_init_vcpu(env);
 
     kvm_init_ipi(env);
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH 06/22] kvm: Drop redundant kvm_enabled from kvm_cpu_thread_fn
@ 2011-01-27 13:09   ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpus.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/cpus.c b/cpus.c
index ceb3a83..cd3f89b 100644
--- a/cpus.c
+++ b/cpus.c
@@ -606,8 +606,8 @@ static void *kvm_cpu_thread_fn(void *arg)
 
     qemu_mutex_lock(&qemu_global_mutex);
     qemu_thread_self(env->thread);
-    if (kvm_enabled())
-        kvm_init_vcpu(env);
+
+    kvm_init_vcpu(env);
 
     kvm_init_ipi(env);
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 07/22] kvm: Handle kvm_init_vcpu errors
  2011-01-27 13:09 ` [Qemu-devel] " Jan Kiszka
@ 2011-01-27 13:09   ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, qemu-devel

Do not ignore errors of kvm_init_vcpu, they are fatal.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpus.c |   19 +++++++++++++++----
 1 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/cpus.c b/cpus.c
index cd3f89b..f89826a 100644
--- a/cpus.c
+++ b/cpus.c
@@ -273,12 +273,18 @@ void qemu_main_loop_start(void)
 void qemu_init_vcpu(void *_env)
 {
     CPUState *env = _env;
+    int r;
 
     env->nr_cores = smp_cores;
     env->nr_threads = smp_threads;
-    if (kvm_enabled())
-        kvm_init_vcpu(env);
-    return;
+
+    if (kvm_enabled()) {
+        r = kvm_init_vcpu(env);
+        if (r < 0) {
+            fprintf(stderr, "kvm_init_vcpu failed: %s\n", strerror(-r));
+            exit(1);
+        }
+    }
 }
 
 int qemu_cpu_self(void *env)
@@ -603,11 +609,16 @@ static int qemu_cpu_exec(CPUState *env);
 static void *kvm_cpu_thread_fn(void *arg)
 {
     CPUState *env = arg;
+    int r;
 
     qemu_mutex_lock(&qemu_global_mutex);
     qemu_thread_self(env->thread);
 
-    kvm_init_vcpu(env);
+    r = kvm_init_vcpu(env);
+    if (r < 0) {
+        fprintf(stderr, "kvm_init_vcpu failed: %s\n", strerror(-r));
+        exit(1);
+    }
 
     kvm_init_ipi(env);
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH 07/22] kvm: Handle kvm_init_vcpu errors
@ 2011-01-27 13:09   ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm

Do not ignore errors of kvm_init_vcpu, they are fatal.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpus.c |   19 +++++++++++++++----
 1 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/cpus.c b/cpus.c
index cd3f89b..f89826a 100644
--- a/cpus.c
+++ b/cpus.c
@@ -273,12 +273,18 @@ void qemu_main_loop_start(void)
 void qemu_init_vcpu(void *_env)
 {
     CPUState *env = _env;
+    int r;
 
     env->nr_cores = smp_cores;
     env->nr_threads = smp_threads;
-    if (kvm_enabled())
-        kvm_init_vcpu(env);
-    return;
+
+    if (kvm_enabled()) {
+        r = kvm_init_vcpu(env);
+        if (r < 0) {
+            fprintf(stderr, "kvm_init_vcpu failed: %s\n", strerror(-r));
+            exit(1);
+        }
+    }
 }
 
 int qemu_cpu_self(void *env)
@@ -603,11 +609,16 @@ static int qemu_cpu_exec(CPUState *env);
 static void *kvm_cpu_thread_fn(void *arg)
 {
     CPUState *env = arg;
+    int r;
 
     qemu_mutex_lock(&qemu_global_mutex);
     qemu_thread_self(env->thread);
 
-    kvm_init_vcpu(env);
+    r = kvm_init_vcpu(env);
+    if (r < 0) {
+        fprintf(stderr, "kvm_init_vcpu failed: %s\n", strerror(-r));
+        exit(1);
+    }
 
     kvm_init_ipi(env);
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 08/22] kvm: Provide sigbus services arch-independently
  2011-01-27 13:09 ` [Qemu-devel] " Jan Kiszka
@ 2011-01-27 13:09   ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: kvm, qemu-devel, Huang Ying, Alexander Graf, Paolo Bonzini

Provide arch-independent kvm_on_sigbus* stubs to remove the #ifdef'ery
from cpus.c. This patch also fixes --disable-kvm build by providing the
missing kvm_on_sigbus_vcpu kvm-stub.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
CC: Huang Ying <ying.huang@intel.com>
CC: Alexander Graf <agraf@suse.de>
CC: Paolo Bonzini <pbonzini@redhat.com>
---
 cpus.c             |   10 ++++------
 kvm-all.c          |   10 ++++++++++
 kvm-stub.c         |    5 +++++
 kvm.h              |    7 +++++--
 target-i386/kvm.c  |    4 ++--
 target-ppc/kvm.c   |   10 ++++++++++
 target-s390x/kvm.c |   10 ++++++++++
 7 files changed, 46 insertions(+), 10 deletions(-)

diff --git a/cpus.c b/cpus.c
index f89826a..ce40e67 100644
--- a/cpus.c
+++ b/cpus.c
@@ -542,10 +542,9 @@ static void sigbus_reraise(void)
 static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
                            void *ctx)
 {
-#if defined(TARGET_I386)
-    if (kvm_on_sigbus(siginfo->ssi_code, (void *)(intptr_t)siginfo->ssi_addr))
-#endif
+    if (kvm_on_sigbus(siginfo->ssi_code, (void *)(intptr_t)siginfo->ssi_addr)) {
         sigbus_reraise();
+    }
 }
 
 static void qemu_kvm_eat_signal(CPUState *env, int timeout)
@@ -578,10 +577,9 @@ static void qemu_kvm_eat_signal(CPUState *env, int timeout)
 
         switch (r) {
         case SIGBUS:
-#ifdef TARGET_I386
-            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr))
-#endif
+            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {
                 sigbus_reraise();
+            }
             break;
         default:
             break;
diff --git a/kvm-all.c b/kvm-all.c
index 1a55a10..5bfa8c0 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1362,3 +1362,13 @@ int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, uint16_t val, bool assign)
     return -ENOSYS;
 #endif
 }
+
+int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr)
+{
+    return kvm_arch_on_sigbus_vcpu(env, code, addr);
+}
+
+int kvm_on_sigbus(int code, void *addr)
+{
+    return kvm_arch_on_sigbus(code, addr);
+}
diff --git a/kvm-stub.c b/kvm-stub.c
index 88682f2..d6b6c8e 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -147,6 +147,11 @@ int kvm_set_ioeventfd_mmio_long(int fd, uint32_t adr, uint32_t val, bool assign)
     return -ENOSYS;
 }
 
+int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr)
+{
+    return 1;
+}
+
 int kvm_on_sigbus(int code, void *addr)
 {
     return 1;
diff --git a/kvm.h b/kvm.h
index ca57517..b2fb5c6 100644
--- a/kvm.h
+++ b/kvm.h
@@ -81,6 +81,9 @@ int kvm_set_signal_mask(CPUState *env, const sigset_t *sigset);
 int kvm_pit_in_kernel(void);
 int kvm_irqchip_in_kernel(void);
 
+int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr);
+int kvm_on_sigbus(int code, void *addr);
+
 /* internal API */
 
 struct KVMState;
@@ -121,8 +124,8 @@ int kvm_arch_init_vcpu(CPUState *env);
 
 void kvm_arch_reset_vcpu(CPUState *env);
 
-int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr);
-int kvm_on_sigbus(int code, void *addr);
+int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr);
+int kvm_arch_on_sigbus(int code, void *addr);
 
 struct kvm_guest_debug;
 struct kvm_debug_exit_arch;
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 8e8880a..dd2cadc 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1837,7 +1837,7 @@ static void kvm_mce_inj_srao_memscrub2(CPUState *env, target_phys_addr_t paddr)
 
 #endif
 
-int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr)
+int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr)
 {
 #if defined(KVM_CAP_MCE)
     void *vaddr;
@@ -1887,7 +1887,7 @@ int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr)
     return 0;
 }
 
-int kvm_on_sigbus(int code, void *addr)
+int kvm_arch_on_sigbus(int code, void *addr)
 {
 #if defined(KVM_CAP_MCE)
     if ((first_cpu->mcg_cap & MCG_SER_P) && addr && code == BUS_MCEERR_AO) {
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 710eca1..93ecc57 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -404,3 +404,13 @@ bool kvm_arch_stop_on_emulation_error(CPUState *env)
 {
     return true;
 }
+
+int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr)
+{
+    return 1;
+}
+
+int kvm_arch_on_sigbus(int code, void *addr)
+{
+    return 1;
+}
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 38823f5..1702c46 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -505,3 +505,13 @@ bool kvm_arch_stop_on_emulation_error(CPUState *env)
 {
     return true;
 }
+
+int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr)
+{
+    return 1;
+}
+
+int kvm_arch_on_sigbus(int code, void *addr)
+{
+    return 1;
+}
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH 08/22] kvm: Provide sigbus services arch-independently
@ 2011-01-27 13:09   ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: Alexander Graf, Paolo Bonzini, qemu-devel, kvm, Huang Ying

Provide arch-independent kvm_on_sigbus* stubs to remove the #ifdef'ery
from cpus.c. This patch also fixes --disable-kvm build by providing the
missing kvm_on_sigbus_vcpu kvm-stub.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
CC: Huang Ying <ying.huang@intel.com>
CC: Alexander Graf <agraf@suse.de>
CC: Paolo Bonzini <pbonzini@redhat.com>
---
 cpus.c             |   10 ++++------
 kvm-all.c          |   10 ++++++++++
 kvm-stub.c         |    5 +++++
 kvm.h              |    7 +++++--
 target-i386/kvm.c  |    4 ++--
 target-ppc/kvm.c   |   10 ++++++++++
 target-s390x/kvm.c |   10 ++++++++++
 7 files changed, 46 insertions(+), 10 deletions(-)

diff --git a/cpus.c b/cpus.c
index f89826a..ce40e67 100644
--- a/cpus.c
+++ b/cpus.c
@@ -542,10 +542,9 @@ static void sigbus_reraise(void)
 static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
                            void *ctx)
 {
-#if defined(TARGET_I386)
-    if (kvm_on_sigbus(siginfo->ssi_code, (void *)(intptr_t)siginfo->ssi_addr))
-#endif
+    if (kvm_on_sigbus(siginfo->ssi_code, (void *)(intptr_t)siginfo->ssi_addr)) {
         sigbus_reraise();
+    }
 }
 
 static void qemu_kvm_eat_signal(CPUState *env, int timeout)
@@ -578,10 +577,9 @@ static void qemu_kvm_eat_signal(CPUState *env, int timeout)
 
         switch (r) {
         case SIGBUS:
-#ifdef TARGET_I386
-            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr))
-#endif
+            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {
                 sigbus_reraise();
+            }
             break;
         default:
             break;
diff --git a/kvm-all.c b/kvm-all.c
index 1a55a10..5bfa8c0 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1362,3 +1362,13 @@ int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, uint16_t val, bool assign)
     return -ENOSYS;
 #endif
 }
+
+int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr)
+{
+    return kvm_arch_on_sigbus_vcpu(env, code, addr);
+}
+
+int kvm_on_sigbus(int code, void *addr)
+{
+    return kvm_arch_on_sigbus(code, addr);
+}
diff --git a/kvm-stub.c b/kvm-stub.c
index 88682f2..d6b6c8e 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -147,6 +147,11 @@ int kvm_set_ioeventfd_mmio_long(int fd, uint32_t adr, uint32_t val, bool assign)
     return -ENOSYS;
 }
 
+int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr)
+{
+    return 1;
+}
+
 int kvm_on_sigbus(int code, void *addr)
 {
     return 1;
diff --git a/kvm.h b/kvm.h
index ca57517..b2fb5c6 100644
--- a/kvm.h
+++ b/kvm.h
@@ -81,6 +81,9 @@ int kvm_set_signal_mask(CPUState *env, const sigset_t *sigset);
 int kvm_pit_in_kernel(void);
 int kvm_irqchip_in_kernel(void);
 
+int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr);
+int kvm_on_sigbus(int code, void *addr);
+
 /* internal API */
 
 struct KVMState;
@@ -121,8 +124,8 @@ int kvm_arch_init_vcpu(CPUState *env);
 
 void kvm_arch_reset_vcpu(CPUState *env);
 
-int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr);
-int kvm_on_sigbus(int code, void *addr);
+int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr);
+int kvm_arch_on_sigbus(int code, void *addr);
 
 struct kvm_guest_debug;
 struct kvm_debug_exit_arch;
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 8e8880a..dd2cadc 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1837,7 +1837,7 @@ static void kvm_mce_inj_srao_memscrub2(CPUState *env, target_phys_addr_t paddr)
 
 #endif
 
-int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr)
+int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr)
 {
 #if defined(KVM_CAP_MCE)
     void *vaddr;
@@ -1887,7 +1887,7 @@ int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr)
     return 0;
 }
 
-int kvm_on_sigbus(int code, void *addr)
+int kvm_arch_on_sigbus(int code, void *addr)
 {
 #if defined(KVM_CAP_MCE)
     if ((first_cpu->mcg_cap & MCG_SER_P) && addr && code == BUS_MCEERR_AO) {
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 710eca1..93ecc57 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -404,3 +404,13 @@ bool kvm_arch_stop_on_emulation_error(CPUState *env)
 {
     return true;
 }
+
+int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr)
+{
+    return 1;
+}
+
+int kvm_arch_on_sigbus(int code, void *addr)
+{
+    return 1;
+}
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 38823f5..1702c46 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -505,3 +505,13 @@ bool kvm_arch_stop_on_emulation_error(CPUState *env)
 {
     return true;
 }
+
+int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr)
+{
+    return 1;
+}
+
+int kvm_arch_on_sigbus(int code, void *addr)
+{
+    return 1;
+}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 09/22] Refactor signal setup functions in cpus.c
  2011-01-27 13:09 ` [Qemu-devel] " Jan Kiszka
@ 2011-01-27 13:09   ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, qemu-devel

Move {tcg,kvm}_init_ipi and block_io_signals to avoid prototypes, rename
the former two to clarify that they deal with more than SIG_IPI. No
functional changes - except for the tiny fixup of strerror usage.

The forward declaration of sigbus_handler is just temporarily, it will
be moved in a succeeding patch. qemu_kvm_init_cpu_signals is moved into
the !_WIN32 block as we will soon need it also for !CONFIG_IOTHREAD.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpus.c |  162 +++++++++++++++++++++++++++++++++-------------------------------
 1 files changed, 83 insertions(+), 79 deletions(-)

diff --git a/cpus.c b/cpus.c
index ce40e67..16bd8fa 100644
--- a/cpus.c
+++ b/cpus.c
@@ -230,7 +230,35 @@ fail:
     close(fds[1]);
     return err;
 }
-#else
+
+#ifdef CONFIG_IOTHREAD
+static void dummy_signal(int sig)
+{
+}
+
+static void qemu_kvm_init_cpu_signals(CPUState *env)
+{
+    int r;
+    sigset_t set;
+    struct sigaction sigact;
+
+    memset(&sigact, 0, sizeof(sigact));
+    sigact.sa_handler = dummy_signal;
+    sigaction(SIG_IPI, &sigact, NULL);
+
+    pthread_sigmask(SIG_BLOCK, NULL, &set);
+    sigdelset(&set, SIG_IPI);
+    sigdelset(&set, SIGBUS);
+    r = kvm_set_signal_mask(env, &set);
+    if (r) {
+        fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
+        exit(1);
+    }
+}
+#endif
+
+#else /* _WIN32 */
+
 HANDLE qemu_event_handle;
 
 static void dummy_event_handler(void *opaque)
@@ -256,7 +284,7 @@ static void qemu_event_increment(void)
         exit (1);
     }
 }
-#endif
+#endif /* _WIN32 */
 
 #ifndef CONFIG_IOTHREAD
 int qemu_init_main_loop(void)
@@ -351,10 +379,6 @@ static QemuCond qemu_system_cond;
 static QemuCond qemu_pause_cond;
 static QemuCond qemu_work_cond;
 
-static void tcg_init_ipi(void);
-static void kvm_init_ipi(CPUState *env);
-static sigset_t block_io_signals(void);
-
 /* If we have signalfd, we mask out the signals we want to handle and then
  * use signalfd to listen for them.  We rely on whatever the current signal
  * handler is to dispatch the signals when we receive them.
@@ -390,6 +414,57 @@ static void sigfd_handler(void *opaque)
     }
 }
 
+static void cpu_signal(int sig)
+{
+    if (cpu_single_env) {
+        cpu_exit(cpu_single_env);
+    }
+    exit_request = 1;
+}
+
+static void qemu_tcg_init_cpu_signals(void)
+{
+    sigset_t set;
+    struct sigaction sigact;
+
+    memset(&sigact, 0, sizeof(sigact));
+    sigact.sa_handler = cpu_signal;
+    sigaction(SIG_IPI, &sigact, NULL);
+
+    sigemptyset(&set);
+    sigaddset(&set, SIG_IPI);
+    pthread_sigmask(SIG_UNBLOCK, &set, NULL);
+}
+
+static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
+                           void *ctx);
+
+static sigset_t block_io_signals(void)
+{
+    sigset_t set;
+    struct sigaction action;
+
+    /* SIGUSR2 used by posix-aio-compat.c */
+    sigemptyset(&set);
+    sigaddset(&set, SIGUSR2);
+    pthread_sigmask(SIG_UNBLOCK, &set, NULL);
+
+    sigemptyset(&set);
+    sigaddset(&set, SIGIO);
+    sigaddset(&set, SIGALRM);
+    sigaddset(&set, SIG_IPI);
+    sigaddset(&set, SIGBUS);
+    pthread_sigmask(SIG_BLOCK, &set, NULL);
+
+    memset(&action, 0, sizeof(action));
+    action.sa_flags = SA_SIGINFO;
+    action.sa_sigaction = (void (*)(int, siginfo_t*, void*))sigbus_handler;
+    sigaction(SIGBUS, &action, NULL);
+    prctl(PR_MCE_KILL, 1, 1, 0, 0);
+
+    return set;
+}
+
 static int qemu_signalfd_init(sigset_t mask)
 {
     int sigfd;
@@ -618,7 +693,7 @@ static void *kvm_cpu_thread_fn(void *arg)
         exit(1);
     }
 
-    kvm_init_ipi(env);
+    qemu_kvm_init_cpu_signals(env);
 
     /* signal CPU creation */
     env->created = 1;
@@ -641,7 +716,7 @@ static void *tcg_cpu_thread_fn(void *arg)
 {
     CPUState *env = arg;
 
-    tcg_init_ipi();
+    qemu_tcg_init_cpu_signals();
     qemu_thread_self(env->thread);
 
     /* signal CPU creation */
@@ -682,77 +757,6 @@ int qemu_cpu_self(void *_env)
     return qemu_thread_equal(&this, env->thread);
 }
 
-static void cpu_signal(int sig)
-{
-    if (cpu_single_env)
-        cpu_exit(cpu_single_env);
-    exit_request = 1;
-}
-
-static void tcg_init_ipi(void)
-{
-    sigset_t set;
-    struct sigaction sigact;
-
-    memset(&sigact, 0, sizeof(sigact));
-    sigact.sa_handler = cpu_signal;
-    sigaction(SIG_IPI, &sigact, NULL);
-
-    sigemptyset(&set);
-    sigaddset(&set, SIG_IPI);
-    pthread_sigmask(SIG_UNBLOCK, &set, NULL);
-}
-
-static void dummy_signal(int sig)
-{
-}
-
-static void kvm_init_ipi(CPUState *env)
-{
-    int r;
-    sigset_t set;
-    struct sigaction sigact;
-
-    memset(&sigact, 0, sizeof(sigact));
-    sigact.sa_handler = dummy_signal;
-    sigaction(SIG_IPI, &sigact, NULL);
-
-    pthread_sigmask(SIG_BLOCK, NULL, &set);
-    sigdelset(&set, SIG_IPI);
-    sigdelset(&set, SIGBUS);
-    r = kvm_set_signal_mask(env, &set);
-    if (r) {
-        fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(r));
-        exit(1);
-    }
-}
-
-static sigset_t block_io_signals(void)
-{
-    sigset_t set;
-    struct sigaction action;
-
-    /* SIGUSR2 used by posix-aio-compat.c */
-    sigemptyset(&set);
-    sigaddset(&set, SIGUSR2);
-    pthread_sigmask(SIG_UNBLOCK, &set, NULL);
-
-    sigemptyset(&set);
-    sigaddset(&set, SIGIO);
-    sigaddset(&set, SIGALRM);
-    sigaddset(&set, SIG_IPI);
-    sigaddset(&set, SIGBUS);
-    pthread_sigmask(SIG_BLOCK, &set, NULL);
-
-    memset(&action, 0, sizeof(action));
-    action.sa_flags = SA_SIGINFO;
-    action.sa_sigaction = (void (*)(int, siginfo_t*, void*))sigbus_handler;
-    sigaction(SIGBUS, &action, NULL);
-    prctl(PR_MCE_KILL, 1, 1, 0, 0);
-
-    return set;
-}
-
 void qemu_mutex_lock_iothread(void)
 {
     if (kvm_enabled()) {
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH 09/22] Refactor signal setup functions in cpus.c
@ 2011-01-27 13:09   ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm

Move {tcg,kvm}_init_ipi and block_io_signals to avoid prototypes, rename
the former two to clarify that they deal with more than SIG_IPI. No
functional changes - except for the tiny fixup of strerror usage.

The forward declaration of sigbus_handler is just temporarily, it will
be moved in a succeeding patch. qemu_kvm_init_cpu_signals is moved into
the !_WIN32 block as we will soon need it also for !CONFIG_IOTHREAD.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpus.c |  162 +++++++++++++++++++++++++++++++++-------------------------------
 1 files changed, 83 insertions(+), 79 deletions(-)

diff --git a/cpus.c b/cpus.c
index ce40e67..16bd8fa 100644
--- a/cpus.c
+++ b/cpus.c
@@ -230,7 +230,35 @@ fail:
     close(fds[1]);
     return err;
 }
-#else
+
+#ifdef CONFIG_IOTHREAD
+static void dummy_signal(int sig)
+{
+}
+
+static void qemu_kvm_init_cpu_signals(CPUState *env)
+{
+    int r;
+    sigset_t set;
+    struct sigaction sigact;
+
+    memset(&sigact, 0, sizeof(sigact));
+    sigact.sa_handler = dummy_signal;
+    sigaction(SIG_IPI, &sigact, NULL);
+
+    pthread_sigmask(SIG_BLOCK, NULL, &set);
+    sigdelset(&set, SIG_IPI);
+    sigdelset(&set, SIGBUS);
+    r = kvm_set_signal_mask(env, &set);
+    if (r) {
+        fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
+        exit(1);
+    }
+}
+#endif
+
+#else /* _WIN32 */
+
 HANDLE qemu_event_handle;
 
 static void dummy_event_handler(void *opaque)
@@ -256,7 +284,7 @@ static void qemu_event_increment(void)
         exit (1);
     }
 }
-#endif
+#endif /* _WIN32 */
 
 #ifndef CONFIG_IOTHREAD
 int qemu_init_main_loop(void)
@@ -351,10 +379,6 @@ static QemuCond qemu_system_cond;
 static QemuCond qemu_pause_cond;
 static QemuCond qemu_work_cond;
 
-static void tcg_init_ipi(void);
-static void kvm_init_ipi(CPUState *env);
-static sigset_t block_io_signals(void);
-
 /* If we have signalfd, we mask out the signals we want to handle and then
  * use signalfd to listen for them.  We rely on whatever the current signal
  * handler is to dispatch the signals when we receive them.
@@ -390,6 +414,57 @@ static void sigfd_handler(void *opaque)
     }
 }
 
+static void cpu_signal(int sig)
+{
+    if (cpu_single_env) {
+        cpu_exit(cpu_single_env);
+    }
+    exit_request = 1;
+}
+
+static void qemu_tcg_init_cpu_signals(void)
+{
+    sigset_t set;
+    struct sigaction sigact;
+
+    memset(&sigact, 0, sizeof(sigact));
+    sigact.sa_handler = cpu_signal;
+    sigaction(SIG_IPI, &sigact, NULL);
+
+    sigemptyset(&set);
+    sigaddset(&set, SIG_IPI);
+    pthread_sigmask(SIG_UNBLOCK, &set, NULL);
+}
+
+static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
+                           void *ctx);
+
+static sigset_t block_io_signals(void)
+{
+    sigset_t set;
+    struct sigaction action;
+
+    /* SIGUSR2 used by posix-aio-compat.c */
+    sigemptyset(&set);
+    sigaddset(&set, SIGUSR2);
+    pthread_sigmask(SIG_UNBLOCK, &set, NULL);
+
+    sigemptyset(&set);
+    sigaddset(&set, SIGIO);
+    sigaddset(&set, SIGALRM);
+    sigaddset(&set, SIG_IPI);
+    sigaddset(&set, SIGBUS);
+    pthread_sigmask(SIG_BLOCK, &set, NULL);
+
+    memset(&action, 0, sizeof(action));
+    action.sa_flags = SA_SIGINFO;
+    action.sa_sigaction = (void (*)(int, siginfo_t*, void*))sigbus_handler;
+    sigaction(SIGBUS, &action, NULL);
+    prctl(PR_MCE_KILL, 1, 1, 0, 0);
+
+    return set;
+}
+
 static int qemu_signalfd_init(sigset_t mask)
 {
     int sigfd;
@@ -618,7 +693,7 @@ static void *kvm_cpu_thread_fn(void *arg)
         exit(1);
     }
 
-    kvm_init_ipi(env);
+    qemu_kvm_init_cpu_signals(env);
 
     /* signal CPU creation */
     env->created = 1;
@@ -641,7 +716,7 @@ static void *tcg_cpu_thread_fn(void *arg)
 {
     CPUState *env = arg;
 
-    tcg_init_ipi();
+    qemu_tcg_init_cpu_signals();
     qemu_thread_self(env->thread);
 
     /* signal CPU creation */
@@ -682,77 +757,6 @@ int qemu_cpu_self(void *_env)
     return qemu_thread_equal(&this, env->thread);
 }
 
-static void cpu_signal(int sig)
-{
-    if (cpu_single_env)
-        cpu_exit(cpu_single_env);
-    exit_request = 1;
-}
-
-static void tcg_init_ipi(void)
-{
-    sigset_t set;
-    struct sigaction sigact;
-
-    memset(&sigact, 0, sizeof(sigact));
-    sigact.sa_handler = cpu_signal;
-    sigaction(SIG_IPI, &sigact, NULL);
-
-    sigemptyset(&set);
-    sigaddset(&set, SIG_IPI);
-    pthread_sigmask(SIG_UNBLOCK, &set, NULL);
-}
-
-static void dummy_signal(int sig)
-{
-}
-
-static void kvm_init_ipi(CPUState *env)
-{
-    int r;
-    sigset_t set;
-    struct sigaction sigact;
-
-    memset(&sigact, 0, sizeof(sigact));
-    sigact.sa_handler = dummy_signal;
-    sigaction(SIG_IPI, &sigact, NULL);
-
-    pthread_sigmask(SIG_BLOCK, NULL, &set);
-    sigdelset(&set, SIG_IPI);
-    sigdelset(&set, SIGBUS);
-    r = kvm_set_signal_mask(env, &set);
-    if (r) {
-        fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(r));
-        exit(1);
-    }
-}
-
-static sigset_t block_io_signals(void)
-{
-    sigset_t set;
-    struct sigaction action;
-
-    /* SIGUSR2 used by posix-aio-compat.c */
-    sigemptyset(&set);
-    sigaddset(&set, SIGUSR2);
-    pthread_sigmask(SIG_UNBLOCK, &set, NULL);
-
-    sigemptyset(&set);
-    sigaddset(&set, SIGIO);
-    sigaddset(&set, SIGALRM);
-    sigaddset(&set, SIG_IPI);
-    sigaddset(&set, SIGBUS);
-    pthread_sigmask(SIG_BLOCK, &set, NULL);
-
-    memset(&action, 0, sizeof(action));
-    action.sa_flags = SA_SIGINFO;
-    action.sa_sigaction = (void (*)(int, siginfo_t*, void*))sigbus_handler;
-    sigaction(SIGBUS, &action, NULL);
-    prctl(PR_MCE_KILL, 1, 1, 0, 0);
-
-    return set;
-}
-
 void qemu_mutex_lock_iothread(void)
 {
     if (kvm_enabled()) {
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 10/22] kvm: Set up signal mask also for !CONFIG_IOTHREAD
  2011-01-27 13:09 ` [Qemu-devel] " Jan Kiszka
@ 2011-01-27 13:09   ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, qemu-devel

Block SIG_IPI, unblock it during KVM_RUN, just like in io-thread mode.
It's unused so far, but this infrastructure will be required for
self-IPIs and to process SIGBUS plus, in KVM mode, SIGIO and SIGALRM. As
Windows doesn't support signal services, we need to provide a stub for
the init function.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpus.c |   13 +++++++++++--
 1 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/cpus.c b/cpus.c
index 16bd8fa..03c89b4 100644
--- a/cpus.c
+++ b/cpus.c
@@ -231,7 +231,6 @@ fail:
     return err;
 }
 
-#ifdef CONFIG_IOTHREAD
 static void dummy_signal(int sig)
 {
 }
@@ -246,6 +245,12 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
     sigact.sa_handler = dummy_signal;
     sigaction(SIG_IPI, &sigact, NULL);
 
+#ifndef CONFIG_IOTHREAD
+    sigemptyset(&set);
+    sigaddset(&set, SIG_IPI);
+    pthread_sigmask(SIG_BLOCK, &set, NULL);
+#endif
+
     pthread_sigmask(SIG_BLOCK, NULL, &set);
     sigdelset(&set, SIG_IPI);
     sigdelset(&set, SIGBUS);
@@ -255,7 +260,6 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
         exit(1);
     }
 }
-#endif
 
 #else /* _WIN32 */
 
@@ -284,6 +288,10 @@ static void qemu_event_increment(void)
         exit (1);
     }
 }
+
+static void qemu_kvm_init_cpu_signals(CPUState *env)
+{
+}
 #endif /* _WIN32 */
 
 #ifndef CONFIG_IOTHREAD
@@ -312,6 +320,7 @@ void qemu_init_vcpu(void *_env)
             fprintf(stderr, "kvm_init_vcpu failed: %s\n", strerror(-r));
             exit(1);
         }
+        qemu_kvm_init_cpu_signals(env);
     }
 }
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH 10/22] kvm: Set up signal mask also for !CONFIG_IOTHREAD
@ 2011-01-27 13:09   ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm

Block SIG_IPI, unblock it during KVM_RUN, just like in io-thread mode.
It's unused so far, but this infrastructure will be required for
self-IPIs and to process SIGBUS plus, in KVM mode, SIGIO and SIGALRM. As
Windows doesn't support signal services, we need to provide a stub for
the init function.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpus.c |   13 +++++++++++--
 1 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/cpus.c b/cpus.c
index 16bd8fa..03c89b4 100644
--- a/cpus.c
+++ b/cpus.c
@@ -231,7 +231,6 @@ fail:
     return err;
 }
 
-#ifdef CONFIG_IOTHREAD
 static void dummy_signal(int sig)
 {
 }
@@ -246,6 +245,12 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
     sigact.sa_handler = dummy_signal;
     sigaction(SIG_IPI, &sigact, NULL);
 
+#ifndef CONFIG_IOTHREAD
+    sigemptyset(&set);
+    sigaddset(&set, SIG_IPI);
+    pthread_sigmask(SIG_BLOCK, &set, NULL);
+#endif
+
     pthread_sigmask(SIG_BLOCK, NULL, &set);
     sigdelset(&set, SIG_IPI);
     sigdelset(&set, SIGBUS);
@@ -255,7 +260,6 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
         exit(1);
     }
 }
-#endif
 
 #else /* _WIN32 */
 
@@ -284,6 +288,10 @@ static void qemu_event_increment(void)
         exit (1);
     }
 }
+
+static void qemu_kvm_init_cpu_signals(CPUState *env)
+{
+}
 #endif /* _WIN32 */
 
 #ifndef CONFIG_IOTHREAD
@@ -312,6 +320,7 @@ void qemu_init_vcpu(void *_env)
             fprintf(stderr, "kvm_init_vcpu failed: %s\n", strerror(-r));
             exit(1);
         }
+        qemu_kvm_init_cpu_signals(env);
     }
 }
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 11/22] kvm: Refactor qemu_kvm_eat_signals
  2011-01-27 13:09 ` [Qemu-devel] " Jan Kiszka
@ 2011-01-27 13:09   ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, qemu-devel

We do not use the timeout, so drop its logic. As we always poll our
signals, we do not need to drop the global lock. Removing those calls
allows some further simplifications. Also fix the error processing of
sigpending at this chance.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
---
 cpus.c |   23 +++++++----------------
 1 files changed, 7 insertions(+), 16 deletions(-)

diff --git a/cpus.c b/cpus.c
index 03c89b4..9071848 100644
--- a/cpus.c
+++ b/cpus.c
@@ -631,31 +631,22 @@ static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
     }
 }
 
-static void qemu_kvm_eat_signal(CPUState *env, int timeout)
+static void qemu_kvm_eat_signals(CPUState *env)
 {
-    struct timespec ts;
-    int r, e;
+    struct timespec ts = { 0, 0 };
     siginfo_t siginfo;
     sigset_t waitset;
     sigset_t chkset;
-
-    ts.tv_sec = timeout / 1000;
-    ts.tv_nsec = (timeout % 1000) * 1000000;
+    int r;
 
     sigemptyset(&waitset);
     sigaddset(&waitset, SIG_IPI);
     sigaddset(&waitset, SIGBUS);
 
     do {
-        qemu_mutex_unlock(&qemu_global_mutex);
-
         r = sigtimedwait(&waitset, &siginfo, &ts);
-        e = errno;
-
-        qemu_mutex_lock(&qemu_global_mutex);
-
-        if (r == -1 && !(e == EAGAIN || e == EINTR)) {
-            fprintf(stderr, "sigtimedwait: %s\n", strerror(e));
+        if (r == -1 && !(errno == EAGAIN || errno == EINTR)) {
+            perror("sigtimedwait");
             exit(1);
         }
 
@@ -671,7 +662,7 @@ static void qemu_kvm_eat_signal(CPUState *env, int timeout)
 
         r = sigpending(&chkset);
         if (r == -1) {
-            fprintf(stderr, "sigpending: %s\n", strerror(e));
+            perror("sigpending");
             exit(1);
         }
     } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
@@ -682,7 +673,7 @@ static void qemu_kvm_wait_io_event(CPUState *env)
     while (!cpu_has_work(env))
         qemu_cond_timedwait(env->halt_cond, &qemu_global_mutex, 1000);
 
-    qemu_kvm_eat_signal(env, 0);
+    qemu_kvm_eat_signals(env);
     qemu_wait_io_event_common(env);
 }
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH 11/22] kvm: Refactor qemu_kvm_eat_signals
@ 2011-01-27 13:09   ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm

We do not use the timeout, so drop its logic. As we always poll our
signals, we do not need to drop the global lock. Removing those calls
allows some further simplifications. Also fix the error processing of
sigpending at this chance.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
---
 cpus.c |   23 +++++++----------------
 1 files changed, 7 insertions(+), 16 deletions(-)

diff --git a/cpus.c b/cpus.c
index 03c89b4..9071848 100644
--- a/cpus.c
+++ b/cpus.c
@@ -631,31 +631,22 @@ static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
     }
 }
 
-static void qemu_kvm_eat_signal(CPUState *env, int timeout)
+static void qemu_kvm_eat_signals(CPUState *env)
 {
-    struct timespec ts;
-    int r, e;
+    struct timespec ts = { 0, 0 };
     siginfo_t siginfo;
     sigset_t waitset;
     sigset_t chkset;
-
-    ts.tv_sec = timeout / 1000;
-    ts.tv_nsec = (timeout % 1000) * 1000000;
+    int r;
 
     sigemptyset(&waitset);
     sigaddset(&waitset, SIG_IPI);
     sigaddset(&waitset, SIGBUS);
 
     do {
-        qemu_mutex_unlock(&qemu_global_mutex);
-
         r = sigtimedwait(&waitset, &siginfo, &ts);
-        e = errno;
-
-        qemu_mutex_lock(&qemu_global_mutex);
-
-        if (r == -1 && !(e == EAGAIN || e == EINTR)) {
-            fprintf(stderr, "sigtimedwait: %s\n", strerror(e));
+        if (r == -1 && !(errno == EAGAIN || errno == EINTR)) {
+            perror("sigtimedwait");
             exit(1);
         }
 
@@ -671,7 +662,7 @@ static void qemu_kvm_eat_signal(CPUState *env, int timeout)
 
         r = sigpending(&chkset);
         if (r == -1) {
-            fprintf(stderr, "sigpending: %s\n", strerror(e));
+            perror("sigpending");
             exit(1);
         }
     } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
@@ -682,7 +673,7 @@ static void qemu_kvm_wait_io_event(CPUState *env)
     while (!cpu_has_work(env))
         qemu_cond_timedwait(env->halt_cond, &qemu_global_mutex, 1000);
 
-    qemu_kvm_eat_signal(env, 0);
+    qemu_kvm_eat_signals(env);
     qemu_wait_io_event_common(env);
 }
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 12/22] kvm: Call qemu_kvm_eat_signals also under !CONFIG_IOTHREAD
  2011-01-27 13:09 ` [Qemu-devel] " Jan Kiszka
@ 2011-01-27 13:09   ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, qemu-devel

Move qemu_kvm_eat_signals around and call it also when the IO-thread is
not used. Do not yet process SIGBUS, will be armed in a separate step.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpus.c |   88 ++++++++++++++++++++++++++++++++++++---------------------------
 1 files changed, 50 insertions(+), 38 deletions(-)

diff --git a/cpus.c b/cpus.c
index 9071848..558c0d3 100644
--- a/cpus.c
+++ b/cpus.c
@@ -261,6 +261,45 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
     }
 }
 
+static void qemu_kvm_eat_signals(CPUState *env)
+{
+    struct timespec ts = { 0, 0 };
+    siginfo_t siginfo;
+    sigset_t waitset;
+    sigset_t chkset;
+    int r;
+
+    sigemptyset(&waitset);
+    sigaddset(&waitset, SIG_IPI);
+    sigaddset(&waitset, SIGBUS);
+
+    do {
+        r = sigtimedwait(&waitset, &siginfo, &ts);
+        if (r == -1 && !(errno == EAGAIN || errno == EINTR)) {
+            perror("sigtimedwait");
+            exit(1);
+        }
+
+        switch (r) {
+#ifdef CONFIG_IOTHREAD
+        case SIGBUS:
+            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {
+                sigbus_reraise();
+            }
+            break;
+#endif
+        default:
+            break;
+        }
+
+        r = sigpending(&chkset);
+        if (r == -1) {
+            perror("sigpending");
+            exit(1);
+        }
+    } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
+}
+
 #else /* _WIN32 */
 
 HANDLE qemu_event_handle;
@@ -292,6 +331,10 @@ static void qemu_event_increment(void)
 static void qemu_kvm_init_cpu_signals(CPUState *env)
 {
 }
+
+static void qemu_kvm_eat_signals(CPUState *env)
+{
+}
 #endif /* _WIN32 */
 
 #ifndef CONFIG_IOTHREAD
@@ -631,43 +674,6 @@ static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
     }
 }
 
-static void qemu_kvm_eat_signals(CPUState *env)
-{
-    struct timespec ts = { 0, 0 };
-    siginfo_t siginfo;
-    sigset_t waitset;
-    sigset_t chkset;
-    int r;
-
-    sigemptyset(&waitset);
-    sigaddset(&waitset, SIG_IPI);
-    sigaddset(&waitset, SIGBUS);
-
-    do {
-        r = sigtimedwait(&waitset, &siginfo, &ts);
-        if (r == -1 && !(errno == EAGAIN || errno == EINTR)) {
-            perror("sigtimedwait");
-            exit(1);
-        }
-
-        switch (r) {
-        case SIGBUS:
-            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {
-                sigbus_reraise();
-            }
-            break;
-        default:
-            break;
-        }
-
-        r = sigpending(&chkset);
-        if (r == -1) {
-            perror("sigpending");
-            exit(1);
-        }
-    } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
-}
-
 static void qemu_kvm_wait_io_event(CPUState *env)
 {
     while (!cpu_has_work(env))
@@ -932,6 +938,8 @@ static int qemu_cpu_exec(CPUState *env)
 
 bool cpu_exec_all(void)
 {
+    int r;
+
     if (next_cpu == NULL)
         next_cpu = first_cpu;
     for (; next_cpu != NULL && !exit_request; next_cpu = next_cpu->next_cpu) {
@@ -943,7 +951,11 @@ bool cpu_exec_all(void)
         if (qemu_alarm_pending())
             break;
         if (cpu_can_run(env)) {
-            if (qemu_cpu_exec(env) == EXCP_DEBUG) {
+            r = qemu_cpu_exec(env);
+            if (kvm_enabled()) {
+                qemu_kvm_eat_signals(env);
+            }
+            if (r == EXCP_DEBUG) {
                 break;
             }
         } else if (env->stop) {
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH 12/22] kvm: Call qemu_kvm_eat_signals also under !CONFIG_IOTHREAD
@ 2011-01-27 13:09   ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm

Move qemu_kvm_eat_signals around and call it also when the IO-thread is
not used. Do not yet process SIGBUS, will be armed in a separate step.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpus.c |   88 ++++++++++++++++++++++++++++++++++++---------------------------
 1 files changed, 50 insertions(+), 38 deletions(-)

diff --git a/cpus.c b/cpus.c
index 9071848..558c0d3 100644
--- a/cpus.c
+++ b/cpus.c
@@ -261,6 +261,45 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
     }
 }
 
+static void qemu_kvm_eat_signals(CPUState *env)
+{
+    struct timespec ts = { 0, 0 };
+    siginfo_t siginfo;
+    sigset_t waitset;
+    sigset_t chkset;
+    int r;
+
+    sigemptyset(&waitset);
+    sigaddset(&waitset, SIG_IPI);
+    sigaddset(&waitset, SIGBUS);
+
+    do {
+        r = sigtimedwait(&waitset, &siginfo, &ts);
+        if (r == -1 && !(errno == EAGAIN || errno == EINTR)) {
+            perror("sigtimedwait");
+            exit(1);
+        }
+
+        switch (r) {
+#ifdef CONFIG_IOTHREAD
+        case SIGBUS:
+            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {
+                sigbus_reraise();
+            }
+            break;
+#endif
+        default:
+            break;
+        }
+
+        r = sigpending(&chkset);
+        if (r == -1) {
+            perror("sigpending");
+            exit(1);
+        }
+    } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
+}
+
 #else /* _WIN32 */
 
 HANDLE qemu_event_handle;
@@ -292,6 +331,10 @@ static void qemu_event_increment(void)
 static void qemu_kvm_init_cpu_signals(CPUState *env)
 {
 }
+
+static void qemu_kvm_eat_signals(CPUState *env)
+{
+}
 #endif /* _WIN32 */
 
 #ifndef CONFIG_IOTHREAD
@@ -631,43 +674,6 @@ static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
     }
 }
 
-static void qemu_kvm_eat_signals(CPUState *env)
-{
-    struct timespec ts = { 0, 0 };
-    siginfo_t siginfo;
-    sigset_t waitset;
-    sigset_t chkset;
-    int r;
-
-    sigemptyset(&waitset);
-    sigaddset(&waitset, SIG_IPI);
-    sigaddset(&waitset, SIGBUS);
-
-    do {
-        r = sigtimedwait(&waitset, &siginfo, &ts);
-        if (r == -1 && !(errno == EAGAIN || errno == EINTR)) {
-            perror("sigtimedwait");
-            exit(1);
-        }
-
-        switch (r) {
-        case SIGBUS:
-            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {
-                sigbus_reraise();
-            }
-            break;
-        default:
-            break;
-        }
-
-        r = sigpending(&chkset);
-        if (r == -1) {
-            perror("sigpending");
-            exit(1);
-        }
-    } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
-}
-
 static void qemu_kvm_wait_io_event(CPUState *env)
 {
     while (!cpu_has_work(env))
@@ -932,6 +938,8 @@ static int qemu_cpu_exec(CPUState *env)
 
 bool cpu_exec_all(void)
 {
+    int r;
+
     if (next_cpu == NULL)
         next_cpu = first_cpu;
     for (; next_cpu != NULL && !exit_request; next_cpu = next_cpu->next_cpu) {
@@ -943,7 +951,11 @@ bool cpu_exec_all(void)
         if (qemu_alarm_pending())
             break;
         if (cpu_can_run(env)) {
-            if (qemu_cpu_exec(env) == EXCP_DEBUG) {
+            r = qemu_cpu_exec(env);
+            if (kvm_enabled()) {
+                qemu_kvm_eat_signals(env);
+            }
+            if (r == EXCP_DEBUG) {
                 break;
             }
         } else if (env->stop) {
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 13/22] Set up signalfd under !CONFIG_IOTHREAD
  2011-01-27 13:09 ` [Qemu-devel] " Jan Kiszka
@ 2011-01-27 13:09   ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, qemu-devel

Will be required for SIGBUS handling. For obvious reasons, this will
remain a nop on Windows hosts.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 Makefile.objs |    2 +-
 cpus.c        |  117 +++++++++++++++++++++++++++++++--------------------------
 2 files changed, 65 insertions(+), 54 deletions(-)

diff --git a/Makefile.objs b/Makefile.objs
index c3e52c5..81b9a5b 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -141,7 +141,7 @@ common-obj-y += $(addprefix ui/, $(ui-obj-y))
 
 common-obj-y += iov.o acl.o
 common-obj-$(CONFIG_THREAD) += qemu-thread.o
-common-obj-$(CONFIG_IOTHREAD) += compatfd.o
+common-obj-$(CONFIG_POSIX) += compatfd.o
 common-obj-y += notify.o event_notifier.o
 common-obj-y += qemu-timer.o qemu-timer-common.o
 
diff --git a/cpus.c b/cpus.c
index 558c0d3..fc3f222 100644
--- a/cpus.c
+++ b/cpus.c
@@ -261,6 +261,59 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
     }
 }
 
+/* If we have signalfd, we mask out the signals we want to handle and then
+ * use signalfd to listen for them.  We rely on whatever the current signal
+ * handler is to dispatch the signals when we receive them.
+ */
+static void sigfd_handler(void *opaque)
+{
+    int fd = (unsigned long) opaque;
+    struct qemu_signalfd_siginfo info;
+    struct sigaction action;
+    ssize_t len;
+
+    while (1) {
+        do {
+            len = read(fd, &info, sizeof(info));
+        } while (len == -1 && errno == EINTR);
+
+        if (len == -1 && errno == EAGAIN) {
+            break;
+        }
+
+        if (len != sizeof(info)) {
+            printf("read from sigfd returned %zd: %m\n", len);
+            return;
+        }
+
+        sigaction(info.ssi_signo, NULL, &action);
+        if ((action.sa_flags & SA_SIGINFO) && action.sa_sigaction) {
+            action.sa_sigaction(info.ssi_signo,
+                                (siginfo_t *)&info, NULL);
+        } else if (action.sa_handler) {
+            action.sa_handler(info.ssi_signo);
+        }
+    }
+}
+
+static int qemu_signalfd_init(sigset_t mask)
+{
+    int sigfd;
+
+    sigfd = qemu_signalfd(&mask);
+    if (sigfd == -1) {
+        fprintf(stderr, "failed to create signalfd\n");
+        return -errno;
+    }
+
+    fcntl_setfl(sigfd, O_NONBLOCK);
+
+    qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL,
+                         (void *)(unsigned long) sigfd);
+
+    return 0;
+}
+
 static void qemu_kvm_eat_signals(CPUState *env)
 {
     struct timespec ts = { 0, 0 };
@@ -340,6 +393,17 @@ static void qemu_kvm_eat_signals(CPUState *env)
 #ifndef CONFIG_IOTHREAD
 int qemu_init_main_loop(void)
 {
+#ifndef _WIN32
+    sigset_t blocked_signals;
+    int ret;
+
+    sigemptyset(&blocked_signals);
+
+    ret = qemu_signalfd_init(blocked_signals);
+    if (ret) {
+        return ret;
+    }
+#endif
     cpu_set_debug_excp_handler(cpu_debug_handler);
 
     return qemu_event_init();
@@ -431,41 +495,6 @@ static QemuCond qemu_system_cond;
 static QemuCond qemu_pause_cond;
 static QemuCond qemu_work_cond;
 
-/* If we have signalfd, we mask out the signals we want to handle and then
- * use signalfd to listen for them.  We rely on whatever the current signal
- * handler is to dispatch the signals when we receive them.
- */
-static void sigfd_handler(void *opaque)
-{
-    int fd = (unsigned long) opaque;
-    struct qemu_signalfd_siginfo info;
-    struct sigaction action;
-    ssize_t len;
-
-    while (1) {
-        do {
-            len = read(fd, &info, sizeof(info));
-        } while (len == -1 && errno == EINTR);
-
-        if (len == -1 && errno == EAGAIN) {
-            break;
-        }
-
-        if (len != sizeof(info)) {
-            printf("read from sigfd returned %zd: %m\n", len);
-            return;
-        }
-
-        sigaction(info.ssi_signo, NULL, &action);
-        if ((action.sa_flags & SA_SIGINFO) && action.sa_sigaction) {
-            action.sa_sigaction(info.ssi_signo,
-                                (siginfo_t *)&info, NULL);
-        } else if (action.sa_handler) {
-            action.sa_handler(info.ssi_signo);
-        }
-    }
-}
-
 static void cpu_signal(int sig)
 {
     if (cpu_single_env) {
@@ -517,24 +546,6 @@ static sigset_t block_io_signals(void)
     return set;
 }
 
-static int qemu_signalfd_init(sigset_t mask)
-{
-    int sigfd;
-
-    sigfd = qemu_signalfd(&mask);
-    if (sigfd == -1) {
-        fprintf(stderr, "failed to create signalfd\n");
-        return -errno;
-    }
-
-    fcntl_setfl(sigfd, O_NONBLOCK);
-
-    qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL,
-                         (void *)(unsigned long) sigfd);
-
-    return 0;
-}
-
 int qemu_init_main_loop(void)
 {
     int ret;
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH 13/22] Set up signalfd under !CONFIG_IOTHREAD
@ 2011-01-27 13:09   ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm

Will be required for SIGBUS handling. For obvious reasons, this will
remain a nop on Windows hosts.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 Makefile.objs |    2 +-
 cpus.c        |  117 +++++++++++++++++++++++++++++++--------------------------
 2 files changed, 65 insertions(+), 54 deletions(-)

diff --git a/Makefile.objs b/Makefile.objs
index c3e52c5..81b9a5b 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -141,7 +141,7 @@ common-obj-y += $(addprefix ui/, $(ui-obj-y))
 
 common-obj-y += iov.o acl.o
 common-obj-$(CONFIG_THREAD) += qemu-thread.o
-common-obj-$(CONFIG_IOTHREAD) += compatfd.o
+common-obj-$(CONFIG_POSIX) += compatfd.o
 common-obj-y += notify.o event_notifier.o
 common-obj-y += qemu-timer.o qemu-timer-common.o
 
diff --git a/cpus.c b/cpus.c
index 558c0d3..fc3f222 100644
--- a/cpus.c
+++ b/cpus.c
@@ -261,6 +261,59 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
     }
 }
 
+/* If we have signalfd, we mask out the signals we want to handle and then
+ * use signalfd to listen for them.  We rely on whatever the current signal
+ * handler is to dispatch the signals when we receive them.
+ */
+static void sigfd_handler(void *opaque)
+{
+    int fd = (unsigned long) opaque;
+    struct qemu_signalfd_siginfo info;
+    struct sigaction action;
+    ssize_t len;
+
+    while (1) {
+        do {
+            len = read(fd, &info, sizeof(info));
+        } while (len == -1 && errno == EINTR);
+
+        if (len == -1 && errno == EAGAIN) {
+            break;
+        }
+
+        if (len != sizeof(info)) {
+            printf("read from sigfd returned %zd: %m\n", len);
+            return;
+        }
+
+        sigaction(info.ssi_signo, NULL, &action);
+        if ((action.sa_flags & SA_SIGINFO) && action.sa_sigaction) {
+            action.sa_sigaction(info.ssi_signo,
+                                (siginfo_t *)&info, NULL);
+        } else if (action.sa_handler) {
+            action.sa_handler(info.ssi_signo);
+        }
+    }
+}
+
+static int qemu_signalfd_init(sigset_t mask)
+{
+    int sigfd;
+
+    sigfd = qemu_signalfd(&mask);
+    if (sigfd == -1) {
+        fprintf(stderr, "failed to create signalfd\n");
+        return -errno;
+    }
+
+    fcntl_setfl(sigfd, O_NONBLOCK);
+
+    qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL,
+                         (void *)(unsigned long) sigfd);
+
+    return 0;
+}
+
 static void qemu_kvm_eat_signals(CPUState *env)
 {
     struct timespec ts = { 0, 0 };
@@ -340,6 +393,17 @@ static void qemu_kvm_eat_signals(CPUState *env)
 #ifndef CONFIG_IOTHREAD
 int qemu_init_main_loop(void)
 {
+#ifndef _WIN32
+    sigset_t blocked_signals;
+    int ret;
+
+    sigemptyset(&blocked_signals);
+
+    ret = qemu_signalfd_init(blocked_signals);
+    if (ret) {
+        return ret;
+    }
+#endif
     cpu_set_debug_excp_handler(cpu_debug_handler);
 
     return qemu_event_init();
@@ -431,41 +495,6 @@ static QemuCond qemu_system_cond;
 static QemuCond qemu_pause_cond;
 static QemuCond qemu_work_cond;
 
-/* If we have signalfd, we mask out the signals we want to handle and then
- * use signalfd to listen for them.  We rely on whatever the current signal
- * handler is to dispatch the signals when we receive them.
- */
-static void sigfd_handler(void *opaque)
-{
-    int fd = (unsigned long) opaque;
-    struct qemu_signalfd_siginfo info;
-    struct sigaction action;
-    ssize_t len;
-
-    while (1) {
-        do {
-            len = read(fd, &info, sizeof(info));
-        } while (len == -1 && errno == EINTR);
-
-        if (len == -1 && errno == EAGAIN) {
-            break;
-        }
-
-        if (len != sizeof(info)) {
-            printf("read from sigfd returned %zd: %m\n", len);
-            return;
-        }
-
-        sigaction(info.ssi_signo, NULL, &action);
-        if ((action.sa_flags & SA_SIGINFO) && action.sa_sigaction) {
-            action.sa_sigaction(info.ssi_signo,
-                                (siginfo_t *)&info, NULL);
-        } else if (action.sa_handler) {
-            action.sa_handler(info.ssi_signo);
-        }
-    }
-}
-
 static void cpu_signal(int sig)
 {
     if (cpu_single_env) {
@@ -517,24 +546,6 @@ static sigset_t block_io_signals(void)
     return set;
 }
 
-static int qemu_signalfd_init(sigset_t mask)
-{
-    int sigfd;
-
-    sigfd = qemu_signalfd(&mask);
-    if (sigfd == -1) {
-        fprintf(stderr, "failed to create signalfd\n");
-        return -errno;
-    }
-
-    fcntl_setfl(sigfd, O_NONBLOCK);
-
-    qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL,
-                         (void *)(unsigned long) sigfd);
-
-    return 0;
-}
-
 int qemu_init_main_loop(void)
 {
     int ret;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
  2011-01-27 13:09 ` [Qemu-devel] " Jan Kiszka
@ 2011-01-27 13:09   ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, qemu-devel, Stefan Hajnoczi

Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
checking for exit_request on vcpu entry and timer signals arriving
before KVM starts to catch them. Plug it by blocking both timer related
signals also on !CONFIG_IOTHREAD and process those via signalfd.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
CC: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 cpus.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/cpus.c b/cpus.c
index fc3f222..29b1070 100644
--- a/cpus.c
+++ b/cpus.c
@@ -254,6 +254,10 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
     pthread_sigmask(SIG_BLOCK, NULL, &set);
     sigdelset(&set, SIG_IPI);
     sigdelset(&set, SIGBUS);
+#ifndef CONFIG_IOTHREAD
+    sigdelset(&set, SIGIO);
+    sigdelset(&set, SIGALRM);
+#endif
     r = kvm_set_signal_mask(env, &set);
     if (r) {
         fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
@@ -351,6 +355,12 @@ static void qemu_kvm_eat_signals(CPUState *env)
             exit(1);
         }
     } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
+
+#ifndef CONFIG_IOTHREAD
+    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
+        qemu_notify_event();
+    }
+#endif
 }
 
 #else /* _WIN32 */
@@ -398,6 +408,14 @@ int qemu_init_main_loop(void)
     int ret;
 
     sigemptyset(&blocked_signals);
+    if (kvm_enabled()) {
+        /*
+         * We need to process timer signals synchronously to avoid a race
+         * between exit_request check and KVM vcpu entry.
+         */
+        sigaddset(&blocked_signals, SIGIO);
+        sigaddset(&blocked_signals, SIGALRM);
+    }
 
     ret = qemu_signalfd_init(blocked_signals);
     if (ret) {
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
@ 2011-01-27 13:09   ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm, Stefan Hajnoczi

Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
checking for exit_request on vcpu entry and timer signals arriving
before KVM starts to catch them. Plug it by blocking both timer related
signals also on !CONFIG_IOTHREAD and process those via signalfd.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
CC: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 cpus.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/cpus.c b/cpus.c
index fc3f222..29b1070 100644
--- a/cpus.c
+++ b/cpus.c
@@ -254,6 +254,10 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
     pthread_sigmask(SIG_BLOCK, NULL, &set);
     sigdelset(&set, SIG_IPI);
     sigdelset(&set, SIGBUS);
+#ifndef CONFIG_IOTHREAD
+    sigdelset(&set, SIGIO);
+    sigdelset(&set, SIGALRM);
+#endif
     r = kvm_set_signal_mask(env, &set);
     if (r) {
         fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
@@ -351,6 +355,12 @@ static void qemu_kvm_eat_signals(CPUState *env)
             exit(1);
         }
     } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
+
+#ifndef CONFIG_IOTHREAD
+    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
+        qemu_notify_event();
+    }
+#endif
 }
 
 #else /* _WIN32 */
@@ -398,6 +408,14 @@ int qemu_init_main_loop(void)
     int ret;
 
     sigemptyset(&blocked_signals);
+    if (kvm_enabled()) {
+        /*
+         * We need to process timer signals synchronously to avoid a race
+         * between exit_request check and KVM vcpu entry.
+         */
+        sigaddset(&blocked_signals, SIGIO);
+        sigaddset(&blocked_signals, SIGALRM);
+    }
 
     ret = qemu_signalfd_init(blocked_signals);
     if (ret) {
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 15/22] kvm: Add MCE signal support for !CONFIG_IOTHREAD
  2011-01-27 13:09 ` [Qemu-devel] " Jan Kiszka
@ 2011-01-27 13:09   ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: kvm, qemu-devel, Huang Ying, Hidetoshi Seto, Jin Dongming

Currently, we only configure and process MCE-related SIGBUS events if
CONFIG_IOTHREAD is enabled. The groundwork is laid, we just need to
factor out the required handler registration and system configuration.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
CC: Huang Ying <ying.huang@intel.com>
CC: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
CC: Jin Dongming <jin.dongming@np.css.fujitsu.com>
---
 cpus.c |  106 ++++++++++++++++++++++++++++++++++++++++------------------------
 1 files changed, 66 insertions(+), 40 deletions(-)

diff --git a/cpus.c b/cpus.c
index 29b1070..bba59e5 100644
--- a/cpus.c
+++ b/cpus.c
@@ -34,9 +34,6 @@
 
 #include "cpus.h"
 #include "compatfd.h"
-#ifdef CONFIG_LINUX
-#include <sys/prctl.h>
-#endif
 
 #ifdef SIGRTMIN
 #define SIG_IPI (SIGRTMIN+4)
@@ -44,10 +41,24 @@
 #define SIG_IPI SIGUSR1
 #endif
 
+#ifdef CONFIG_LINUX
+
+#include <sys/prctl.h>
+
 #ifndef PR_MCE_KILL
 #define PR_MCE_KILL 33
 #endif
 
+#ifndef PR_MCE_KILL_SET
+#define PR_MCE_KILL_SET 1
+#endif
+
+#ifndef PR_MCE_KILL_EARLY
+#define PR_MCE_KILL_EARLY 1
+#endif
+
+#endif /* CONFIG_LINUX */
+
 static CPUState *next_cpu;
 
 /***********************************************************/
@@ -166,6 +177,52 @@ static void cpu_debug_handler(CPUState *env)
     vm_stop(EXCP_DEBUG);
 }
 
+#ifdef CONFIG_LINUX
+static void sigbus_reraise(void)
+{
+    sigset_t set;
+    struct sigaction action;
+
+    memset(&action, 0, sizeof(action));
+    action.sa_handler = SIG_DFL;
+    if (!sigaction(SIGBUS, &action, NULL)) {
+        raise(SIGBUS);
+        sigemptyset(&set);
+        sigaddset(&set, SIGBUS);
+        sigprocmask(SIG_UNBLOCK, &set, NULL);
+    }
+    perror("Failed to re-raise SIGBUS!\n");
+    abort();
+}
+
+static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
+                           void *ctx)
+{
+    if (kvm_on_sigbus(siginfo->ssi_code,
+                      (void *)(intptr_t)siginfo->ssi_addr)) {
+        sigbus_reraise();
+    }
+}
+
+static void qemu_init_sigbus(void)
+{
+    struct sigaction action;
+
+    memset(&action, 0, sizeof(action));
+    action.sa_flags = SA_SIGINFO;
+    action.sa_sigaction = (void (*)(int, siginfo_t*, void*))sigbus_handler;
+    sigaction(SIGBUS, &action, NULL);
+
+    prctl(PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_EARLY, 0, 0);
+}
+
+#else /* !CONFIG_LINUX */
+
+static void qemu_init_sigbus(void)
+{
+}
+#endif /* !CONFIG_LINUX */
+
 #ifndef _WIN32
 static int io_thread_fd = -1;
 
@@ -248,6 +305,7 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
 #ifndef CONFIG_IOTHREAD
     sigemptyset(&set);
     sigaddset(&set, SIG_IPI);
+    sigaddset(&set, SIGBUS);
     pthread_sigmask(SIG_BLOCK, &set, NULL);
 #endif
 
@@ -338,13 +396,11 @@ static void qemu_kvm_eat_signals(CPUState *env)
         }
 
         switch (r) {
-#ifdef CONFIG_IOTHREAD
         case SIGBUS:
             if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {
                 sigbus_reraise();
             }
             break;
-#endif
         default:
             break;
         }
@@ -408,6 +464,7 @@ int qemu_init_main_loop(void)
     int ret;
 
     sigemptyset(&blocked_signals);
+    sigaddset(&blocked_signals, SIGBUS);
     if (kvm_enabled()) {
         /*
          * We need to process timer signals synchronously to avoid a race
@@ -424,6 +481,8 @@ int qemu_init_main_loop(void)
 #endif
     cpu_set_debug_excp_handler(cpu_debug_handler);
 
+    qemu_init_sigbus();
+
     return qemu_event_init();
 }
 
@@ -535,13 +594,9 @@ static void qemu_tcg_init_cpu_signals(void)
     pthread_sigmask(SIG_UNBLOCK, &set, NULL);
 }
 
-static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
-                           void *ctx);
-
 static sigset_t block_io_signals(void)
 {
     sigset_t set;
-    struct sigaction action;
 
     /* SIGUSR2 used by posix-aio-compat.c */
     sigemptyset(&set);
@@ -555,12 +610,6 @@ static sigset_t block_io_signals(void)
     sigaddset(&set, SIGBUS);
     pthread_sigmask(SIG_BLOCK, &set, NULL);
 
-    memset(&action, 0, sizeof(action));
-    action.sa_flags = SA_SIGINFO;
-    action.sa_sigaction = (void (*)(int, siginfo_t*, void*))sigbus_handler;
-    sigaction(SIGBUS, &action, NULL);
-    prctl(PR_MCE_KILL, 1, 1, 0, 0);
-
     return set;
 }
 
@@ -571,6 +620,8 @@ int qemu_init_main_loop(void)
 
     cpu_set_debug_excp_handler(cpu_debug_handler);
 
+    qemu_init_sigbus();
+
     blocked_signals = block_io_signals();
 
     ret = qemu_signalfd_init(blocked_signals);
@@ -678,31 +729,6 @@ static void qemu_tcg_wait_io_event(void)
     }
 }
 
-static void sigbus_reraise(void)
-{
-    sigset_t set;
-    struct sigaction action;
-
-    memset(&action, 0, sizeof(action));
-    action.sa_handler = SIG_DFL;
-    if (!sigaction(SIGBUS, &action, NULL)) {
-        raise(SIGBUS);
-        sigemptyset(&set);
-        sigaddset(&set, SIGBUS);
-        sigprocmask(SIG_UNBLOCK, &set, NULL);
-    }
-    perror("Failed to re-raise SIGBUS!\n");
-    abort();
-}
-
-static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
-                           void *ctx)
-{
-    if (kvm_on_sigbus(siginfo->ssi_code, (void *)(intptr_t)siginfo->ssi_addr)) {
-        sigbus_reraise();
-    }
-}
-
 static void qemu_kvm_wait_io_event(CPUState *env)
 {
     while (!cpu_has_work(env))
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH 15/22] kvm: Add MCE signal support for !CONFIG_IOTHREAD
@ 2011-01-27 13:09   ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:09 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: Hidetoshi Seto, Jin Dongming, qemu-devel, kvm, Huang Ying

Currently, we only configure and process MCE-related SIGBUS events if
CONFIG_IOTHREAD is enabled. The groundwork is laid, we just need to
factor out the required handler registration and system configuration.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
CC: Huang Ying <ying.huang@intel.com>
CC: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
CC: Jin Dongming <jin.dongming@np.css.fujitsu.com>
---
 cpus.c |  106 ++++++++++++++++++++++++++++++++++++++++------------------------
 1 files changed, 66 insertions(+), 40 deletions(-)

diff --git a/cpus.c b/cpus.c
index 29b1070..bba59e5 100644
--- a/cpus.c
+++ b/cpus.c
@@ -34,9 +34,6 @@
 
 #include "cpus.h"
 #include "compatfd.h"
-#ifdef CONFIG_LINUX
-#include <sys/prctl.h>
-#endif
 
 #ifdef SIGRTMIN
 #define SIG_IPI (SIGRTMIN+4)
@@ -44,10 +41,24 @@
 #define SIG_IPI SIGUSR1
 #endif
 
+#ifdef CONFIG_LINUX
+
+#include <sys/prctl.h>
+
 #ifndef PR_MCE_KILL
 #define PR_MCE_KILL 33
 #endif
 
+#ifndef PR_MCE_KILL_SET
+#define PR_MCE_KILL_SET 1
+#endif
+
+#ifndef PR_MCE_KILL_EARLY
+#define PR_MCE_KILL_EARLY 1
+#endif
+
+#endif /* CONFIG_LINUX */
+
 static CPUState *next_cpu;
 
 /***********************************************************/
@@ -166,6 +177,52 @@ static void cpu_debug_handler(CPUState *env)
     vm_stop(EXCP_DEBUG);
 }
 
+#ifdef CONFIG_LINUX
+static void sigbus_reraise(void)
+{
+    sigset_t set;
+    struct sigaction action;
+
+    memset(&action, 0, sizeof(action));
+    action.sa_handler = SIG_DFL;
+    if (!sigaction(SIGBUS, &action, NULL)) {
+        raise(SIGBUS);
+        sigemptyset(&set);
+        sigaddset(&set, SIGBUS);
+        sigprocmask(SIG_UNBLOCK, &set, NULL);
+    }
+    perror("Failed to re-raise SIGBUS!\n");
+    abort();
+}
+
+static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
+                           void *ctx)
+{
+    if (kvm_on_sigbus(siginfo->ssi_code,
+                      (void *)(intptr_t)siginfo->ssi_addr)) {
+        sigbus_reraise();
+    }
+}
+
+static void qemu_init_sigbus(void)
+{
+    struct sigaction action;
+
+    memset(&action, 0, sizeof(action));
+    action.sa_flags = SA_SIGINFO;
+    action.sa_sigaction = (void (*)(int, siginfo_t*, void*))sigbus_handler;
+    sigaction(SIGBUS, &action, NULL);
+
+    prctl(PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_EARLY, 0, 0);
+}
+
+#else /* !CONFIG_LINUX */
+
+static void qemu_init_sigbus(void)
+{
+}
+#endif /* !CONFIG_LINUX */
+
 #ifndef _WIN32
 static int io_thread_fd = -1;
 
@@ -248,6 +305,7 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
 #ifndef CONFIG_IOTHREAD
     sigemptyset(&set);
     sigaddset(&set, SIG_IPI);
+    sigaddset(&set, SIGBUS);
     pthread_sigmask(SIG_BLOCK, &set, NULL);
 #endif
 
@@ -338,13 +396,11 @@ static void qemu_kvm_eat_signals(CPUState *env)
         }
 
         switch (r) {
-#ifdef CONFIG_IOTHREAD
         case SIGBUS:
             if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {
                 sigbus_reraise();
             }
             break;
-#endif
         default:
             break;
         }
@@ -408,6 +464,7 @@ int qemu_init_main_loop(void)
     int ret;
 
     sigemptyset(&blocked_signals);
+    sigaddset(&blocked_signals, SIGBUS);
     if (kvm_enabled()) {
         /*
          * We need to process timer signals synchronously to avoid a race
@@ -424,6 +481,8 @@ int qemu_init_main_loop(void)
 #endif
     cpu_set_debug_excp_handler(cpu_debug_handler);
 
+    qemu_init_sigbus();
+
     return qemu_event_init();
 }
 
@@ -535,13 +594,9 @@ static void qemu_tcg_init_cpu_signals(void)
     pthread_sigmask(SIG_UNBLOCK, &set, NULL);
 }
 
-static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
-                           void *ctx);
-
 static sigset_t block_io_signals(void)
 {
     sigset_t set;
-    struct sigaction action;
 
     /* SIGUSR2 used by posix-aio-compat.c */
     sigemptyset(&set);
@@ -555,12 +610,6 @@ static sigset_t block_io_signals(void)
     sigaddset(&set, SIGBUS);
     pthread_sigmask(SIG_BLOCK, &set, NULL);
 
-    memset(&action, 0, sizeof(action));
-    action.sa_flags = SA_SIGINFO;
-    action.sa_sigaction = (void (*)(int, siginfo_t*, void*))sigbus_handler;
-    sigaction(SIGBUS, &action, NULL);
-    prctl(PR_MCE_KILL, 1, 1, 0, 0);
-
     return set;
 }
 
@@ -571,6 +620,8 @@ int qemu_init_main_loop(void)
 
     cpu_set_debug_excp_handler(cpu_debug_handler);
 
+    qemu_init_sigbus();
+
     blocked_signals = block_io_signals();
 
     ret = qemu_signalfd_init(blocked_signals);
@@ -678,31 +729,6 @@ static void qemu_tcg_wait_io_event(void)
     }
 }
 
-static void sigbus_reraise(void)
-{
-    sigset_t set;
-    struct sigaction action;
-
-    memset(&action, 0, sizeof(action));
-    action.sa_handler = SIG_DFL;
-    if (!sigaction(SIGBUS, &action, NULL)) {
-        raise(SIGBUS);
-        sigemptyset(&set);
-        sigaddset(&set, SIGBUS);
-        sigprocmask(SIG_UNBLOCK, &set, NULL);
-    }
-    perror("Failed to re-raise SIGBUS!\n");
-    abort();
-}
-
-static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
-                           void *ctx)
-{
-    if (kvm_on_sigbus(siginfo->ssi_code, (void *)(intptr_t)siginfo->ssi_addr)) {
-        sigbus_reraise();
-    }
-}
-
 static void qemu_kvm_wait_io_event(CPUState *env)
 {
     while (!cpu_has_work(env))
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 16/22] Introduce VCPU self-signaling service
  2011-01-27 13:09 ` [Qemu-devel] " Jan Kiszka
@ 2011-01-27 13:10   ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:10 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, qemu-devel

Introduce qemu_cpu_kick_self to send SIG_IPI to the calling VCPU
context. First user will be kvm.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpus.c        |   21 +++++++++++++++++++++
 qemu-common.h |    1 +
 2 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/cpus.c b/cpus.c
index bba59e5..88bed4e 100644
--- a/cpus.c
+++ b/cpus.c
@@ -531,6 +531,17 @@ void qemu_cpu_kick(void *env)
     return;
 }
 
+void qemu_cpu_kick_self(void)
+{
+#ifndef _WIN32
+    assert(cpu_single_env);
+
+    raise(SIG_IPI);
+#else
+    abort();
+#endif
+}
+
 void qemu_notify_event(void)
 {
     CPUState *env = cpu_single_env;
@@ -808,6 +819,16 @@ void qemu_cpu_kick(void *_env)
     }
 }
 
+void qemu_cpu_kick_self(void)
+{
+    assert(cpu_single_env);
+
+    if (!cpu_single_env->thread_kicked) {
+        qemu_thread_signal(cpu_single_env->thread, SIG_IPI);
+        cpu_single_env->thread_kicked = true;
+    }
+}
+
 int qemu_cpu_self(void *_env)
 {
     CPUState *env = _env;
diff --git a/qemu-common.h b/qemu-common.h
index 63d9943..220c8c8 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -287,6 +287,7 @@ void qemu_notify_event(void);
 
 /* Unblock cpu */
 void qemu_cpu_kick(void *env);
+void qemu_cpu_kick_self(void);
 int qemu_cpu_self(void *env);
 
 /* work queue */
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH 16/22] Introduce VCPU self-signaling service
@ 2011-01-27 13:10   ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:10 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm

Introduce qemu_cpu_kick_self to send SIG_IPI to the calling VCPU
context. First user will be kvm.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpus.c        |   21 +++++++++++++++++++++
 qemu-common.h |    1 +
 2 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/cpus.c b/cpus.c
index bba59e5..88bed4e 100644
--- a/cpus.c
+++ b/cpus.c
@@ -531,6 +531,17 @@ void qemu_cpu_kick(void *env)
     return;
 }
 
+void qemu_cpu_kick_self(void)
+{
+#ifndef _WIN32
+    assert(cpu_single_env);
+
+    raise(SIG_IPI);
+#else
+    abort();
+#endif
+}
+
 void qemu_notify_event(void)
 {
     CPUState *env = cpu_single_env;
@@ -808,6 +819,16 @@ void qemu_cpu_kick(void *_env)
     }
 }
 
+void qemu_cpu_kick_self(void)
+{
+    assert(cpu_single_env);
+
+    if (!cpu_single_env->thread_kicked) {
+        qemu_thread_signal(cpu_single_env->thread, SIG_IPI);
+        cpu_single_env->thread_kicked = true;
+    }
+}
+
 int qemu_cpu_self(void *_env)
 {
     CPUState *env = _env;
diff --git a/qemu-common.h b/qemu-common.h
index 63d9943..220c8c8 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -287,6 +287,7 @@ void qemu_notify_event(void);
 
 /* Unblock cpu */
 void qemu_cpu_kick(void *env);
+void qemu_cpu_kick_self(void);
 int qemu_cpu_self(void *env);
 
 /* work queue */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 17/22] kvm: Move irqchip event processing out of inner loop
  2011-01-27 13:09 ` [Qemu-devel] " Jan Kiszka
@ 2011-01-27 13:10   ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:10 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, qemu-devel

Align with qemu-kvm and prepare for IO exit fix: There is no need to run
kvm_arch_process_irqchip_events in the inner VCPU loop. Any state change
this service processes will first cause an exit from kvm_cpu_exec
anyway. And we will have to reenter the kernel on IO exits
unconditionally, something that the current logic prevents.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kvm-all.c |   11 ++++++-----
 1 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 5bfa8c0..46ecc1c 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -892,6 +892,12 @@ int kvm_cpu_exec(CPUState *env)
 
     DPRINTF("kvm_cpu_exec()\n");
 
+    if (kvm_arch_process_irqchip_events(env)) {
+        env->exit_request = 0;
+        env->exception_index = EXCP_HLT;
+        return 0;
+    }
+
     do {
 #ifndef CONFIG_IOTHREAD
         if (env->exit_request) {
@@ -901,11 +907,6 @@ int kvm_cpu_exec(CPUState *env)
         }
 #endif
 
-        if (kvm_arch_process_irqchip_events(env)) {
-            ret = 0;
-            break;
-        }
-
         if (env->kvm_vcpu_dirty) {
             kvm_arch_put_registers(env, KVM_PUT_RUNTIME_STATE);
             env->kvm_vcpu_dirty = 0;
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH 17/22] kvm: Move irqchip event processing out of inner loop
@ 2011-01-27 13:10   ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:10 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm

Align with qemu-kvm and prepare for IO exit fix: There is no need to run
kvm_arch_process_irqchip_events in the inner VCPU loop. Any state change
this service processes will first cause an exit from kvm_cpu_exec
anyway. And we will have to reenter the kernel on IO exits
unconditionally, something that the current logic prevents.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kvm-all.c |   11 ++++++-----
 1 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 5bfa8c0..46ecc1c 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -892,6 +892,12 @@ int kvm_cpu_exec(CPUState *env)
 
     DPRINTF("kvm_cpu_exec()\n");
 
+    if (kvm_arch_process_irqchip_events(env)) {
+        env->exit_request = 0;
+        env->exception_index = EXCP_HLT;
+        return 0;
+    }
+
     do {
 #ifndef CONFIG_IOTHREAD
         if (env->exit_request) {
@@ -901,11 +907,6 @@ int kvm_cpu_exec(CPUState *env)
         }
 #endif
 
-        if (kvm_arch_process_irqchip_events(env)) {
-            ret = 0;
-            break;
-        }
-
         if (env->kvm_vcpu_dirty) {
             kvm_arch_put_registers(env, KVM_PUT_RUNTIME_STATE);
             env->kvm_vcpu_dirty = 0;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 18/22] kvm: Unconditionally reenter kernel after IO exits
  2011-01-27 13:09 ` [Qemu-devel] " Jan Kiszka
@ 2011-01-27 13:10   ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:10 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, qemu-devel, Gleb Natapov

KVM requires to reenter the kernel after IO exits in order to complete
instruction emulation. Failing to do so will leave the kernel state
inconsistently behind. To ensure that we will get back ASAP, we issue a
self-signal that will cause KVM_RUN to return once the pending
operations are completed.

This patch also fixes the missing exit_request check in kvm_cpu_exec in
the CONFIG_IOTHREAD case.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
CC: Gleb Natapov <gleb@redhat.com>
---
 kvm-all.c |   20 +++++++++++---------
 1 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 46ecc1c..d961697 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -199,7 +199,6 @@ int kvm_pit_in_kernel(void)
     return kvm_state->pit_in_kernel;
 }
 
-
 int kvm_init_vcpu(CPUState *env)
 {
     KVMState *s = kvm_state;
@@ -899,23 +898,26 @@ int kvm_cpu_exec(CPUState *env)
     }
 
     do {
-#ifndef CONFIG_IOTHREAD
-        if (env->exit_request) {
-            DPRINTF("interrupt exit requested\n");
-            ret = 0;
-            break;
-        }
-#endif
-
         if (env->kvm_vcpu_dirty) {
             kvm_arch_put_registers(env, KVM_PUT_RUNTIME_STATE);
             env->kvm_vcpu_dirty = 0;
         }
 
         kvm_arch_pre_run(env, run);
+        if (env->exit_request) {
+            DPRINTF("interrupt exit requested\n");
+            /*
+             * KVM requires us to reenter the kernel after IO exits to complete
+             * instruction emulation. This self-signal will ensure that we
+             * leave ASAP again.
+             */
+            qemu_cpu_kick_self();
+        }
         cpu_single_env = NULL;
         qemu_mutex_unlock_iothread();
+
         ret = kvm_vcpu_ioctl(env, KVM_RUN, 0);
+
         qemu_mutex_lock_iothread();
         cpu_single_env = env;
         kvm_arch_post_run(env, run);
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH 18/22] kvm: Unconditionally reenter kernel after IO exits
@ 2011-01-27 13:10   ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:10 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: Gleb Natapov, qemu-devel, kvm

KVM requires to reenter the kernel after IO exits in order to complete
instruction emulation. Failing to do so will leave the kernel state
inconsistently behind. To ensure that we will get back ASAP, we issue a
self-signal that will cause KVM_RUN to return once the pending
operations are completed.

This patch also fixes the missing exit_request check in kvm_cpu_exec in
the CONFIG_IOTHREAD case.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
CC: Gleb Natapov <gleb@redhat.com>
---
 kvm-all.c |   20 +++++++++++---------
 1 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 46ecc1c..d961697 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -199,7 +199,6 @@ int kvm_pit_in_kernel(void)
     return kvm_state->pit_in_kernel;
 }
 
-
 int kvm_init_vcpu(CPUState *env)
 {
     KVMState *s = kvm_state;
@@ -899,23 +898,26 @@ int kvm_cpu_exec(CPUState *env)
     }
 
     do {
-#ifndef CONFIG_IOTHREAD
-        if (env->exit_request) {
-            DPRINTF("interrupt exit requested\n");
-            ret = 0;
-            break;
-        }
-#endif
-
         if (env->kvm_vcpu_dirty) {
             kvm_arch_put_registers(env, KVM_PUT_RUNTIME_STATE);
             env->kvm_vcpu_dirty = 0;
         }
 
         kvm_arch_pre_run(env, run);
+        if (env->exit_request) {
+            DPRINTF("interrupt exit requested\n");
+            /*
+             * KVM requires us to reenter the kernel after IO exits to complete
+             * instruction emulation. This self-signal will ensure that we
+             * leave ASAP again.
+             */
+            qemu_cpu_kick_self();
+        }
         cpu_single_env = NULL;
         qemu_mutex_unlock_iothread();
+
         ret = kvm_vcpu_ioctl(env, KVM_RUN, 0);
+
         qemu_mutex_lock_iothread();
         cpu_single_env = env;
         kvm_arch_post_run(env, run);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 19/22] kvm: Remove static return code of kvm_handle_io
  2011-01-27 13:09 ` [Qemu-devel] " Jan Kiszka
@ 2011-01-27 13:10   ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:10 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, qemu-devel

Improve the readability of the exit dispatcher by moving the static
return value of kvm_handle_io to its caller.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kvm-all.c |   17 ++++++++---------
 1 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index d961697..cf54256 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -770,8 +770,8 @@ err:
     return ret;
 }
 
-static int kvm_handle_io(uint16_t port, void *data, int direction, int size,
-                         uint32_t count)
+static void kvm_handle_io(uint16_t port, void *data, int direction, int size,
+                          uint32_t count)
 {
     int i;
     uint8_t *ptr = data;
@@ -805,8 +805,6 @@ static int kvm_handle_io(uint16_t port, void *data, int direction, int size,
 
         ptr += size;
     }
-
-    return 1;
 }
 
 #ifdef KVM_CAP_INTERNAL_ERROR_DATA
@@ -940,11 +938,12 @@ int kvm_cpu_exec(CPUState *env)
         switch (run->exit_reason) {
         case KVM_EXIT_IO:
             DPRINTF("handle_io\n");
-            ret = kvm_handle_io(run->io.port,
-                                (uint8_t *)run + run->io.data_offset,
-                                run->io.direction,
-                                run->io.size,
-                                run->io.count);
+            kvm_handle_io(run->io.port,
+                          (uint8_t *)run + run->io.data_offset,
+                          run->io.direction,
+                          run->io.size,
+                          run->io.count);
+            ret = 1;
             break;
         case KVM_EXIT_MMIO:
             DPRINTF("handle_mmio\n");
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH 19/22] kvm: Remove static return code of kvm_handle_io
@ 2011-01-27 13:10   ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:10 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm

Improve the readability of the exit dispatcher by moving the static
return value of kvm_handle_io to its caller.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kvm-all.c |   17 ++++++++---------
 1 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index d961697..cf54256 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -770,8 +770,8 @@ err:
     return ret;
 }
 
-static int kvm_handle_io(uint16_t port, void *data, int direction, int size,
-                         uint32_t count)
+static void kvm_handle_io(uint16_t port, void *data, int direction, int size,
+                          uint32_t count)
 {
     int i;
     uint8_t *ptr = data;
@@ -805,8 +805,6 @@ static int kvm_handle_io(uint16_t port, void *data, int direction, int size,
 
         ptr += size;
     }
-
-    return 1;
 }
 
 #ifdef KVM_CAP_INTERNAL_ERROR_DATA
@@ -940,11 +938,12 @@ int kvm_cpu_exec(CPUState *env)
         switch (run->exit_reason) {
         case KVM_EXIT_IO:
             DPRINTF("handle_io\n");
-            ret = kvm_handle_io(run->io.port,
-                                (uint8_t *)run + run->io.data_offset,
-                                run->io.direction,
-                                run->io.size,
-                                run->io.count);
+            kvm_handle_io(run->io.port,
+                          (uint8_t *)run + run->io.data_offset,
+                          run->io.direction,
+                          run->io.size,
+                          run->io.count);
+            ret = 1;
             break;
         case KVM_EXIT_MMIO:
             DPRINTF("handle_mmio\n");
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 20/22] kvm: Leave kvm_cpu_exec directly after KVM_EXIT_SHUTDOWN
  2011-01-27 13:09 ` [Qemu-devel] " Jan Kiszka
@ 2011-01-27 13:10   ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:10 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, qemu-devel

The reset we issue on KVM_EXIT_SHUTDOWN implies that we should also
leave the VCPU loop. As we now check for exit_request which is set by
qemu_system_reset_request, this bug is no longer critical. Still it's an
unneeded extra turn.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kvm-all.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index cf54256..35860df 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -959,7 +959,6 @@ int kvm_cpu_exec(CPUState *env)
         case KVM_EXIT_SHUTDOWN:
             DPRINTF("shutdown\n");
             qemu_system_reset_request();
-            ret = 1;
             break;
         case KVM_EXIT_UNKNOWN:
             fprintf(stderr, "KVM: unknown exit, hardware reason %" PRIx64 "\n",
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH 20/22] kvm: Leave kvm_cpu_exec directly after KVM_EXIT_SHUTDOWN
@ 2011-01-27 13:10   ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:10 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm

The reset we issue on KVM_EXIT_SHUTDOWN implies that we should also
leave the VCPU loop. As we now check for exit_request which is set by
qemu_system_reset_request, this bug is no longer critical. Still it's an
unneeded extra turn.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kvm-all.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index cf54256..35860df 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -959,7 +959,6 @@ int kvm_cpu_exec(CPUState *env)
         case KVM_EXIT_SHUTDOWN:
             DPRINTF("shutdown\n");
             qemu_system_reset_request();
-            ret = 1;
             break;
         case KVM_EXIT_UNKNOWN:
             fprintf(stderr, "KVM: unknown exit, hardware reason %" PRIx64 "\n",
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 21/22] Refactor kvm&tcg function names in cpus.c
  2011-01-27 13:09 ` [Qemu-devel] " Jan Kiszka
@ 2011-01-27 13:10   ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:10 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, qemu-devel

Pure interface cosmetics: Ensure that only kvm core services (as
declared in kvm.h) start with "kvm_". Prepend "qemu_" to those that
violate this rule in cpus.c. Also rename the corresponding tcg functions
for the sake of consistency.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpus.c |   16 ++++++++--------
 1 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/cpus.c b/cpus.c
index 88bed4e..559ec55 100644
--- a/cpus.c
+++ b/cpus.c
@@ -751,7 +751,7 @@ static void qemu_kvm_wait_io_event(CPUState *env)
 
 static int qemu_cpu_exec(CPUState *env);
 
-static void *kvm_cpu_thread_fn(void *arg)
+static void *qemu_kvm_cpu_thread_fn(void *arg)
 {
     CPUState *env = arg;
     int r;
@@ -784,7 +784,7 @@ static void *kvm_cpu_thread_fn(void *arg)
     return NULL;
 }
 
-static void *tcg_cpu_thread_fn(void *arg)
+static void *qemu_tcg_cpu_thread_fn(void *arg)
 {
     CPUState *env = arg;
 
@@ -903,7 +903,7 @@ void resume_all_vcpus(void)
     }
 }
 
-static void tcg_init_vcpu(void *_env)
+static void qemu_tcg_init_vcpu(void *_env)
 {
     CPUState *env = _env;
     /* share a single thread for all cpus with TCG */
@@ -911,7 +911,7 @@ static void tcg_init_vcpu(void *_env)
         env->thread = qemu_mallocz(sizeof(QemuThread));
         env->halt_cond = qemu_mallocz(sizeof(QemuCond));
         qemu_cond_init(env->halt_cond);
-        qemu_thread_create(env->thread, tcg_cpu_thread_fn, env);
+        qemu_thread_create(env->thread, qemu_tcg_cpu_thread_fn, env);
         while (env->created == 0)
             qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
         tcg_cpu_thread = env->thread;
@@ -922,12 +922,12 @@ static void tcg_init_vcpu(void *_env)
     }
 }
 
-static void kvm_start_vcpu(CPUState *env)
+static void qemu_kvm_start_vcpu(CPUState *env)
 {
     env->thread = qemu_mallocz(sizeof(QemuThread));
     env->halt_cond = qemu_mallocz(sizeof(QemuCond));
     qemu_cond_init(env->halt_cond);
-    qemu_thread_create(env->thread, kvm_cpu_thread_fn, env);
+    qemu_thread_create(env->thread, qemu_kvm_cpu_thread_fn, env);
     while (env->created == 0)
         qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
 }
@@ -939,9 +939,9 @@ void qemu_init_vcpu(void *_env)
     env->nr_cores = smp_cores;
     env->nr_threads = smp_threads;
     if (kvm_enabled())
-        kvm_start_vcpu(env);
+        qemu_kvm_start_vcpu(env);
     else
-        tcg_init_vcpu(env);
+        qemu_tcg_init_vcpu(env);
 }
 
 void qemu_notify_event(void)
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH 21/22] Refactor kvm&tcg function names in cpus.c
@ 2011-01-27 13:10   ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:10 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm

Pure interface cosmetics: Ensure that only kvm core services (as
declared in kvm.h) start with "kvm_". Prepend "qemu_" to those that
violate this rule in cpus.c. Also rename the corresponding tcg functions
for the sake of consistency.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpus.c |   16 ++++++++--------
 1 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/cpus.c b/cpus.c
index 88bed4e..559ec55 100644
--- a/cpus.c
+++ b/cpus.c
@@ -751,7 +751,7 @@ static void qemu_kvm_wait_io_event(CPUState *env)
 
 static int qemu_cpu_exec(CPUState *env);
 
-static void *kvm_cpu_thread_fn(void *arg)
+static void *qemu_kvm_cpu_thread_fn(void *arg)
 {
     CPUState *env = arg;
     int r;
@@ -784,7 +784,7 @@ static void *kvm_cpu_thread_fn(void *arg)
     return NULL;
 }
 
-static void *tcg_cpu_thread_fn(void *arg)
+static void *qemu_tcg_cpu_thread_fn(void *arg)
 {
     CPUState *env = arg;
 
@@ -903,7 +903,7 @@ void resume_all_vcpus(void)
     }
 }
 
-static void tcg_init_vcpu(void *_env)
+static void qemu_tcg_init_vcpu(void *_env)
 {
     CPUState *env = _env;
     /* share a single thread for all cpus with TCG */
@@ -911,7 +911,7 @@ static void tcg_init_vcpu(void *_env)
         env->thread = qemu_mallocz(sizeof(QemuThread));
         env->halt_cond = qemu_mallocz(sizeof(QemuCond));
         qemu_cond_init(env->halt_cond);
-        qemu_thread_create(env->thread, tcg_cpu_thread_fn, env);
+        qemu_thread_create(env->thread, qemu_tcg_cpu_thread_fn, env);
         while (env->created == 0)
             qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
         tcg_cpu_thread = env->thread;
@@ -922,12 +922,12 @@ static void tcg_init_vcpu(void *_env)
     }
 }
 
-static void kvm_start_vcpu(CPUState *env)
+static void qemu_kvm_start_vcpu(CPUState *env)
 {
     env->thread = qemu_mallocz(sizeof(QemuThread));
     env->halt_cond = qemu_mallocz(sizeof(QemuCond));
     qemu_cond_init(env->halt_cond);
-    qemu_thread_create(env->thread, kvm_cpu_thread_fn, env);
+    qemu_thread_create(env->thread, qemu_kvm_cpu_thread_fn, env);
     while (env->created == 0)
         qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
 }
@@ -939,9 +939,9 @@ void qemu_init_vcpu(void *_env)
     env->nr_cores = smp_cores;
     env->nr_threads = smp_threads;
     if (kvm_enabled())
-        kvm_start_vcpu(env);
+        qemu_kvm_start_vcpu(env);
     else
-        tcg_init_vcpu(env);
+        qemu_tcg_init_vcpu(env);
 }
 
 void qemu_notify_event(void)
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 22/22] Fix a few coding style violations in cpus.c
  2011-01-27 13:09 ` [Qemu-devel] " Jan Kiszka
@ 2011-01-27 13:10   ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:10 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, qemu-devel

No functional changes.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpus.c |   97 ++++++++++++++++++++++++++++++++++++++-------------------------
 1 files changed, 58 insertions(+), 39 deletions(-)

diff --git a/cpus.c b/cpus.c
index 559ec55..f4ec84e 100644
--- a/cpus.c
+++ b/cpus.c
@@ -138,25 +138,26 @@ static void do_vm_stop(int reason)
 
 static int cpu_can_run(CPUState *env)
 {
-    if (env->stop)
+    if (env->stop) {
         return 0;
-    if (env->stopped || !vm_running)
+    }
+    if (env->stopped || !vm_running) {
         return 0;
+    }
     return 1;
 }
 
 static int cpu_has_work(CPUState *env)
 {
-    if (env->stop)
+    if (env->stop || env->queued_work_first) {
         return 1;
-    if (env->queued_work_first)
-        return 1;
-    if (env->stopped || !vm_running)
+    }
+    if (env->stopped || !vm_running) {
         return 0;
-    if (!env->halted)
-        return 1;
-    if (qemu_cpu_has_work(env))
+    }
+    if (!env->halted || qemu_cpu_has_work(env)) {
         return 1;
+    }
     return 0;
 }
 
@@ -164,9 +165,11 @@ static int any_cpu_has_work(void)
 {
     CPUState *env;
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu)
-        if (cpu_has_work(env))
+    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        if (cpu_has_work(env)) {
             return 1;
+        }
+    }
     return 0;
 }
 
@@ -232,9 +235,9 @@ static void qemu_event_increment(void)
     static const uint64_t val = 1;
     ssize_t ret;
 
-    if (io_thread_fd == -1)
+    if (io_thread_fd == -1) {
         return;
-
+    }
     do {
         ret = write(io_thread_fd, &val, sizeof(val));
     } while (ret < 0 && errno == EINTR);
@@ -265,17 +268,17 @@ static int qemu_event_init(void)
     int fds[2];
 
     err = qemu_eventfd(fds);
-    if (err == -1)
+    if (err == -1) {
         return -errno;
-
+    }
     err = fcntl_setfl(fds[0], O_NONBLOCK);
-    if (err < 0)
+    if (err < 0) {
         goto fail;
-
+    }
     err = fcntl_setfl(fds[1], O_NONBLOCK);
-    if (err < 0)
+    if (err < 0) {
         goto fail;
-
+    }
     qemu_set_fd_handler2(fds[0], NULL, qemu_event_read, NULL,
                          (void *)(unsigned long)fds[0]);
 
@@ -528,7 +531,6 @@ void pause_all_vcpus(void)
 
 void qemu_cpu_kick(void *env)
 {
-    return;
 }
 
 void qemu_cpu_kick_self(void)
@@ -636,13 +638,15 @@ int qemu_init_main_loop(void)
     blocked_signals = block_io_signals();
 
     ret = qemu_signalfd_init(blocked_signals);
-    if (ret)
+    if (ret) {
         return ret;
+    }
 
     /* Note eventfd must be drained before signalfd handlers run */
     ret = qemu_event_init();
-    if (ret)
+    if (ret) {
         return ret;
+    }
 
     qemu_cond_init(&qemu_pause_cond);
     qemu_cond_init(&qemu_system_cond);
@@ -672,10 +676,11 @@ void run_on_cpu(CPUState *env, void (*func)(void *data), void *data)
 
     wi.func = func;
     wi.data = data;
-    if (!env->queued_work_first)
+    if (!env->queued_work_first) {
         env->queued_work_first = &wi;
-    else
+    } else {
         env->queued_work_last->next = &wi;
+    }
     env->queued_work_last = &wi;
     wi.next = NULL;
     wi.done = false;
@@ -693,8 +698,9 @@ static void flush_queued_work(CPUState *env)
 {
     struct qemu_work_item *wi;
 
-    if (!env->queued_work_first)
+    if (!env->queued_work_first) {
         return;
+    }
 
     while ((wi = env->queued_work_first)) {
         env->queued_work_first = wi->next;
@@ -720,8 +726,9 @@ static void qemu_tcg_wait_io_event(void)
 {
     CPUState *env;
 
-    while (!any_cpu_has_work())
+    while (!any_cpu_has_work()) {
         qemu_cond_timedwait(tcg_halt_cond, &qemu_global_mutex, 1000);
+    }
 
     qemu_mutex_unlock(&qemu_global_mutex);
 
@@ -742,9 +749,9 @@ static void qemu_tcg_wait_io_event(void)
 
 static void qemu_kvm_wait_io_event(CPUState *env)
 {
-    while (!cpu_has_work(env))
+    while (!cpu_has_work(env)) {
         qemu_cond_timedwait(env->halt_cond, &qemu_global_mutex, 1000);
-
+    }
     qemu_kvm_eat_signals(env);
     qemu_wait_io_event_common(env);
 }
@@ -772,12 +779,14 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
     qemu_cond_signal(&qemu_cpu_cond);
 
     /* and wait for machine initialization */
-    while (!qemu_system_ready)
+    while (!qemu_system_ready) {
         qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
+    }
 
     while (1) {
-        if (cpu_can_run(env))
+        if (cpu_can_run(env)) {
             qemu_cpu_exec(env);
+        }
         qemu_kvm_wait_io_event(env);
     }
 
@@ -793,13 +802,15 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
 
     /* signal CPU creation */
     qemu_mutex_lock(&qemu_global_mutex);
-    for (env = first_cpu; env != NULL; env = env->next_cpu)
+    for (env = first_cpu; env != NULL; env = env->next_cpu) {
         env->created = 1;
+    }
     qemu_cond_signal(&qemu_cpu_cond);
 
     /* and wait for machine initialization */
-    while (!qemu_system_ready)
+    while (!qemu_system_ready) {
         qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
+    }
 
     while (1) {
         cpu_exec_all();
@@ -812,6 +823,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
 void qemu_cpu_kick(void *_env)
 {
     CPUState *env = _env;
+
     qemu_cond_broadcast(env->halt_cond);
     if (!env->thread_kicked) {
         qemu_thread_signal(env->thread, SIG_IPI);
@@ -863,8 +875,9 @@ static int all_vcpus_paused(void)
     CPUState *penv = first_cpu;
 
     while (penv) {
-        if (!penv->stopped)
+        if (!penv->stopped) {
             return 0;
+        }
         penv = (CPUState *)penv->next_cpu;
     }
 
@@ -906,14 +919,16 @@ void resume_all_vcpus(void)
 static void qemu_tcg_init_vcpu(void *_env)
 {
     CPUState *env = _env;
+
     /* share a single thread for all cpus with TCG */
     if (!tcg_cpu_thread) {
         env->thread = qemu_mallocz(sizeof(QemuThread));
         env->halt_cond = qemu_mallocz(sizeof(QemuCond));
         qemu_cond_init(env->halt_cond);
         qemu_thread_create(env->thread, qemu_tcg_cpu_thread_fn, env);
-        while (env->created == 0)
+        while (env->created == 0) {
             qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
+        }
         tcg_cpu_thread = env->thread;
         tcg_halt_cond = env->halt_cond;
     } else {
@@ -928,8 +943,9 @@ static void qemu_kvm_start_vcpu(CPUState *env)
     env->halt_cond = qemu_mallocz(sizeof(QemuCond));
     qemu_cond_init(env->halt_cond);
     qemu_thread_create(env->thread, qemu_kvm_cpu_thread_fn, env);
-    while (env->created == 0)
+    while (env->created == 0) {
         qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
+    }
 }
 
 void qemu_init_vcpu(void *_env)
@@ -938,10 +954,11 @@ void qemu_init_vcpu(void *_env)
 
     env->nr_cores = smp_cores;
     env->nr_threads = smp_threads;
-    if (kvm_enabled())
+    if (kvm_enabled()) {
         qemu_kvm_start_vcpu(env);
-    else
+    } else {
         qemu_tcg_init_vcpu(env);
+    }
 }
 
 void qemu_notify_event(void)
@@ -1016,16 +1033,18 @@ bool cpu_exec_all(void)
 {
     int r;
 
-    if (next_cpu == NULL)
+    if (next_cpu == NULL) {
         next_cpu = first_cpu;
+    }
     for (; next_cpu != NULL && !exit_request; next_cpu = next_cpu->next_cpu) {
         CPUState *env = next_cpu;
 
         qemu_clock_enable(vm_clock,
                           (env->singlestep_enabled & SSTEP_NOTIMER) == 0);
 
-        if (qemu_alarm_pending())
+        if (qemu_alarm_pending()) {
             break;
+        }
         if (cpu_can_run(env)) {
             r = qemu_cpu_exec(env);
             if (kvm_enabled()) {
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH 22/22] Fix a few coding style violations in cpus.c
@ 2011-01-27 13:10   ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 13:10 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm

No functional changes.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpus.c |   97 ++++++++++++++++++++++++++++++++++++++-------------------------
 1 files changed, 58 insertions(+), 39 deletions(-)

diff --git a/cpus.c b/cpus.c
index 559ec55..f4ec84e 100644
--- a/cpus.c
+++ b/cpus.c
@@ -138,25 +138,26 @@ static void do_vm_stop(int reason)
 
 static int cpu_can_run(CPUState *env)
 {
-    if (env->stop)
+    if (env->stop) {
         return 0;
-    if (env->stopped || !vm_running)
+    }
+    if (env->stopped || !vm_running) {
         return 0;
+    }
     return 1;
 }
 
 static int cpu_has_work(CPUState *env)
 {
-    if (env->stop)
+    if (env->stop || env->queued_work_first) {
         return 1;
-    if (env->queued_work_first)
-        return 1;
-    if (env->stopped || !vm_running)
+    }
+    if (env->stopped || !vm_running) {
         return 0;
-    if (!env->halted)
-        return 1;
-    if (qemu_cpu_has_work(env))
+    }
+    if (!env->halted || qemu_cpu_has_work(env)) {
         return 1;
+    }
     return 0;
 }
 
@@ -164,9 +165,11 @@ static int any_cpu_has_work(void)
 {
     CPUState *env;
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu)
-        if (cpu_has_work(env))
+    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        if (cpu_has_work(env)) {
             return 1;
+        }
+    }
     return 0;
 }
 
@@ -232,9 +235,9 @@ static void qemu_event_increment(void)
     static const uint64_t val = 1;
     ssize_t ret;
 
-    if (io_thread_fd == -1)
+    if (io_thread_fd == -1) {
         return;
-
+    }
     do {
         ret = write(io_thread_fd, &val, sizeof(val));
     } while (ret < 0 && errno == EINTR);
@@ -265,17 +268,17 @@ static int qemu_event_init(void)
     int fds[2];
 
     err = qemu_eventfd(fds);
-    if (err == -1)
+    if (err == -1) {
         return -errno;
-
+    }
     err = fcntl_setfl(fds[0], O_NONBLOCK);
-    if (err < 0)
+    if (err < 0) {
         goto fail;
-
+    }
     err = fcntl_setfl(fds[1], O_NONBLOCK);
-    if (err < 0)
+    if (err < 0) {
         goto fail;
-
+    }
     qemu_set_fd_handler2(fds[0], NULL, qemu_event_read, NULL,
                          (void *)(unsigned long)fds[0]);
 
@@ -528,7 +531,6 @@ void pause_all_vcpus(void)
 
 void qemu_cpu_kick(void *env)
 {
-    return;
 }
 
 void qemu_cpu_kick_self(void)
@@ -636,13 +638,15 @@ int qemu_init_main_loop(void)
     blocked_signals = block_io_signals();
 
     ret = qemu_signalfd_init(blocked_signals);
-    if (ret)
+    if (ret) {
         return ret;
+    }
 
     /* Note eventfd must be drained before signalfd handlers run */
     ret = qemu_event_init();
-    if (ret)
+    if (ret) {
         return ret;
+    }
 
     qemu_cond_init(&qemu_pause_cond);
     qemu_cond_init(&qemu_system_cond);
@@ -672,10 +676,11 @@ void run_on_cpu(CPUState *env, void (*func)(void *data), void *data)
 
     wi.func = func;
     wi.data = data;
-    if (!env->queued_work_first)
+    if (!env->queued_work_first) {
         env->queued_work_first = &wi;
-    else
+    } else {
         env->queued_work_last->next = &wi;
+    }
     env->queued_work_last = &wi;
     wi.next = NULL;
     wi.done = false;
@@ -693,8 +698,9 @@ static void flush_queued_work(CPUState *env)
 {
     struct qemu_work_item *wi;
 
-    if (!env->queued_work_first)
+    if (!env->queued_work_first) {
         return;
+    }
 
     while ((wi = env->queued_work_first)) {
         env->queued_work_first = wi->next;
@@ -720,8 +726,9 @@ static void qemu_tcg_wait_io_event(void)
 {
     CPUState *env;
 
-    while (!any_cpu_has_work())
+    while (!any_cpu_has_work()) {
         qemu_cond_timedwait(tcg_halt_cond, &qemu_global_mutex, 1000);
+    }
 
     qemu_mutex_unlock(&qemu_global_mutex);
 
@@ -742,9 +749,9 @@ static void qemu_tcg_wait_io_event(void)
 
 static void qemu_kvm_wait_io_event(CPUState *env)
 {
-    while (!cpu_has_work(env))
+    while (!cpu_has_work(env)) {
         qemu_cond_timedwait(env->halt_cond, &qemu_global_mutex, 1000);
-
+    }
     qemu_kvm_eat_signals(env);
     qemu_wait_io_event_common(env);
 }
@@ -772,12 +779,14 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
     qemu_cond_signal(&qemu_cpu_cond);
 
     /* and wait for machine initialization */
-    while (!qemu_system_ready)
+    while (!qemu_system_ready) {
         qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
+    }
 
     while (1) {
-        if (cpu_can_run(env))
+        if (cpu_can_run(env)) {
             qemu_cpu_exec(env);
+        }
         qemu_kvm_wait_io_event(env);
     }
 
@@ -793,13 +802,15 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
 
     /* signal CPU creation */
     qemu_mutex_lock(&qemu_global_mutex);
-    for (env = first_cpu; env != NULL; env = env->next_cpu)
+    for (env = first_cpu; env != NULL; env = env->next_cpu) {
         env->created = 1;
+    }
     qemu_cond_signal(&qemu_cpu_cond);
 
     /* and wait for machine initialization */
-    while (!qemu_system_ready)
+    while (!qemu_system_ready) {
         qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
+    }
 
     while (1) {
         cpu_exec_all();
@@ -812,6 +823,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
 void qemu_cpu_kick(void *_env)
 {
     CPUState *env = _env;
+
     qemu_cond_broadcast(env->halt_cond);
     if (!env->thread_kicked) {
         qemu_thread_signal(env->thread, SIG_IPI);
@@ -863,8 +875,9 @@ static int all_vcpus_paused(void)
     CPUState *penv = first_cpu;
 
     while (penv) {
-        if (!penv->stopped)
+        if (!penv->stopped) {
             return 0;
+        }
         penv = (CPUState *)penv->next_cpu;
     }
 
@@ -906,14 +919,16 @@ void resume_all_vcpus(void)
 static void qemu_tcg_init_vcpu(void *_env)
 {
     CPUState *env = _env;
+
     /* share a single thread for all cpus with TCG */
     if (!tcg_cpu_thread) {
         env->thread = qemu_mallocz(sizeof(QemuThread));
         env->halt_cond = qemu_mallocz(sizeof(QemuCond));
         qemu_cond_init(env->halt_cond);
         qemu_thread_create(env->thread, qemu_tcg_cpu_thread_fn, env);
-        while (env->created == 0)
+        while (env->created == 0) {
             qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
+        }
         tcg_cpu_thread = env->thread;
         tcg_halt_cond = env->halt_cond;
     } else {
@@ -928,8 +943,9 @@ static void qemu_kvm_start_vcpu(CPUState *env)
     env->halt_cond = qemu_mallocz(sizeof(QemuCond));
     qemu_cond_init(env->halt_cond);
     qemu_thread_create(env->thread, qemu_kvm_cpu_thread_fn, env);
-    while (env->created == 0)
+    while (env->created == 0) {
         qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
+    }
 }
 
 void qemu_init_vcpu(void *_env)
@@ -938,10 +954,11 @@ void qemu_init_vcpu(void *_env)
 
     env->nr_cores = smp_cores;
     env->nr_threads = smp_threads;
-    if (kvm_enabled())
+    if (kvm_enabled()) {
         qemu_kvm_start_vcpu(env);
-    else
+    } else {
         qemu_tcg_init_vcpu(env);
+    }
 }
 
 void qemu_notify_event(void)
@@ -1016,16 +1033,18 @@ bool cpu_exec_all(void)
 {
     int r;
 
-    if (next_cpu == NULL)
+    if (next_cpu == NULL) {
         next_cpu = first_cpu;
+    }
     for (; next_cpu != NULL && !exit_request; next_cpu = next_cpu->next_cpu) {
         CPUState *env = next_cpu;
 
         qemu_clock_enable(vm_clock,
                           (env->singlestep_enabled & SSTEP_NOTIMER) == 0);
 
-        if (qemu_alarm_pending())
+        if (qemu_alarm_pending()) {
             break;
+        }
         if (cpu_can_run(env)) {
             r = qemu_cpu_exec(env);
             if (kvm_enabled()) {
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v2 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
  2011-01-27 13:09   ` [Qemu-devel] " Jan Kiszka
@ 2011-01-27 14:20     ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 14:20 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, qemu-devel, Stefan Hajnoczi

Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
checking for exit_request on vcpu entry and timer signals arriving
before KVM starts to catch them. Plug it by blocking both timer related
signals also on !CONFIG_IOTHREAD and process those via signalfd.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
CC: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---

Added blocking of SIGIO/SIGALRM which was missing in previous version.
Stefan just provided a test case, and that now passes.

However, I realized (and checked) that this fix does not work with
signalfd_compat: The signals will be swallowed by the helper thread.
That affects all host kernels < 2.6.22. Given that we require 2.6.29 as
baseline (unless kvm-kmod is used) and that !CONFIG_IOTHREAD is not that
important for KVM mode, I tend to catch and reject
CONFIG_KVM+!CONFIG_IOTHREAD+!CONFIG_SIGNALFD as unsupported during
configure. Comments?

 cpus.c |   20 ++++++++++++++++++++
 1 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/cpus.c b/cpus.c
index fc3f222..f9d9f9e 100644
--- a/cpus.c
+++ b/cpus.c
@@ -254,6 +254,10 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
     pthread_sigmask(SIG_BLOCK, NULL, &set);
     sigdelset(&set, SIG_IPI);
     sigdelset(&set, SIGBUS);
+#ifndef CONFIG_IOTHREAD
+    sigdelset(&set, SIGIO);
+    sigdelset(&set, SIGALRM);
+#endif
     r = kvm_set_signal_mask(env, &set);
     if (r) {
         fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
@@ -351,6 +355,12 @@ static void qemu_kvm_eat_signals(CPUState *env)
             exit(1);
         }
     } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
+
+#ifndef CONFIG_IOTHREAD
+    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
+        qemu_notify_event();
+    }
+#endif
 }
 
 #else /* _WIN32 */
@@ -398,6 +408,14 @@ int qemu_init_main_loop(void)
     int ret;
 
     sigemptyset(&blocked_signals);
+    if (kvm_enabled()) {
+        /*
+         * We need to process timer signals synchronously to avoid a race
+         * between exit_request check and KVM vcpu entry.
+         */
+        sigaddset(&blocked_signals, SIGIO);
+        sigaddset(&blocked_signals, SIGALRM);
+    }
 
     ret = qemu_signalfd_init(blocked_signals);
     if (ret) {
@@ -535,6 +553,8 @@ static sigset_t block_io_signals(void)
     sigaddset(&set, SIGALRM);
     sigaddset(&set, SIG_IPI);
     sigaddset(&set, SIGBUS);
+    sigaddset(&set, SIGIO);
+    sigaddset(&set, SIGALRM);
     pthread_sigmask(SIG_BLOCK, &set, NULL);
 
     memset(&action, 0, sizeof(action));
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH v2 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
@ 2011-01-27 14:20     ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 14:20 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm, Stefan Hajnoczi

Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
checking for exit_request on vcpu entry and timer signals arriving
before KVM starts to catch them. Plug it by blocking both timer related
signals also on !CONFIG_IOTHREAD and process those via signalfd.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
CC: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---

Added blocking of SIGIO/SIGALRM which was missing in previous version.
Stefan just provided a test case, and that now passes.

However, I realized (and checked) that this fix does not work with
signalfd_compat: The signals will be swallowed by the helper thread.
That affects all host kernels < 2.6.22. Given that we require 2.6.29 as
baseline (unless kvm-kmod is used) and that !CONFIG_IOTHREAD is not that
important for KVM mode, I tend to catch and reject
CONFIG_KVM+!CONFIG_IOTHREAD+!CONFIG_SIGNALFD as unsupported during
configure. Comments?

 cpus.c |   20 ++++++++++++++++++++
 1 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/cpus.c b/cpus.c
index fc3f222..f9d9f9e 100644
--- a/cpus.c
+++ b/cpus.c
@@ -254,6 +254,10 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
     pthread_sigmask(SIG_BLOCK, NULL, &set);
     sigdelset(&set, SIG_IPI);
     sigdelset(&set, SIGBUS);
+#ifndef CONFIG_IOTHREAD
+    sigdelset(&set, SIGIO);
+    sigdelset(&set, SIGALRM);
+#endif
     r = kvm_set_signal_mask(env, &set);
     if (r) {
         fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
@@ -351,6 +355,12 @@ static void qemu_kvm_eat_signals(CPUState *env)
             exit(1);
         }
     } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
+
+#ifndef CONFIG_IOTHREAD
+    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
+        qemu_notify_event();
+    }
+#endif
 }
 
 #else /* _WIN32 */
@@ -398,6 +408,14 @@ int qemu_init_main_loop(void)
     int ret;
 
     sigemptyset(&blocked_signals);
+    if (kvm_enabled()) {
+        /*
+         * We need to process timer signals synchronously to avoid a race
+         * between exit_request check and KVM vcpu entry.
+         */
+        sigaddset(&blocked_signals, SIGIO);
+        sigaddset(&blocked_signals, SIGALRM);
+    }
 
     ret = qemu_signalfd_init(blocked_signals);
     if (ret) {
@@ -535,6 +553,8 @@ static sigset_t block_io_signals(void)
     sigaddset(&set, SIGALRM);
     sigaddset(&set, SIG_IPI);
     sigaddset(&set, SIGBUS);
+    sigaddset(&set, SIGIO);
+    sigaddset(&set, SIGALRM);
     pthread_sigmask(SIG_BLOCK, &set, NULL);
 
     memset(&action, 0, sizeof(action));
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v3 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
  2011-01-27 14:20     ` [Qemu-devel] " Jan Kiszka
@ 2011-01-27 14:33       ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 14:33 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, qemu-devel, Stefan Hajnoczi

Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
checking for exit_request on vcpu entry and timer signals arriving
before KVM starts to catch them. Plug it by blocking both timer related
signals also on !CONFIG_IOTHREAD and process those via signalfd.

As this fix depends on real signalfd support (otherwise the timer
signals only kick the compat helper thread, and the main thread hangs),
we need to detect the invalid constellation and abort configure.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
CC: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---

I don't want to invest that much into !IOTHREAD anymore, so let's see if
the proposed catch&abort is acceptable.

 configure |    6 ++++++
 cpus.c    |   20 ++++++++++++++++++++
 2 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/configure b/configure
index 4673bf0..368ca8a 100755
--- a/configure
+++ b/configure
@@ -2056,6 +2056,12 @@ EOF
 
 if compile_prog "" "" ; then
   signalfd=yes
+elif test "$kvm" = "yes" -a "$io_thread" != "yes"; then
+  echo
+  echo "ERROR: Host kernel lacks signalfd() support,"
+  echo "but KVM depends on it when the IO thread is disabled."
+  echo
+  exit 1
 fi
 
 # check if eventfd is supported
diff --git a/cpus.c b/cpus.c
index fc3f222..f9d9f9e 100644
--- a/cpus.c
+++ b/cpus.c
@@ -254,6 +254,10 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
     pthread_sigmask(SIG_BLOCK, NULL, &set);
     sigdelset(&set, SIG_IPI);
     sigdelset(&set, SIGBUS);
+#ifndef CONFIG_IOTHREAD
+    sigdelset(&set, SIGIO);
+    sigdelset(&set, SIGALRM);
+#endif
     r = kvm_set_signal_mask(env, &set);
     if (r) {
         fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
@@ -351,6 +355,12 @@ static void qemu_kvm_eat_signals(CPUState *env)
             exit(1);
         }
     } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
+
+#ifndef CONFIG_IOTHREAD
+    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
+        qemu_notify_event();
+    }
+#endif
 }
 
 #else /* _WIN32 */
@@ -398,6 +408,14 @@ int qemu_init_main_loop(void)
     int ret;
 
     sigemptyset(&blocked_signals);
+    if (kvm_enabled()) {
+        /*
+         * We need to process timer signals synchronously to avoid a race
+         * between exit_request check and KVM vcpu entry.
+         */
+        sigaddset(&blocked_signals, SIGIO);
+        sigaddset(&blocked_signals, SIGALRM);
+    }
 
     ret = qemu_signalfd_init(blocked_signals);
     if (ret) {
@@ -535,6 +553,8 @@ static sigset_t block_io_signals(void)
     sigaddset(&set, SIGALRM);
     sigaddset(&set, SIG_IPI);
     sigaddset(&set, SIGBUS);
+    sigaddset(&set, SIGIO);
+    sigaddset(&set, SIGALRM);
     pthread_sigmask(SIG_BLOCK, &set, NULL);
 
     memset(&action, 0, sizeof(action));
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH v3 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
@ 2011-01-27 14:33       ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-27 14:33 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm, Stefan Hajnoczi

Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
checking for exit_request on vcpu entry and timer signals arriving
before KVM starts to catch them. Plug it by blocking both timer related
signals also on !CONFIG_IOTHREAD and process those via signalfd.

As this fix depends on real signalfd support (otherwise the timer
signals only kick the compat helper thread, and the main thread hangs),
we need to detect the invalid constellation and abort configure.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
CC: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---

I don't want to invest that much into !IOTHREAD anymore, so let's see if
the proposed catch&abort is acceptable.

 configure |    6 ++++++
 cpus.c    |   20 ++++++++++++++++++++
 2 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/configure b/configure
index 4673bf0..368ca8a 100755
--- a/configure
+++ b/configure
@@ -2056,6 +2056,12 @@ EOF
 
 if compile_prog "" "" ; then
   signalfd=yes
+elif test "$kvm" = "yes" -a "$io_thread" != "yes"; then
+  echo
+  echo "ERROR: Host kernel lacks signalfd() support,"
+  echo "but KVM depends on it when the IO thread is disabled."
+  echo
+  exit 1
 fi
 
 # check if eventfd is supported
diff --git a/cpus.c b/cpus.c
index fc3f222..f9d9f9e 100644
--- a/cpus.c
+++ b/cpus.c
@@ -254,6 +254,10 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
     pthread_sigmask(SIG_BLOCK, NULL, &set);
     sigdelset(&set, SIG_IPI);
     sigdelset(&set, SIGBUS);
+#ifndef CONFIG_IOTHREAD
+    sigdelset(&set, SIGIO);
+    sigdelset(&set, SIGALRM);
+#endif
     r = kvm_set_signal_mask(env, &set);
     if (r) {
         fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
@@ -351,6 +355,12 @@ static void qemu_kvm_eat_signals(CPUState *env)
             exit(1);
         }
     } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
+
+#ifndef CONFIG_IOTHREAD
+    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
+        qemu_notify_event();
+    }
+#endif
 }
 
 #else /* _WIN32 */
@@ -398,6 +408,14 @@ int qemu_init_main_loop(void)
     int ret;
 
     sigemptyset(&blocked_signals);
+    if (kvm_enabled()) {
+        /*
+         * We need to process timer signals synchronously to avoid a race
+         * between exit_request check and KVM vcpu entry.
+         */
+        sigaddset(&blocked_signals, SIGIO);
+        sigaddset(&blocked_signals, SIGALRM);
+    }
 
     ret = qemu_signalfd_init(blocked_signals);
     if (ret) {
@@ -535,6 +553,8 @@ static sigset_t block_io_signals(void)
     sigaddset(&set, SIGALRM);
     sigaddset(&set, SIG_IPI);
     sigaddset(&set, SIGBUS);
+    sigaddset(&set, SIGIO);
+    sigaddset(&set, SIGALRM);
     pthread_sigmask(SIG_BLOCK, &set, NULL);
 
     memset(&action, 0, sizeof(action));
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* Re: [PATCH 08/22] kvm: Provide sigbus services arch-independently
  2011-01-27 13:09   ` [Qemu-devel] " Jan Kiszka
@ 2011-01-27 16:39     ` Paolo Bonzini
  -1 siblings, 0 replies; 146+ messages in thread
From: Paolo Bonzini @ 2011-01-27 16:39 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: Avi Kivity, Marcelo Tosatti, kvm, qemu-devel, Huang Ying, Alexander Graf

On 01/27/2011 02:09 PM, Jan Kiszka wrote:
> Provide arch-independent kvm_on_sigbus* stubs to remove the #ifdef'ery
> from cpus.c. This patch also fixes --disable-kvm build by providing the
> missing kvm_on_sigbus_vcpu kvm-stub.
>
> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
> CC: Huang Ying<ying.huang@intel.com>
> CC: Alexander Graf<agraf@suse.de>
> CC: Paolo Bonzini<pbonzini@redhat.com>
> ---
>   cpus.c             |   10 ++++------
>   kvm-all.c          |   10 ++++++++++
>   kvm-stub.c         |    5 +++++
>   kvm.h              |    7 +++++--
>   target-i386/kvm.c  |    4 ++--
>   target-ppc/kvm.c   |   10 ++++++++++
>   target-s390x/kvm.c |   10 ++++++++++
>   7 files changed, 46 insertions(+), 10 deletions(-)
>
> diff --git a/cpus.c b/cpus.c
> index f89826a..ce40e67 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -542,10 +542,9 @@ static void sigbus_reraise(void)
>   static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
>                              void *ctx)
>   {
> -#if defined(TARGET_I386)
> -    if (kvm_on_sigbus(siginfo->ssi_code, (void *)(intptr_t)siginfo->ssi_addr))
> -#endif
> +    if (kvm_on_sigbus(siginfo->ssi_code, (void *)(intptr_t)siginfo->ssi_addr)) {
>           sigbus_reraise();
> +    }
>   }
>
>   static void qemu_kvm_eat_signal(CPUState *env, int timeout)
> @@ -578,10 +577,9 @@ static void qemu_kvm_eat_signal(CPUState *env, int timeout)
>
>           switch (r) {
>           case SIGBUS:
> -#ifdef TARGET_I386
> -            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr))
> -#endif
> +            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {
>                   sigbus_reraise();
> +            }
>               break;
>           default:
>               break;
> diff --git a/kvm-all.c b/kvm-all.c
> index 1a55a10..5bfa8c0 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -1362,3 +1362,13 @@ int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, uint16_t val, bool assign)
>       return -ENOSYS;
>   #endif
>   }
> +
> +int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr)
> +{
> +    return kvm_arch_on_sigbus_vcpu(env, code, addr);
> +}
> +
> +int kvm_on_sigbus(int code, void *addr)
> +{
> +    return kvm_arch_on_sigbus(code, addr);
> +}
> diff --git a/kvm-stub.c b/kvm-stub.c
> index 88682f2..d6b6c8e 100644
> --- a/kvm-stub.c
> +++ b/kvm-stub.c
> @@ -147,6 +147,11 @@ int kvm_set_ioeventfd_mmio_long(int fd, uint32_t adr, uint32_t val, bool assign)
>       return -ENOSYS;
>   }
>
> +int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr)
> +{
> +    return 1;
> +}
> +
>   int kvm_on_sigbus(int code, void *addr)
>   {
>       return 1;
> diff --git a/kvm.h b/kvm.h
> index ca57517..b2fb5c6 100644
> --- a/kvm.h
> +++ b/kvm.h
> @@ -81,6 +81,9 @@ int kvm_set_signal_mask(CPUState *env, const sigset_t *sigset);
>   int kvm_pit_in_kernel(void);
>   int kvm_irqchip_in_kernel(void);
>
> +int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr);
> +int kvm_on_sigbus(int code, void *addr);
> +
>   /* internal API */
>
>   struct KVMState;
> @@ -121,8 +124,8 @@ int kvm_arch_init_vcpu(CPUState *env);
>
>   void kvm_arch_reset_vcpu(CPUState *env);
>
> -int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr);
> -int kvm_on_sigbus(int code, void *addr);
> +int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr);
> +int kvm_arch_on_sigbus(int code, void *addr);
>
>   struct kvm_guest_debug;
>   struct kvm_debug_exit_arch;
> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> index 8e8880a..dd2cadc 100644
> --- a/target-i386/kvm.c
> +++ b/target-i386/kvm.c
> @@ -1837,7 +1837,7 @@ static void kvm_mce_inj_srao_memscrub2(CPUState *env, target_phys_addr_t paddr)
>
>   #endif
>
> -int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr)
> +int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr)
>   {
>   #if defined(KVM_CAP_MCE)
>       void *vaddr;
> @@ -1887,7 +1887,7 @@ int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr)
>       return 0;
>   }
>
> -int kvm_on_sigbus(int code, void *addr)
> +int kvm_arch_on_sigbus(int code, void *addr)
>   {
>   #if defined(KVM_CAP_MCE)
>       if ((first_cpu->mcg_cap&  MCG_SER_P)&&  addr&&  code == BUS_MCEERR_AO) {
> diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
> index 710eca1..93ecc57 100644
> --- a/target-ppc/kvm.c
> +++ b/target-ppc/kvm.c
> @@ -404,3 +404,13 @@ bool kvm_arch_stop_on_emulation_error(CPUState *env)
>   {
>       return true;
>   }
> +
> +int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr)
> +{
> +    return 1;
> +}
> +
> +int kvm_arch_on_sigbus(int code, void *addr)
> +{
> +    return 1;
> +}
> diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
> index 38823f5..1702c46 100644
> --- a/target-s390x/kvm.c
> +++ b/target-s390x/kvm.c
> @@ -505,3 +505,13 @@ bool kvm_arch_stop_on_emulation_error(CPUState *env)
>   {
>       return true;
>   }
> +
> +int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr)
> +{
> +    return 1;
> +}
> +
> +int kvm_arch_on_sigbus(int code, void *addr)
> +{
> +    return 1;
> +}

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

Paolo

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 08/22] kvm: Provide sigbus services arch-independently
@ 2011-01-27 16:39     ` Paolo Bonzini
  0 siblings, 0 replies; 146+ messages in thread
From: Paolo Bonzini @ 2011-01-27 16:39 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: kvm, Marcelo Tosatti, Alexander Graf, qemu-devel, Avi Kivity, Huang Ying

On 01/27/2011 02:09 PM, Jan Kiszka wrote:
> Provide arch-independent kvm_on_sigbus* stubs to remove the #ifdef'ery
> from cpus.c. This patch also fixes --disable-kvm build by providing the
> missing kvm_on_sigbus_vcpu kvm-stub.
>
> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
> CC: Huang Ying<ying.huang@intel.com>
> CC: Alexander Graf<agraf@suse.de>
> CC: Paolo Bonzini<pbonzini@redhat.com>
> ---
>   cpus.c             |   10 ++++------
>   kvm-all.c          |   10 ++++++++++
>   kvm-stub.c         |    5 +++++
>   kvm.h              |    7 +++++--
>   target-i386/kvm.c  |    4 ++--
>   target-ppc/kvm.c   |   10 ++++++++++
>   target-s390x/kvm.c |   10 ++++++++++
>   7 files changed, 46 insertions(+), 10 deletions(-)
>
> diff --git a/cpus.c b/cpus.c
> index f89826a..ce40e67 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -542,10 +542,9 @@ static void sigbus_reraise(void)
>   static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
>                              void *ctx)
>   {
> -#if defined(TARGET_I386)
> -    if (kvm_on_sigbus(siginfo->ssi_code, (void *)(intptr_t)siginfo->ssi_addr))
> -#endif
> +    if (kvm_on_sigbus(siginfo->ssi_code, (void *)(intptr_t)siginfo->ssi_addr)) {
>           sigbus_reraise();
> +    }
>   }
>
>   static void qemu_kvm_eat_signal(CPUState *env, int timeout)
> @@ -578,10 +577,9 @@ static void qemu_kvm_eat_signal(CPUState *env, int timeout)
>
>           switch (r) {
>           case SIGBUS:
> -#ifdef TARGET_I386
> -            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr))
> -#endif
> +            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {
>                   sigbus_reraise();
> +            }
>               break;
>           default:
>               break;
> diff --git a/kvm-all.c b/kvm-all.c
> index 1a55a10..5bfa8c0 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -1362,3 +1362,13 @@ int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, uint16_t val, bool assign)
>       return -ENOSYS;
>   #endif
>   }
> +
> +int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr)
> +{
> +    return kvm_arch_on_sigbus_vcpu(env, code, addr);
> +}
> +
> +int kvm_on_sigbus(int code, void *addr)
> +{
> +    return kvm_arch_on_sigbus(code, addr);
> +}
> diff --git a/kvm-stub.c b/kvm-stub.c
> index 88682f2..d6b6c8e 100644
> --- a/kvm-stub.c
> +++ b/kvm-stub.c
> @@ -147,6 +147,11 @@ int kvm_set_ioeventfd_mmio_long(int fd, uint32_t adr, uint32_t val, bool assign)
>       return -ENOSYS;
>   }
>
> +int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr)
> +{
> +    return 1;
> +}
> +
>   int kvm_on_sigbus(int code, void *addr)
>   {
>       return 1;
> diff --git a/kvm.h b/kvm.h
> index ca57517..b2fb5c6 100644
> --- a/kvm.h
> +++ b/kvm.h
> @@ -81,6 +81,9 @@ int kvm_set_signal_mask(CPUState *env, const sigset_t *sigset);
>   int kvm_pit_in_kernel(void);
>   int kvm_irqchip_in_kernel(void);
>
> +int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr);
> +int kvm_on_sigbus(int code, void *addr);
> +
>   /* internal API */
>
>   struct KVMState;
> @@ -121,8 +124,8 @@ int kvm_arch_init_vcpu(CPUState *env);
>
>   void kvm_arch_reset_vcpu(CPUState *env);
>
> -int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr);
> -int kvm_on_sigbus(int code, void *addr);
> +int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr);
> +int kvm_arch_on_sigbus(int code, void *addr);
>
>   struct kvm_guest_debug;
>   struct kvm_debug_exit_arch;
> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> index 8e8880a..dd2cadc 100644
> --- a/target-i386/kvm.c
> +++ b/target-i386/kvm.c
> @@ -1837,7 +1837,7 @@ static void kvm_mce_inj_srao_memscrub2(CPUState *env, target_phys_addr_t paddr)
>
>   #endif
>
> -int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr)
> +int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr)
>   {
>   #if defined(KVM_CAP_MCE)
>       void *vaddr;
> @@ -1887,7 +1887,7 @@ int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr)
>       return 0;
>   }
>
> -int kvm_on_sigbus(int code, void *addr)
> +int kvm_arch_on_sigbus(int code, void *addr)
>   {
>   #if defined(KVM_CAP_MCE)
>       if ((first_cpu->mcg_cap&  MCG_SER_P)&&  addr&&  code == BUS_MCEERR_AO) {
> diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
> index 710eca1..93ecc57 100644
> --- a/target-ppc/kvm.c
> +++ b/target-ppc/kvm.c
> @@ -404,3 +404,13 @@ bool kvm_arch_stop_on_emulation_error(CPUState *env)
>   {
>       return true;
>   }
> +
> +int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr)
> +{
> +    return 1;
> +}
> +
> +int kvm_arch_on_sigbus(int code, void *addr)
> +{
> +    return 1;
> +}
> diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
> index 38823f5..1702c46 100644
> --- a/target-s390x/kvm.c
> +++ b/target-s390x/kvm.c
> @@ -505,3 +505,13 @@ bool kvm_arch_stop_on_emulation_error(CPUState *env)
>   {
>       return true;
>   }
> +
> +int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr)
> +{
> +    return 1;
> +}
> +
> +int kvm_arch_on_sigbus(int code, void *addr)
> +{
> +    return 1;
> +}

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

Paolo

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 10/22] kvm: Set up signal mask also for !CONFIG_IOTHREAD
  2011-01-27 13:09   ` [Qemu-devel] " Jan Kiszka
@ 2011-01-28  8:08     ` Paolo Bonzini
  -1 siblings, 0 replies; 146+ messages in thread
From: Paolo Bonzini @ 2011-01-28  8:08 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Avi Kivity, Marcelo Tosatti, kvm, qemu-devel

On 01/27/2011 02:09 PM, Jan Kiszka wrote:
> Block SIG_IPI, unblock it during KVM_RUN, just like in io-thread mode.
> It's unused so far, but this infrastructure will be required for
> self-IPIs and to process SIGBUS plus, in KVM mode, SIGIO and SIGALRM. As
> Windows doesn't support signal services, we need to provide a stub for
> the init function.
>
> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
> ---
>   cpus.c |   13 +++++++++++--
>   1 files changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/cpus.c b/cpus.c
> index 16bd8fa..03c89b4 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -231,7 +231,6 @@ fail:
>       return err;
>   }
>
> -#ifdef CONFIG_IOTHREAD
>   static void dummy_signal(int sig)
>   {
>   }
> @@ -246,6 +245,12 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
>       sigact.sa_handler = dummy_signal;
>       sigaction(SIG_IPI,&sigact, NULL);
>
> +#ifndef CONFIG_IOTHREAD
> +    sigemptyset(&set);
> +    sigaddset(&set, SIG_IPI);
> +    pthread_sigmask(SIG_BLOCK,&set, NULL);
> +#endif
> +
>       pthread_sigmask(SIG_BLOCK, NULL,&set);
>       sigdelset(&set, SIG_IPI);
>       sigdelset(&set, SIGBUS);
> @@ -255,7 +260,6 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
>           exit(1);
>       }
>   }
> -#endif
>
>   #else /* _WIN32 */
>
> @@ -284,6 +288,10 @@ static void qemu_event_increment(void)
>           exit (1);
>       }
>   }
> +
> +static void qemu_kvm_init_cpu_signals(CPUState *env)
> +{
> +}
>   #endif /* _WIN32 */
>
>   #ifndef CONFIG_IOTHREAD
> @@ -312,6 +320,7 @@ void qemu_init_vcpu(void *_env)
>               fprintf(stderr, "kvm_init_vcpu failed: %s\n", strerror(-r));
>               exit(1);
>           }
> +        qemu_kvm_init_cpu_signals(env);
>       }
>   }
>

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 10/22] kvm: Set up signal mask also for !CONFIG_IOTHREAD
@ 2011-01-28  8:08     ` Paolo Bonzini
  0 siblings, 0 replies; 146+ messages in thread
From: Paolo Bonzini @ 2011-01-28  8:08 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Marcelo Tosatti, Avi Kivity, kvm, qemu-devel

On 01/27/2011 02:09 PM, Jan Kiszka wrote:
> Block SIG_IPI, unblock it during KVM_RUN, just like in io-thread mode.
> It's unused so far, but this infrastructure will be required for
> self-IPIs and to process SIGBUS plus, in KVM mode, SIGIO and SIGALRM. As
> Windows doesn't support signal services, we need to provide a stub for
> the init function.
>
> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
> ---
>   cpus.c |   13 +++++++++++--
>   1 files changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/cpus.c b/cpus.c
> index 16bd8fa..03c89b4 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -231,7 +231,6 @@ fail:
>       return err;
>   }
>
> -#ifdef CONFIG_IOTHREAD
>   static void dummy_signal(int sig)
>   {
>   }
> @@ -246,6 +245,12 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
>       sigact.sa_handler = dummy_signal;
>       sigaction(SIG_IPI,&sigact, NULL);
>
> +#ifndef CONFIG_IOTHREAD
> +    sigemptyset(&set);
> +    sigaddset(&set, SIG_IPI);
> +    pthread_sigmask(SIG_BLOCK,&set, NULL);
> +#endif
> +
>       pthread_sigmask(SIG_BLOCK, NULL,&set);
>       sigdelset(&set, SIG_IPI);
>       sigdelset(&set, SIGBUS);
> @@ -255,7 +260,6 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
>           exit(1);
>       }
>   }
> -#endif
>
>   #else /* _WIN32 */
>
> @@ -284,6 +288,10 @@ static void qemu_event_increment(void)
>           exit (1);
>       }
>   }
> +
> +static void qemu_kvm_init_cpu_signals(CPUState *env)
> +{
> +}
>   #endif /* _WIN32 */
>
>   #ifndef CONFIG_IOTHREAD
> @@ -312,6 +320,7 @@ void qemu_init_vcpu(void *_env)
>               fprintf(stderr, "kvm_init_vcpu failed: %s\n", strerror(-r));
>               exit(1);
>           }
> +        qemu_kvm_init_cpu_signals(env);
>       }
>   }
>

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 12/22] kvm: Call qemu_kvm_eat_signals also under !CONFIG_IOTHREAD
  2011-01-27 13:09   ` [Qemu-devel] " Jan Kiszka
@ 2011-01-28  8:09     ` Paolo Bonzini
  -1 siblings, 0 replies; 146+ messages in thread
From: Paolo Bonzini @ 2011-01-28  8:09 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Avi Kivity, Marcelo Tosatti, kvm, qemu-devel

On 01/27/2011 02:09 PM, Jan Kiszka wrote:
> Move qemu_kvm_eat_signals around and call it also when the IO-thread is
> not used. Do not yet process SIGBUS, will be armed in a separate step.
>
> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
> ---
>   cpus.c |   88 ++++++++++++++++++++++++++++++++++++---------------------------
>   1 files changed, 50 insertions(+), 38 deletions(-)
>
> diff --git a/cpus.c b/cpus.c
> index 9071848..558c0d3 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -261,6 +261,45 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
>       }
>   }
>
> +static void qemu_kvm_eat_signals(CPUState *env)
> +{
> +    struct timespec ts = { 0, 0 };
> +    siginfo_t siginfo;
> +    sigset_t waitset;
> +    sigset_t chkset;
> +    int r;
> +
> +    sigemptyset(&waitset);
> +    sigaddset(&waitset, SIG_IPI);
> +    sigaddset(&waitset, SIGBUS);
> +
> +    do {
> +        r = sigtimedwait(&waitset,&siginfo,&ts);
> +        if (r == -1&&  !(errno == EAGAIN || errno == EINTR)) {
> +            perror("sigtimedwait");
> +            exit(1);
> +        }
> +
> +        switch (r) {
> +#ifdef CONFIG_IOTHREAD
> +        case SIGBUS:
> +            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {
> +                sigbus_reraise();
> +            }
> +            break;
> +#endif
> +        default:
> +            break;
> +        }
> +
> +        r = sigpending(&chkset);
> +        if (r == -1) {
> +            perror("sigpending");
> +            exit(1);
> +        }
> +    } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
> +}
> +
>   #else /* _WIN32 */
>
>   HANDLE qemu_event_handle;
> @@ -292,6 +331,10 @@ static void qemu_event_increment(void)
>   static void qemu_kvm_init_cpu_signals(CPUState *env)
>   {
>   }
> +
> +static void qemu_kvm_eat_signals(CPUState *env)
> +{
> +}
>   #endif /* _WIN32 */
>
>   #ifndef CONFIG_IOTHREAD
> @@ -631,43 +674,6 @@ static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
>       }
>   }
>
> -static void qemu_kvm_eat_signals(CPUState *env)
> -{
> -    struct timespec ts = { 0, 0 };
> -    siginfo_t siginfo;
> -    sigset_t waitset;
> -    sigset_t chkset;
> -    int r;
> -
> -    sigemptyset(&waitset);
> -    sigaddset(&waitset, SIG_IPI);
> -    sigaddset(&waitset, SIGBUS);
> -
> -    do {
> -        r = sigtimedwait(&waitset,&siginfo,&ts);
> -        if (r == -1&&  !(errno == EAGAIN || errno == EINTR)) {
> -            perror("sigtimedwait");
> -            exit(1);
> -        }
> -
> -        switch (r) {
> -        case SIGBUS:
> -            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {
> -                sigbus_reraise();
> -            }
> -            break;
> -        default:
> -            break;
> -        }
> -
> -        r = sigpending(&chkset);
> -        if (r == -1) {
> -            perror("sigpending");
> -            exit(1);
> -        }
> -    } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
> -}
> -
>   static void qemu_kvm_wait_io_event(CPUState *env)
>   {
>       while (!cpu_has_work(env))
> @@ -932,6 +938,8 @@ static int qemu_cpu_exec(CPUState *env)
>
>   bool cpu_exec_all(void)
>   {
> +    int r;
> +
>       if (next_cpu == NULL)
>           next_cpu = first_cpu;
>       for (; next_cpu != NULL&&  !exit_request; next_cpu = next_cpu->next_cpu) {
> @@ -943,7 +951,11 @@ bool cpu_exec_all(void)
>           if (qemu_alarm_pending())
>               break;
>           if (cpu_can_run(env)) {
> -            if (qemu_cpu_exec(env) == EXCP_DEBUG) {
> +            r = qemu_cpu_exec(env);
> +            if (kvm_enabled()) {
> +                qemu_kvm_eat_signals(env);
> +            }
> +            if (r == EXCP_DEBUG) {
>                   break;
>               }
>           } else if (env->stop) {

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

Paolo

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 12/22] kvm: Call qemu_kvm_eat_signals also under !CONFIG_IOTHREAD
@ 2011-01-28  8:09     ` Paolo Bonzini
  0 siblings, 0 replies; 146+ messages in thread
From: Paolo Bonzini @ 2011-01-28  8:09 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Marcelo Tosatti, Avi Kivity, kvm, qemu-devel

On 01/27/2011 02:09 PM, Jan Kiszka wrote:
> Move qemu_kvm_eat_signals around and call it also when the IO-thread is
> not used. Do not yet process SIGBUS, will be armed in a separate step.
>
> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
> ---
>   cpus.c |   88 ++++++++++++++++++++++++++++++++++++---------------------------
>   1 files changed, 50 insertions(+), 38 deletions(-)
>
> diff --git a/cpus.c b/cpus.c
> index 9071848..558c0d3 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -261,6 +261,45 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
>       }
>   }
>
> +static void qemu_kvm_eat_signals(CPUState *env)
> +{
> +    struct timespec ts = { 0, 0 };
> +    siginfo_t siginfo;
> +    sigset_t waitset;
> +    sigset_t chkset;
> +    int r;
> +
> +    sigemptyset(&waitset);
> +    sigaddset(&waitset, SIG_IPI);
> +    sigaddset(&waitset, SIGBUS);
> +
> +    do {
> +        r = sigtimedwait(&waitset,&siginfo,&ts);
> +        if (r == -1&&  !(errno == EAGAIN || errno == EINTR)) {
> +            perror("sigtimedwait");
> +            exit(1);
> +        }
> +
> +        switch (r) {
> +#ifdef CONFIG_IOTHREAD
> +        case SIGBUS:
> +            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {
> +                sigbus_reraise();
> +            }
> +            break;
> +#endif
> +        default:
> +            break;
> +        }
> +
> +        r = sigpending(&chkset);
> +        if (r == -1) {
> +            perror("sigpending");
> +            exit(1);
> +        }
> +    } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
> +}
> +
>   #else /* _WIN32 */
>
>   HANDLE qemu_event_handle;
> @@ -292,6 +331,10 @@ static void qemu_event_increment(void)
>   static void qemu_kvm_init_cpu_signals(CPUState *env)
>   {
>   }
> +
> +static void qemu_kvm_eat_signals(CPUState *env)
> +{
> +}
>   #endif /* _WIN32 */
>
>   #ifndef CONFIG_IOTHREAD
> @@ -631,43 +674,6 @@ static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
>       }
>   }
>
> -static void qemu_kvm_eat_signals(CPUState *env)
> -{
> -    struct timespec ts = { 0, 0 };
> -    siginfo_t siginfo;
> -    sigset_t waitset;
> -    sigset_t chkset;
> -    int r;
> -
> -    sigemptyset(&waitset);
> -    sigaddset(&waitset, SIG_IPI);
> -    sigaddset(&waitset, SIGBUS);
> -
> -    do {
> -        r = sigtimedwait(&waitset,&siginfo,&ts);
> -        if (r == -1&&  !(errno == EAGAIN || errno == EINTR)) {
> -            perror("sigtimedwait");
> -            exit(1);
> -        }
> -
> -        switch (r) {
> -        case SIGBUS:
> -            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {
> -                sigbus_reraise();
> -            }
> -            break;
> -        default:
> -            break;
> -        }
> -
> -        r = sigpending(&chkset);
> -        if (r == -1) {
> -            perror("sigpending");
> -            exit(1);
> -        }
> -    } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
> -}
> -
>   static void qemu_kvm_wait_io_event(CPUState *env)
>   {
>       while (!cpu_has_work(env))
> @@ -932,6 +938,8 @@ static int qemu_cpu_exec(CPUState *env)
>
>   bool cpu_exec_all(void)
>   {
> +    int r;
> +
>       if (next_cpu == NULL)
>           next_cpu = first_cpu;
>       for (; next_cpu != NULL&&  !exit_request; next_cpu = next_cpu->next_cpu) {
> @@ -943,7 +951,11 @@ bool cpu_exec_all(void)
>           if (qemu_alarm_pending())
>               break;
>           if (cpu_can_run(env)) {
> -            if (qemu_cpu_exec(env) == EXCP_DEBUG) {
> +            r = qemu_cpu_exec(env);
> +            if (kvm_enabled()) {
> +                qemu_kvm_eat_signals(env);
> +            }
> +            if (r == EXCP_DEBUG) {
>                   break;
>               }
>           } else if (env->stop) {

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

Paolo

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 13/22] Set up signalfd under !CONFIG_IOTHREAD
  2011-01-27 13:09   ` [Qemu-devel] " Jan Kiszka
@ 2011-01-28  8:11     ` Paolo Bonzini
  -1 siblings, 0 replies; 146+ messages in thread
From: Paolo Bonzini @ 2011-01-28  8:11 UTC (permalink / raw)
  To: kvm; +Cc: qemu-devel

On 01/27/2011 02:09 PM, Jan Kiszka wrote:
> Will be required for SIGBUS handling. For obvious reasons, this will
> remain a nop on Windows hosts.
>
> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
> ---
>   Makefile.objs |    2 +-
>   cpus.c        |  117 +++++++++++++++++++++++++++++++--------------------------
>   2 files changed, 65 insertions(+), 54 deletions(-)
>
> diff --git a/Makefile.objs b/Makefile.objs
> index c3e52c5..81b9a5b 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -141,7 +141,7 @@ common-obj-y += $(addprefix ui/, $(ui-obj-y))
>
>   common-obj-y += iov.o acl.o
>   common-obj-$(CONFIG_THREAD) += qemu-thread.o
> -common-obj-$(CONFIG_IOTHREAD) += compatfd.o
> +common-obj-$(CONFIG_POSIX) += compatfd.o
>   common-obj-y += notify.o event_notifier.o
>   common-obj-y += qemu-timer.o qemu-timer-common.o
>
> diff --git a/cpus.c b/cpus.c
> index 558c0d3..fc3f222 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -261,6 +261,59 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
>       }
>   }
>
> +/* If we have signalfd, we mask out the signals we want to handle and then
> + * use signalfd to listen for them.  We rely on whatever the current signal
> + * handler is to dispatch the signals when we receive them.
> + */
> +static void sigfd_handler(void *opaque)
> +{
> +    int fd = (unsigned long) opaque;
> +    struct qemu_signalfd_siginfo info;
> +    struct sigaction action;
> +    ssize_t len;
> +
> +    while (1) {
> +        do {
> +            len = read(fd,&info, sizeof(info));
> +        } while (len == -1&&  errno == EINTR);
> +
> +        if (len == -1&&  errno == EAGAIN) {
> +            break;
> +        }
> +
> +        if (len != sizeof(info)) {
> +            printf("read from sigfd returned %zd: %m\n", len);
> +            return;
> +        }
> +
> +        sigaction(info.ssi_signo, NULL,&action);
> +        if ((action.sa_flags&  SA_SIGINFO)&&  action.sa_sigaction) {
> +            action.sa_sigaction(info.ssi_signo,
> +                                (siginfo_t *)&info, NULL);
> +        } else if (action.sa_handler) {
> +            action.sa_handler(info.ssi_signo);
> +        }
> +    }
> +}
> +
> +static int qemu_signalfd_init(sigset_t mask)
> +{
> +    int sigfd;
> +
> +    sigfd = qemu_signalfd(&mask);
> +    if (sigfd == -1) {
> +        fprintf(stderr, "failed to create signalfd\n");
> +        return -errno;
> +    }
> +
> +    fcntl_setfl(sigfd, O_NONBLOCK);
> +
> +    qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL,
> +                         (void *)(unsigned long) sigfd);
> +
> +    return 0;
> +}
> +
>   static void qemu_kvm_eat_signals(CPUState *env)
>   {
>       struct timespec ts = { 0, 0 };
> @@ -340,6 +393,17 @@ static void qemu_kvm_eat_signals(CPUState *env)
>   #ifndef CONFIG_IOTHREAD
>   int qemu_init_main_loop(void)
>   {
> +#ifndef _WIN32
> +    sigset_t blocked_signals;
> +    int ret;
> +
> +    sigemptyset(&blocked_signals);
> +
> +    ret = qemu_signalfd_init(blocked_signals);
> +    if (ret) {
> +        return ret;
> +    }
> +#endif
>       cpu_set_debug_excp_handler(cpu_debug_handler);
>
>       return qemu_event_init();
> @@ -431,41 +495,6 @@ static QemuCond qemu_system_cond;
>   static QemuCond qemu_pause_cond;
>   static QemuCond qemu_work_cond;
>
> -/* If we have signalfd, we mask out the signals we want to handle and then
> - * use signalfd to listen for them.  We rely on whatever the current signal
> - * handler is to dispatch the signals when we receive them.
> - */
> -static void sigfd_handler(void *opaque)
> -{
> -    int fd = (unsigned long) opaque;
> -    struct qemu_signalfd_siginfo info;
> -    struct sigaction action;
> -    ssize_t len;
> -
> -    while (1) {
> -        do {
> -            len = read(fd,&info, sizeof(info));
> -        } while (len == -1&&  errno == EINTR);
> -
> -        if (len == -1&&  errno == EAGAIN) {
> -            break;
> -        }
> -
> -        if (len != sizeof(info)) {
> -            printf("read from sigfd returned %zd: %m\n", len);
> -            return;
> -        }
> -
> -        sigaction(info.ssi_signo, NULL,&action);
> -        if ((action.sa_flags&  SA_SIGINFO)&&  action.sa_sigaction) {
> -            action.sa_sigaction(info.ssi_signo,
> -                                (siginfo_t *)&info, NULL);
> -        } else if (action.sa_handler) {
> -            action.sa_handler(info.ssi_signo);
> -        }
> -    }
> -}
> -
>   static void cpu_signal(int sig)
>   {
>       if (cpu_single_env) {
> @@ -517,24 +546,6 @@ static sigset_t block_io_signals(void)
>       return set;
>   }
>
> -static int qemu_signalfd_init(sigset_t mask)
> -{
> -    int sigfd;
> -
> -    sigfd = qemu_signalfd(&mask);
> -    if (sigfd == -1) {
> -        fprintf(stderr, "failed to create signalfd\n");
> -        return -errno;
> -    }
> -
> -    fcntl_setfl(sigfd, O_NONBLOCK);
> -
> -    qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL,
> -                         (void *)(unsigned long) sigfd);
> -
> -    return 0;
> -}
> -
>   int qemu_init_main_loop(void)
>   {
>       int ret;

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

Paolo


^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 13/22] Set up signalfd under !CONFIG_IOTHREAD
@ 2011-01-28  8:11     ` Paolo Bonzini
  0 siblings, 0 replies; 146+ messages in thread
From: Paolo Bonzini @ 2011-01-28  8:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: kvm

On 01/27/2011 02:09 PM, Jan Kiszka wrote:
> Will be required for SIGBUS handling. For obvious reasons, this will
> remain a nop on Windows hosts.
>
> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
> ---
>   Makefile.objs |    2 +-
>   cpus.c        |  117 +++++++++++++++++++++++++++++++--------------------------
>   2 files changed, 65 insertions(+), 54 deletions(-)
>
> diff --git a/Makefile.objs b/Makefile.objs
> index c3e52c5..81b9a5b 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -141,7 +141,7 @@ common-obj-y += $(addprefix ui/, $(ui-obj-y))
>
>   common-obj-y += iov.o acl.o
>   common-obj-$(CONFIG_THREAD) += qemu-thread.o
> -common-obj-$(CONFIG_IOTHREAD) += compatfd.o
> +common-obj-$(CONFIG_POSIX) += compatfd.o
>   common-obj-y += notify.o event_notifier.o
>   common-obj-y += qemu-timer.o qemu-timer-common.o
>
> diff --git a/cpus.c b/cpus.c
> index 558c0d3..fc3f222 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -261,6 +261,59 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
>       }
>   }
>
> +/* If we have signalfd, we mask out the signals we want to handle and then
> + * use signalfd to listen for them.  We rely on whatever the current signal
> + * handler is to dispatch the signals when we receive them.
> + */
> +static void sigfd_handler(void *opaque)
> +{
> +    int fd = (unsigned long) opaque;
> +    struct qemu_signalfd_siginfo info;
> +    struct sigaction action;
> +    ssize_t len;
> +
> +    while (1) {
> +        do {
> +            len = read(fd,&info, sizeof(info));
> +        } while (len == -1&&  errno == EINTR);
> +
> +        if (len == -1&&  errno == EAGAIN) {
> +            break;
> +        }
> +
> +        if (len != sizeof(info)) {
> +            printf("read from sigfd returned %zd: %m\n", len);
> +            return;
> +        }
> +
> +        sigaction(info.ssi_signo, NULL,&action);
> +        if ((action.sa_flags&  SA_SIGINFO)&&  action.sa_sigaction) {
> +            action.sa_sigaction(info.ssi_signo,
> +                                (siginfo_t *)&info, NULL);
> +        } else if (action.sa_handler) {
> +            action.sa_handler(info.ssi_signo);
> +        }
> +    }
> +}
> +
> +static int qemu_signalfd_init(sigset_t mask)
> +{
> +    int sigfd;
> +
> +    sigfd = qemu_signalfd(&mask);
> +    if (sigfd == -1) {
> +        fprintf(stderr, "failed to create signalfd\n");
> +        return -errno;
> +    }
> +
> +    fcntl_setfl(sigfd, O_NONBLOCK);
> +
> +    qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL,
> +                         (void *)(unsigned long) sigfd);
> +
> +    return 0;
> +}
> +
>   static void qemu_kvm_eat_signals(CPUState *env)
>   {
>       struct timespec ts = { 0, 0 };
> @@ -340,6 +393,17 @@ static void qemu_kvm_eat_signals(CPUState *env)
>   #ifndef CONFIG_IOTHREAD
>   int qemu_init_main_loop(void)
>   {
> +#ifndef _WIN32
> +    sigset_t blocked_signals;
> +    int ret;
> +
> +    sigemptyset(&blocked_signals);
> +
> +    ret = qemu_signalfd_init(blocked_signals);
> +    if (ret) {
> +        return ret;
> +    }
> +#endif
>       cpu_set_debug_excp_handler(cpu_debug_handler);
>
>       return qemu_event_init();
> @@ -431,41 +495,6 @@ static QemuCond qemu_system_cond;
>   static QemuCond qemu_pause_cond;
>   static QemuCond qemu_work_cond;
>
> -/* If we have signalfd, we mask out the signals we want to handle and then
> - * use signalfd to listen for them.  We rely on whatever the current signal
> - * handler is to dispatch the signals when we receive them.
> - */
> -static void sigfd_handler(void *opaque)
> -{
> -    int fd = (unsigned long) opaque;
> -    struct qemu_signalfd_siginfo info;
> -    struct sigaction action;
> -    ssize_t len;
> -
> -    while (1) {
> -        do {
> -            len = read(fd,&info, sizeof(info));
> -        } while (len == -1&&  errno == EINTR);
> -
> -        if (len == -1&&  errno == EAGAIN) {
> -            break;
> -        }
> -
> -        if (len != sizeof(info)) {
> -            printf("read from sigfd returned %zd: %m\n", len);
> -            return;
> -        }
> -
> -        sigaction(info.ssi_signo, NULL,&action);
> -        if ((action.sa_flags&  SA_SIGINFO)&&  action.sa_sigaction) {
> -            action.sa_sigaction(info.ssi_signo,
> -                                (siginfo_t *)&info, NULL);
> -        } else if (action.sa_handler) {
> -            action.sa_handler(info.ssi_signo);
> -        }
> -    }
> -}
> -
>   static void cpu_signal(int sig)
>   {
>       if (cpu_single_env) {
> @@ -517,24 +546,6 @@ static sigset_t block_io_signals(void)
>       return set;
>   }
>
> -static int qemu_signalfd_init(sigset_t mask)
> -{
> -    int sigfd;
> -
> -    sigfd = qemu_signalfd(&mask);
> -    if (sigfd == -1) {
> -        fprintf(stderr, "failed to create signalfd\n");
> -        return -errno;
> -    }
> -
> -    fcntl_setfl(sigfd, O_NONBLOCK);
> -
> -    qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL,
> -                         (void *)(unsigned long) sigfd);
> -
> -    return 0;
> -}
> -
>   int qemu_init_main_loop(void)
>   {
>       int ret;

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

Paolo

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 08/22] kvm: Provide sigbus services arch-independently
  2011-01-27 13:09   ` [Qemu-devel] " Jan Kiszka
@ 2011-01-30 14:51     ` Alexander Graf
  -1 siblings, 0 replies; 146+ messages in thread
From: Alexander Graf @ 2011-01-30 14:51 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: Avi Kivity, Marcelo Tosatti, kvm, qemu-devel, Huang Ying, Paolo Bonzini


On 27.01.2011, at 14:09, Jan Kiszka wrote:

> Provide arch-independent kvm_on_sigbus* stubs to remove the #ifdef'ery
> from cpus.c. This patch also fixes --disable-kvm build by providing the
> missing kvm_on_sigbus_vcpu kvm-stub.
> 
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> CC: Huang Ying <ying.huang@intel.com>
> CC: Alexander Graf <agraf@suse.de>
> CC: Paolo Bonzini <pbonzini@redhat.com>

Acked-by: Alexander Graf <agraf@suse.de>


Alex


^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 08/22] kvm: Provide sigbus services arch-independently
@ 2011-01-30 14:51     ` Alexander Graf
  0 siblings, 0 replies; 146+ messages in thread
From: Alexander Graf @ 2011-01-30 14:51 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: kvm, Marcelo Tosatti, qemu-devel, Avi Kivity, Huang Ying, Paolo Bonzini


On 27.01.2011, at 14:09, Jan Kiszka wrote:

> Provide arch-independent kvm_on_sigbus* stubs to remove the #ifdef'ery
> from cpus.c. This patch also fixes --disable-kvm build by providing the
> missing kvm_on_sigbus_vcpu kvm-stub.
> 
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> CC: Huang Ying <ying.huang@intel.com>
> CC: Alexander Graf <agraf@suse.de>
> CC: Paolo Bonzini <pbonzini@redhat.com>

Acked-by: Alexander Graf <agraf@suse.de>


Alex

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 01/22] Prevent abortion on multiple VCPU kicks
  2011-01-27 13:09   ` [Qemu-devel] " Jan Kiszka
@ 2011-01-31  9:44     ` Avi Kivity
  -1 siblings, 0 replies; 146+ messages in thread
From: Avi Kivity @ 2011-01-31  9:44 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Marcelo Tosatti, kvm, qemu-devel

On 01/27/2011 03:09 PM, Jan Kiszka wrote:
> If we call qemu_cpu_kick more than once before the target was able to
> process the signal, pthread_kill will fail, and qemu will abort. Prevent
> this by avoiding the redundant signal.
>

Doesn't fit with the manual page (or with the idea that signals are 
asynchronous):

NAME
        pthread_kill - send a signal to a thread


...

ERRORS
        ESRCH  No thread with the ID thread could be found.

        EINVAL An invalid signal was specified.



-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 01/22] Prevent abortion on multiple VCPU kicks
@ 2011-01-31  9:44     ` Avi Kivity
  0 siblings, 0 replies; 146+ messages in thread
From: Avi Kivity @ 2011-01-31  9:44 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Marcelo Tosatti, qemu-devel, kvm

On 01/27/2011 03:09 PM, Jan Kiszka wrote:
> If we call qemu_cpu_kick more than once before the target was able to
> process the signal, pthread_kill will fail, and qemu will abort. Prevent
> this by avoiding the redundant signal.
>

Doesn't fit with the manual page (or with the idea that signals are 
asynchronous):

NAME
        pthread_kill - send a signal to a thread


...

ERRORS
        ESRCH  No thread with the ID thread could be found.

        EINVAL An invalid signal was specified.



-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 04/22] Leave inner main_loop faster on pending requests
  2011-01-27 13:09   ` [Qemu-devel] " Jan Kiszka
@ 2011-01-31  9:52     ` Avi Kivity
  -1 siblings, 0 replies; 146+ messages in thread
From: Avi Kivity @ 2011-01-31  9:52 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Marcelo Tosatti, kvm, qemu-devel

On 01/27/2011 03:09 PM, Jan Kiszka wrote:
> If there is any pending request that requires us to leave the inner loop
> if main_loop, makes sure we do this as soon as possible by enforcing
> non-blocking IO processing.
>
> At this change, move variable definitions out of the inner loop to
> improve readability.
>
> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
> ---
>   vl.c |   11 +++++++----
>   1 files changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/vl.c b/vl.c
> index 5fad700..2ebc55b 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -1384,18 +1384,21 @@ qemu_irq qemu_system_powerdown;
>
>   static void main_loop(void)
>   {
> +    bool nonblocking = false;
> +#ifdef CONFIG_PROFILER
> +    int64_t ti;
> +#endif
>       int r;
>
>       qemu_main_loop_start();
>
>       for (;;) {
>           do {
> -            bool nonblocking = false;
> -#ifdef CONFIG_PROFILER
> -            int64_t ti;
> -#endif
>   #ifndef CONFIG_IOTHREAD
>               nonblocking = cpu_exec_all();
> +            if (!vm_can_run()) {
> +                nonblocking = true;
> +            }

Doesn't this cause vmstop to spin?  We'll never execute 
main_loop_wait(false) if I read the code correctly?

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 04/22] Leave inner main_loop faster on pending requests
@ 2011-01-31  9:52     ` Avi Kivity
  0 siblings, 0 replies; 146+ messages in thread
From: Avi Kivity @ 2011-01-31  9:52 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Marcelo Tosatti, qemu-devel, kvm

On 01/27/2011 03:09 PM, Jan Kiszka wrote:
> If there is any pending request that requires us to leave the inner loop
> if main_loop, makes sure we do this as soon as possible by enforcing
> non-blocking IO processing.
>
> At this change, move variable definitions out of the inner loop to
> improve readability.
>
> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
> ---
>   vl.c |   11 +++++++----
>   1 files changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/vl.c b/vl.c
> index 5fad700..2ebc55b 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -1384,18 +1384,21 @@ qemu_irq qemu_system_powerdown;
>
>   static void main_loop(void)
>   {
> +    bool nonblocking = false;
> +#ifdef CONFIG_PROFILER
> +    int64_t ti;
> +#endif
>       int r;
>
>       qemu_main_loop_start();
>
>       for (;;) {
>           do {
> -            bool nonblocking = false;
> -#ifdef CONFIG_PROFILER
> -            int64_t ti;
> -#endif
>   #ifndef CONFIG_IOTHREAD
>               nonblocking = cpu_exec_all();
> +            if (!vm_can_run()) {
> +                nonblocking = true;
> +            }

Doesn't this cause vmstop to spin?  We'll never execute 
main_loop_wait(false) if I read the code correctly?

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v3 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
  2011-01-27 14:33       ` [Qemu-devel] " Jan Kiszka
@ 2011-01-31 10:03         ` Avi Kivity
  -1 siblings, 0 replies; 146+ messages in thread
From: Avi Kivity @ 2011-01-31 10:03 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Marcelo Tosatti, kvm, qemu-devel, Stefan Hajnoczi

On 01/27/2011 04:33 PM, Jan Kiszka wrote:
> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
> checking for exit_request on vcpu entry and timer signals arriving
> before KVM starts to catch them. Plug it by blocking both timer related
> signals also on !CONFIG_IOTHREAD and process those via signalfd.
>
> As this fix depends on real signalfd support (otherwise the timer
> signals only kick the compat helper thread, and the main thread hangs),
> we need to detect the invalid constellation and abort configure.
>
> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
> CC: Stefan Hajnoczi<stefanha@linux.vnet.ibm.com>
> ---
>
> I don't want to invest that much into !IOTHREAD anymore, so let's see if
> the proposed catch&abort is acceptable.
>

I don't understand the dependency on signalfd.  The normal way of doing 
things, either waiting for the signal in sigtimedwait() or in 
ioctl(KVM_RUN), works with SIGALRM just fine.

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH v3 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
@ 2011-01-31 10:03         ` Avi Kivity
  0 siblings, 0 replies; 146+ messages in thread
From: Avi Kivity @ 2011-01-31 10:03 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Marcelo Tosatti, qemu-devel, kvm, Stefan Hajnoczi

On 01/27/2011 04:33 PM, Jan Kiszka wrote:
> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
> checking for exit_request on vcpu entry and timer signals arriving
> before KVM starts to catch them. Plug it by blocking both timer related
> signals also on !CONFIG_IOTHREAD and process those via signalfd.
>
> As this fix depends on real signalfd support (otherwise the timer
> signals only kick the compat helper thread, and the main thread hangs),
> we need to detect the invalid constellation and abort configure.
>
> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
> CC: Stefan Hajnoczi<stefanha@linux.vnet.ibm.com>
> ---
>
> I don't want to invest that much into !IOTHREAD anymore, so let's see if
> the proposed catch&abort is acceptable.
>

I don't understand the dependency on signalfd.  The normal way of doing 
things, either waiting for the signal in sigtimedwait() or in 
ioctl(KVM_RUN), works with SIGALRM just fine.

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 17/22] kvm: Move irqchip event processing out of inner loop
  2011-01-27 13:10   ` [Qemu-devel] " Jan Kiszka
@ 2011-01-31 10:08     ` Avi Kivity
  -1 siblings, 0 replies; 146+ messages in thread
From: Avi Kivity @ 2011-01-31 10:08 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Marcelo Tosatti, kvm, qemu-devel

On 01/27/2011 03:10 PM, Jan Kiszka wrote:
> Align with qemu-kvm and prepare for IO exit fix: There is no need to run
> kvm_arch_process_irqchip_events in the inner VCPU loop. Any state change
> this service processes will first cause an exit from kvm_cpu_exec
> anyway. And we will have to reenter the kernel on IO exits
> unconditionally, something that the current logic prevents.
>
> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
> ---
>   kvm-all.c |   11 ++++++-----
>   1 files changed, 6 insertions(+), 5 deletions(-)
>
> diff --git a/kvm-all.c b/kvm-all.c
> index 5bfa8c0..46ecc1c 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -892,6 +892,12 @@ int kvm_cpu_exec(CPUState *env)
>
>       DPRINTF("kvm_cpu_exec()\n");
>
> +    if (kvm_arch_process_irqchip_events(env)) {
> +        env->exit_request = 0;
> +        env->exception_index = EXCP_HLT;
> +        return 0;
> +    }
> +
>       do {
>   #ifndef CONFIG_IOTHREAD
>           if (env->exit_request) {
> @@ -901,11 +907,6 @@ int kvm_cpu_exec(CPUState *env)
>           }

We check for ->exit_request here

>   #endif
>
> -        if (kvm_arch_process_irqchip_events(env)) {
> -            ret = 0;
> -            break;
> -        }
> -

But this checks for ->interrupt_request.  What ensures that we exit when 
->interrupt_request is set?

>           if (env->kvm_vcpu_dirty) {
>               kvm_arch_put_registers(env, KVM_PUT_RUNTIME_STATE);
>               env->kvm_vcpu_dirty = 0;


-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 17/22] kvm: Move irqchip event processing out of inner loop
@ 2011-01-31 10:08     ` Avi Kivity
  0 siblings, 0 replies; 146+ messages in thread
From: Avi Kivity @ 2011-01-31 10:08 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Marcelo Tosatti, qemu-devel, kvm

On 01/27/2011 03:10 PM, Jan Kiszka wrote:
> Align with qemu-kvm and prepare for IO exit fix: There is no need to run
> kvm_arch_process_irqchip_events in the inner VCPU loop. Any state change
> this service processes will first cause an exit from kvm_cpu_exec
> anyway. And we will have to reenter the kernel on IO exits
> unconditionally, something that the current logic prevents.
>
> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
> ---
>   kvm-all.c |   11 ++++++-----
>   1 files changed, 6 insertions(+), 5 deletions(-)
>
> diff --git a/kvm-all.c b/kvm-all.c
> index 5bfa8c0..46ecc1c 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -892,6 +892,12 @@ int kvm_cpu_exec(CPUState *env)
>
>       DPRINTF("kvm_cpu_exec()\n");
>
> +    if (kvm_arch_process_irqchip_events(env)) {
> +        env->exit_request = 0;
> +        env->exception_index = EXCP_HLT;
> +        return 0;
> +    }
> +
>       do {
>   #ifndef CONFIG_IOTHREAD
>           if (env->exit_request) {
> @@ -901,11 +907,6 @@ int kvm_cpu_exec(CPUState *env)
>           }

We check for ->exit_request here

>   #endif
>
> -        if (kvm_arch_process_irqchip_events(env)) {
> -            ret = 0;
> -            break;
> -        }
> -

But this checks for ->interrupt_request.  What ensures that we exit when 
->interrupt_request is set?

>           if (env->kvm_vcpu_dirty) {
>               kvm_arch_put_registers(env, KVM_PUT_RUNTIME_STATE);
>               env->kvm_vcpu_dirty = 0;


-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 00/22] [uq/master] Patch queue, part II
  2011-01-27 13:09 ` [Qemu-devel] " Jan Kiszka
@ 2011-01-31 10:12   ` Avi Kivity
  -1 siblings, 0 replies; 146+ messages in thread
From: Avi Kivity @ 2011-01-31 10:12 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: Marcelo Tosatti, kvm, qemu-devel, Alexander Graf, Gleb Natapov,
	Hidetoshi Seto, Huang Ying, Jin Dongming, Paolo Bonzini,
	Stefan Hajnoczi

On 01/27/2011 03:09 PM, Jan Kiszka wrote:
> This second round of patches focus on issues in cpus.c, primarily signal
> related. The highlights are
>
>   - Add missing KVM_RUN continuation after I/O exits
>   - Fix for timer signal race in KVM entry code under !CONFIG_IOTHREAD
>     (based on Stefan's findings)
>   - MCE signal processing under !CONFIG_IOTHREAD
>   - Prevent abortion on multiple VCPU kicks
>   - Fixed synchronous (ie. VCPU-issued) reset request processing
>
> Topics remaining for a third round are cleanups and refactorings of the
> KVM VCPU entry/exit path, MCE rework, and a few assorted cleanups. But I
> will wait at least until these bits here are ready for an upstream
> merge.
>

Pretty nice.  Is this standalone or does it depend on unmerged changes?

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 00/22] [uq/master] Patch queue, part II
@ 2011-01-31 10:12   ` Avi Kivity
  0 siblings, 0 replies; 146+ messages in thread
From: Avi Kivity @ 2011-01-31 10:12 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: Hidetoshi Seto, kvm, Gleb Natapov, Marcelo Tosatti, qemu-devel,
	Alexander Graf, Huang Ying, Paolo Bonzini, Stefan Hajnoczi,
	Jin Dongming

On 01/27/2011 03:09 PM, Jan Kiszka wrote:
> This second round of patches focus on issues in cpus.c, primarily signal
> related. The highlights are
>
>   - Add missing KVM_RUN continuation after I/O exits
>   - Fix for timer signal race in KVM entry code under !CONFIG_IOTHREAD
>     (based on Stefan's findings)
>   - MCE signal processing under !CONFIG_IOTHREAD
>   - Prevent abortion on multiple VCPU kicks
>   - Fixed synchronous (ie. VCPU-issued) reset request processing
>
> Topics remaining for a third round are cleanups and refactorings of the
> KVM VCPU entry/exit path, MCE rework, and a few assorted cleanups. But I
> will wait at least until these bits here are ready for an upstream
> merge.
>

Pretty nice.  Is this standalone or does it depend on unmerged changes?

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 01/22] Prevent abortion on multiple VCPU kicks
  2011-01-31  9:44     ` [Qemu-devel] " Avi Kivity
@ 2011-01-31 11:19       ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 11:19 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Marcelo Tosatti, kvm, qemu-devel

On 2011-01-31 10:44, Avi Kivity wrote:
> On 01/27/2011 03:09 PM, Jan Kiszka wrote:
>> If we call qemu_cpu_kick more than once before the target was able to
>> process the signal, pthread_kill will fail, and qemu will abort. Prevent
>> this by avoiding the redundant signal.
>>
> 
> Doesn't fit with the manual page (or with the idea that signals are 
> asynchronous):
> 
> NAME
>         pthread_kill - send a signal to a thread
> 
> 
> ...
> 
> ERRORS
>         ESRCH  No thread with the ID thread could be found.
> 
>         EINVAL An invalid signal was specified.
> 

Valid remark, but I was receiving EAGAIN for blocked RT signals. Don't
know if this is Linux-specific. A quick glance at the man pages did not
reveal if this is allowed or at least gray area.

However, even when selectively ignoring this, it's more efficient to
catch the redundant signaling in user space.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 01/22] Prevent abortion on multiple VCPU kicks
@ 2011-01-31 11:19       ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 11:19 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Marcelo Tosatti, qemu-devel, kvm

On 2011-01-31 10:44, Avi Kivity wrote:
> On 01/27/2011 03:09 PM, Jan Kiszka wrote:
>> If we call qemu_cpu_kick more than once before the target was able to
>> process the signal, pthread_kill will fail, and qemu will abort. Prevent
>> this by avoiding the redundant signal.
>>
> 
> Doesn't fit with the manual page (or with the idea that signals are 
> asynchronous):
> 
> NAME
>         pthread_kill - send a signal to a thread
> 
> 
> ...
> 
> ERRORS
>         ESRCH  No thread with the ID thread could be found.
> 
>         EINVAL An invalid signal was specified.
> 

Valid remark, but I was receiving EAGAIN for blocked RT signals. Don't
know if this is Linux-specific. A quick glance at the man pages did not
reveal if this is allowed or at least gray area.

However, even when selectively ignoring this, it's more efficient to
catch the redundant signaling in user space.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 04/22] Leave inner main_loop faster on pending requests
  2011-01-31  9:52     ` [Qemu-devel] " Avi Kivity
@ 2011-01-31 11:22       ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 11:22 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Marcelo Tosatti, kvm, qemu-devel

On 2011-01-31 10:52, Avi Kivity wrote:
> On 01/27/2011 03:09 PM, Jan Kiszka wrote:
>> If there is any pending request that requires us to leave the inner loop
>> if main_loop, makes sure we do this as soon as possible by enforcing
>> non-blocking IO processing.
>>
>> At this change, move variable definitions out of the inner loop to
>> improve readability.
>>
>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>> ---
>>   vl.c |   11 +++++++----
>>   1 files changed, 7 insertions(+), 4 deletions(-)
>>
>> diff --git a/vl.c b/vl.c
>> index 5fad700..2ebc55b 100644
>> --- a/vl.c
>> +++ b/vl.c
>> @@ -1384,18 +1384,21 @@ qemu_irq qemu_system_powerdown;
>>
>>   static void main_loop(void)
>>   {
>> +    bool nonblocking = false;
>> +#ifdef CONFIG_PROFILER
>> +    int64_t ti;
>> +#endif
>>       int r;
>>
>>       qemu_main_loop_start();
>>
>>       for (;;) {
>>           do {
>> -            bool nonblocking = false;
>> -#ifdef CONFIG_PROFILER
>> -            int64_t ti;
>> -#endif
>>   #ifndef CONFIG_IOTHREAD
>>               nonblocking = cpu_exec_all();
>> +            if (!vm_can_run()) {
>> +                nonblocking = true;
>> +            }
> 
> Doesn't this cause vmstop to spin?  We'll never execute 
> main_loop_wait(false) if I read the code correctly?
> 

The code path is not changed, we just poll instead of wait in
main_loop_wait.

Also, I didn't get your error scenario yet. Even if we left the loop
here, what magic would main_loop_wait do to vmstop processing? The stop
request is handled outside the loop, that's why we should leave ASAP.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 04/22] Leave inner main_loop faster on pending requests
@ 2011-01-31 11:22       ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 11:22 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Marcelo Tosatti, qemu-devel, kvm

On 2011-01-31 10:52, Avi Kivity wrote:
> On 01/27/2011 03:09 PM, Jan Kiszka wrote:
>> If there is any pending request that requires us to leave the inner loop
>> if main_loop, makes sure we do this as soon as possible by enforcing
>> non-blocking IO processing.
>>
>> At this change, move variable definitions out of the inner loop to
>> improve readability.
>>
>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>> ---
>>   vl.c |   11 +++++++----
>>   1 files changed, 7 insertions(+), 4 deletions(-)
>>
>> diff --git a/vl.c b/vl.c
>> index 5fad700..2ebc55b 100644
>> --- a/vl.c
>> +++ b/vl.c
>> @@ -1384,18 +1384,21 @@ qemu_irq qemu_system_powerdown;
>>
>>   static void main_loop(void)
>>   {
>> +    bool nonblocking = false;
>> +#ifdef CONFIG_PROFILER
>> +    int64_t ti;
>> +#endif
>>       int r;
>>
>>       qemu_main_loop_start();
>>
>>       for (;;) {
>>           do {
>> -            bool nonblocking = false;
>> -#ifdef CONFIG_PROFILER
>> -            int64_t ti;
>> -#endif
>>   #ifndef CONFIG_IOTHREAD
>>               nonblocking = cpu_exec_all();
>> +            if (!vm_can_run()) {
>> +                nonblocking = true;
>> +            }
> 
> Doesn't this cause vmstop to spin?  We'll never execute 
> main_loop_wait(false) if I read the code correctly?
> 

The code path is not changed, we just poll instead of wait in
main_loop_wait.

Also, I didn't get your error scenario yet. Even if we left the loop
here, what magic would main_loop_wait do to vmstop processing? The stop
request is handled outside the loop, that's why we should leave ASAP.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v3 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
  2011-01-31 10:03         ` [Qemu-devel] " Avi Kivity
@ 2011-01-31 11:27           ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 11:27 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Marcelo Tosatti, kvm, qemu-devel, Stefan Hajnoczi

On 2011-01-31 11:03, Avi Kivity wrote:
> On 01/27/2011 04:33 PM, Jan Kiszka wrote:
>> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
>> checking for exit_request on vcpu entry and timer signals arriving
>> before KVM starts to catch them. Plug it by blocking both timer related
>> signals also on !CONFIG_IOTHREAD and process those via signalfd.
>>
>> As this fix depends on real signalfd support (otherwise the timer
>> signals only kick the compat helper thread, and the main thread hangs),
>> we need to detect the invalid constellation and abort configure.
>>
>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>> CC: Stefan Hajnoczi<stefanha@linux.vnet.ibm.com>
>> ---
>>
>> I don't want to invest that much into !IOTHREAD anymore, so let's see if
>> the proposed catch&abort is acceptable.
>>
> 
> I don't understand the dependency on signalfd.  The normal way of doing 
> things, either waiting for the signal in sigtimedwait() or in 
> ioctl(KVM_RUN), works with SIGALRM just fine.

And how would you be kicked out of the select() call if it is waiting
with a timeout? We only have a single thread here.

The only alternative is Stefan's original proposal. But that required
fiddling with the signal mask twice per KVM_RUN.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH v3 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
@ 2011-01-31 11:27           ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 11:27 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Marcelo Tosatti, qemu-devel, kvm, Stefan Hajnoczi

On 2011-01-31 11:03, Avi Kivity wrote:
> On 01/27/2011 04:33 PM, Jan Kiszka wrote:
>> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
>> checking for exit_request on vcpu entry and timer signals arriving
>> before KVM starts to catch them. Plug it by blocking both timer related
>> signals also on !CONFIG_IOTHREAD and process those via signalfd.
>>
>> As this fix depends on real signalfd support (otherwise the timer
>> signals only kick the compat helper thread, and the main thread hangs),
>> we need to detect the invalid constellation and abort configure.
>>
>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>> CC: Stefan Hajnoczi<stefanha@linux.vnet.ibm.com>
>> ---
>>
>> I don't want to invest that much into !IOTHREAD anymore, so let's see if
>> the proposed catch&abort is acceptable.
>>
> 
> I don't understand the dependency on signalfd.  The normal way of doing 
> things, either waiting for the signal in sigtimedwait() or in 
> ioctl(KVM_RUN), works with SIGALRM just fine.

And how would you be kicked out of the select() call if it is waiting
with a timeout? We only have a single thread here.

The only alternative is Stefan's original proposal. But that required
fiddling with the signal mask twice per KVM_RUN.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 17/22] kvm: Move irqchip event processing out of inner loop
  2011-01-31 10:08     ` [Qemu-devel] " Avi Kivity
@ 2011-01-31 11:36       ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 11:36 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Marcelo Tosatti, kvm, qemu-devel

On 2011-01-31 11:08, Avi Kivity wrote:
> On 01/27/2011 03:10 PM, Jan Kiszka wrote:
>> Align with qemu-kvm and prepare for IO exit fix: There is no need to run
>> kvm_arch_process_irqchip_events in the inner VCPU loop. Any state change
>> this service processes will first cause an exit from kvm_cpu_exec
>> anyway. And we will have to reenter the kernel on IO exits
>> unconditionally, something that the current logic prevents.
>>
>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>> ---
>>   kvm-all.c |   11 ++++++-----
>>   1 files changed, 6 insertions(+), 5 deletions(-)
>>
>> diff --git a/kvm-all.c b/kvm-all.c
>> index 5bfa8c0..46ecc1c 100644
>> --- a/kvm-all.c
>> +++ b/kvm-all.c
>> @@ -892,6 +892,12 @@ int kvm_cpu_exec(CPUState *env)
>>
>>       DPRINTF("kvm_cpu_exec()\n");
>>
>> +    if (kvm_arch_process_irqchip_events(env)) {
>> +        env->exit_request = 0;
>> +        env->exception_index = EXCP_HLT;
>> +        return 0;
>> +    }
>> +
>>       do {
>>   #ifndef CONFIG_IOTHREAD
>>           if (env->exit_request) {
>> @@ -901,11 +907,6 @@ int kvm_cpu_exec(CPUState *env)
>>           }
> 
> We check for ->exit_request here
> 
>>   #endif
>>
>> -        if (kvm_arch_process_irqchip_events(env)) {
>> -            ret = 0;
>> -            break;
>> -        }
>> -
> 
> But this checks for ->interrupt_request.  What ensures that we exit when 
> ->interrupt_request is set?

Good question, need to check again. But if that turns out to be an
issue, qemu-kvm would be broken as well. I'm just aligning the code here.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 17/22] kvm: Move irqchip event processing out of inner loop
@ 2011-01-31 11:36       ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 11:36 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Marcelo Tosatti, qemu-devel, kvm

On 2011-01-31 11:08, Avi Kivity wrote:
> On 01/27/2011 03:10 PM, Jan Kiszka wrote:
>> Align with qemu-kvm and prepare for IO exit fix: There is no need to run
>> kvm_arch_process_irqchip_events in the inner VCPU loop. Any state change
>> this service processes will first cause an exit from kvm_cpu_exec
>> anyway. And we will have to reenter the kernel on IO exits
>> unconditionally, something that the current logic prevents.
>>
>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>> ---
>>   kvm-all.c |   11 ++++++-----
>>   1 files changed, 6 insertions(+), 5 deletions(-)
>>
>> diff --git a/kvm-all.c b/kvm-all.c
>> index 5bfa8c0..46ecc1c 100644
>> --- a/kvm-all.c
>> +++ b/kvm-all.c
>> @@ -892,6 +892,12 @@ int kvm_cpu_exec(CPUState *env)
>>
>>       DPRINTF("kvm_cpu_exec()\n");
>>
>> +    if (kvm_arch_process_irqchip_events(env)) {
>> +        env->exit_request = 0;
>> +        env->exception_index = EXCP_HLT;
>> +        return 0;
>> +    }
>> +
>>       do {
>>   #ifndef CONFIG_IOTHREAD
>>           if (env->exit_request) {
>> @@ -901,11 +907,6 @@ int kvm_cpu_exec(CPUState *env)
>>           }
> 
> We check for ->exit_request here
> 
>>   #endif
>>
>> -        if (kvm_arch_process_irqchip_events(env)) {
>> -            ret = 0;
>> -            break;
>> -        }
>> -
> 
> But this checks for ->interrupt_request.  What ensures that we exit when 
> ->interrupt_request is set?

Good question, need to check again. But if that turns out to be an
issue, qemu-kvm would be broken as well. I'm just aligning the code here.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 00/22] [uq/master] Patch queue, part II
  2011-01-31 10:12   ` [Qemu-devel] " Avi Kivity
@ 2011-01-31 12:03     ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 12:03 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Marcelo Tosatti, kvm, qemu-devel, Alexander Graf, Gleb Natapov,
	Hidetoshi Seto, Huang Ying, Jin Dongming, Paolo Bonzini,
	Stefan Hajnoczi

On 2011-01-31 11:12, Avi Kivity wrote:
> On 01/27/2011 03:09 PM, Jan Kiszka wrote:
>> This second round of patches focus on issues in cpus.c, primarily signal
>> related. The highlights are
>>
>>   - Add missing KVM_RUN continuation after I/O exits
>>   - Fix for timer signal race in KVM entry code under !CONFIG_IOTHREAD
>>     (based on Stefan's findings)
>>   - MCE signal processing under !CONFIG_IOTHREAD
>>   - Prevent abortion on multiple VCPU kicks
>>   - Fixed synchronous (ie. VCPU-issued) reset request processing
>>
>> Topics remaining for a third round are cleanups and refactorings of the
>> KVM VCPU entry/exit path, MCE rework, and a few assorted cleanups. But I
>> will wait at least until these bits here are ready for an upstream
>> merge.
>>
> 
> Pretty nice.  Is this standalone or does it depend on unmerged changes?
> 

It only depends on my previous patches in current uq/master.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 00/22] [uq/master] Patch queue, part II
@ 2011-01-31 12:03     ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 12:03 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Hidetoshi Seto, kvm, Gleb Natapov, Marcelo Tosatti, qemu-devel,
	Alexander Graf, Huang Ying, Paolo Bonzini, Stefan Hajnoczi,
	Jin Dongming

On 2011-01-31 11:12, Avi Kivity wrote:
> On 01/27/2011 03:09 PM, Jan Kiszka wrote:
>> This second round of patches focus on issues in cpus.c, primarily signal
>> related. The highlights are
>>
>>   - Add missing KVM_RUN continuation after I/O exits
>>   - Fix for timer signal race in KVM entry code under !CONFIG_IOTHREAD
>>     (based on Stefan's findings)
>>   - MCE signal processing under !CONFIG_IOTHREAD
>>   - Prevent abortion on multiple VCPU kicks
>>   - Fixed synchronous (ie. VCPU-issued) reset request processing
>>
>> Topics remaining for a third round are cleanups and refactorings of the
>> KVM VCPU entry/exit path, MCE rework, and a few assorted cleanups. But I
>> will wait at least until these bits here are ready for an upstream
>> merge.
>>
> 
> Pretty nice.  Is this standalone or does it depend on unmerged changes?
> 

It only depends on my previous patches in current uq/master.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [Qemu-devel] Re: [PATCH v3 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
  2011-01-31 11:27           ` [Qemu-devel] " Jan Kiszka
@ 2011-01-31 12:13             ` Stefan Hajnoczi
  -1 siblings, 0 replies; 146+ messages in thread
From: Stefan Hajnoczi @ 2011-01-31 12:13 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Avi Kivity, Marcelo Tosatti, qemu-devel, kvm, Stefan Hajnoczi

On Mon, Jan 31, 2011 at 11:27 AM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
> On 2011-01-31 11:03, Avi Kivity wrote:
>> On 01/27/2011 04:33 PM, Jan Kiszka wrote:
>>> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
>>> checking for exit_request on vcpu entry and timer signals arriving
>>> before KVM starts to catch them. Plug it by blocking both timer related
>>> signals also on !CONFIG_IOTHREAD and process those via signalfd.
>>>
>>> As this fix depends on real signalfd support (otherwise the timer
>>> signals only kick the compat helper thread, and the main thread hangs),
>>> we need to detect the invalid constellation and abort configure.
>>>
>>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>>> CC: Stefan Hajnoczi<stefanha@linux.vnet.ibm.com>
>>> ---
>>>
>>> I don't want to invest that much into !IOTHREAD anymore, so let's see if
>>> the proposed catch&abort is acceptable.
>>>
>>
>> I don't understand the dependency on signalfd.  The normal way of doing
>> things, either waiting for the signal in sigtimedwait() or in
>> ioctl(KVM_RUN), works with SIGALRM just fine.
>
> And how would you be kicked out of the select() call if it is waiting
> with a timeout? We only have a single thread here.
>
> The only alternative is Stefan's original proposal. But that required
> fiddling with the signal mask twice per KVM_RUN.

I think my original patch messed with the sigmask in the wrong place,
as you mentioned doing it twice per KVM_RUN isn't a good idea.  I
wonder if we can enable SIGALRM only in blocking calls and guest code
execution but without signalfd.  It might be possible, I don't see an
immediate problem with doing that, we might have to use pselect(2) or
similar in a few places.

Stefan

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [Qemu-devel] Re: [PATCH v3 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
@ 2011-01-31 12:13             ` Stefan Hajnoczi
  0 siblings, 0 replies; 146+ messages in thread
From: Stefan Hajnoczi @ 2011-01-31 12:13 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Marcelo Tosatti, Stefan Hajnoczi, Avi Kivity, kvm, qemu-devel

On Mon, Jan 31, 2011 at 11:27 AM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
> On 2011-01-31 11:03, Avi Kivity wrote:
>> On 01/27/2011 04:33 PM, Jan Kiszka wrote:
>>> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
>>> checking for exit_request on vcpu entry and timer signals arriving
>>> before KVM starts to catch them. Plug it by blocking both timer related
>>> signals also on !CONFIG_IOTHREAD and process those via signalfd.
>>>
>>> As this fix depends on real signalfd support (otherwise the timer
>>> signals only kick the compat helper thread, and the main thread hangs),
>>> we need to detect the invalid constellation and abort configure.
>>>
>>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>>> CC: Stefan Hajnoczi<stefanha@linux.vnet.ibm.com>
>>> ---
>>>
>>> I don't want to invest that much into !IOTHREAD anymore, so let's see if
>>> the proposed catch&abort is acceptable.
>>>
>>
>> I don't understand the dependency on signalfd.  The normal way of doing
>> things, either waiting for the signal in sigtimedwait() or in
>> ioctl(KVM_RUN), works with SIGALRM just fine.
>
> And how would you be kicked out of the select() call if it is waiting
> with a timeout? We only have a single thread here.
>
> The only alternative is Stefan's original proposal. But that required
> fiddling with the signal mask twice per KVM_RUN.

I think my original patch messed with the sigmask in the wrong place,
as you mentioned doing it twice per KVM_RUN isn't a good idea.  I
wonder if we can enable SIGALRM only in blocking calls and guest code
execution but without signalfd.  It might be possible, I don't see an
immediate problem with doing that, we might have to use pselect(2) or
similar in a few places.

Stefan

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [Qemu-devel] Re: [PATCH v3 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
  2011-01-31 12:13             ` Stefan Hajnoczi
@ 2011-01-31 12:18               ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 12:18 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: Avi Kivity, Marcelo Tosatti, qemu-devel, kvm, Stefan Hajnoczi

On 2011-01-31 13:13, Stefan Hajnoczi wrote:
> On Mon, Jan 31, 2011 at 11:27 AM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
>> On 2011-01-31 11:03, Avi Kivity wrote:
>>> On 01/27/2011 04:33 PM, Jan Kiszka wrote:
>>>> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
>>>> checking for exit_request on vcpu entry and timer signals arriving
>>>> before KVM starts to catch them. Plug it by blocking both timer related
>>>> signals also on !CONFIG_IOTHREAD and process those via signalfd.
>>>>
>>>> As this fix depends on real signalfd support (otherwise the timer
>>>> signals only kick the compat helper thread, and the main thread hangs),
>>>> we need to detect the invalid constellation and abort configure.
>>>>
>>>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>>>> CC: Stefan Hajnoczi<stefanha@linux.vnet.ibm.com>
>>>> ---
>>>>
>>>> I don't want to invest that much into !IOTHREAD anymore, so let's see if
>>>> the proposed catch&abort is acceptable.
>>>>
>>>
>>> I don't understand the dependency on signalfd.  The normal way of doing
>>> things, either waiting for the signal in sigtimedwait() or in
>>> ioctl(KVM_RUN), works with SIGALRM just fine.
>>
>> And how would you be kicked out of the select() call if it is waiting
>> with a timeout? We only have a single thread here.
>>
>> The only alternative is Stefan's original proposal. But that required
>> fiddling with the signal mask twice per KVM_RUN.
> 
> I think my original patch messed with the sigmask in the wrong place,
> as you mentioned doing it twice per KVM_RUN isn't a good idea.  I
> wonder if we can enable SIGALRM only in blocking calls and guest code
> execution but without signalfd.  It might be possible, I don't see an
> immediate problem with doing that, we might have to use pselect(2) or
> similar in a few places.

My main concern about alternative approaches is that IOTHREAD is about
to become the default, and hardly anyone (of the few upstream KVM users)
will run without it in the foreseeable future. The next step will be the
removal of any !CONFIG_IOTHREAD section. So, how much do we want to
invest here (provided my proposal has not remaining issues)?

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [Qemu-devel] Re: [PATCH v3 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
@ 2011-01-31 12:18               ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 12:18 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: Marcelo Tosatti, Stefan Hajnoczi, Avi Kivity, kvm, qemu-devel

On 2011-01-31 13:13, Stefan Hajnoczi wrote:
> On Mon, Jan 31, 2011 at 11:27 AM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
>> On 2011-01-31 11:03, Avi Kivity wrote:
>>> On 01/27/2011 04:33 PM, Jan Kiszka wrote:
>>>> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
>>>> checking for exit_request on vcpu entry and timer signals arriving
>>>> before KVM starts to catch them. Plug it by blocking both timer related
>>>> signals also on !CONFIG_IOTHREAD and process those via signalfd.
>>>>
>>>> As this fix depends on real signalfd support (otherwise the timer
>>>> signals only kick the compat helper thread, and the main thread hangs),
>>>> we need to detect the invalid constellation and abort configure.
>>>>
>>>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>>>> CC: Stefan Hajnoczi<stefanha@linux.vnet.ibm.com>
>>>> ---
>>>>
>>>> I don't want to invest that much into !IOTHREAD anymore, so let's see if
>>>> the proposed catch&abort is acceptable.
>>>>
>>>
>>> I don't understand the dependency on signalfd.  The normal way of doing
>>> things, either waiting for the signal in sigtimedwait() or in
>>> ioctl(KVM_RUN), works with SIGALRM just fine.
>>
>> And how would you be kicked out of the select() call if it is waiting
>> with a timeout? We only have a single thread here.
>>
>> The only alternative is Stefan's original proposal. But that required
>> fiddling with the signal mask twice per KVM_RUN.
> 
> I think my original patch messed with the sigmask in the wrong place,
> as you mentioned doing it twice per KVM_RUN isn't a good idea.  I
> wonder if we can enable SIGALRM only in blocking calls and guest code
> execution but without signalfd.  It might be possible, I don't see an
> immediate problem with doing that, we might have to use pselect(2) or
> similar in a few places.

My main concern about alternative approaches is that IOTHREAD is about
to become the default, and hardly anyone (of the few upstream KVM users)
will run without it in the foreseeable future. The next step will be the
removal of any !CONFIG_IOTHREAD section. So, how much do we want to
invest here (provided my proposal has not remaining issues)?

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 17/22] kvm: Move irqchip event processing out of inner loop
  2011-01-31 11:36       ` [Qemu-devel] " Jan Kiszka
@ 2011-01-31 13:04         ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 13:04 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Marcelo Tosatti, kvm, qemu-devel

On 2011-01-31 12:36, Jan Kiszka wrote:
> On 2011-01-31 11:08, Avi Kivity wrote:
>> On 01/27/2011 03:10 PM, Jan Kiszka wrote:
>>> Align with qemu-kvm and prepare for IO exit fix: There is no need to run
>>> kvm_arch_process_irqchip_events in the inner VCPU loop. Any state change
>>> this service processes will first cause an exit from kvm_cpu_exec
>>> anyway. And we will have to reenter the kernel on IO exits
>>> unconditionally, something that the current logic prevents.
>>>
>>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>>> ---
>>>   kvm-all.c |   11 ++++++-----
>>>   1 files changed, 6 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/kvm-all.c b/kvm-all.c
>>> index 5bfa8c0..46ecc1c 100644
>>> --- a/kvm-all.c
>>> +++ b/kvm-all.c
>>> @@ -892,6 +892,12 @@ int kvm_cpu_exec(CPUState *env)
>>>
>>>       DPRINTF("kvm_cpu_exec()\n");
>>>
>>> +    if (kvm_arch_process_irqchip_events(env)) {
>>> +        env->exit_request = 0;
>>> +        env->exception_index = EXCP_HLT;
>>> +        return 0;
>>> +    }
>>> +
>>>       do {
>>>   #ifndef CONFIG_IOTHREAD
>>>           if (env->exit_request) {
>>> @@ -901,11 +907,6 @@ int kvm_cpu_exec(CPUState *env)
>>>           }
>>
>> We check for ->exit_request here
>>
>>>   #endif
>>>
>>> -        if (kvm_arch_process_irqchip_events(env)) {
>>> -            ret = 0;
>>> -            break;
>>> -        }
>>> -
>>
>> But this checks for ->interrupt_request.  What ensures that we exit when 
>> ->interrupt_request is set?
> 
> Good question, need to check again. But if that turns out to be an
> issue, qemu-kvm would be broken as well. I'm just aligning the code here.
> 

The only thing we miss by moving process_irqchip_events is a self-INIT
of an AP - if such thing exists in real life. In that case, the AP would
cause a reset of itself, followed by a transition to HALT state.

A self-SIPI has no effect as A) a CPU can't send a SIPI from
wait-on-SIPI state and B) SIPIs are ignored in any other state.

Will post a version that additionally checks for pending INIT as well
and injects a self-ipi then.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 17/22] kvm: Move irqchip event processing out of inner loop
@ 2011-01-31 13:04         ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 13:04 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Marcelo Tosatti, qemu-devel, kvm

On 2011-01-31 12:36, Jan Kiszka wrote:
> On 2011-01-31 11:08, Avi Kivity wrote:
>> On 01/27/2011 03:10 PM, Jan Kiszka wrote:
>>> Align with qemu-kvm and prepare for IO exit fix: There is no need to run
>>> kvm_arch_process_irqchip_events in the inner VCPU loop. Any state change
>>> this service processes will first cause an exit from kvm_cpu_exec
>>> anyway. And we will have to reenter the kernel on IO exits
>>> unconditionally, something that the current logic prevents.
>>>
>>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>>> ---
>>>   kvm-all.c |   11 ++++++-----
>>>   1 files changed, 6 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/kvm-all.c b/kvm-all.c
>>> index 5bfa8c0..46ecc1c 100644
>>> --- a/kvm-all.c
>>> +++ b/kvm-all.c
>>> @@ -892,6 +892,12 @@ int kvm_cpu_exec(CPUState *env)
>>>
>>>       DPRINTF("kvm_cpu_exec()\n");
>>>
>>> +    if (kvm_arch_process_irqchip_events(env)) {
>>> +        env->exit_request = 0;
>>> +        env->exception_index = EXCP_HLT;
>>> +        return 0;
>>> +    }
>>> +
>>>       do {
>>>   #ifndef CONFIG_IOTHREAD
>>>           if (env->exit_request) {
>>> @@ -901,11 +907,6 @@ int kvm_cpu_exec(CPUState *env)
>>>           }
>>
>> We check for ->exit_request here
>>
>>>   #endif
>>>
>>> -        if (kvm_arch_process_irqchip_events(env)) {
>>> -            ret = 0;
>>> -            break;
>>> -        }
>>> -
>>
>> But this checks for ->interrupt_request.  What ensures that we exit when 
>> ->interrupt_request is set?
> 
> Good question, need to check again. But if that turns out to be an
> issue, qemu-kvm would be broken as well. I'm just aligning the code here.
> 

The only thing we miss by moving process_irqchip_events is a self-INIT
of an AP - if such thing exists in real life. In that case, the AP would
cause a reset of itself, followed by a transition to HALT state.

A self-SIPI has no effect as A) a CPU can't send a SIPI from
wait-on-SIPI state and B) SIPIs are ignored in any other state.

Will post a version that additionally checks for pending INIT as well
and injects a self-ipi then.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 01/22] Prevent abortion on multiple VCPU kicks
  2011-01-31 11:19       ` [Qemu-devel] " Jan Kiszka
@ 2011-01-31 13:16         ` Avi Kivity
  -1 siblings, 0 replies; 146+ messages in thread
From: Avi Kivity @ 2011-01-31 13:16 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Marcelo Tosatti, kvm, qemu-devel

On 01/31/2011 01:19 PM, Jan Kiszka wrote:
> On 2011-01-31 10:44, Avi Kivity wrote:
> >  On 01/27/2011 03:09 PM, Jan Kiszka wrote:
> >>  If we call qemu_cpu_kick more than once before the target was able to
> >>  process the signal, pthread_kill will fail, and qemu will abort. Prevent
> >>  this by avoiding the redundant signal.
> >>
> >
> >  Doesn't fit with the manual page (or with the idea that signals are
> >  asynchronous):
> >
> >  NAME
> >          pthread_kill - send a signal to a thread
> >
> >
> >  ...
> >
> >  ERRORS
> >          ESRCH  No thread with the ID thread could be found.
> >
> >          EINVAL An invalid signal was specified.
> >
>
> Valid remark, but I was receiving EAGAIN for blocked RT signals. Don't
> know if this is Linux-specific. A quick glance at the man pages did not
> reveal if this is allowed or at least gray area.
>

     } else if (!is_si_special(info)) {
         if (sig >= SIGRTMIN && info->si_code != SI_USER) {
             /*
              * Queue overflow, abort.  We may abort if the
              * signal was rt and sent by user using something
              * other than kill().
              */
             trace_signal_overflow_fail(sig, group, info);
             return -EAGAIN;
         }

> However, even when selectively ignoring this, it's more efficient to
> catch the redundant signaling in user space.

Yes.

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 01/22] Prevent abortion on multiple VCPU kicks
@ 2011-01-31 13:16         ` Avi Kivity
  0 siblings, 0 replies; 146+ messages in thread
From: Avi Kivity @ 2011-01-31 13:16 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Marcelo Tosatti, qemu-devel, kvm

On 01/31/2011 01:19 PM, Jan Kiszka wrote:
> On 2011-01-31 10:44, Avi Kivity wrote:
> >  On 01/27/2011 03:09 PM, Jan Kiszka wrote:
> >>  If we call qemu_cpu_kick more than once before the target was able to
> >>  process the signal, pthread_kill will fail, and qemu will abort. Prevent
> >>  this by avoiding the redundant signal.
> >>
> >
> >  Doesn't fit with the manual page (or with the idea that signals are
> >  asynchronous):
> >
> >  NAME
> >          pthread_kill - send a signal to a thread
> >
> >
> >  ...
> >
> >  ERRORS
> >          ESRCH  No thread with the ID thread could be found.
> >
> >          EINVAL An invalid signal was specified.
> >
>
> Valid remark, but I was receiving EAGAIN for blocked RT signals. Don't
> know if this is Linux-specific. A quick glance at the man pages did not
> reveal if this is allowed or at least gray area.
>

     } else if (!is_si_special(info)) {
         if (sig >= SIGRTMIN && info->si_code != SI_USER) {
             /*
              * Queue overflow, abort.  We may abort if the
              * signal was rt and sent by user using something
              * other than kill().
              */
             trace_signal_overflow_fail(sig, group, info);
             return -EAGAIN;
         }

> However, even when selectively ignoring this, it's more efficient to
> catch the redundant signaling in user space.

Yes.

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 04/22] Leave inner main_loop faster on pending requests
  2011-01-31 11:22       ` [Qemu-devel] " Jan Kiszka
@ 2011-01-31 13:17         ` Avi Kivity
  -1 siblings, 0 replies; 146+ messages in thread
From: Avi Kivity @ 2011-01-31 13:17 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Marcelo Tosatti, kvm, qemu-devel

On 01/31/2011 01:22 PM, Jan Kiszka wrote:
> On 2011-01-31 10:52, Avi Kivity wrote:
> >  On 01/27/2011 03:09 PM, Jan Kiszka wrote:
> >>  If there is any pending request that requires us to leave the inner loop
> >>  if main_loop, makes sure we do this as soon as possible by enforcing
> >>  non-blocking IO processing.
> >>
> >>  At this change, move variable definitions out of the inner loop to
> >>  improve readability.
> >>
> >>  Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
> >>  ---
> >>    vl.c |   11 +++++++----
> >>    1 files changed, 7 insertions(+), 4 deletions(-)
> >>
> >>  diff --git a/vl.c b/vl.c
> >>  index 5fad700..2ebc55b 100644
> >>  --- a/vl.c
> >>  +++ b/vl.c
> >>  @@ -1384,18 +1384,21 @@ qemu_irq qemu_system_powerdown;
> >>
> >>    static void main_loop(void)
> >>    {
> >>  +    bool nonblocking = false;
> >>  +#ifdef CONFIG_PROFILER
> >>  +    int64_t ti;
> >>  +#endif
> >>        int r;
> >>
> >>        qemu_main_loop_start();
> >>
> >>        for (;;) {
> >>            do {
> >>  -            bool nonblocking = false;
> >>  -#ifdef CONFIG_PROFILER
> >>  -            int64_t ti;
> >>  -#endif
> >>    #ifndef CONFIG_IOTHREAD
> >>                nonblocking = cpu_exec_all();
> >>  +            if (!vm_can_run()) {
> >>  +                nonblocking = true;
> >>  +            }
> >
> >  Doesn't this cause vmstop to spin?  We'll never execute
> >  main_loop_wait(false) if I read the code correctly?
> >
>
> The code path is not changed, we just poll instead of wait in
> main_loop_wait.

Where do we wait then?

> Also, I didn't get your error scenario yet. Even if we left the loop
> here, what magic would main_loop_wait do to vmstop processing? The stop
> request is handled outside the loop, that's why we should leave ASAP.

I'm just missing the alternate place where we sleep.  If there's no such 
place, we spin.

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 04/22] Leave inner main_loop faster on pending requests
@ 2011-01-31 13:17         ` Avi Kivity
  0 siblings, 0 replies; 146+ messages in thread
From: Avi Kivity @ 2011-01-31 13:17 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Marcelo Tosatti, qemu-devel, kvm

On 01/31/2011 01:22 PM, Jan Kiszka wrote:
> On 2011-01-31 10:52, Avi Kivity wrote:
> >  On 01/27/2011 03:09 PM, Jan Kiszka wrote:
> >>  If there is any pending request that requires us to leave the inner loop
> >>  if main_loop, makes sure we do this as soon as possible by enforcing
> >>  non-blocking IO processing.
> >>
> >>  At this change, move variable definitions out of the inner loop to
> >>  improve readability.
> >>
> >>  Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
> >>  ---
> >>    vl.c |   11 +++++++----
> >>    1 files changed, 7 insertions(+), 4 deletions(-)
> >>
> >>  diff --git a/vl.c b/vl.c
> >>  index 5fad700..2ebc55b 100644
> >>  --- a/vl.c
> >>  +++ b/vl.c
> >>  @@ -1384,18 +1384,21 @@ qemu_irq qemu_system_powerdown;
> >>
> >>    static void main_loop(void)
> >>    {
> >>  +    bool nonblocking = false;
> >>  +#ifdef CONFIG_PROFILER
> >>  +    int64_t ti;
> >>  +#endif
> >>        int r;
> >>
> >>        qemu_main_loop_start();
> >>
> >>        for (;;) {
> >>            do {
> >>  -            bool nonblocking = false;
> >>  -#ifdef CONFIG_PROFILER
> >>  -            int64_t ti;
> >>  -#endif
> >>    #ifndef CONFIG_IOTHREAD
> >>                nonblocking = cpu_exec_all();
> >>  +            if (!vm_can_run()) {
> >>  +                nonblocking = true;
> >>  +            }
> >
> >  Doesn't this cause vmstop to spin?  We'll never execute
> >  main_loop_wait(false) if I read the code correctly?
> >
>
> The code path is not changed, we just poll instead of wait in
> main_loop_wait.

Where do we wait then?

> Also, I didn't get your error scenario yet. Even if we left the loop
> here, what magic would main_loop_wait do to vmstop processing? The stop
> request is handled outside the loop, that's why we should leave ASAP.

I'm just missing the alternate place where we sleep.  If there's no such 
place, we spin.

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v3 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
  2011-01-31 11:27           ` [Qemu-devel] " Jan Kiszka
@ 2011-01-31 13:22             ` Avi Kivity
  -1 siblings, 0 replies; 146+ messages in thread
From: Avi Kivity @ 2011-01-31 13:22 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Marcelo Tosatti, kvm, qemu-devel, Stefan Hajnoczi

On 01/31/2011 01:27 PM, Jan Kiszka wrote:
> On 2011-01-31 11:03, Avi Kivity wrote:
> >  On 01/27/2011 04:33 PM, Jan Kiszka wrote:
> >>  Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
> >>  checking for exit_request on vcpu entry and timer signals arriving
> >>  before KVM starts to catch them. Plug it by blocking both timer related
> >>  signals also on !CONFIG_IOTHREAD and process those via signalfd.
> >>
> >>  As this fix depends on real signalfd support (otherwise the timer
> >>  signals only kick the compat helper thread, and the main thread hangs),
> >>  we need to detect the invalid constellation and abort configure.
> >>
> >>  Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
> >>  CC: Stefan Hajnoczi<stefanha@linux.vnet.ibm.com>
> >>  ---
> >>
> >>  I don't want to invest that much into !IOTHREAD anymore, so let's see if
> >>  the proposed catch&abort is acceptable.
> >>
> >
> >  I don't understand the dependency on signalfd.  The normal way of doing
> >  things, either waiting for the signal in sigtimedwait() or in
> >  ioctl(KVM_RUN), works with SIGALRM just fine.
>
> And how would you be kicked out of the select() call if it is waiting
> with a timeout? We only have a single thread here.

If we use signalfd() (either kernel provided or thread+pipe), we kick 
out of select by select()ing it (though I don't see how it works without 
an iothread, since an fd can't stop a vcpu unless you enable SIGIO on 
it, which is silly for signalfd)

If you leave it as a naked signal, then it can break out of either 
pselect() or vcpu.

Since the goal is to drop !CONFIG_IOTHREAD, the first path seems better, 
I just don't understand the problem with emulated signalfd().


-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH v3 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
@ 2011-01-31 13:22             ` Avi Kivity
  0 siblings, 0 replies; 146+ messages in thread
From: Avi Kivity @ 2011-01-31 13:22 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Marcelo Tosatti, qemu-devel, kvm, Stefan Hajnoczi

On 01/31/2011 01:27 PM, Jan Kiszka wrote:
> On 2011-01-31 11:03, Avi Kivity wrote:
> >  On 01/27/2011 04:33 PM, Jan Kiszka wrote:
> >>  Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
> >>  checking for exit_request on vcpu entry and timer signals arriving
> >>  before KVM starts to catch them. Plug it by blocking both timer related
> >>  signals also on !CONFIG_IOTHREAD and process those via signalfd.
> >>
> >>  As this fix depends on real signalfd support (otherwise the timer
> >>  signals only kick the compat helper thread, and the main thread hangs),
> >>  we need to detect the invalid constellation and abort configure.
> >>
> >>  Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
> >>  CC: Stefan Hajnoczi<stefanha@linux.vnet.ibm.com>
> >>  ---
> >>
> >>  I don't want to invest that much into !IOTHREAD anymore, so let's see if
> >>  the proposed catch&abort is acceptable.
> >>
> >
> >  I don't understand the dependency on signalfd.  The normal way of doing
> >  things, either waiting for the signal in sigtimedwait() or in
> >  ioctl(KVM_RUN), works with SIGALRM just fine.
>
> And how would you be kicked out of the select() call if it is waiting
> with a timeout? We only have a single thread here.

If we use signalfd() (either kernel provided or thread+pipe), we kick 
out of select by select()ing it (though I don't see how it works without 
an iothread, since an fd can't stop a vcpu unless you enable SIGIO on 
it, which is silly for signalfd)

If you leave it as a naked signal, then it can break out of either 
pselect() or vcpu.

Since the goal is to drop !CONFIG_IOTHREAD, the first path seems better, 
I just don't understand the problem with emulated signalfd().


-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [Qemu-devel] Re: [PATCH v3 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
  2011-01-31 12:18               ` Jan Kiszka
@ 2011-01-31 13:35                 ` Stefan Hajnoczi
  -1 siblings, 0 replies; 146+ messages in thread
From: Stefan Hajnoczi @ 2011-01-31 13:35 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Avi Kivity, Marcelo Tosatti, qemu-devel, kvm, Stefan Hajnoczi

On Mon, Jan 31, 2011 at 12:18 PM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
> On 2011-01-31 13:13, Stefan Hajnoczi wrote:
>> On Mon, Jan 31, 2011 at 11:27 AM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
>>> On 2011-01-31 11:03, Avi Kivity wrote:
>>>> On 01/27/2011 04:33 PM, Jan Kiszka wrote:
>>>>> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
>>>>> checking for exit_request on vcpu entry and timer signals arriving
>>>>> before KVM starts to catch them. Plug it by blocking both timer related
>>>>> signals also on !CONFIG_IOTHREAD and process those via signalfd.
>>>>>
>>>>> As this fix depends on real signalfd support (otherwise the timer
>>>>> signals only kick the compat helper thread, and the main thread hangs),
>>>>> we need to detect the invalid constellation and abort configure.
>>>>>
>>>>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>>>>> CC: Stefan Hajnoczi<stefanha@linux.vnet.ibm.com>
>>>>> ---
>>>>>
>>>>> I don't want to invest that much into !IOTHREAD anymore, so let's see if
>>>>> the proposed catch&abort is acceptable.
>>>>>
>>>>
>>>> I don't understand the dependency on signalfd.  The normal way of doing
>>>> things, either waiting for the signal in sigtimedwait() or in
>>>> ioctl(KVM_RUN), works with SIGALRM just fine.
>>>
>>> And how would you be kicked out of the select() call if it is waiting
>>> with a timeout? We only have a single thread here.
>>>
>>> The only alternative is Stefan's original proposal. But that required
>>> fiddling with the signal mask twice per KVM_RUN.
>>
>> I think my original patch messed with the sigmask in the wrong place,
>> as you mentioned doing it twice per KVM_RUN isn't a good idea.  I
>> wonder if we can enable SIGALRM only in blocking calls and guest code
>> execution but without signalfd.  It might be possible, I don't see an
>> immediate problem with doing that, we might have to use pselect(2) or
>> similar in a few places.
>
> My main concern about alternative approaches is that IOTHREAD is about
> to become the default, and hardly anyone (of the few upstream KVM users)
> will run without it in the foreseeable future. The next step will be the
> removal of any !CONFIG_IOTHREAD section. So, how much do we want to
> invest here (provided my proposal has not remaining issues)?

Yes, you're right.  I'm not volunteering to dig more into this, the
best case would be to switch to a non-I/O thread world that works for
everybody.

Stefan

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [Qemu-devel] Re: [PATCH v3 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
@ 2011-01-31 13:35                 ` Stefan Hajnoczi
  0 siblings, 0 replies; 146+ messages in thread
From: Stefan Hajnoczi @ 2011-01-31 13:35 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Marcelo Tosatti, Stefan Hajnoczi, Avi Kivity, kvm, qemu-devel

On Mon, Jan 31, 2011 at 12:18 PM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
> On 2011-01-31 13:13, Stefan Hajnoczi wrote:
>> On Mon, Jan 31, 2011 at 11:27 AM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
>>> On 2011-01-31 11:03, Avi Kivity wrote:
>>>> On 01/27/2011 04:33 PM, Jan Kiszka wrote:
>>>>> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
>>>>> checking for exit_request on vcpu entry and timer signals arriving
>>>>> before KVM starts to catch them. Plug it by blocking both timer related
>>>>> signals also on !CONFIG_IOTHREAD and process those via signalfd.
>>>>>
>>>>> As this fix depends on real signalfd support (otherwise the timer
>>>>> signals only kick the compat helper thread, and the main thread hangs),
>>>>> we need to detect the invalid constellation and abort configure.
>>>>>
>>>>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>>>>> CC: Stefan Hajnoczi<stefanha@linux.vnet.ibm.com>
>>>>> ---
>>>>>
>>>>> I don't want to invest that much into !IOTHREAD anymore, so let's see if
>>>>> the proposed catch&abort is acceptable.
>>>>>
>>>>
>>>> I don't understand the dependency on signalfd.  The normal way of doing
>>>> things, either waiting for the signal in sigtimedwait() or in
>>>> ioctl(KVM_RUN), works with SIGALRM just fine.
>>>
>>> And how would you be kicked out of the select() call if it is waiting
>>> with a timeout? We only have a single thread here.
>>>
>>> The only alternative is Stefan's original proposal. But that required
>>> fiddling with the signal mask twice per KVM_RUN.
>>
>> I think my original patch messed with the sigmask in the wrong place,
>> as you mentioned doing it twice per KVM_RUN isn't a good idea.  I
>> wonder if we can enable SIGALRM only in blocking calls and guest code
>> execution but without signalfd.  It might be possible, I don't see an
>> immediate problem with doing that, we might have to use pselect(2) or
>> similar in a few places.
>
> My main concern about alternative approaches is that IOTHREAD is about
> to become the default, and hardly anyone (of the few upstream KVM users)
> will run without it in the foreseeable future. The next step will be the
> removal of any !CONFIG_IOTHREAD section. So, how much do we want to
> invest here (provided my proposal has not remaining issues)?

Yes, you're right.  I'm not volunteering to dig more into this, the
best case would be to switch to a non-I/O thread world that works for
everybody.

Stefan

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v3 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
  2011-01-31 13:22             ` [Qemu-devel] " Avi Kivity
@ 2011-01-31 14:31               ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 14:31 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Marcelo Tosatti, kvm, qemu-devel, Stefan Hajnoczi

On 2011-01-31 14:22, Avi Kivity wrote:
> On 01/31/2011 01:27 PM, Jan Kiszka wrote:
>> On 2011-01-31 11:03, Avi Kivity wrote:
>>>  On 01/27/2011 04:33 PM, Jan Kiszka wrote:
>>>>  Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
>>>>  checking for exit_request on vcpu entry and timer signals arriving
>>>>  before KVM starts to catch them. Plug it by blocking both timer related
>>>>  signals also on !CONFIG_IOTHREAD and process those via signalfd.
>>>>
>>>>  As this fix depends on real signalfd support (otherwise the timer
>>>>  signals only kick the compat helper thread, and the main thread hangs),
>>>>  we need to detect the invalid constellation and abort configure.
>>>>
>>>>  Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>>>>  CC: Stefan Hajnoczi<stefanha@linux.vnet.ibm.com>
>>>>  ---
>>>>
>>>>  I don't want to invest that much into !IOTHREAD anymore, so let's see if
>>>>  the proposed catch&abort is acceptable.
>>>>
>>>
>>>  I don't understand the dependency on signalfd.  The normal way of doing
>>>  things, either waiting for the signal in sigtimedwait() or in
>>>  ioctl(KVM_RUN), works with SIGALRM just fine.
>>
>> And how would you be kicked out of the select() call if it is waiting
>> with a timeout? We only have a single thread here.
> 
> If we use signalfd() (either kernel provided or thread+pipe), we kick 
> out of select by select()ing it (though I don't see how it works without 
> an iothread, since an fd can't stop a vcpu unless you enable SIGIO on 
> it, which is silly for signalfd)
> 
> If you leave it as a naked signal, then it can break out of either 
> pselect() or vcpu.
> 
> Since the goal is to drop !CONFIG_IOTHREAD, the first path seems better, 
> I just don't understand the problem with emulated signalfd().
> 

With the emulated signalfd, there won't be any signal for the VCPU while
in KVM_RUN.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH v3 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
@ 2011-01-31 14:31               ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 14:31 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Marcelo Tosatti, qemu-devel, kvm, Stefan Hajnoczi

On 2011-01-31 14:22, Avi Kivity wrote:
> On 01/31/2011 01:27 PM, Jan Kiszka wrote:
>> On 2011-01-31 11:03, Avi Kivity wrote:
>>>  On 01/27/2011 04:33 PM, Jan Kiszka wrote:
>>>>  Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
>>>>  checking for exit_request on vcpu entry and timer signals arriving
>>>>  before KVM starts to catch them. Plug it by blocking both timer related
>>>>  signals also on !CONFIG_IOTHREAD and process those via signalfd.
>>>>
>>>>  As this fix depends on real signalfd support (otherwise the timer
>>>>  signals only kick the compat helper thread, and the main thread hangs),
>>>>  we need to detect the invalid constellation and abort configure.
>>>>
>>>>  Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>>>>  CC: Stefan Hajnoczi<stefanha@linux.vnet.ibm.com>
>>>>  ---
>>>>
>>>>  I don't want to invest that much into !IOTHREAD anymore, so let's see if
>>>>  the proposed catch&abort is acceptable.
>>>>
>>>
>>>  I don't understand the dependency on signalfd.  The normal way of doing
>>>  things, either waiting for the signal in sigtimedwait() or in
>>>  ioctl(KVM_RUN), works with SIGALRM just fine.
>>
>> And how would you be kicked out of the select() call if it is waiting
>> with a timeout? We only have a single thread here.
> 
> If we use signalfd() (either kernel provided or thread+pipe), we kick 
> out of select by select()ing it (though I don't see how it works without 
> an iothread, since an fd can't stop a vcpu unless you enable SIGIO on 
> it, which is silly for signalfd)
> 
> If you leave it as a naked signal, then it can break out of either 
> pselect() or vcpu.
> 
> Since the goal is to drop !CONFIG_IOTHREAD, the first path seems better, 
> I just don't understand the problem with emulated signalfd().
> 

With the emulated signalfd, there won't be any signal for the VCPU while
in KVM_RUN.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 04/22] Leave inner main_loop faster on pending requests
  2011-01-31 13:17         ` [Qemu-devel] " Avi Kivity
@ 2011-01-31 14:32           ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 14:32 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Marcelo Tosatti, kvm, qemu-devel

On 2011-01-31 14:17, Avi Kivity wrote:
> On 01/31/2011 01:22 PM, Jan Kiszka wrote:
>> On 2011-01-31 10:52, Avi Kivity wrote:
>>>  On 01/27/2011 03:09 PM, Jan Kiszka wrote:
>>>>  If there is any pending request that requires us to leave the inner loop
>>>>  if main_loop, makes sure we do this as soon as possible by enforcing
>>>>  non-blocking IO processing.
>>>>
>>>>  At this change, move variable definitions out of the inner loop to
>>>>  improve readability.
>>>>
>>>>  Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>>>>  ---
>>>>    vl.c |   11 +++++++----
>>>>    1 files changed, 7 insertions(+), 4 deletions(-)
>>>>
>>>>  diff --git a/vl.c b/vl.c
>>>>  index 5fad700..2ebc55b 100644
>>>>  --- a/vl.c
>>>>  +++ b/vl.c
>>>>  @@ -1384,18 +1384,21 @@ qemu_irq qemu_system_powerdown;
>>>>
>>>>    static void main_loop(void)
>>>>    {
>>>>  +    bool nonblocking = false;
>>>>  +#ifdef CONFIG_PROFILER
>>>>  +    int64_t ti;
>>>>  +#endif
>>>>        int r;
>>>>
>>>>        qemu_main_loop_start();
>>>>
>>>>        for (;;) {
>>>>            do {
>>>>  -            bool nonblocking = false;
>>>>  -#ifdef CONFIG_PROFILER
>>>>  -            int64_t ti;
>>>>  -#endif
>>>>    #ifndef CONFIG_IOTHREAD
>>>>                nonblocking = cpu_exec_all();
>>>>  +            if (!vm_can_run()) {
>>>>  +                nonblocking = true;
>>>>  +            }
>>>
>>>  Doesn't this cause vmstop to spin?  We'll never execute
>>>  main_loop_wait(false) if I read the code correctly?
>>>
>>
>> The code path is not changed, we just poll instead of wait in
>> main_loop_wait.
> 
> Where do we wait then?
> 
>> Also, I didn't get your error scenario yet. Even if we left the loop
>> here, what magic would main_loop_wait do to vmstop processing? The stop
>> request is handled outside the loop, that's why we should leave ASAP.
> 
> I'm just missing the alternate place where we sleep.  If there's no such 
> place, we spin.
> 

Probably you are misled by the name of vm_can_run. It should better be
renamed to requests_pending or something like that - iow, it is only
true if some request is pending and not if just the vm is in stop mode.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 04/22] Leave inner main_loop faster on pending requests
@ 2011-01-31 14:32           ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 14:32 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Marcelo Tosatti, qemu-devel, kvm

On 2011-01-31 14:17, Avi Kivity wrote:
> On 01/31/2011 01:22 PM, Jan Kiszka wrote:
>> On 2011-01-31 10:52, Avi Kivity wrote:
>>>  On 01/27/2011 03:09 PM, Jan Kiszka wrote:
>>>>  If there is any pending request that requires us to leave the inner loop
>>>>  if main_loop, makes sure we do this as soon as possible by enforcing
>>>>  non-blocking IO processing.
>>>>
>>>>  At this change, move variable definitions out of the inner loop to
>>>>  improve readability.
>>>>
>>>>  Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>>>>  ---
>>>>    vl.c |   11 +++++++----
>>>>    1 files changed, 7 insertions(+), 4 deletions(-)
>>>>
>>>>  diff --git a/vl.c b/vl.c
>>>>  index 5fad700..2ebc55b 100644
>>>>  --- a/vl.c
>>>>  +++ b/vl.c
>>>>  @@ -1384,18 +1384,21 @@ qemu_irq qemu_system_powerdown;
>>>>
>>>>    static void main_loop(void)
>>>>    {
>>>>  +    bool nonblocking = false;
>>>>  +#ifdef CONFIG_PROFILER
>>>>  +    int64_t ti;
>>>>  +#endif
>>>>        int r;
>>>>
>>>>        qemu_main_loop_start();
>>>>
>>>>        for (;;) {
>>>>            do {
>>>>  -            bool nonblocking = false;
>>>>  -#ifdef CONFIG_PROFILER
>>>>  -            int64_t ti;
>>>>  -#endif
>>>>    #ifndef CONFIG_IOTHREAD
>>>>                nonblocking = cpu_exec_all();
>>>>  +            if (!vm_can_run()) {
>>>>  +                nonblocking = true;
>>>>  +            }
>>>
>>>  Doesn't this cause vmstop to spin?  We'll never execute
>>>  main_loop_wait(false) if I read the code correctly?
>>>
>>
>> The code path is not changed, we just poll instead of wait in
>> main_loop_wait.
> 
> Where do we wait then?
> 
>> Also, I didn't get your error scenario yet. Even if we left the loop
>> here, what magic would main_loop_wait do to vmstop processing? The stop
>> request is handled outside the loop, that's why we should leave ASAP.
> 
> I'm just missing the alternate place where we sleep.  If there's no such 
> place, we spin.
> 

Probably you are misled by the name of vm_can_run. It should better be
renamed to requests_pending or something like that - iow, it is only
true if some request is pending and not if just the vm is in stop mode.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 17/22] kvm: Move irqchip event processing out of inner loop
  2011-01-31 13:04         ` [Qemu-devel] " Jan Kiszka
@ 2011-01-31 15:40           ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 15:40 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Marcelo Tosatti, kvm, qemu-devel

On 2011-01-31 14:04, Jan Kiszka wrote:
> On 2011-01-31 12:36, Jan Kiszka wrote:
>> On 2011-01-31 11:08, Avi Kivity wrote:
>>> On 01/27/2011 03:10 PM, Jan Kiszka wrote:
>>>> Align with qemu-kvm and prepare for IO exit fix: There is no need to run
>>>> kvm_arch_process_irqchip_events in the inner VCPU loop. Any state change
>>>> this service processes will first cause an exit from kvm_cpu_exec
>>>> anyway. And we will have to reenter the kernel on IO exits
>>>> unconditionally, something that the current logic prevents.
>>>>
>>>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>>>> ---
>>>>   kvm-all.c |   11 ++++++-----
>>>>   1 files changed, 6 insertions(+), 5 deletions(-)
>>>>
>>>> diff --git a/kvm-all.c b/kvm-all.c
>>>> index 5bfa8c0..46ecc1c 100644
>>>> --- a/kvm-all.c
>>>> +++ b/kvm-all.c
>>>> @@ -892,6 +892,12 @@ int kvm_cpu_exec(CPUState *env)
>>>>
>>>>       DPRINTF("kvm_cpu_exec()\n");
>>>>
>>>> +    if (kvm_arch_process_irqchip_events(env)) {
>>>> +        env->exit_request = 0;
>>>> +        env->exception_index = EXCP_HLT;
>>>> +        return 0;
>>>> +    }
>>>> +
>>>>       do {
>>>>   #ifndef CONFIG_IOTHREAD
>>>>           if (env->exit_request) {
>>>> @@ -901,11 +907,6 @@ int kvm_cpu_exec(CPUState *env)
>>>>           }
>>>
>>> We check for ->exit_request here
>>>
>>>>   #endif
>>>>
>>>> -        if (kvm_arch_process_irqchip_events(env)) {
>>>> -            ret = 0;
>>>> -            break;
>>>> -        }
>>>> -
>>>
>>> But this checks for ->interrupt_request.  What ensures that we exit when 
>>> ->interrupt_request is set?
>>
>> Good question, need to check again. But if that turns out to be an
>> issue, qemu-kvm would be broken as well. I'm just aligning the code here.
>>
> 
> The only thing we miss by moving process_irqchip_events is a self-INIT
> of an AP - if such thing exists in real life. In that case, the AP would
> cause a reset of itself, followed by a transition to HALT state.

I checked again with the Intel spec, and a self-INIT is invalid (at
least when specified via shorthand). So I'm under the impression now
that we can safely ignore this case and leave the patch as is.

Any different views?

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 17/22] kvm: Move irqchip event processing out of inner loop
@ 2011-01-31 15:40           ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 15:40 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Marcelo Tosatti, qemu-devel, kvm

On 2011-01-31 14:04, Jan Kiszka wrote:
> On 2011-01-31 12:36, Jan Kiszka wrote:
>> On 2011-01-31 11:08, Avi Kivity wrote:
>>> On 01/27/2011 03:10 PM, Jan Kiszka wrote:
>>>> Align with qemu-kvm and prepare for IO exit fix: There is no need to run
>>>> kvm_arch_process_irqchip_events in the inner VCPU loop. Any state change
>>>> this service processes will first cause an exit from kvm_cpu_exec
>>>> anyway. And we will have to reenter the kernel on IO exits
>>>> unconditionally, something that the current logic prevents.
>>>>
>>>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>>>> ---
>>>>   kvm-all.c |   11 ++++++-----
>>>>   1 files changed, 6 insertions(+), 5 deletions(-)
>>>>
>>>> diff --git a/kvm-all.c b/kvm-all.c
>>>> index 5bfa8c0..46ecc1c 100644
>>>> --- a/kvm-all.c
>>>> +++ b/kvm-all.c
>>>> @@ -892,6 +892,12 @@ int kvm_cpu_exec(CPUState *env)
>>>>
>>>>       DPRINTF("kvm_cpu_exec()\n");
>>>>
>>>> +    if (kvm_arch_process_irqchip_events(env)) {
>>>> +        env->exit_request = 0;
>>>> +        env->exception_index = EXCP_HLT;
>>>> +        return 0;
>>>> +    }
>>>> +
>>>>       do {
>>>>   #ifndef CONFIG_IOTHREAD
>>>>           if (env->exit_request) {
>>>> @@ -901,11 +907,6 @@ int kvm_cpu_exec(CPUState *env)
>>>>           }
>>>
>>> We check for ->exit_request here
>>>
>>>>   #endif
>>>>
>>>> -        if (kvm_arch_process_irqchip_events(env)) {
>>>> -            ret = 0;
>>>> -            break;
>>>> -        }
>>>> -
>>>
>>> But this checks for ->interrupt_request.  What ensures that we exit when 
>>> ->interrupt_request is set?
>>
>> Good question, need to check again. But if that turns out to be an
>> issue, qemu-kvm would be broken as well. I'm just aligning the code here.
>>
> 
> The only thing we miss by moving process_irqchip_events is a self-INIT
> of an AP - if such thing exists in real life. In that case, the AP would
> cause a reset of itself, followed by a transition to HALT state.

I checked again with the Intel spec, and a self-INIT is invalid (at
least when specified via shorthand). So I'm under the impression now
that we can safely ignore this case and leave the patch as is.

Any different views?

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v3 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
  2011-01-31 14:31               ` [Qemu-devel] " Jan Kiszka
@ 2011-01-31 16:30                 ` Avi Kivity
  -1 siblings, 0 replies; 146+ messages in thread
From: Avi Kivity @ 2011-01-31 16:30 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Marcelo Tosatti, kvm, qemu-devel, Stefan Hajnoczi

On 01/31/2011 04:31 PM, Jan Kiszka wrote:
> >>
> >>  And how would you be kicked out of the select() call if it is waiting
> >>  with a timeout? We only have a single thread here.
> >
> >  If we use signalfd() (either kernel provided or thread+pipe), we kick
> >  out of select by select()ing it (though I don't see how it works without
> >  an iothread, since an fd can't stop a vcpu unless you enable SIGIO on
> >  it, which is silly for signalfd)
> >
> >  If you leave it as a naked signal, then it can break out of either
> >  pselect() or vcpu.
> >
> >  Since the goal is to drop !CONFIG_IOTHREAD, the first path seems better,
> >  I just don't understand the problem with emulated signalfd().
> >
>
> With the emulated signalfd, there won't be any signal for the VCPU while
> in KVM_RUN.
>

I see it now - with a real signalfd, kvm unmasks the signal, and that 
takes precedence over signalfd and exits the vcpu.

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH v3 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
@ 2011-01-31 16:30                 ` Avi Kivity
  0 siblings, 0 replies; 146+ messages in thread
From: Avi Kivity @ 2011-01-31 16:30 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Marcelo Tosatti, qemu-devel, kvm, Stefan Hajnoczi

On 01/31/2011 04:31 PM, Jan Kiszka wrote:
> >>
> >>  And how would you be kicked out of the select() call if it is waiting
> >>  with a timeout? We only have a single thread here.
> >
> >  If we use signalfd() (either kernel provided or thread+pipe), we kick
> >  out of select by select()ing it (though I don't see how it works without
> >  an iothread, since an fd can't stop a vcpu unless you enable SIGIO on
> >  it, which is silly for signalfd)
> >
> >  If you leave it as a naked signal, then it can break out of either
> >  pselect() or vcpu.
> >
> >  Since the goal is to drop !CONFIG_IOTHREAD, the first path seems better,
> >  I just don't understand the problem with emulated signalfd().
> >
>
> With the emulated signalfd, there won't be any signal for the VCPU while
> in KVM_RUN.
>

I see it now - with a real signalfd, kvm unmasks the signal, and that 
takes precedence over signalfd and exits the vcpu.

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 17/22] kvm: Move irqchip event processing out of inner loop
  2011-01-31 15:40           ` [Qemu-devel] " Jan Kiszka
@ 2011-01-31 16:38             ` Gleb Natapov
  -1 siblings, 0 replies; 146+ messages in thread
From: Gleb Natapov @ 2011-01-31 16:38 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Avi Kivity, Marcelo Tosatti, kvm, qemu-devel

On Mon, Jan 31, 2011 at 04:40:34PM +0100, Jan Kiszka wrote:
> On 2011-01-31 14:04, Jan Kiszka wrote:
> > On 2011-01-31 12:36, Jan Kiszka wrote:
> >> On 2011-01-31 11:08, Avi Kivity wrote:
> >>> On 01/27/2011 03:10 PM, Jan Kiszka wrote:
> >>>> Align with qemu-kvm and prepare for IO exit fix: There is no need to run
> >>>> kvm_arch_process_irqchip_events in the inner VCPU loop. Any state change
> >>>> this service processes will first cause an exit from kvm_cpu_exec
> >>>> anyway. And we will have to reenter the kernel on IO exits
> >>>> unconditionally, something that the current logic prevents.
> >>>>
> >>>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
> >>>> ---
> >>>>   kvm-all.c |   11 ++++++-----
> >>>>   1 files changed, 6 insertions(+), 5 deletions(-)
> >>>>
> >>>> diff --git a/kvm-all.c b/kvm-all.c
> >>>> index 5bfa8c0..46ecc1c 100644
> >>>> --- a/kvm-all.c
> >>>> +++ b/kvm-all.c
> >>>> @@ -892,6 +892,12 @@ int kvm_cpu_exec(CPUState *env)
> >>>>
> >>>>       DPRINTF("kvm_cpu_exec()\n");
> >>>>
> >>>> +    if (kvm_arch_process_irqchip_events(env)) {
> >>>> +        env->exit_request = 0;
> >>>> +        env->exception_index = EXCP_HLT;
> >>>> +        return 0;
> >>>> +    }
> >>>> +
> >>>>       do {
> >>>>   #ifndef CONFIG_IOTHREAD
> >>>>           if (env->exit_request) {
> >>>> @@ -901,11 +907,6 @@ int kvm_cpu_exec(CPUState *env)
> >>>>           }
> >>>
> >>> We check for ->exit_request here
> >>>
> >>>>   #endif
> >>>>
> >>>> -        if (kvm_arch_process_irqchip_events(env)) {
> >>>> -            ret = 0;
> >>>> -            break;
> >>>> -        }
> >>>> -
> >>>
> >>> But this checks for ->interrupt_request.  What ensures that we exit when 
> >>> ->interrupt_request is set?
> >>
> >> Good question, need to check again. But if that turns out to be an
> >> issue, qemu-kvm would be broken as well. I'm just aligning the code here.
> >>
> > 
> > The only thing we miss by moving process_irqchip_events is a self-INIT
> > of an AP - if such thing exists in real life. In that case, the AP would
> > cause a reset of itself, followed by a transition to HALT state.
> 
> I checked again with the Intel spec, and a self-INIT is invalid (at
> least when specified via shorthand). So I'm under the impression now
> that we can safely ignore this case and leave the patch as is.
> 
> Any different views?
> 
IIRC if you don't use shorthand you can send INIT to self.

--
			Gleb.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 17/22] kvm: Move irqchip event processing out of inner loop
@ 2011-01-31 16:38             ` Gleb Natapov
  0 siblings, 0 replies; 146+ messages in thread
From: Gleb Natapov @ 2011-01-31 16:38 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Marcelo Tosatti, Avi Kivity, kvm, qemu-devel

On Mon, Jan 31, 2011 at 04:40:34PM +0100, Jan Kiszka wrote:
> On 2011-01-31 14:04, Jan Kiszka wrote:
> > On 2011-01-31 12:36, Jan Kiszka wrote:
> >> On 2011-01-31 11:08, Avi Kivity wrote:
> >>> On 01/27/2011 03:10 PM, Jan Kiszka wrote:
> >>>> Align with qemu-kvm and prepare for IO exit fix: There is no need to run
> >>>> kvm_arch_process_irqchip_events in the inner VCPU loop. Any state change
> >>>> this service processes will first cause an exit from kvm_cpu_exec
> >>>> anyway. And we will have to reenter the kernel on IO exits
> >>>> unconditionally, something that the current logic prevents.
> >>>>
> >>>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
> >>>> ---
> >>>>   kvm-all.c |   11 ++++++-----
> >>>>   1 files changed, 6 insertions(+), 5 deletions(-)
> >>>>
> >>>> diff --git a/kvm-all.c b/kvm-all.c
> >>>> index 5bfa8c0..46ecc1c 100644
> >>>> --- a/kvm-all.c
> >>>> +++ b/kvm-all.c
> >>>> @@ -892,6 +892,12 @@ int kvm_cpu_exec(CPUState *env)
> >>>>
> >>>>       DPRINTF("kvm_cpu_exec()\n");
> >>>>
> >>>> +    if (kvm_arch_process_irqchip_events(env)) {
> >>>> +        env->exit_request = 0;
> >>>> +        env->exception_index = EXCP_HLT;
> >>>> +        return 0;
> >>>> +    }
> >>>> +
> >>>>       do {
> >>>>   #ifndef CONFIG_IOTHREAD
> >>>>           if (env->exit_request) {
> >>>> @@ -901,11 +907,6 @@ int kvm_cpu_exec(CPUState *env)
> >>>>           }
> >>>
> >>> We check for ->exit_request here
> >>>
> >>>>   #endif
> >>>>
> >>>> -        if (kvm_arch_process_irqchip_events(env)) {
> >>>> -            ret = 0;
> >>>> -            break;
> >>>> -        }
> >>>> -
> >>>
> >>> But this checks for ->interrupt_request.  What ensures that we exit when 
> >>> ->interrupt_request is set?
> >>
> >> Good question, need to check again. But if that turns out to be an
> >> issue, qemu-kvm would be broken as well. I'm just aligning the code here.
> >>
> > 
> > The only thing we miss by moving process_irqchip_events is a self-INIT
> > of an AP - if such thing exists in real life. In that case, the AP would
> > cause a reset of itself, followed by a transition to HALT state.
> 
> I checked again with the Intel spec, and a self-INIT is invalid (at
> least when specified via shorthand). So I'm under the impression now
> that we can safely ignore this case and leave the patch as is.
> 
> Any different views?
> 
IIRC if you don't use shorthand you can send INIT to self.

--
			Gleb.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 17/22] kvm: Move irqchip event processing out of inner loop
  2011-01-31 16:38             ` [Qemu-devel] " Gleb Natapov
@ 2011-01-31 16:41               ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 16:41 UTC (permalink / raw)
  To: Gleb Natapov; +Cc: Avi Kivity, Marcelo Tosatti, kvm, qemu-devel

On 2011-01-31 17:38, Gleb Natapov wrote:
> On Mon, Jan 31, 2011 at 04:40:34PM +0100, Jan Kiszka wrote:
>> On 2011-01-31 14:04, Jan Kiszka wrote:
>>> On 2011-01-31 12:36, Jan Kiszka wrote:
>>>> On 2011-01-31 11:08, Avi Kivity wrote:
>>>>> On 01/27/2011 03:10 PM, Jan Kiszka wrote:
>>>>>> Align with qemu-kvm and prepare for IO exit fix: There is no need to run
>>>>>> kvm_arch_process_irqchip_events in the inner VCPU loop. Any state change
>>>>>> this service processes will first cause an exit from kvm_cpu_exec
>>>>>> anyway. And we will have to reenter the kernel on IO exits
>>>>>> unconditionally, something that the current logic prevents.
>>>>>>
>>>>>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>>>>>> ---
>>>>>>   kvm-all.c |   11 ++++++-----
>>>>>>   1 files changed, 6 insertions(+), 5 deletions(-)
>>>>>>
>>>>>> diff --git a/kvm-all.c b/kvm-all.c
>>>>>> index 5bfa8c0..46ecc1c 100644
>>>>>> --- a/kvm-all.c
>>>>>> +++ b/kvm-all.c
>>>>>> @@ -892,6 +892,12 @@ int kvm_cpu_exec(CPUState *env)
>>>>>>
>>>>>>       DPRINTF("kvm_cpu_exec()\n");
>>>>>>
>>>>>> +    if (kvm_arch_process_irqchip_events(env)) {
>>>>>> +        env->exit_request = 0;
>>>>>> +        env->exception_index = EXCP_HLT;
>>>>>> +        return 0;
>>>>>> +    }
>>>>>> +
>>>>>>       do {
>>>>>>   #ifndef CONFIG_IOTHREAD
>>>>>>           if (env->exit_request) {
>>>>>> @@ -901,11 +907,6 @@ int kvm_cpu_exec(CPUState *env)
>>>>>>           }
>>>>>
>>>>> We check for ->exit_request here
>>>>>
>>>>>>   #endif
>>>>>>
>>>>>> -        if (kvm_arch_process_irqchip_events(env)) {
>>>>>> -            ret = 0;
>>>>>> -            break;
>>>>>> -        }
>>>>>> -
>>>>>
>>>>> But this checks for ->interrupt_request.  What ensures that we exit when 
>>>>> ->interrupt_request is set?
>>>>
>>>> Good question, need to check again. But if that turns out to be an
>>>> issue, qemu-kvm would be broken as well. I'm just aligning the code here.
>>>>
>>>
>>> The only thing we miss by moving process_irqchip_events is a self-INIT
>>> of an AP - if such thing exists in real life. In that case, the AP would
>>> cause a reset of itself, followed by a transition to HALT state.
>>
>> I checked again with the Intel spec, and a self-INIT is invalid (at
>> least when specified via shorthand). So I'm under the impression now
>> that we can safely ignore this case and leave the patch as is.
>>
>> Any different views?
>>
> IIRC if you don't use shorthand you can send INIT to self.

We didn't care so far (in qemu-kvm), do you think we should?

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 17/22] kvm: Move irqchip event processing out of inner loop
@ 2011-01-31 16:41               ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 16:41 UTC (permalink / raw)
  To: Gleb Natapov; +Cc: Marcelo Tosatti, Avi Kivity, kvm, qemu-devel

On 2011-01-31 17:38, Gleb Natapov wrote:
> On Mon, Jan 31, 2011 at 04:40:34PM +0100, Jan Kiszka wrote:
>> On 2011-01-31 14:04, Jan Kiszka wrote:
>>> On 2011-01-31 12:36, Jan Kiszka wrote:
>>>> On 2011-01-31 11:08, Avi Kivity wrote:
>>>>> On 01/27/2011 03:10 PM, Jan Kiszka wrote:
>>>>>> Align with qemu-kvm and prepare for IO exit fix: There is no need to run
>>>>>> kvm_arch_process_irqchip_events in the inner VCPU loop. Any state change
>>>>>> this service processes will first cause an exit from kvm_cpu_exec
>>>>>> anyway. And we will have to reenter the kernel on IO exits
>>>>>> unconditionally, something that the current logic prevents.
>>>>>>
>>>>>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>>>>>> ---
>>>>>>   kvm-all.c |   11 ++++++-----
>>>>>>   1 files changed, 6 insertions(+), 5 deletions(-)
>>>>>>
>>>>>> diff --git a/kvm-all.c b/kvm-all.c
>>>>>> index 5bfa8c0..46ecc1c 100644
>>>>>> --- a/kvm-all.c
>>>>>> +++ b/kvm-all.c
>>>>>> @@ -892,6 +892,12 @@ int kvm_cpu_exec(CPUState *env)
>>>>>>
>>>>>>       DPRINTF("kvm_cpu_exec()\n");
>>>>>>
>>>>>> +    if (kvm_arch_process_irqchip_events(env)) {
>>>>>> +        env->exit_request = 0;
>>>>>> +        env->exception_index = EXCP_HLT;
>>>>>> +        return 0;
>>>>>> +    }
>>>>>> +
>>>>>>       do {
>>>>>>   #ifndef CONFIG_IOTHREAD
>>>>>>           if (env->exit_request) {
>>>>>> @@ -901,11 +907,6 @@ int kvm_cpu_exec(CPUState *env)
>>>>>>           }
>>>>>
>>>>> We check for ->exit_request here
>>>>>
>>>>>>   #endif
>>>>>>
>>>>>> -        if (kvm_arch_process_irqchip_events(env)) {
>>>>>> -            ret = 0;
>>>>>> -            break;
>>>>>> -        }
>>>>>> -
>>>>>
>>>>> But this checks for ->interrupt_request.  What ensures that we exit when 
>>>>> ->interrupt_request is set?
>>>>
>>>> Good question, need to check again. But if that turns out to be an
>>>> issue, qemu-kvm would be broken as well. I'm just aligning the code here.
>>>>
>>>
>>> The only thing we miss by moving process_irqchip_events is a self-INIT
>>> of an AP - if such thing exists in real life. In that case, the AP would
>>> cause a reset of itself, followed by a transition to HALT state.
>>
>> I checked again with the Intel spec, and a self-INIT is invalid (at
>> least when specified via shorthand). So I'm under the impression now
>> that we can safely ignore this case and leave the patch as is.
>>
>> Any different views?
>>
> IIRC if you don't use shorthand you can send INIT to self.

We didn't care so far (in qemu-kvm), do you think we should?

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 17/22] kvm: Move irqchip event processing out of inner loop
  2011-01-31 16:41               ` [Qemu-devel] " Jan Kiszka
@ 2011-01-31 16:45                 ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 16:45 UTC (permalink / raw)
  To: Gleb Natapov; +Cc: Avi Kivity, Marcelo Tosatti, kvm, qemu-devel

On 2011-01-31 17:41, Jan Kiszka wrote:
> On 2011-01-31 17:38, Gleb Natapov wrote:
>> On Mon, Jan 31, 2011 at 04:40:34PM +0100, Jan Kiszka wrote:
>>> On 2011-01-31 14:04, Jan Kiszka wrote:
>>>> On 2011-01-31 12:36, Jan Kiszka wrote:
>>>>> On 2011-01-31 11:08, Avi Kivity wrote:
>>>>>> On 01/27/2011 03:10 PM, Jan Kiszka wrote:
>>>>>>> Align with qemu-kvm and prepare for IO exit fix: There is no need to run
>>>>>>> kvm_arch_process_irqchip_events in the inner VCPU loop. Any state change
>>>>>>> this service processes will first cause an exit from kvm_cpu_exec
>>>>>>> anyway. And we will have to reenter the kernel on IO exits
>>>>>>> unconditionally, something that the current logic prevents.
>>>>>>>
>>>>>>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>>>>>>> ---
>>>>>>>   kvm-all.c |   11 ++++++-----
>>>>>>>   1 files changed, 6 insertions(+), 5 deletions(-)
>>>>>>>
>>>>>>> diff --git a/kvm-all.c b/kvm-all.c
>>>>>>> index 5bfa8c0..46ecc1c 100644
>>>>>>> --- a/kvm-all.c
>>>>>>> +++ b/kvm-all.c
>>>>>>> @@ -892,6 +892,12 @@ int kvm_cpu_exec(CPUState *env)
>>>>>>>
>>>>>>>       DPRINTF("kvm_cpu_exec()\n");
>>>>>>>
>>>>>>> +    if (kvm_arch_process_irqchip_events(env)) {
>>>>>>> +        env->exit_request = 0;
>>>>>>> +        env->exception_index = EXCP_HLT;
>>>>>>> +        return 0;
>>>>>>> +    }
>>>>>>> +
>>>>>>>       do {
>>>>>>>   #ifndef CONFIG_IOTHREAD
>>>>>>>           if (env->exit_request) {
>>>>>>> @@ -901,11 +907,6 @@ int kvm_cpu_exec(CPUState *env)
>>>>>>>           }
>>>>>>
>>>>>> We check for ->exit_request here
>>>>>>
>>>>>>>   #endif
>>>>>>>
>>>>>>> -        if (kvm_arch_process_irqchip_events(env)) {
>>>>>>> -            ret = 0;
>>>>>>> -            break;
>>>>>>> -        }
>>>>>>> -
>>>>>>
>>>>>> But this checks for ->interrupt_request.  What ensures that we exit when 
>>>>>> ->interrupt_request is set?
>>>>>
>>>>> Good question, need to check again. But if that turns out to be an
>>>>> issue, qemu-kvm would be broken as well. I'm just aligning the code here.
>>>>>
>>>>
>>>> The only thing we miss by moving process_irqchip_events is a self-INIT
>>>> of an AP - if such thing exists in real life. In that case, the AP would
>>>> cause a reset of itself, followed by a transition to HALT state.
>>>
>>> I checked again with the Intel spec, and a self-INIT is invalid (at
>>> least when specified via shorthand). So I'm under the impression now
>>> that we can safely ignore this case and leave the patch as is.
>>>
>>> Any different views?
>>>
>> IIRC if you don't use shorthand you can send INIT to self.
> 
> We didn't care so far (in qemu-kvm), do you think we should?

...and the kernel model should have barked "INIT on a runnable vcpu" in
such cases (BTW, that's user triggerable and should likely be rate limited).

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 17/22] kvm: Move irqchip event processing out of inner loop
@ 2011-01-31 16:45                 ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 16:45 UTC (permalink / raw)
  To: Gleb Natapov; +Cc: Marcelo Tosatti, Avi Kivity, kvm, qemu-devel

On 2011-01-31 17:41, Jan Kiszka wrote:
> On 2011-01-31 17:38, Gleb Natapov wrote:
>> On Mon, Jan 31, 2011 at 04:40:34PM +0100, Jan Kiszka wrote:
>>> On 2011-01-31 14:04, Jan Kiszka wrote:
>>>> On 2011-01-31 12:36, Jan Kiszka wrote:
>>>>> On 2011-01-31 11:08, Avi Kivity wrote:
>>>>>> On 01/27/2011 03:10 PM, Jan Kiszka wrote:
>>>>>>> Align with qemu-kvm and prepare for IO exit fix: There is no need to run
>>>>>>> kvm_arch_process_irqchip_events in the inner VCPU loop. Any state change
>>>>>>> this service processes will first cause an exit from kvm_cpu_exec
>>>>>>> anyway. And we will have to reenter the kernel on IO exits
>>>>>>> unconditionally, something that the current logic prevents.
>>>>>>>
>>>>>>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>>>>>>> ---
>>>>>>>   kvm-all.c |   11 ++++++-----
>>>>>>>   1 files changed, 6 insertions(+), 5 deletions(-)
>>>>>>>
>>>>>>> diff --git a/kvm-all.c b/kvm-all.c
>>>>>>> index 5bfa8c0..46ecc1c 100644
>>>>>>> --- a/kvm-all.c
>>>>>>> +++ b/kvm-all.c
>>>>>>> @@ -892,6 +892,12 @@ int kvm_cpu_exec(CPUState *env)
>>>>>>>
>>>>>>>       DPRINTF("kvm_cpu_exec()\n");
>>>>>>>
>>>>>>> +    if (kvm_arch_process_irqchip_events(env)) {
>>>>>>> +        env->exit_request = 0;
>>>>>>> +        env->exception_index = EXCP_HLT;
>>>>>>> +        return 0;
>>>>>>> +    }
>>>>>>> +
>>>>>>>       do {
>>>>>>>   #ifndef CONFIG_IOTHREAD
>>>>>>>           if (env->exit_request) {
>>>>>>> @@ -901,11 +907,6 @@ int kvm_cpu_exec(CPUState *env)
>>>>>>>           }
>>>>>>
>>>>>> We check for ->exit_request here
>>>>>>
>>>>>>>   #endif
>>>>>>>
>>>>>>> -        if (kvm_arch_process_irqchip_events(env)) {
>>>>>>> -            ret = 0;
>>>>>>> -            break;
>>>>>>> -        }
>>>>>>> -
>>>>>>
>>>>>> But this checks for ->interrupt_request.  What ensures that we exit when 
>>>>>> ->interrupt_request is set?
>>>>>
>>>>> Good question, need to check again. But if that turns out to be an
>>>>> issue, qemu-kvm would be broken as well. I'm just aligning the code here.
>>>>>
>>>>
>>>> The only thing we miss by moving process_irqchip_events is a self-INIT
>>>> of an AP - if such thing exists in real life. In that case, the AP would
>>>> cause a reset of itself, followed by a transition to HALT state.
>>>
>>> I checked again with the Intel spec, and a self-INIT is invalid (at
>>> least when specified via shorthand). So I'm under the impression now
>>> that we can safely ignore this case and leave the patch as is.
>>>
>>> Any different views?
>>>
>> IIRC if you don't use shorthand you can send INIT to self.
> 
> We didn't care so far (in qemu-kvm), do you think we should?

...and the kernel model should have barked "INIT on a runnable vcpu" in
such cases (BTW, that's user triggerable and should likely be rate limited).

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 17/22] kvm: Move irqchip event processing out of inner loop
  2011-01-31 16:41               ` [Qemu-devel] " Jan Kiszka
@ 2011-01-31 16:50                 ` Gleb Natapov
  -1 siblings, 0 replies; 146+ messages in thread
From: Gleb Natapov @ 2011-01-31 16:50 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Avi Kivity, Marcelo Tosatti, kvm, qemu-devel

On Mon, Jan 31, 2011 at 05:41:24PM +0100, Jan Kiszka wrote:
> On 2011-01-31 17:38, Gleb Natapov wrote:
> > On Mon, Jan 31, 2011 at 04:40:34PM +0100, Jan Kiszka wrote:
> >> On 2011-01-31 14:04, Jan Kiszka wrote:
> >>> On 2011-01-31 12:36, Jan Kiszka wrote:
> >>>> On 2011-01-31 11:08, Avi Kivity wrote:
> >>>>> On 01/27/2011 03:10 PM, Jan Kiszka wrote:
> >>>>>> Align with qemu-kvm and prepare for IO exit fix: There is no need to run
> >>>>>> kvm_arch_process_irqchip_events in the inner VCPU loop. Any state change
> >>>>>> this service processes will first cause an exit from kvm_cpu_exec
> >>>>>> anyway. And we will have to reenter the kernel on IO exits
> >>>>>> unconditionally, something that the current logic prevents.
> >>>>>>
> >>>>>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
> >>>>>> ---
> >>>>>>   kvm-all.c |   11 ++++++-----
> >>>>>>   1 files changed, 6 insertions(+), 5 deletions(-)
> >>>>>>
> >>>>>> diff --git a/kvm-all.c b/kvm-all.c
> >>>>>> index 5bfa8c0..46ecc1c 100644
> >>>>>> --- a/kvm-all.c
> >>>>>> +++ b/kvm-all.c
> >>>>>> @@ -892,6 +892,12 @@ int kvm_cpu_exec(CPUState *env)
> >>>>>>
> >>>>>>       DPRINTF("kvm_cpu_exec()\n");
> >>>>>>
> >>>>>> +    if (kvm_arch_process_irqchip_events(env)) {
> >>>>>> +        env->exit_request = 0;
> >>>>>> +        env->exception_index = EXCP_HLT;
> >>>>>> +        return 0;
> >>>>>> +    }
> >>>>>> +
> >>>>>>       do {
> >>>>>>   #ifndef CONFIG_IOTHREAD
> >>>>>>           if (env->exit_request) {
> >>>>>> @@ -901,11 +907,6 @@ int kvm_cpu_exec(CPUState *env)
> >>>>>>           }
> >>>>>
> >>>>> We check for ->exit_request here
> >>>>>
> >>>>>>   #endif
> >>>>>>
> >>>>>> -        if (kvm_arch_process_irqchip_events(env)) {
> >>>>>> -            ret = 0;
> >>>>>> -            break;
> >>>>>> -        }
> >>>>>> -
> >>>>>
> >>>>> But this checks for ->interrupt_request.  What ensures that we exit when 
> >>>>> ->interrupt_request is set?
> >>>>
> >>>> Good question, need to check again. But if that turns out to be an
> >>>> issue, qemu-kvm would be broken as well. I'm just aligning the code here.
> >>>>
> >>>
> >>> The only thing we miss by moving process_irqchip_events is a self-INIT
> >>> of an AP - if such thing exists in real life. In that case, the AP would
> >>> cause a reset of itself, followed by a transition to HALT state.
> >>
> >> I checked again with the Intel spec, and a self-INIT is invalid (at
> >> least when specified via shorthand). So I'm under the impression now
> >> that we can safely ignore this case and leave the patch as is.
> >>
> >> Any different views?
> >>
> > IIRC if you don't use shorthand you can send INIT to self.
> 
> We didn't care so far (in qemu-kvm), do you think we should?
> 
Doesn't kernel lapic emulation support this?

--
			Gleb.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 17/22] kvm: Move irqchip event processing out of inner loop
@ 2011-01-31 16:50                 ` Gleb Natapov
  0 siblings, 0 replies; 146+ messages in thread
From: Gleb Natapov @ 2011-01-31 16:50 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Marcelo Tosatti, Avi Kivity, kvm, qemu-devel

On Mon, Jan 31, 2011 at 05:41:24PM +0100, Jan Kiszka wrote:
> On 2011-01-31 17:38, Gleb Natapov wrote:
> > On Mon, Jan 31, 2011 at 04:40:34PM +0100, Jan Kiszka wrote:
> >> On 2011-01-31 14:04, Jan Kiszka wrote:
> >>> On 2011-01-31 12:36, Jan Kiszka wrote:
> >>>> On 2011-01-31 11:08, Avi Kivity wrote:
> >>>>> On 01/27/2011 03:10 PM, Jan Kiszka wrote:
> >>>>>> Align with qemu-kvm and prepare for IO exit fix: There is no need to run
> >>>>>> kvm_arch_process_irqchip_events in the inner VCPU loop. Any state change
> >>>>>> this service processes will first cause an exit from kvm_cpu_exec
> >>>>>> anyway. And we will have to reenter the kernel on IO exits
> >>>>>> unconditionally, something that the current logic prevents.
> >>>>>>
> >>>>>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
> >>>>>> ---
> >>>>>>   kvm-all.c |   11 ++++++-----
> >>>>>>   1 files changed, 6 insertions(+), 5 deletions(-)
> >>>>>>
> >>>>>> diff --git a/kvm-all.c b/kvm-all.c
> >>>>>> index 5bfa8c0..46ecc1c 100644
> >>>>>> --- a/kvm-all.c
> >>>>>> +++ b/kvm-all.c
> >>>>>> @@ -892,6 +892,12 @@ int kvm_cpu_exec(CPUState *env)
> >>>>>>
> >>>>>>       DPRINTF("kvm_cpu_exec()\n");
> >>>>>>
> >>>>>> +    if (kvm_arch_process_irqchip_events(env)) {
> >>>>>> +        env->exit_request = 0;
> >>>>>> +        env->exception_index = EXCP_HLT;
> >>>>>> +        return 0;
> >>>>>> +    }
> >>>>>> +
> >>>>>>       do {
> >>>>>>   #ifndef CONFIG_IOTHREAD
> >>>>>>           if (env->exit_request) {
> >>>>>> @@ -901,11 +907,6 @@ int kvm_cpu_exec(CPUState *env)
> >>>>>>           }
> >>>>>
> >>>>> We check for ->exit_request here
> >>>>>
> >>>>>>   #endif
> >>>>>>
> >>>>>> -        if (kvm_arch_process_irqchip_events(env)) {
> >>>>>> -            ret = 0;
> >>>>>> -            break;
> >>>>>> -        }
> >>>>>> -
> >>>>>
> >>>>> But this checks for ->interrupt_request.  What ensures that we exit when 
> >>>>> ->interrupt_request is set?
> >>>>
> >>>> Good question, need to check again. But if that turns out to be an
> >>>> issue, qemu-kvm would be broken as well. I'm just aligning the code here.
> >>>>
> >>>
> >>> The only thing we miss by moving process_irqchip_events is a self-INIT
> >>> of an AP - if such thing exists in real life. In that case, the AP would
> >>> cause a reset of itself, followed by a transition to HALT state.
> >>
> >> I checked again with the Intel spec, and a self-INIT is invalid (at
> >> least when specified via shorthand). So I'm under the impression now
> >> that we can safely ignore this case and leave the patch as is.
> >>
> >> Any different views?
> >>
> > IIRC if you don't use shorthand you can send INIT to self.
> 
> We didn't care so far (in qemu-kvm), do you think we should?
> 
Doesn't kernel lapic emulation support this?

--
			Gleb.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 17/22] kvm: Move irqchip event processing out of inner loop
  2011-01-31 16:50                 ` [Qemu-devel] " Gleb Natapov
@ 2011-01-31 16:52                   ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 16:52 UTC (permalink / raw)
  To: Gleb Natapov; +Cc: Avi Kivity, Marcelo Tosatti, kvm, qemu-devel

On 2011-01-31 17:50, Gleb Natapov wrote:
> On Mon, Jan 31, 2011 at 05:41:24PM +0100, Jan Kiszka wrote:
>> On 2011-01-31 17:38, Gleb Natapov wrote:
>>> On Mon, Jan 31, 2011 at 04:40:34PM +0100, Jan Kiszka wrote:
>>>> On 2011-01-31 14:04, Jan Kiszka wrote:
>>>>> On 2011-01-31 12:36, Jan Kiszka wrote:
>>>>>> On 2011-01-31 11:08, Avi Kivity wrote:
>>>>>>> On 01/27/2011 03:10 PM, Jan Kiszka wrote:
>>>>>>>> Align with qemu-kvm and prepare for IO exit fix: There is no need to run
>>>>>>>> kvm_arch_process_irqchip_events in the inner VCPU loop. Any state change
>>>>>>>> this service processes will first cause an exit from kvm_cpu_exec
>>>>>>>> anyway. And we will have to reenter the kernel on IO exits
>>>>>>>> unconditionally, something that the current logic prevents.
>>>>>>>>
>>>>>>>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>>>>>>>> ---
>>>>>>>>   kvm-all.c |   11 ++++++-----
>>>>>>>>   1 files changed, 6 insertions(+), 5 deletions(-)
>>>>>>>>
>>>>>>>> diff --git a/kvm-all.c b/kvm-all.c
>>>>>>>> index 5bfa8c0..46ecc1c 100644
>>>>>>>> --- a/kvm-all.c
>>>>>>>> +++ b/kvm-all.c
>>>>>>>> @@ -892,6 +892,12 @@ int kvm_cpu_exec(CPUState *env)
>>>>>>>>
>>>>>>>>       DPRINTF("kvm_cpu_exec()\n");
>>>>>>>>
>>>>>>>> +    if (kvm_arch_process_irqchip_events(env)) {
>>>>>>>> +        env->exit_request = 0;
>>>>>>>> +        env->exception_index = EXCP_HLT;
>>>>>>>> +        return 0;
>>>>>>>> +    }
>>>>>>>> +
>>>>>>>>       do {
>>>>>>>>   #ifndef CONFIG_IOTHREAD
>>>>>>>>           if (env->exit_request) {
>>>>>>>> @@ -901,11 +907,6 @@ int kvm_cpu_exec(CPUState *env)
>>>>>>>>           }
>>>>>>>
>>>>>>> We check for ->exit_request here
>>>>>>>
>>>>>>>>   #endif
>>>>>>>>
>>>>>>>> -        if (kvm_arch_process_irqchip_events(env)) {
>>>>>>>> -            ret = 0;
>>>>>>>> -            break;
>>>>>>>> -        }
>>>>>>>> -
>>>>>>>
>>>>>>> But this checks for ->interrupt_request.  What ensures that we exit when 
>>>>>>> ->interrupt_request is set?
>>>>>>
>>>>>> Good question, need to check again. But if that turns out to be an
>>>>>> issue, qemu-kvm would be broken as well. I'm just aligning the code here.
>>>>>>
>>>>>
>>>>> The only thing we miss by moving process_irqchip_events is a self-INIT
>>>>> of an AP - if such thing exists in real life. In that case, the AP would
>>>>> cause a reset of itself, followed by a transition to HALT state.
>>>>
>>>> I checked again with the Intel spec, and a self-INIT is invalid (at
>>>> least when specified via shorthand). So I'm under the impression now
>>>> that we can safely ignore this case and leave the patch as is.
>>>>
>>>> Any different views?
>>>>
>>> IIRC if you don't use shorthand you can send INIT to self.
>>
>> We didn't care so far (in qemu-kvm), do you think we should?
>>
> Doesn't kernel lapic emulation support this?

See the my other mail: It supports it, but it apparently doesn't expects
this to happen.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 17/22] kvm: Move irqchip event processing out of inner loop
@ 2011-01-31 16:52                   ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 16:52 UTC (permalink / raw)
  To: Gleb Natapov; +Cc: Marcelo Tosatti, Avi Kivity, kvm, qemu-devel

On 2011-01-31 17:50, Gleb Natapov wrote:
> On Mon, Jan 31, 2011 at 05:41:24PM +0100, Jan Kiszka wrote:
>> On 2011-01-31 17:38, Gleb Natapov wrote:
>>> On Mon, Jan 31, 2011 at 04:40:34PM +0100, Jan Kiszka wrote:
>>>> On 2011-01-31 14:04, Jan Kiszka wrote:
>>>>> On 2011-01-31 12:36, Jan Kiszka wrote:
>>>>>> On 2011-01-31 11:08, Avi Kivity wrote:
>>>>>>> On 01/27/2011 03:10 PM, Jan Kiszka wrote:
>>>>>>>> Align with qemu-kvm and prepare for IO exit fix: There is no need to run
>>>>>>>> kvm_arch_process_irqchip_events in the inner VCPU loop. Any state change
>>>>>>>> this service processes will first cause an exit from kvm_cpu_exec
>>>>>>>> anyway. And we will have to reenter the kernel on IO exits
>>>>>>>> unconditionally, something that the current logic prevents.
>>>>>>>>
>>>>>>>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
>>>>>>>> ---
>>>>>>>>   kvm-all.c |   11 ++++++-----
>>>>>>>>   1 files changed, 6 insertions(+), 5 deletions(-)
>>>>>>>>
>>>>>>>> diff --git a/kvm-all.c b/kvm-all.c
>>>>>>>> index 5bfa8c0..46ecc1c 100644
>>>>>>>> --- a/kvm-all.c
>>>>>>>> +++ b/kvm-all.c
>>>>>>>> @@ -892,6 +892,12 @@ int kvm_cpu_exec(CPUState *env)
>>>>>>>>
>>>>>>>>       DPRINTF("kvm_cpu_exec()\n");
>>>>>>>>
>>>>>>>> +    if (kvm_arch_process_irqchip_events(env)) {
>>>>>>>> +        env->exit_request = 0;
>>>>>>>> +        env->exception_index = EXCP_HLT;
>>>>>>>> +        return 0;
>>>>>>>> +    }
>>>>>>>> +
>>>>>>>>       do {
>>>>>>>>   #ifndef CONFIG_IOTHREAD
>>>>>>>>           if (env->exit_request) {
>>>>>>>> @@ -901,11 +907,6 @@ int kvm_cpu_exec(CPUState *env)
>>>>>>>>           }
>>>>>>>
>>>>>>> We check for ->exit_request here
>>>>>>>
>>>>>>>>   #endif
>>>>>>>>
>>>>>>>> -        if (kvm_arch_process_irqchip_events(env)) {
>>>>>>>> -            ret = 0;
>>>>>>>> -            break;
>>>>>>>> -        }
>>>>>>>> -
>>>>>>>
>>>>>>> But this checks for ->interrupt_request.  What ensures that we exit when 
>>>>>>> ->interrupt_request is set?
>>>>>>
>>>>>> Good question, need to check again. But if that turns out to be an
>>>>>> issue, qemu-kvm would be broken as well. I'm just aligning the code here.
>>>>>>
>>>>>
>>>>> The only thing we miss by moving process_irqchip_events is a self-INIT
>>>>> of an AP - if such thing exists in real life. In that case, the AP would
>>>>> cause a reset of itself, followed by a transition to HALT state.
>>>>
>>>> I checked again with the Intel spec, and a self-INIT is invalid (at
>>>> least when specified via shorthand). So I'm under the impression now
>>>> that we can safely ignore this case and leave the patch as is.
>>>>
>>>> Any different views?
>>>>
>>> IIRC if you don't use shorthand you can send INIT to self.
>>
>> We didn't care so far (in qemu-kvm), do you think we should?
>>
> Doesn't kernel lapic emulation support this?

See the my other mail: It supports it, but it apparently doesn't expects
this to happen.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 17/22] kvm: Move irqchip event processing out of inner loop
  2011-01-31 16:52                   ` [Qemu-devel] " Jan Kiszka
@ 2011-01-31 16:56                     ` Gleb Natapov
  -1 siblings, 0 replies; 146+ messages in thread
From: Gleb Natapov @ 2011-01-31 16:56 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Avi Kivity, Marcelo Tosatti, kvm, qemu-devel

On Mon, Jan 31, 2011 at 05:52:13PM +0100, Jan Kiszka wrote:
> On 2011-01-31 17:50, Gleb Natapov wrote:
> > On Mon, Jan 31, 2011 at 05:41:24PM +0100, Jan Kiszka wrote:
> >> On 2011-01-31 17:38, Gleb Natapov wrote:
> >>> On Mon, Jan 31, 2011 at 04:40:34PM +0100, Jan Kiszka wrote:
> >>>> On 2011-01-31 14:04, Jan Kiszka wrote:
> >>>>> On 2011-01-31 12:36, Jan Kiszka wrote:
> >>>>>> On 2011-01-31 11:08, Avi Kivity wrote:
> >>>>>>> On 01/27/2011 03:10 PM, Jan Kiszka wrote:
> >>>>>>>> Align with qemu-kvm and prepare for IO exit fix: There is no need to run
> >>>>>>>> kvm_arch_process_irqchip_events in the inner VCPU loop. Any state change
> >>>>>>>> this service processes will first cause an exit from kvm_cpu_exec
> >>>>>>>> anyway. And we will have to reenter the kernel on IO exits
> >>>>>>>> unconditionally, something that the current logic prevents.
> >>>>>>>>
> >>>>>>>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
> >>>>>>>> ---
> >>>>>>>>   kvm-all.c |   11 ++++++-----
> >>>>>>>>   1 files changed, 6 insertions(+), 5 deletions(-)
> >>>>>>>>
> >>>>>>>> diff --git a/kvm-all.c b/kvm-all.c
> >>>>>>>> index 5bfa8c0..46ecc1c 100644
> >>>>>>>> --- a/kvm-all.c
> >>>>>>>> +++ b/kvm-all.c
> >>>>>>>> @@ -892,6 +892,12 @@ int kvm_cpu_exec(CPUState *env)
> >>>>>>>>
> >>>>>>>>       DPRINTF("kvm_cpu_exec()\n");
> >>>>>>>>
> >>>>>>>> +    if (kvm_arch_process_irqchip_events(env)) {
> >>>>>>>> +        env->exit_request = 0;
> >>>>>>>> +        env->exception_index = EXCP_HLT;
> >>>>>>>> +        return 0;
> >>>>>>>> +    }
> >>>>>>>> +
> >>>>>>>>       do {
> >>>>>>>>   #ifndef CONFIG_IOTHREAD
> >>>>>>>>           if (env->exit_request) {
> >>>>>>>> @@ -901,11 +907,6 @@ int kvm_cpu_exec(CPUState *env)
> >>>>>>>>           }
> >>>>>>>
> >>>>>>> We check for ->exit_request here
> >>>>>>>
> >>>>>>>>   #endif
> >>>>>>>>
> >>>>>>>> -        if (kvm_arch_process_irqchip_events(env)) {
> >>>>>>>> -            ret = 0;
> >>>>>>>> -            break;
> >>>>>>>> -        }
> >>>>>>>> -
> >>>>>>>
> >>>>>>> But this checks for ->interrupt_request.  What ensures that we exit when 
> >>>>>>> ->interrupt_request is set?
> >>>>>>
> >>>>>> Good question, need to check again. But if that turns out to be an
> >>>>>> issue, qemu-kvm would be broken as well. I'm just aligning the code here.
> >>>>>>
> >>>>>
> >>>>> The only thing we miss by moving process_irqchip_events is a self-INIT
> >>>>> of an AP - if such thing exists in real life. In that case, the AP would
> >>>>> cause a reset of itself, followed by a transition to HALT state.
> >>>>
> >>>> I checked again with the Intel spec, and a self-INIT is invalid (at
> >>>> least when specified via shorthand). So I'm under the impression now
> >>>> that we can safely ignore this case and leave the patch as is.
> >>>>
> >>>> Any different views?
> >>>>
> >>> IIRC if you don't use shorthand you can send INIT to self.
> >>
> >> We didn't care so far (in qemu-kvm), do you think we should?
> >>
> > Doesn't kernel lapic emulation support this?
> 
> See the my other mail: It supports it, but it apparently doesn't expects
> this to happen.
> 
I saw it, but I do not understand why do we print this message. May be
it was used for debugging in early stages of KVM development.

--
			Gleb.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 17/22] kvm: Move irqchip event processing out of inner loop
@ 2011-01-31 16:56                     ` Gleb Natapov
  0 siblings, 0 replies; 146+ messages in thread
From: Gleb Natapov @ 2011-01-31 16:56 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Marcelo Tosatti, Avi Kivity, kvm, qemu-devel

On Mon, Jan 31, 2011 at 05:52:13PM +0100, Jan Kiszka wrote:
> On 2011-01-31 17:50, Gleb Natapov wrote:
> > On Mon, Jan 31, 2011 at 05:41:24PM +0100, Jan Kiszka wrote:
> >> On 2011-01-31 17:38, Gleb Natapov wrote:
> >>> On Mon, Jan 31, 2011 at 04:40:34PM +0100, Jan Kiszka wrote:
> >>>> On 2011-01-31 14:04, Jan Kiszka wrote:
> >>>>> On 2011-01-31 12:36, Jan Kiszka wrote:
> >>>>>> On 2011-01-31 11:08, Avi Kivity wrote:
> >>>>>>> On 01/27/2011 03:10 PM, Jan Kiszka wrote:
> >>>>>>>> Align with qemu-kvm and prepare for IO exit fix: There is no need to run
> >>>>>>>> kvm_arch_process_irqchip_events in the inner VCPU loop. Any state change
> >>>>>>>> this service processes will first cause an exit from kvm_cpu_exec
> >>>>>>>> anyway. And we will have to reenter the kernel on IO exits
> >>>>>>>> unconditionally, something that the current logic prevents.
> >>>>>>>>
> >>>>>>>> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
> >>>>>>>> ---
> >>>>>>>>   kvm-all.c |   11 ++++++-----
> >>>>>>>>   1 files changed, 6 insertions(+), 5 deletions(-)
> >>>>>>>>
> >>>>>>>> diff --git a/kvm-all.c b/kvm-all.c
> >>>>>>>> index 5bfa8c0..46ecc1c 100644
> >>>>>>>> --- a/kvm-all.c
> >>>>>>>> +++ b/kvm-all.c
> >>>>>>>> @@ -892,6 +892,12 @@ int kvm_cpu_exec(CPUState *env)
> >>>>>>>>
> >>>>>>>>       DPRINTF("kvm_cpu_exec()\n");
> >>>>>>>>
> >>>>>>>> +    if (kvm_arch_process_irqchip_events(env)) {
> >>>>>>>> +        env->exit_request = 0;
> >>>>>>>> +        env->exception_index = EXCP_HLT;
> >>>>>>>> +        return 0;
> >>>>>>>> +    }
> >>>>>>>> +
> >>>>>>>>       do {
> >>>>>>>>   #ifndef CONFIG_IOTHREAD
> >>>>>>>>           if (env->exit_request) {
> >>>>>>>> @@ -901,11 +907,6 @@ int kvm_cpu_exec(CPUState *env)
> >>>>>>>>           }
> >>>>>>>
> >>>>>>> We check for ->exit_request here
> >>>>>>>
> >>>>>>>>   #endif
> >>>>>>>>
> >>>>>>>> -        if (kvm_arch_process_irqchip_events(env)) {
> >>>>>>>> -            ret = 0;
> >>>>>>>> -            break;
> >>>>>>>> -        }
> >>>>>>>> -
> >>>>>>>
> >>>>>>> But this checks for ->interrupt_request.  What ensures that we exit when 
> >>>>>>> ->interrupt_request is set?
> >>>>>>
> >>>>>> Good question, need to check again. But if that turns out to be an
> >>>>>> issue, qemu-kvm would be broken as well. I'm just aligning the code here.
> >>>>>>
> >>>>>
> >>>>> The only thing we miss by moving process_irqchip_events is a self-INIT
> >>>>> of an AP - if such thing exists in real life. In that case, the AP would
> >>>>> cause a reset of itself, followed by a transition to HALT state.
> >>>>
> >>>> I checked again with the Intel spec, and a self-INIT is invalid (at
> >>>> least when specified via shorthand). So I'm under the impression now
> >>>> that we can safely ignore this case and leave the patch as is.
> >>>>
> >>>> Any different views?
> >>>>
> >>> IIRC if you don't use shorthand you can send INIT to self.
> >>
> >> We didn't care so far (in qemu-kvm), do you think we should?
> >>
> > Doesn't kernel lapic emulation support this?
> 
> See the my other mail: It supports it, but it apparently doesn't expects
> this to happen.
> 
I saw it, but I do not understand why do we print this message. May be
it was used for debugging in early stages of KVM development.

--
			Gleb.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 17&18/22] kvm: Unconditionally reenter kernel after IO exits
  2011-01-31 16:56                     ` [Qemu-devel] " Gleb Natapov
@ 2011-01-31 18:06                       ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 18:06 UTC (permalink / raw)
  To: Gleb Natapov, Avi Kivity, Marcelo Tosatti; +Cc: kvm, qemu-devel

On 2011-01-31 17:56, Gleb Natapov wrote:
>>>>>>> The only thing we miss by moving process_irqchip_events is a self-INIT
>>>>>>> of an AP - if such thing exists in real life. In that case, the AP would
>>>>>>> cause a reset of itself, followed by a transition to HALT state.
>>>>>>
>>>>>> I checked again with the Intel spec, and a self-INIT is invalid (at
>>>>>> least when specified via shorthand). So I'm under the impression now
>>>>>> that we can safely ignore this case and leave the patch as is.
>>>>>>
>>>>>> Any different views?
>>>>>>
>>>>> IIRC if you don't use shorthand you can send INIT to self.
>>>>
>>>> We didn't care so far (in qemu-kvm), do you think we should?
>>>>
>>> Doesn't kernel lapic emulation support this?
>>
>> See the my other mail: It supports it, but it apparently doesn't expects
>> this to happen.
>>
> I saw it, but I do not understand why do we print this message. May be
> it was used for debugging in early stages of KVM development.
> 

OK, lets' try to handle this in user space as well. The following patch
replaces both 17 & 18 from my original series as we can no longer split
things up.

Jan

--------8<--------

KVM requires to reenter the kernel after IO exits in order to complete
instruction emulation. Failing to do so will leave the kernel state
inconsistently behind. To ensure that we will get back ASAP, we issue a
self-signal that will cause KVM_RUN to return once the pending
operations are completed.

We can move kvm_arch_process_irqchip_events out of the inner VCPU loop.
The only state that mattered at its old place was a pending INIT
request. Catch it in kvm_arch_pre_run and also trigger a self-signal to
process the request on next kvm_cpu_exec.

This patch also fixes the missing exit_request check in kvm_cpu_exec in
the CONFIG_IOTHREAD case.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
CC: Gleb Natapov <gleb@redhat.com>
---
 kvm-all.c         |   31 +++++++++++++++++--------------
 target-i386/kvm.c |    5 +++++
 2 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 5bfa8c0..d961697 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -199,7 +199,6 @@ int kvm_pit_in_kernel(void)
     return kvm_state->pit_in_kernel;
 }
 
-
 int kvm_init_vcpu(CPUState *env)
 {
     KVMState *s = kvm_state;
@@ -892,29 +891,33 @@ int kvm_cpu_exec(CPUState *env)
 
     DPRINTF("kvm_cpu_exec()\n");
 
-    do {
-#ifndef CONFIG_IOTHREAD
-        if (env->exit_request) {
-            DPRINTF("interrupt exit requested\n");
-            ret = 0;
-            break;
-        }
-#endif
-
-        if (kvm_arch_process_irqchip_events(env)) {
-            ret = 0;
-            break;
-        }
+    if (kvm_arch_process_irqchip_events(env)) {
+        env->exit_request = 0;
+        env->exception_index = EXCP_HLT;
+        return 0;
+    }
 
+    do {
         if (env->kvm_vcpu_dirty) {
             kvm_arch_put_registers(env, KVM_PUT_RUNTIME_STATE);
             env->kvm_vcpu_dirty = 0;
         }
 
         kvm_arch_pre_run(env, run);
+        if (env->exit_request) {
+            DPRINTF("interrupt exit requested\n");
+            /*
+             * KVM requires us to reenter the kernel after IO exits to complete
+             * instruction emulation. This self-signal will ensure that we
+             * leave ASAP again.
+             */
+            qemu_cpu_kick_self();
+        }
         cpu_single_env = NULL;
         qemu_mutex_unlock_iothread();
+
         ret = kvm_vcpu_ioctl(env, KVM_RUN, 0);
+
         qemu_mutex_lock_iothread();
         cpu_single_env = env;
         kvm_arch_post_run(env, run);
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 9df8ff8..8a87244 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1426,6 +1426,11 @@ int kvm_arch_get_registers(CPUState *env)
 
 int kvm_arch_pre_run(CPUState *env, struct kvm_run *run)
 {
+    /* Force the VCPU out of its inner loop to process the INIT request */
+    if (env->interrupt_request & CPU_INTERRUPT_INIT) {
+        env->exit_request = 1;
+    }
+
     /* Inject NMI */
     if (env->interrupt_request & CPU_INTERRUPT_NMI) {
         env->interrupt_request &= ~CPU_INTERRUPT_NMI;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [Qemu-devel] [PATCH v2 17&18/22] kvm: Unconditionally reenter kernel after IO exits
@ 2011-01-31 18:06                       ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-01-31 18:06 UTC (permalink / raw)
  To: Gleb Natapov, Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm

On 2011-01-31 17:56, Gleb Natapov wrote:
>>>>>>> The only thing we miss by moving process_irqchip_events is a self-INIT
>>>>>>> of an AP - if such thing exists in real life. In that case, the AP would
>>>>>>> cause a reset of itself, followed by a transition to HALT state.
>>>>>>
>>>>>> I checked again with the Intel spec, and a self-INIT is invalid (at
>>>>>> least when specified via shorthand). So I'm under the impression now
>>>>>> that we can safely ignore this case and leave the patch as is.
>>>>>>
>>>>>> Any different views?
>>>>>>
>>>>> IIRC if you don't use shorthand you can send INIT to self.
>>>>
>>>> We didn't care so far (in qemu-kvm), do you think we should?
>>>>
>>> Doesn't kernel lapic emulation support this?
>>
>> See the my other mail: It supports it, but it apparently doesn't expects
>> this to happen.
>>
> I saw it, but I do not understand why do we print this message. May be
> it was used for debugging in early stages of KVM development.
> 

OK, lets' try to handle this in user space as well. The following patch
replaces both 17 & 18 from my original series as we can no longer split
things up.

Jan

--------8<--------

KVM requires to reenter the kernel after IO exits in order to complete
instruction emulation. Failing to do so will leave the kernel state
inconsistently behind. To ensure that we will get back ASAP, we issue a
self-signal that will cause KVM_RUN to return once the pending
operations are completed.

We can move kvm_arch_process_irqchip_events out of the inner VCPU loop.
The only state that mattered at its old place was a pending INIT
request. Catch it in kvm_arch_pre_run and also trigger a self-signal to
process the request on next kvm_cpu_exec.

This patch also fixes the missing exit_request check in kvm_cpu_exec in
the CONFIG_IOTHREAD case.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
CC: Gleb Natapov <gleb@redhat.com>
---
 kvm-all.c         |   31 +++++++++++++++++--------------
 target-i386/kvm.c |    5 +++++
 2 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 5bfa8c0..d961697 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -199,7 +199,6 @@ int kvm_pit_in_kernel(void)
     return kvm_state->pit_in_kernel;
 }
 
-
 int kvm_init_vcpu(CPUState *env)
 {
     KVMState *s = kvm_state;
@@ -892,29 +891,33 @@ int kvm_cpu_exec(CPUState *env)
 
     DPRINTF("kvm_cpu_exec()\n");
 
-    do {
-#ifndef CONFIG_IOTHREAD
-        if (env->exit_request) {
-            DPRINTF("interrupt exit requested\n");
-            ret = 0;
-            break;
-        }
-#endif
-
-        if (kvm_arch_process_irqchip_events(env)) {
-            ret = 0;
-            break;
-        }
+    if (kvm_arch_process_irqchip_events(env)) {
+        env->exit_request = 0;
+        env->exception_index = EXCP_HLT;
+        return 0;
+    }
 
+    do {
         if (env->kvm_vcpu_dirty) {
             kvm_arch_put_registers(env, KVM_PUT_RUNTIME_STATE);
             env->kvm_vcpu_dirty = 0;
         }
 
         kvm_arch_pre_run(env, run);
+        if (env->exit_request) {
+            DPRINTF("interrupt exit requested\n");
+            /*
+             * KVM requires us to reenter the kernel after IO exits to complete
+             * instruction emulation. This self-signal will ensure that we
+             * leave ASAP again.
+             */
+            qemu_cpu_kick_self();
+        }
         cpu_single_env = NULL;
         qemu_mutex_unlock_iothread();
+
         ret = kvm_vcpu_ioctl(env, KVM_RUN, 0);
+
         qemu_mutex_lock_iothread();
         cpu_single_env = env;
         kvm_arch_post_run(env, run);
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 9df8ff8..8a87244 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1426,6 +1426,11 @@ int kvm_arch_get_registers(CPUState *env)
 
 int kvm_arch_pre_run(CPUState *env, struct kvm_run *run)
 {
+    /* Force the VCPU out of its inner loop to process the INIT request */
+    if (env->interrupt_request & CPU_INTERRUPT_INIT) {
+        env->exit_request = 1;
+    }
+
     /* Inject NMI */
     if (env->interrupt_request & CPU_INTERRUPT_NMI) {
         env->interrupt_request &= ~CPU_INTERRUPT_NMI;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* Re: [PATCH 12/22] kvm: Call qemu_kvm_eat_signals also under !CONFIG_IOTHREAD
  2011-01-27 13:09   ` [Qemu-devel] " Jan Kiszka
@ 2011-02-01 12:38     ` Marcelo Tosatti
  -1 siblings, 0 replies; 146+ messages in thread
From: Marcelo Tosatti @ 2011-02-01 12:38 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Avi Kivity, kvm, qemu-devel

On Thu, Jan 27, 2011 at 02:09:56PM +0100, Jan Kiszka wrote:
> Move qemu_kvm_eat_signals around and call it also when the IO-thread is
> not used. Do not yet process SIGBUS, will be armed in a separate step.
> 
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> ---
>  cpus.c |   88 ++++++++++++++++++++++++++++++++++++---------------------------
>  1 files changed, 50 insertions(+), 38 deletions(-)
> 
> diff --git a/cpus.c b/cpus.c
> index 9071848..558c0d3 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -261,6 +261,45 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
>      }
>  }
>  
> +static void qemu_kvm_eat_signals(CPUState *env)
> +{
> +    struct timespec ts = { 0, 0 };
> +    siginfo_t siginfo;
> +    sigset_t waitset;
> +    sigset_t chkset;
> +    int r;
> +
> +    sigemptyset(&waitset);
> +    sigaddset(&waitset, SIG_IPI);
> +    sigaddset(&waitset, SIGBUS);
> +
> +    do {
> +        r = sigtimedwait(&waitset, &siginfo, &ts);
> +        if (r == -1 && !(errno == EAGAIN || errno == EINTR)) {
> +            perror("sigtimedwait");
> +            exit(1);
> +        }
> +
> +        switch (r) {
> +#ifdef CONFIG_IOTHREAD
> +        case SIGBUS:
> +            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {
> +                sigbus_reraise();
> +            }
> +            break;
> +#endif
> +        default:
> +            break;
> +        }
> +
> +        r = sigpending(&chkset);
> +        if (r == -1) {
> +            perror("sigpending");
> +            exit(1);
> +        }
> +    } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
> +}
> +
>  #else /* _WIN32 */
>  
>  HANDLE qemu_event_handle;
> @@ -292,6 +331,10 @@ static void qemu_event_increment(void)
>  static void qemu_kvm_init_cpu_signals(CPUState *env)
>  {
>  }
> +
> +static void qemu_kvm_eat_signals(CPUState *env)
> +{
> +}
>  #endif /* _WIN32 */
>  
>  #ifndef CONFIG_IOTHREAD
> @@ -631,43 +674,6 @@ static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
>      }
>  }
>  
> -static void qemu_kvm_eat_signals(CPUState *env)
> -{
> -    struct timespec ts = { 0, 0 };
> -    siginfo_t siginfo;
> -    sigset_t waitset;
> -    sigset_t chkset;
> -    int r;
> -
> -    sigemptyset(&waitset);
> -    sigaddset(&waitset, SIG_IPI);
> -    sigaddset(&waitset, SIGBUS);
> -
> -    do {
> -        r = sigtimedwait(&waitset, &siginfo, &ts);
> -        if (r == -1 && !(errno == EAGAIN || errno == EINTR)) {
> -            perror("sigtimedwait");
> -            exit(1);
> -        }
> -
> -        switch (r) {
> -        case SIGBUS:
> -            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {
> -                sigbus_reraise();
> -            }
> -            break;
> -        default:
> -            break;
> -        }
> -
> -        r = sigpending(&chkset);
> -        if (r == -1) {
> -            perror("sigpending");
> -            exit(1);
> -        }
> -    } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
> -}
> -
>  static void qemu_kvm_wait_io_event(CPUState *env)
>  {
>      while (!cpu_has_work(env))
> @@ -932,6 +938,8 @@ static int qemu_cpu_exec(CPUState *env)
>  
>  bool cpu_exec_all(void)
>  {
> +    int r;
> +
>      if (next_cpu == NULL)
>          next_cpu = first_cpu;
>      for (; next_cpu != NULL && !exit_request; next_cpu = next_cpu->next_cpu) {
> @@ -943,7 +951,11 @@ bool cpu_exec_all(void)
>          if (qemu_alarm_pending())
>              break;
>          if (cpu_can_run(env)) {
> -            if (qemu_cpu_exec(env) == EXCP_DEBUG) {
> +            r = qemu_cpu_exec(env);
> +            if (kvm_enabled()) {
> +                qemu_kvm_eat_signals(env);
> +            }
> +            if (r == EXCP_DEBUG) {
>                  break;
>              }

As mentioned before, signal processing should be independent of
cpu_can_run (still want to process SIGALRM if vm is stopped, for
example).


^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 12/22] kvm: Call qemu_kvm_eat_signals also under !CONFIG_IOTHREAD
@ 2011-02-01 12:38     ` Marcelo Tosatti
  0 siblings, 0 replies; 146+ messages in thread
From: Marcelo Tosatti @ 2011-02-01 12:38 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Avi Kivity, kvm, qemu-devel

On Thu, Jan 27, 2011 at 02:09:56PM +0100, Jan Kiszka wrote:
> Move qemu_kvm_eat_signals around and call it also when the IO-thread is
> not used. Do not yet process SIGBUS, will be armed in a separate step.
> 
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> ---
>  cpus.c |   88 ++++++++++++++++++++++++++++++++++++---------------------------
>  1 files changed, 50 insertions(+), 38 deletions(-)
> 
> diff --git a/cpus.c b/cpus.c
> index 9071848..558c0d3 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -261,6 +261,45 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
>      }
>  }
>  
> +static void qemu_kvm_eat_signals(CPUState *env)
> +{
> +    struct timespec ts = { 0, 0 };
> +    siginfo_t siginfo;
> +    sigset_t waitset;
> +    sigset_t chkset;
> +    int r;
> +
> +    sigemptyset(&waitset);
> +    sigaddset(&waitset, SIG_IPI);
> +    sigaddset(&waitset, SIGBUS);
> +
> +    do {
> +        r = sigtimedwait(&waitset, &siginfo, &ts);
> +        if (r == -1 && !(errno == EAGAIN || errno == EINTR)) {
> +            perror("sigtimedwait");
> +            exit(1);
> +        }
> +
> +        switch (r) {
> +#ifdef CONFIG_IOTHREAD
> +        case SIGBUS:
> +            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {
> +                sigbus_reraise();
> +            }
> +            break;
> +#endif
> +        default:
> +            break;
> +        }
> +
> +        r = sigpending(&chkset);
> +        if (r == -1) {
> +            perror("sigpending");
> +            exit(1);
> +        }
> +    } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
> +}
> +
>  #else /* _WIN32 */
>  
>  HANDLE qemu_event_handle;
> @@ -292,6 +331,10 @@ static void qemu_event_increment(void)
>  static void qemu_kvm_init_cpu_signals(CPUState *env)
>  {
>  }
> +
> +static void qemu_kvm_eat_signals(CPUState *env)
> +{
> +}
>  #endif /* _WIN32 */
>  
>  #ifndef CONFIG_IOTHREAD
> @@ -631,43 +674,6 @@ static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
>      }
>  }
>  
> -static void qemu_kvm_eat_signals(CPUState *env)
> -{
> -    struct timespec ts = { 0, 0 };
> -    siginfo_t siginfo;
> -    sigset_t waitset;
> -    sigset_t chkset;
> -    int r;
> -
> -    sigemptyset(&waitset);
> -    sigaddset(&waitset, SIG_IPI);
> -    sigaddset(&waitset, SIGBUS);
> -
> -    do {
> -        r = sigtimedwait(&waitset, &siginfo, &ts);
> -        if (r == -1 && !(errno == EAGAIN || errno == EINTR)) {
> -            perror("sigtimedwait");
> -            exit(1);
> -        }
> -
> -        switch (r) {
> -        case SIGBUS:
> -            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {
> -                sigbus_reraise();
> -            }
> -            break;
> -        default:
> -            break;
> -        }
> -
> -        r = sigpending(&chkset);
> -        if (r == -1) {
> -            perror("sigpending");
> -            exit(1);
> -        }
> -    } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
> -}
> -
>  static void qemu_kvm_wait_io_event(CPUState *env)
>  {
>      while (!cpu_has_work(env))
> @@ -932,6 +938,8 @@ static int qemu_cpu_exec(CPUState *env)
>  
>  bool cpu_exec_all(void)
>  {
> +    int r;
> +
>      if (next_cpu == NULL)
>          next_cpu = first_cpu;
>      for (; next_cpu != NULL && !exit_request; next_cpu = next_cpu->next_cpu) {
> @@ -943,7 +951,11 @@ bool cpu_exec_all(void)
>          if (qemu_alarm_pending())
>              break;
>          if (cpu_can_run(env)) {
> -            if (qemu_cpu_exec(env) == EXCP_DEBUG) {
> +            r = qemu_cpu_exec(env);
> +            if (kvm_enabled()) {
> +                qemu_kvm_eat_signals(env);
> +            }
> +            if (r == EXCP_DEBUG) {
>                  break;
>              }

As mentioned before, signal processing should be independent of
cpu_can_run (still want to process SIGALRM if vm is stopped, for
example).

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
  2011-01-27 13:09   ` [Qemu-devel] " Jan Kiszka
@ 2011-02-01 12:47     ` Marcelo Tosatti
  -1 siblings, 0 replies; 146+ messages in thread
From: Marcelo Tosatti @ 2011-02-01 12:47 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Avi Kivity, kvm, qemu-devel, Stefan Hajnoczi

On Thu, Jan 27, 2011 at 02:09:58PM +0100, Jan Kiszka wrote:
> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
> checking for exit_request on vcpu entry and timer signals arriving
> before KVM starts to catch them. Plug it by blocking both timer related
> signals also on !CONFIG_IOTHREAD and process those via signalfd.
> 
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> CC: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> ---
>  cpus.c |   18 ++++++++++++++++++
>  1 files changed, 18 insertions(+), 0 deletions(-)
> 
> diff --git a/cpus.c b/cpus.c
> index fc3f222..29b1070 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -254,6 +254,10 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
>      pthread_sigmask(SIG_BLOCK, NULL, &set);
>      sigdelset(&set, SIG_IPI);
>      sigdelset(&set, SIGBUS);
> +#ifndef CONFIG_IOTHREAD
> +    sigdelset(&set, SIGIO);
> +    sigdelset(&set, SIGALRM);
> +#endif

I'd prefer separate qemu_kvm_init_cpu_signals in the !IOTHREAD
section.

>      r = kvm_set_signal_mask(env, &set);
>      if (r) {
>          fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
> @@ -351,6 +355,12 @@ static void qemu_kvm_eat_signals(CPUState *env)
>              exit(1);
>          }
>      } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
> +
> +#ifndef CONFIG_IOTHREAD
> +    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
> +        qemu_notify_event();
> +    }
> +#endif

Why is this necessary?

You should break out of cpu_exec_all if there's a pending alarm (see
qemu_alarm_pending()).

>  }
>  
>  #else /* _WIN32 */
> @@ -398,6 +408,14 @@ int qemu_init_main_loop(void)
>      int ret;
>  
>      sigemptyset(&blocked_signals);
> +    if (kvm_enabled()) {
> +        /*
> +         * We need to process timer signals synchronously to avoid a race
> +         * between exit_request check and KVM vcpu entry.
> +         */
> +        sigaddset(&blocked_signals, SIGIO);
> +        sigaddset(&blocked_signals, SIGALRM);
> +    }

A block_io_signals() function for !IOTHREAD would be nicer.

>  
>      ret = qemu_signalfd_init(blocked_signals);
>      if (ret) {
> -- 
> 1.7.1

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
@ 2011-02-01 12:47     ` Marcelo Tosatti
  0 siblings, 0 replies; 146+ messages in thread
From: Marcelo Tosatti @ 2011-02-01 12:47 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Stefan Hajnoczi, Avi Kivity, kvm, qemu-devel

On Thu, Jan 27, 2011 at 02:09:58PM +0100, Jan Kiszka wrote:
> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
> checking for exit_request on vcpu entry and timer signals arriving
> before KVM starts to catch them. Plug it by blocking both timer related
> signals also on !CONFIG_IOTHREAD and process those via signalfd.
> 
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> CC: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> ---
>  cpus.c |   18 ++++++++++++++++++
>  1 files changed, 18 insertions(+), 0 deletions(-)
> 
> diff --git a/cpus.c b/cpus.c
> index fc3f222..29b1070 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -254,6 +254,10 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
>      pthread_sigmask(SIG_BLOCK, NULL, &set);
>      sigdelset(&set, SIG_IPI);
>      sigdelset(&set, SIGBUS);
> +#ifndef CONFIG_IOTHREAD
> +    sigdelset(&set, SIGIO);
> +    sigdelset(&set, SIGALRM);
> +#endif

I'd prefer separate qemu_kvm_init_cpu_signals in the !IOTHREAD
section.

>      r = kvm_set_signal_mask(env, &set);
>      if (r) {
>          fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
> @@ -351,6 +355,12 @@ static void qemu_kvm_eat_signals(CPUState *env)
>              exit(1);
>          }
>      } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
> +
> +#ifndef CONFIG_IOTHREAD
> +    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
> +        qemu_notify_event();
> +    }
> +#endif

Why is this necessary?

You should break out of cpu_exec_all if there's a pending alarm (see
qemu_alarm_pending()).

>  }
>  
>  #else /* _WIN32 */
> @@ -398,6 +408,14 @@ int qemu_init_main_loop(void)
>      int ret;
>  
>      sigemptyset(&blocked_signals);
> +    if (kvm_enabled()) {
> +        /*
> +         * We need to process timer signals synchronously to avoid a race
> +         * between exit_request check and KVM vcpu entry.
> +         */
> +        sigaddset(&blocked_signals, SIGIO);
> +        sigaddset(&blocked_signals, SIGALRM);
> +    }

A block_io_signals() function for !IOTHREAD would be nicer.

>  
>      ret = qemu_signalfd_init(blocked_signals);
>      if (ret) {
> -- 
> 1.7.1

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 12/22] kvm: Call qemu_kvm_eat_signals also under !CONFIG_IOTHREAD
  2011-02-01 12:38     ` [Qemu-devel] " Marcelo Tosatti
@ 2011-02-01 12:49       ` Marcelo Tosatti
  -1 siblings, 0 replies; 146+ messages in thread
From: Marcelo Tosatti @ 2011-02-01 12:49 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Avi Kivity, kvm, qemu-devel

On Tue, Feb 01, 2011 at 10:38:35AM -0200, Marcelo Tosatti wrote:
> > @@ -943,7 +951,11 @@ bool cpu_exec_all(void)
> >          if (qemu_alarm_pending())
> >              break;
> >          if (cpu_can_run(env)) {
> > -            if (qemu_cpu_exec(env) == EXCP_DEBUG) {
> > +            r = qemu_cpu_exec(env);
> > +            if (kvm_enabled()) {
> > +                qemu_kvm_eat_signals(env);
> > +            }
> > +            if (r == EXCP_DEBUG) {
> >                  break;
> >              }
> 
> As mentioned before, signal processing should be independent of
> cpu_can_run (still want to process SIGALRM if vm is stopped, for
> example).

Nevermind that comment.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 12/22] kvm: Call qemu_kvm_eat_signals also under !CONFIG_IOTHREAD
@ 2011-02-01 12:49       ` Marcelo Tosatti
  0 siblings, 0 replies; 146+ messages in thread
From: Marcelo Tosatti @ 2011-02-01 12:49 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Avi Kivity, kvm, qemu-devel

On Tue, Feb 01, 2011 at 10:38:35AM -0200, Marcelo Tosatti wrote:
> > @@ -943,7 +951,11 @@ bool cpu_exec_all(void)
> >          if (qemu_alarm_pending())
> >              break;
> >          if (cpu_can_run(env)) {
> > -            if (qemu_cpu_exec(env) == EXCP_DEBUG) {
> > +            r = qemu_cpu_exec(env);
> > +            if (kvm_enabled()) {
> > +                qemu_kvm_eat_signals(env);
> > +            }
> > +            if (r == EXCP_DEBUG) {
> >                  break;
> >              }
> 
> As mentioned before, signal processing should be independent of
> cpu_can_run (still want to process SIGALRM if vm is stopped, for
> example).

Nevermind that comment.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 16/22] Introduce VCPU self-signaling service
  2011-01-27 13:10   ` [Qemu-devel] " Jan Kiszka
@ 2011-02-01 13:14     ` Marcelo Tosatti
  -1 siblings, 0 replies; 146+ messages in thread
From: Marcelo Tosatti @ 2011-02-01 13:14 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Avi Kivity, kvm, qemu-devel

On Thu, Jan 27, 2011 at 02:10:00PM +0100, Jan Kiszka wrote:
> Introduce qemu_cpu_kick_self to send SIG_IPI to the calling VCPU
> context. First user will be kvm.
> 
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> ---
>  cpus.c        |   21 +++++++++++++++++++++
>  qemu-common.h |    1 +
>  2 files changed, 22 insertions(+), 0 deletions(-)
> 
> diff --git a/cpus.c b/cpus.c
> index bba59e5..88bed4e 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -531,6 +531,17 @@ void qemu_cpu_kick(void *env)
>      return;
>  }
>  
> +void qemu_cpu_kick_self(void)
> +{
> +#ifndef _WIN32
> +    assert(cpu_single_env);
> +
> +    raise(SIG_IPI);
> +#else
> +    abort();
> +#endif
> +}
> +
>  void qemu_notify_event(void)
>  {
>      CPUState *env = cpu_single_env;
> @@ -808,6 +819,16 @@ void qemu_cpu_kick(void *_env)
>      }
>  }
>  
> +void qemu_cpu_kick_self(void)
> +{
> +    assert(cpu_single_env);
> +
> +    if (!cpu_single_env->thread_kicked) {
> +        qemu_thread_signal(cpu_single_env->thread, SIG_IPI);
> +        cpu_single_env->thread_kicked = true;
> +    }
> +}
> +

There is no need to use cpu_single_env, can pass CPUState instead.


^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 16/22] Introduce VCPU self-signaling service
@ 2011-02-01 13:14     ` Marcelo Tosatti
  0 siblings, 0 replies; 146+ messages in thread
From: Marcelo Tosatti @ 2011-02-01 13:14 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Avi Kivity, kvm, qemu-devel

On Thu, Jan 27, 2011 at 02:10:00PM +0100, Jan Kiszka wrote:
> Introduce qemu_cpu_kick_self to send SIG_IPI to the calling VCPU
> context. First user will be kvm.
> 
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> ---
>  cpus.c        |   21 +++++++++++++++++++++
>  qemu-common.h |    1 +
>  2 files changed, 22 insertions(+), 0 deletions(-)
> 
> diff --git a/cpus.c b/cpus.c
> index bba59e5..88bed4e 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -531,6 +531,17 @@ void qemu_cpu_kick(void *env)
>      return;
>  }
>  
> +void qemu_cpu_kick_self(void)
> +{
> +#ifndef _WIN32
> +    assert(cpu_single_env);
> +
> +    raise(SIG_IPI);
> +#else
> +    abort();
> +#endif
> +}
> +
>  void qemu_notify_event(void)
>  {
>      CPUState *env = cpu_single_env;
> @@ -808,6 +819,16 @@ void qemu_cpu_kick(void *_env)
>      }
>  }
>  
> +void qemu_cpu_kick_self(void)
> +{
> +    assert(cpu_single_env);
> +
> +    if (!cpu_single_env->thread_kicked) {
> +        qemu_thread_signal(cpu_single_env->thread, SIG_IPI);
> +        cpu_single_env->thread_kicked = true;
> +    }
> +}
> +

There is no need to use cpu_single_env, can pass CPUState instead.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 12/22] kvm: Call qemu_kvm_eat_signals also under !CONFIG_IOTHREAD
  2011-02-01 12:38     ` [Qemu-devel] " Marcelo Tosatti
@ 2011-02-01 13:21       ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-02-01 13:21 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Avi Kivity, kvm, qemu-devel

On 2011-02-01 13:38, Marcelo Tosatti wrote:
> On Thu, Jan 27, 2011 at 02:09:56PM +0100, Jan Kiszka wrote:
>> Move qemu_kvm_eat_signals around and call it also when the IO-thread is
>> not used. Do not yet process SIGBUS, will be armed in a separate step.
>>
>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>> ---
>>  cpus.c |   88 ++++++++++++++++++++++++++++++++++++---------------------------
>>  1 files changed, 50 insertions(+), 38 deletions(-)
>>
>> diff --git a/cpus.c b/cpus.c
>> index 9071848..558c0d3 100644
>> --- a/cpus.c
>> +++ b/cpus.c
>> @@ -261,6 +261,45 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
>>      }
>>  }
>>  
>> +static void qemu_kvm_eat_signals(CPUState *env)
>> +{
>> +    struct timespec ts = { 0, 0 };
>> +    siginfo_t siginfo;
>> +    sigset_t waitset;
>> +    sigset_t chkset;
>> +    int r;
>> +
>> +    sigemptyset(&waitset);
>> +    sigaddset(&waitset, SIG_IPI);
>> +    sigaddset(&waitset, SIGBUS);
>> +
>> +    do {
>> +        r = sigtimedwait(&waitset, &siginfo, &ts);
>> +        if (r == -1 && !(errno == EAGAIN || errno == EINTR)) {
>> +            perror("sigtimedwait");
>> +            exit(1);
>> +        }
>> +
>> +        switch (r) {
>> +#ifdef CONFIG_IOTHREAD
>> +        case SIGBUS:
>> +            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {
>> +                sigbus_reraise();
>> +            }
>> +            break;
>> +#endif
>> +        default:
>> +            break;
>> +        }
>> +
>> +        r = sigpending(&chkset);
>> +        if (r == -1) {
>> +            perror("sigpending");
>> +            exit(1);
>> +        }
>> +    } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
>> +}
>> +
>>  #else /* _WIN32 */
>>  
>>  HANDLE qemu_event_handle;
>> @@ -292,6 +331,10 @@ static void qemu_event_increment(void)
>>  static void qemu_kvm_init_cpu_signals(CPUState *env)
>>  {
>>  }
>> +
>> +static void qemu_kvm_eat_signals(CPUState *env)
>> +{
>> +}
>>  #endif /* _WIN32 */
>>  
>>  #ifndef CONFIG_IOTHREAD
>> @@ -631,43 +674,6 @@ static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
>>      }
>>  }
>>  
>> -static void qemu_kvm_eat_signals(CPUState *env)
>> -{
>> -    struct timespec ts = { 0, 0 };
>> -    siginfo_t siginfo;
>> -    sigset_t waitset;
>> -    sigset_t chkset;
>> -    int r;
>> -
>> -    sigemptyset(&waitset);
>> -    sigaddset(&waitset, SIG_IPI);
>> -    sigaddset(&waitset, SIGBUS);
>> -
>> -    do {
>> -        r = sigtimedwait(&waitset, &siginfo, &ts);
>> -        if (r == -1 && !(errno == EAGAIN || errno == EINTR)) {
>> -            perror("sigtimedwait");
>> -            exit(1);
>> -        }
>> -
>> -        switch (r) {
>> -        case SIGBUS:
>> -            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {
>> -                sigbus_reraise();
>> -            }
>> -            break;
>> -        default:
>> -            break;
>> -        }
>> -
>> -        r = sigpending(&chkset);
>> -        if (r == -1) {
>> -            perror("sigpending");
>> -            exit(1);
>> -        }
>> -    } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
>> -}
>> -
>>  static void qemu_kvm_wait_io_event(CPUState *env)
>>  {
>>      while (!cpu_has_work(env))
>> @@ -932,6 +938,8 @@ static int qemu_cpu_exec(CPUState *env)
>>  
>>  bool cpu_exec_all(void)
>>  {
>> +    int r;
>> +
>>      if (next_cpu == NULL)
>>          next_cpu = first_cpu;
>>      for (; next_cpu != NULL && !exit_request; next_cpu = next_cpu->next_cpu) {
>> @@ -943,7 +951,11 @@ bool cpu_exec_all(void)
>>          if (qemu_alarm_pending())
>>              break;
>>          if (cpu_can_run(env)) {
>> -            if (qemu_cpu_exec(env) == EXCP_DEBUG) {
>> +            r = qemu_cpu_exec(env);
>> +            if (kvm_enabled()) {
>> +                qemu_kvm_eat_signals(env);
>> +            }
>> +            if (r == EXCP_DEBUG) {
>>                  break;
>>              }
> 
> As mentioned before, signal processing should be independent of
> cpu_can_run (still want to process SIGALRM if vm is stopped, for
> example).
> 

For those signals that matter, it is.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 12/22] kvm: Call qemu_kvm_eat_signals also under !CONFIG_IOTHREAD
@ 2011-02-01 13:21       ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-02-01 13:21 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Avi Kivity, kvm, qemu-devel

On 2011-02-01 13:38, Marcelo Tosatti wrote:
> On Thu, Jan 27, 2011 at 02:09:56PM +0100, Jan Kiszka wrote:
>> Move qemu_kvm_eat_signals around and call it also when the IO-thread is
>> not used. Do not yet process SIGBUS, will be armed in a separate step.
>>
>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>> ---
>>  cpus.c |   88 ++++++++++++++++++++++++++++++++++++---------------------------
>>  1 files changed, 50 insertions(+), 38 deletions(-)
>>
>> diff --git a/cpus.c b/cpus.c
>> index 9071848..558c0d3 100644
>> --- a/cpus.c
>> +++ b/cpus.c
>> @@ -261,6 +261,45 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
>>      }
>>  }
>>  
>> +static void qemu_kvm_eat_signals(CPUState *env)
>> +{
>> +    struct timespec ts = { 0, 0 };
>> +    siginfo_t siginfo;
>> +    sigset_t waitset;
>> +    sigset_t chkset;
>> +    int r;
>> +
>> +    sigemptyset(&waitset);
>> +    sigaddset(&waitset, SIG_IPI);
>> +    sigaddset(&waitset, SIGBUS);
>> +
>> +    do {
>> +        r = sigtimedwait(&waitset, &siginfo, &ts);
>> +        if (r == -1 && !(errno == EAGAIN || errno == EINTR)) {
>> +            perror("sigtimedwait");
>> +            exit(1);
>> +        }
>> +
>> +        switch (r) {
>> +#ifdef CONFIG_IOTHREAD
>> +        case SIGBUS:
>> +            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {
>> +                sigbus_reraise();
>> +            }
>> +            break;
>> +#endif
>> +        default:
>> +            break;
>> +        }
>> +
>> +        r = sigpending(&chkset);
>> +        if (r == -1) {
>> +            perror("sigpending");
>> +            exit(1);
>> +        }
>> +    } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
>> +}
>> +
>>  #else /* _WIN32 */
>>  
>>  HANDLE qemu_event_handle;
>> @@ -292,6 +331,10 @@ static void qemu_event_increment(void)
>>  static void qemu_kvm_init_cpu_signals(CPUState *env)
>>  {
>>  }
>> +
>> +static void qemu_kvm_eat_signals(CPUState *env)
>> +{
>> +}
>>  #endif /* _WIN32 */
>>  
>>  #ifndef CONFIG_IOTHREAD
>> @@ -631,43 +674,6 @@ static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
>>      }
>>  }
>>  
>> -static void qemu_kvm_eat_signals(CPUState *env)
>> -{
>> -    struct timespec ts = { 0, 0 };
>> -    siginfo_t siginfo;
>> -    sigset_t waitset;
>> -    sigset_t chkset;
>> -    int r;
>> -
>> -    sigemptyset(&waitset);
>> -    sigaddset(&waitset, SIG_IPI);
>> -    sigaddset(&waitset, SIGBUS);
>> -
>> -    do {
>> -        r = sigtimedwait(&waitset, &siginfo, &ts);
>> -        if (r == -1 && !(errno == EAGAIN || errno == EINTR)) {
>> -            perror("sigtimedwait");
>> -            exit(1);
>> -        }
>> -
>> -        switch (r) {
>> -        case SIGBUS:
>> -            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {
>> -                sigbus_reraise();
>> -            }
>> -            break;
>> -        default:
>> -            break;
>> -        }
>> -
>> -        r = sigpending(&chkset);
>> -        if (r == -1) {
>> -            perror("sigpending");
>> -            exit(1);
>> -        }
>> -    } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
>> -}
>> -
>>  static void qemu_kvm_wait_io_event(CPUState *env)
>>  {
>>      while (!cpu_has_work(env))
>> @@ -932,6 +938,8 @@ static int qemu_cpu_exec(CPUState *env)
>>  
>>  bool cpu_exec_all(void)
>>  {
>> +    int r;
>> +
>>      if (next_cpu == NULL)
>>          next_cpu = first_cpu;
>>      for (; next_cpu != NULL && !exit_request; next_cpu = next_cpu->next_cpu) {
>> @@ -943,7 +951,11 @@ bool cpu_exec_all(void)
>>          if (qemu_alarm_pending())
>>              break;
>>          if (cpu_can_run(env)) {
>> -            if (qemu_cpu_exec(env) == EXCP_DEBUG) {
>> +            r = qemu_cpu_exec(env);
>> +            if (kvm_enabled()) {
>> +                qemu_kvm_eat_signals(env);
>> +            }
>> +            if (r == EXCP_DEBUG) {
>>                  break;
>>              }
> 
> As mentioned before, signal processing should be independent of
> cpu_can_run (still want to process SIGALRM if vm is stopped, for
> example).
> 

For those signals that matter, it is.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
  2011-02-01 12:47     ` [Qemu-devel] " Marcelo Tosatti
@ 2011-02-01 13:32       ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-02-01 13:32 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Avi Kivity, kvm, qemu-devel, Stefan Hajnoczi

On 2011-02-01 13:47, Marcelo Tosatti wrote:
> On Thu, Jan 27, 2011 at 02:09:58PM +0100, Jan Kiszka wrote:
>> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
>> checking for exit_request on vcpu entry and timer signals arriving
>> before KVM starts to catch them. Plug it by blocking both timer related
>> signals also on !CONFIG_IOTHREAD and process those via signalfd.
>>
>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>> CC: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
>> ---
>>  cpus.c |   18 ++++++++++++++++++
>>  1 files changed, 18 insertions(+), 0 deletions(-)
>>
>> diff --git a/cpus.c b/cpus.c
>> index fc3f222..29b1070 100644
>> --- a/cpus.c
>> +++ b/cpus.c
>> @@ -254,6 +254,10 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
>>      pthread_sigmask(SIG_BLOCK, NULL, &set);
>>      sigdelset(&set, SIG_IPI);
>>      sigdelset(&set, SIGBUS);
>> +#ifndef CONFIG_IOTHREAD
>> +    sigdelset(&set, SIGIO);
>> +    sigdelset(&set, SIGALRM);
>> +#endif
> 
> I'd prefer separate qemu_kvm_init_cpu_signals in the !IOTHREAD
> section.

You mean to duplicate qemu_kvm_init_cpu_signals for both configurations?

> 
>>      r = kvm_set_signal_mask(env, &set);
>>      if (r) {
>>          fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
>> @@ -351,6 +355,12 @@ static void qemu_kvm_eat_signals(CPUState *env)
>>              exit(1);
>>          }
>>      } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
>> +
>> +#ifndef CONFIG_IOTHREAD
>> +    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
>> +        qemu_notify_event();
>> +    }
>> +#endif
> 
> Why is this necessary?
> 
> You should break out of cpu_exec_all if there's a pending alarm (see
> qemu_alarm_pending()).

qemu_alarm_pending() is not true until the signal is actually taken. The
alarm handler sets the required flags.

> 
>>  }
>>  
>>  #else /* _WIN32 */
>> @@ -398,6 +408,14 @@ int qemu_init_main_loop(void)
>>      int ret;
>>  
>>      sigemptyset(&blocked_signals);
>> +    if (kvm_enabled()) {
>> +        /*
>> +         * We need to process timer signals synchronously to avoid a race
>> +         * between exit_request check and KVM vcpu entry.
>> +         */
>> +        sigaddset(&blocked_signals, SIGIO);
>> +        sigaddset(&blocked_signals, SIGALRM);
>> +    }
> 
> A block_io_signals() function for !IOTHREAD would be nicer.

Well, we aren't blocking all I/O signals, so I decided against causing
confusion to people that try to compare the result against real
block_io_signals. If you mean just pushing those lines that set up
blocked_signals into a separate function, then I need to find a good
name for it.

> 
>>  
>>      ret = qemu_signalfd_init(blocked_signals);
>>      if (ret) {
>> -- 
>> 1.7.1

Thanks,
Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
@ 2011-02-01 13:32       ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-02-01 13:32 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Stefan Hajnoczi, Avi Kivity, kvm, qemu-devel

On 2011-02-01 13:47, Marcelo Tosatti wrote:
> On Thu, Jan 27, 2011 at 02:09:58PM +0100, Jan Kiszka wrote:
>> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
>> checking for exit_request on vcpu entry and timer signals arriving
>> before KVM starts to catch them. Plug it by blocking both timer related
>> signals also on !CONFIG_IOTHREAD and process those via signalfd.
>>
>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>> CC: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
>> ---
>>  cpus.c |   18 ++++++++++++++++++
>>  1 files changed, 18 insertions(+), 0 deletions(-)
>>
>> diff --git a/cpus.c b/cpus.c
>> index fc3f222..29b1070 100644
>> --- a/cpus.c
>> +++ b/cpus.c
>> @@ -254,6 +254,10 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
>>      pthread_sigmask(SIG_BLOCK, NULL, &set);
>>      sigdelset(&set, SIG_IPI);
>>      sigdelset(&set, SIGBUS);
>> +#ifndef CONFIG_IOTHREAD
>> +    sigdelset(&set, SIGIO);
>> +    sigdelset(&set, SIGALRM);
>> +#endif
> 
> I'd prefer separate qemu_kvm_init_cpu_signals in the !IOTHREAD
> section.

You mean to duplicate qemu_kvm_init_cpu_signals for both configurations?

> 
>>      r = kvm_set_signal_mask(env, &set);
>>      if (r) {
>>          fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
>> @@ -351,6 +355,12 @@ static void qemu_kvm_eat_signals(CPUState *env)
>>              exit(1);
>>          }
>>      } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
>> +
>> +#ifndef CONFIG_IOTHREAD
>> +    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
>> +        qemu_notify_event();
>> +    }
>> +#endif
> 
> Why is this necessary?
> 
> You should break out of cpu_exec_all if there's a pending alarm (see
> qemu_alarm_pending()).

qemu_alarm_pending() is not true until the signal is actually taken. The
alarm handler sets the required flags.

> 
>>  }
>>  
>>  #else /* _WIN32 */
>> @@ -398,6 +408,14 @@ int qemu_init_main_loop(void)
>>      int ret;
>>  
>>      sigemptyset(&blocked_signals);
>> +    if (kvm_enabled()) {
>> +        /*
>> +         * We need to process timer signals synchronously to avoid a race
>> +         * between exit_request check and KVM vcpu entry.
>> +         */
>> +        sigaddset(&blocked_signals, SIGIO);
>> +        sigaddset(&blocked_signals, SIGALRM);
>> +    }
> 
> A block_io_signals() function for !IOTHREAD would be nicer.

Well, we aren't blocking all I/O signals, so I decided against causing
confusion to people that try to compare the result against real
block_io_signals. If you mean just pushing those lines that set up
blocked_signals into a separate function, then I need to find a good
name for it.

> 
>>  
>>      ret = qemu_signalfd_init(blocked_signals);
>>      if (ret) {
>> -- 
>> 1.7.1

Thanks,
Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 16/22] Introduce VCPU self-signaling service
  2011-02-01 13:14     ` [Qemu-devel] " Marcelo Tosatti
@ 2011-02-01 13:33       ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-02-01 13:33 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Avi Kivity, kvm, qemu-devel

On 2011-02-01 14:14, Marcelo Tosatti wrote:
> On Thu, Jan 27, 2011 at 02:10:00PM +0100, Jan Kiszka wrote:
>> Introduce qemu_cpu_kick_self to send SIG_IPI to the calling VCPU
>> context. First user will be kvm.
>>
>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>> ---
>>  cpus.c        |   21 +++++++++++++++++++++
>>  qemu-common.h |    1 +
>>  2 files changed, 22 insertions(+), 0 deletions(-)
>>
>> diff --git a/cpus.c b/cpus.c
>> index bba59e5..88bed4e 100644
>> --- a/cpus.c
>> +++ b/cpus.c
>> @@ -531,6 +531,17 @@ void qemu_cpu_kick(void *env)
>>      return;
>>  }
>>  
>> +void qemu_cpu_kick_self(void)
>> +{
>> +#ifndef _WIN32
>> +    assert(cpu_single_env);
>> +
>> +    raise(SIG_IPI);
>> +#else
>> +    abort();
>> +#endif
>> +}
>> +
>>  void qemu_notify_event(void)
>>  {
>>      CPUState *env = cpu_single_env;
>> @@ -808,6 +819,16 @@ void qemu_cpu_kick(void *_env)
>>      }
>>  }
>>  
>> +void qemu_cpu_kick_self(void)
>> +{
>> +    assert(cpu_single_env);
>> +
>> +    if (!cpu_single_env->thread_kicked) {
>> +        qemu_thread_signal(cpu_single_env->thread, SIG_IPI);
>> +        cpu_single_env->thread_kicked = true;
>> +    }
>> +}
>> +
> 
> There is no need to use cpu_single_env, can pass CPUState instead.
> 

It's done intentionally this way: function shall not be used for a
remote env.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 16/22] Introduce VCPU self-signaling service
@ 2011-02-01 13:33       ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-02-01 13:33 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Avi Kivity, kvm, qemu-devel

On 2011-02-01 14:14, Marcelo Tosatti wrote:
> On Thu, Jan 27, 2011 at 02:10:00PM +0100, Jan Kiszka wrote:
>> Introduce qemu_cpu_kick_self to send SIG_IPI to the calling VCPU
>> context. First user will be kvm.
>>
>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>> ---
>>  cpus.c        |   21 +++++++++++++++++++++
>>  qemu-common.h |    1 +
>>  2 files changed, 22 insertions(+), 0 deletions(-)
>>
>> diff --git a/cpus.c b/cpus.c
>> index bba59e5..88bed4e 100644
>> --- a/cpus.c
>> +++ b/cpus.c
>> @@ -531,6 +531,17 @@ void qemu_cpu_kick(void *env)
>>      return;
>>  }
>>  
>> +void qemu_cpu_kick_self(void)
>> +{
>> +#ifndef _WIN32
>> +    assert(cpu_single_env);
>> +
>> +    raise(SIG_IPI);
>> +#else
>> +    abort();
>> +#endif
>> +}
>> +
>>  void qemu_notify_event(void)
>>  {
>>      CPUState *env = cpu_single_env;
>> @@ -808,6 +819,16 @@ void qemu_cpu_kick(void *_env)
>>      }
>>  }
>>  
>> +void qemu_cpu_kick_self(void)
>> +{
>> +    assert(cpu_single_env);
>> +
>> +    if (!cpu_single_env->thread_kicked) {
>> +        qemu_thread_signal(cpu_single_env->thread, SIG_IPI);
>> +        cpu_single_env->thread_kicked = true;
>> +    }
>> +}
>> +
> 
> There is no need to use cpu_single_env, can pass CPUState instead.
> 

It's done intentionally this way: function shall not be used for a
remote env.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
  2011-02-01 13:32       ` [Qemu-devel] " Jan Kiszka
@ 2011-02-01 13:48         ` Marcelo Tosatti
  -1 siblings, 0 replies; 146+ messages in thread
From: Marcelo Tosatti @ 2011-02-01 13:48 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Avi Kivity, kvm, qemu-devel, Stefan Hajnoczi

On Tue, Feb 01, 2011 at 02:32:38PM +0100, Jan Kiszka wrote:
> On 2011-02-01 13:47, Marcelo Tosatti wrote:
> > On Thu, Jan 27, 2011 at 02:09:58PM +0100, Jan Kiszka wrote:
> >> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
> >> checking for exit_request on vcpu entry and timer signals arriving
> >> before KVM starts to catch them. Plug it by blocking both timer related
> >> signals also on !CONFIG_IOTHREAD and process those via signalfd.
> >>
> >> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> >> CC: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> >> ---
> >>  cpus.c |   18 ++++++++++++++++++
> >>  1 files changed, 18 insertions(+), 0 deletions(-)
> >>
> >> diff --git a/cpus.c b/cpus.c
> >> index fc3f222..29b1070 100644
> >> --- a/cpus.c
> >> +++ b/cpus.c
> >> @@ -254,6 +254,10 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
> >>      pthread_sigmask(SIG_BLOCK, NULL, &set);
> >>      sigdelset(&set, SIG_IPI);
> >>      sigdelset(&set, SIGBUS);
> >> +#ifndef CONFIG_IOTHREAD
> >> +    sigdelset(&set, SIGIO);
> >> +    sigdelset(&set, SIGALRM);
> >> +#endif
> > 
> > I'd prefer separate qemu_kvm_init_cpu_signals in the !IOTHREAD
> > section.
> 
> You mean to duplicate qemu_kvm_init_cpu_signals for both configurations?

Yes, so to avoid #ifdefs spread.

> >> +
> >> +#ifndef CONFIG_IOTHREAD
> >> +    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
> >> +        qemu_notify_event();
> >> +    }
> >> +#endif
> > 
> > Why is this necessary?
> > 
> > You should break out of cpu_exec_all if there's a pending alarm (see
> > qemu_alarm_pending()).
> 
> qemu_alarm_pending() is not true until the signal is actually taken. The
> alarm handler sets the required flags.

Right. What i mean is you need to execute the signal handler inside
cpu_exec_all loop (so that alarm pending is set).

So, if there is a SIGALRM pending, qemu_run_timers has highest
priority, not vcpu execution.

> >>  
> >>  #else /* _WIN32 */
> >> @@ -398,6 +408,14 @@ int qemu_init_main_loop(void)
> >>      int ret;
> >>  
> >>      sigemptyset(&blocked_signals);
> >> +    if (kvm_enabled()) {
> >> +        /*
> >> +         * We need to process timer signals synchronously to avoid a race
> >> +         * between exit_request check and KVM vcpu entry.
> >> +         */
> >> +        sigaddset(&blocked_signals, SIGIO);
> >> +        sigaddset(&blocked_signals, SIGALRM);
> >> +    }
> > 
> > A block_io_signals() function for !IOTHREAD would be nicer.
> 
> Well, we aren't blocking all I/O signals, so I decided against causing
> confusion to people that try to compare the result against real
> block_io_signals. If you mean just pushing those lines that set up
> blocked_signals into a separate function, then I need to find a good
> name for it.

Yes, separate function, similar to CONFIG_IOTHREAD case (feel free to
rename function).


^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
@ 2011-02-01 13:48         ` Marcelo Tosatti
  0 siblings, 0 replies; 146+ messages in thread
From: Marcelo Tosatti @ 2011-02-01 13:48 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Stefan Hajnoczi, Avi Kivity, kvm, qemu-devel

On Tue, Feb 01, 2011 at 02:32:38PM +0100, Jan Kiszka wrote:
> On 2011-02-01 13:47, Marcelo Tosatti wrote:
> > On Thu, Jan 27, 2011 at 02:09:58PM +0100, Jan Kiszka wrote:
> >> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
> >> checking for exit_request on vcpu entry and timer signals arriving
> >> before KVM starts to catch them. Plug it by blocking both timer related
> >> signals also on !CONFIG_IOTHREAD and process those via signalfd.
> >>
> >> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> >> CC: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> >> ---
> >>  cpus.c |   18 ++++++++++++++++++
> >>  1 files changed, 18 insertions(+), 0 deletions(-)
> >>
> >> diff --git a/cpus.c b/cpus.c
> >> index fc3f222..29b1070 100644
> >> --- a/cpus.c
> >> +++ b/cpus.c
> >> @@ -254,6 +254,10 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
> >>      pthread_sigmask(SIG_BLOCK, NULL, &set);
> >>      sigdelset(&set, SIG_IPI);
> >>      sigdelset(&set, SIGBUS);
> >> +#ifndef CONFIG_IOTHREAD
> >> +    sigdelset(&set, SIGIO);
> >> +    sigdelset(&set, SIGALRM);
> >> +#endif
> > 
> > I'd prefer separate qemu_kvm_init_cpu_signals in the !IOTHREAD
> > section.
> 
> You mean to duplicate qemu_kvm_init_cpu_signals for both configurations?

Yes, so to avoid #ifdefs spread.

> >> +
> >> +#ifndef CONFIG_IOTHREAD
> >> +    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
> >> +        qemu_notify_event();
> >> +    }
> >> +#endif
> > 
> > Why is this necessary?
> > 
> > You should break out of cpu_exec_all if there's a pending alarm (see
> > qemu_alarm_pending()).
> 
> qemu_alarm_pending() is not true until the signal is actually taken. The
> alarm handler sets the required flags.

Right. What i mean is you need to execute the signal handler inside
cpu_exec_all loop (so that alarm pending is set).

So, if there is a SIGALRM pending, qemu_run_timers has highest
priority, not vcpu execution.

> >>  
> >>  #else /* _WIN32 */
> >> @@ -398,6 +408,14 @@ int qemu_init_main_loop(void)
> >>      int ret;
> >>  
> >>      sigemptyset(&blocked_signals);
> >> +    if (kvm_enabled()) {
> >> +        /*
> >> +         * We need to process timer signals synchronously to avoid a race
> >> +         * between exit_request check and KVM vcpu entry.
> >> +         */
> >> +        sigaddset(&blocked_signals, SIGIO);
> >> +        sigaddset(&blocked_signals, SIGALRM);
> >> +    }
> > 
> > A block_io_signals() function for !IOTHREAD would be nicer.
> 
> Well, we aren't blocking all I/O signals, so I decided against causing
> confusion to people that try to compare the result against real
> block_io_signals. If you mean just pushing those lines that set up
> blocked_signals into a separate function, then I need to find a good
> name for it.

Yes, separate function, similar to CONFIG_IOTHREAD case (feel free to
rename function).

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 16/22] Introduce VCPU self-signaling service
  2011-02-01 13:33       ` [Qemu-devel] " Jan Kiszka
@ 2011-02-01 13:50         ` Marcelo Tosatti
  -1 siblings, 0 replies; 146+ messages in thread
From: Marcelo Tosatti @ 2011-02-01 13:50 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Avi Kivity, kvm, qemu-devel

On Tue, Feb 01, 2011 at 02:33:45PM +0100, Jan Kiszka wrote:
> >> +++ b/cpus.c
> >> @@ -531,6 +531,17 @@ void qemu_cpu_kick(void *env)
> >>      return;
> >>  }
> >>  
> >> +void qemu_cpu_kick_self(void)
> >> +{
> >> +#ifndef _WIN32
> >> +    assert(cpu_single_env);
> >> +
> >> +    raise(SIG_IPI);
> >> +#else
> >> +    abort();
> >> +#endif
> >> +}
> >> +
> >>  void qemu_notify_event(void)
> >>  {
> >>      CPUState *env = cpu_single_env;
> >> @@ -808,6 +819,16 @@ void qemu_cpu_kick(void *_env)
> >>      }
> >>  }
> >>  
> >> +void qemu_cpu_kick_self(void)
> >> +{
> >> +    assert(cpu_single_env);
> >> +
> >> +    if (!cpu_single_env->thread_kicked) {
> >> +        qemu_thread_signal(cpu_single_env->thread, SIG_IPI);
> >> +        cpu_single_env->thread_kicked = true;
> >> +    }
> >> +}
> >> +
> > 
> > There is no need to use cpu_single_env, can pass CPUState instead.
> > 
> 
> It's done intentionally this way: function shall not be used for a
> remote env.
> 
> Jan

Can assert on qemu_cpu_self(env) for that.


^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 16/22] Introduce VCPU self-signaling service
@ 2011-02-01 13:50         ` Marcelo Tosatti
  0 siblings, 0 replies; 146+ messages in thread
From: Marcelo Tosatti @ 2011-02-01 13:50 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Avi Kivity, kvm, qemu-devel

On Tue, Feb 01, 2011 at 02:33:45PM +0100, Jan Kiszka wrote:
> >> +++ b/cpus.c
> >> @@ -531,6 +531,17 @@ void qemu_cpu_kick(void *env)
> >>      return;
> >>  }
> >>  
> >> +void qemu_cpu_kick_self(void)
> >> +{
> >> +#ifndef _WIN32
> >> +    assert(cpu_single_env);
> >> +
> >> +    raise(SIG_IPI);
> >> +#else
> >> +    abort();
> >> +#endif
> >> +}
> >> +
> >>  void qemu_notify_event(void)
> >>  {
> >>      CPUState *env = cpu_single_env;
> >> @@ -808,6 +819,16 @@ void qemu_cpu_kick(void *_env)
> >>      }
> >>  }
> >>  
> >> +void qemu_cpu_kick_self(void)
> >> +{
> >> +    assert(cpu_single_env);
> >> +
> >> +    if (!cpu_single_env->thread_kicked) {
> >> +        qemu_thread_signal(cpu_single_env->thread, SIG_IPI);
> >> +        cpu_single_env->thread_kicked = true;
> >> +    }
> >> +}
> >> +
> > 
> > There is no need to use cpu_single_env, can pass CPUState instead.
> > 
> 
> It's done intentionally this way: function shall not be used for a
> remote env.
> 
> Jan

Can assert on qemu_cpu_self(env) for that.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
  2011-02-01 13:48         ` [Qemu-devel] " Marcelo Tosatti
@ 2011-02-01 13:58           ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-02-01 13:58 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Avi Kivity, kvm, qemu-devel, Stefan Hajnoczi

On 2011-02-01 14:48, Marcelo Tosatti wrote:
> On Tue, Feb 01, 2011 at 02:32:38PM +0100, Jan Kiszka wrote:
>> On 2011-02-01 13:47, Marcelo Tosatti wrote:
>>> On Thu, Jan 27, 2011 at 02:09:58PM +0100, Jan Kiszka wrote:
>>>> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
>>>> checking for exit_request on vcpu entry and timer signals arriving
>>>> before KVM starts to catch them. Plug it by blocking both timer related
>>>> signals also on !CONFIG_IOTHREAD and process those via signalfd.
>>>>
>>>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>>>> CC: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
>>>> ---
>>>>  cpus.c |   18 ++++++++++++++++++
>>>>  1 files changed, 18 insertions(+), 0 deletions(-)
>>>>
>>>> diff --git a/cpus.c b/cpus.c
>>>> index fc3f222..29b1070 100644
>>>> --- a/cpus.c
>>>> +++ b/cpus.c
>>>> @@ -254,6 +254,10 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
>>>>      pthread_sigmask(SIG_BLOCK, NULL, &set);
>>>>      sigdelset(&set, SIG_IPI);
>>>>      sigdelset(&set, SIGBUS);
>>>> +#ifndef CONFIG_IOTHREAD
>>>> +    sigdelset(&set, SIGIO);
>>>> +    sigdelset(&set, SIGALRM);
>>>> +#endif
>>>
>>> I'd prefer separate qemu_kvm_init_cpu_signals in the !IOTHREAD
>>> section.
>>
>> You mean to duplicate qemu_kvm_init_cpu_signals for both configurations?
> 
> Yes, so to avoid #ifdefs spread.

Would exchange some #ifdefs against ifndef _WIN32. Haven't measured the
delta though.

> 
>>>> +
>>>> +#ifndef CONFIG_IOTHREAD
>>>> +    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
>>>> +        qemu_notify_event();
>>>> +    }
>>>> +#endif
>>>
>>> Why is this necessary?
>>>
>>> You should break out of cpu_exec_all if there's a pending alarm (see
>>> qemu_alarm_pending()).
>>
>> qemu_alarm_pending() is not true until the signal is actually taken. The
>> alarm handler sets the required flags.
> 
> Right. What i mean is you need to execute the signal handler inside
> cpu_exec_all loop (so that alarm pending is set).
> 
> So, if there is a SIGALRM pending, qemu_run_timers has highest
> priority, not vcpu execution.

We leave the vcpu loop (thanks to notify_event), process the signal in
the event loop and run the timer handler. This pattern is IMO less
invasive to the existing code, specifically as it is about to die
long-term anyway.

> 
>>>>  
>>>>  #else /* _WIN32 */
>>>> @@ -398,6 +408,14 @@ int qemu_init_main_loop(void)
>>>>      int ret;
>>>>  
>>>>      sigemptyset(&blocked_signals);
>>>> +    if (kvm_enabled()) {
>>>> +        /*
>>>> +         * We need to process timer signals synchronously to avoid a race
>>>> +         * between exit_request check and KVM vcpu entry.
>>>> +         */
>>>> +        sigaddset(&blocked_signals, SIGIO);
>>>> +        sigaddset(&blocked_signals, SIGALRM);
>>>> +    }
>>>
>>> A block_io_signals() function for !IOTHREAD would be nicer.
>>
>> Well, we aren't blocking all I/O signals, so I decided against causing
>> confusion to people that try to compare the result against real
>> block_io_signals. If you mean just pushing those lines that set up
>> blocked_signals into a separate function, then I need to find a good
>> name for it.
> 
> Yes, separate function, similar to CONFIG_IOTHREAD case (feel free to
> rename function).
> 

Will check.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
@ 2011-02-01 13:58           ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-02-01 13:58 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Stefan Hajnoczi, Avi Kivity, kvm, qemu-devel

On 2011-02-01 14:48, Marcelo Tosatti wrote:
> On Tue, Feb 01, 2011 at 02:32:38PM +0100, Jan Kiszka wrote:
>> On 2011-02-01 13:47, Marcelo Tosatti wrote:
>>> On Thu, Jan 27, 2011 at 02:09:58PM +0100, Jan Kiszka wrote:
>>>> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
>>>> checking for exit_request on vcpu entry and timer signals arriving
>>>> before KVM starts to catch them. Plug it by blocking both timer related
>>>> signals also on !CONFIG_IOTHREAD and process those via signalfd.
>>>>
>>>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>>>> CC: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
>>>> ---
>>>>  cpus.c |   18 ++++++++++++++++++
>>>>  1 files changed, 18 insertions(+), 0 deletions(-)
>>>>
>>>> diff --git a/cpus.c b/cpus.c
>>>> index fc3f222..29b1070 100644
>>>> --- a/cpus.c
>>>> +++ b/cpus.c
>>>> @@ -254,6 +254,10 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
>>>>      pthread_sigmask(SIG_BLOCK, NULL, &set);
>>>>      sigdelset(&set, SIG_IPI);
>>>>      sigdelset(&set, SIGBUS);
>>>> +#ifndef CONFIG_IOTHREAD
>>>> +    sigdelset(&set, SIGIO);
>>>> +    sigdelset(&set, SIGALRM);
>>>> +#endif
>>>
>>> I'd prefer separate qemu_kvm_init_cpu_signals in the !IOTHREAD
>>> section.
>>
>> You mean to duplicate qemu_kvm_init_cpu_signals for both configurations?
> 
> Yes, so to avoid #ifdefs spread.

Would exchange some #ifdefs against ifndef _WIN32. Haven't measured the
delta though.

> 
>>>> +
>>>> +#ifndef CONFIG_IOTHREAD
>>>> +    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
>>>> +        qemu_notify_event();
>>>> +    }
>>>> +#endif
>>>
>>> Why is this necessary?
>>>
>>> You should break out of cpu_exec_all if there's a pending alarm (see
>>> qemu_alarm_pending()).
>>
>> qemu_alarm_pending() is not true until the signal is actually taken. The
>> alarm handler sets the required flags.
> 
> Right. What i mean is you need to execute the signal handler inside
> cpu_exec_all loop (so that alarm pending is set).
> 
> So, if there is a SIGALRM pending, qemu_run_timers has highest
> priority, not vcpu execution.

We leave the vcpu loop (thanks to notify_event), process the signal in
the event loop and run the timer handler. This pattern is IMO less
invasive to the existing code, specifically as it is about to die
long-term anyway.

> 
>>>>  
>>>>  #else /* _WIN32 */
>>>> @@ -398,6 +408,14 @@ int qemu_init_main_loop(void)
>>>>      int ret;
>>>>  
>>>>      sigemptyset(&blocked_signals);
>>>> +    if (kvm_enabled()) {
>>>> +        /*
>>>> +         * We need to process timer signals synchronously to avoid a race
>>>> +         * between exit_request check and KVM vcpu entry.
>>>> +         */
>>>> +        sigaddset(&blocked_signals, SIGIO);
>>>> +        sigaddset(&blocked_signals, SIGALRM);
>>>> +    }
>>>
>>> A block_io_signals() function for !IOTHREAD would be nicer.
>>
>> Well, we aren't blocking all I/O signals, so I decided against causing
>> confusion to people that try to compare the result against real
>> block_io_signals. If you mean just pushing those lines that set up
>> blocked_signals into a separate function, then I need to find a good
>> name for it.
> 
> Yes, separate function, similar to CONFIG_IOTHREAD case (feel free to
> rename function).
> 

Will check.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 16/22] Introduce VCPU self-signaling service
  2011-02-01 13:50         ` [Qemu-devel] " Marcelo Tosatti
@ 2011-02-01 13:59           ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-02-01 13:59 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Avi Kivity, kvm, qemu-devel

On 2011-02-01 14:50, Marcelo Tosatti wrote:
> On Tue, Feb 01, 2011 at 02:33:45PM +0100, Jan Kiszka wrote:
>>>> +++ b/cpus.c
>>>> @@ -531,6 +531,17 @@ void qemu_cpu_kick(void *env)
>>>>      return;
>>>>  }
>>>>  
>>>> +void qemu_cpu_kick_self(void)
>>>> +{
>>>> +#ifndef _WIN32
>>>> +    assert(cpu_single_env);
>>>> +
>>>> +    raise(SIG_IPI);
>>>> +#else
>>>> +    abort();
>>>> +#endif
>>>> +}
>>>> +
>>>>  void qemu_notify_event(void)
>>>>  {
>>>>      CPUState *env = cpu_single_env;
>>>> @@ -808,6 +819,16 @@ void qemu_cpu_kick(void *_env)
>>>>      }
>>>>  }
>>>>  
>>>> +void qemu_cpu_kick_self(void)
>>>> +{
>>>> +    assert(cpu_single_env);
>>>> +
>>>> +    if (!cpu_single_env->thread_kicked) {
>>>> +        qemu_thread_signal(cpu_single_env->thread, SIG_IPI);
>>>> +        cpu_single_env->thread_kicked = true;
>>>> +    }
>>>> +}
>>>> +
>>>
>>> There is no need to use cpu_single_env, can pass CPUState instead.
>>>
>>
>> It's done intentionally this way: function shall not be used for a
>> remote env.
>>
>> Jan
> 
> Can assert on qemu_cpu_self(env) for that.
> 

We already assert on cpu_single_env which is the right condition.
Removing env from the parameter list avoids that someone even thinks
about misusing it.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 16/22] Introduce VCPU self-signaling service
@ 2011-02-01 13:59           ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-02-01 13:59 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Avi Kivity, kvm, qemu-devel

On 2011-02-01 14:50, Marcelo Tosatti wrote:
> On Tue, Feb 01, 2011 at 02:33:45PM +0100, Jan Kiszka wrote:
>>>> +++ b/cpus.c
>>>> @@ -531,6 +531,17 @@ void qemu_cpu_kick(void *env)
>>>>      return;
>>>>  }
>>>>  
>>>> +void qemu_cpu_kick_self(void)
>>>> +{
>>>> +#ifndef _WIN32
>>>> +    assert(cpu_single_env);
>>>> +
>>>> +    raise(SIG_IPI);
>>>> +#else
>>>> +    abort();
>>>> +#endif
>>>> +}
>>>> +
>>>>  void qemu_notify_event(void)
>>>>  {
>>>>      CPUState *env = cpu_single_env;
>>>> @@ -808,6 +819,16 @@ void qemu_cpu_kick(void *_env)
>>>>      }
>>>>  }
>>>>  
>>>> +void qemu_cpu_kick_self(void)
>>>> +{
>>>> +    assert(cpu_single_env);
>>>> +
>>>> +    if (!cpu_single_env->thread_kicked) {
>>>> +        qemu_thread_signal(cpu_single_env->thread, SIG_IPI);
>>>> +        cpu_single_env->thread_kicked = true;
>>>> +    }
>>>> +}
>>>> +
>>>
>>> There is no need to use cpu_single_env, can pass CPUState instead.
>>>
>>
>> It's done intentionally this way: function shall not be used for a
>> remote env.
>>
>> Jan
> 
> Can assert on qemu_cpu_self(env) for that.
> 

We already assert on cpu_single_env which is the right condition.
Removing env from the parameter list avoids that someone even thinks
about misusing it.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
  2011-02-01 13:58           ` [Qemu-devel] " Jan Kiszka
@ 2011-02-01 14:10             ` Marcelo Tosatti
  -1 siblings, 0 replies; 146+ messages in thread
From: Marcelo Tosatti @ 2011-02-01 14:10 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Avi Kivity, kvm, qemu-devel, Stefan Hajnoczi

On Tue, Feb 01, 2011 at 02:58:02PM +0100, Jan Kiszka wrote:
> On 2011-02-01 14:48, Marcelo Tosatti wrote:
> > On Tue, Feb 01, 2011 at 02:32:38PM +0100, Jan Kiszka wrote:
> >> On 2011-02-01 13:47, Marcelo Tosatti wrote:
> >>> On Thu, Jan 27, 2011 at 02:09:58PM +0100, Jan Kiszka wrote:
> >>>> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
> >>>> checking for exit_request on vcpu entry and timer signals arriving
> >>>> before KVM starts to catch them. Plug it by blocking both timer related
> >>>> signals also on !CONFIG_IOTHREAD and process those via signalfd.
> >>>>
> >>>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> >>>> CC: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> >>>> ---
> >>>>  cpus.c |   18 ++++++++++++++++++
> >>>>  1 files changed, 18 insertions(+), 0 deletions(-)
> >>>>
> >>>> diff --git a/cpus.c b/cpus.c
> >>>> index fc3f222..29b1070 100644
> >>>> --- a/cpus.c
> >>>> +++ b/cpus.c
> >>>> @@ -254,6 +254,10 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
> >>>>      pthread_sigmask(SIG_BLOCK, NULL, &set);
> >>>>      sigdelset(&set, SIG_IPI);
> >>>>      sigdelset(&set, SIGBUS);
> >>>> +#ifndef CONFIG_IOTHREAD
> >>>> +    sigdelset(&set, SIGIO);
> >>>> +    sigdelset(&set, SIGALRM);
> >>>> +#endif
> >>>
> >>> I'd prefer separate qemu_kvm_init_cpu_signals in the !IOTHREAD
> >>> section.
> >>
> >> You mean to duplicate qemu_kvm_init_cpu_signals for both configurations?
> > 
> > Yes, so to avoid #ifdefs spread.
> 
> Would exchange some #ifdefs against ifndef _WIN32. Haven't measured the
> delta though.
> 
> > 
> >>>> +
> >>>> +#ifndef CONFIG_IOTHREAD
> >>>> +    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
> >>>> +        qemu_notify_event();
> >>>> +    }
> >>>> +#endif
> >>>
> >>> Why is this necessary?
> >>>
> >>> You should break out of cpu_exec_all if there's a pending alarm (see
> >>> qemu_alarm_pending()).
> >>
> >> qemu_alarm_pending() is not true until the signal is actually taken. The
> >> alarm handler sets the required flags.
> > 
> > Right. What i mean is you need to execute the signal handler inside
> > cpu_exec_all loop (so that alarm pending is set).
> > 
> > So, if there is a SIGALRM pending, qemu_run_timers has highest
> > priority, not vcpu execution.
> 
> We leave the vcpu loop (thanks to notify_event), process the signal in
> the event loop and run the timer handler. This pattern is IMO less
> invasive to the existing code, specifically as it is about to die
> long-term anyway.

You'll probably see poor timer behaviour on smp guests without iothread
enabled.


^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
@ 2011-02-01 14:10             ` Marcelo Tosatti
  0 siblings, 0 replies; 146+ messages in thread
From: Marcelo Tosatti @ 2011-02-01 14:10 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Stefan Hajnoczi, Avi Kivity, kvm, qemu-devel

On Tue, Feb 01, 2011 at 02:58:02PM +0100, Jan Kiszka wrote:
> On 2011-02-01 14:48, Marcelo Tosatti wrote:
> > On Tue, Feb 01, 2011 at 02:32:38PM +0100, Jan Kiszka wrote:
> >> On 2011-02-01 13:47, Marcelo Tosatti wrote:
> >>> On Thu, Jan 27, 2011 at 02:09:58PM +0100, Jan Kiszka wrote:
> >>>> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
> >>>> checking for exit_request on vcpu entry and timer signals arriving
> >>>> before KVM starts to catch them. Plug it by blocking both timer related
> >>>> signals also on !CONFIG_IOTHREAD and process those via signalfd.
> >>>>
> >>>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> >>>> CC: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> >>>> ---
> >>>>  cpus.c |   18 ++++++++++++++++++
> >>>>  1 files changed, 18 insertions(+), 0 deletions(-)
> >>>>
> >>>> diff --git a/cpus.c b/cpus.c
> >>>> index fc3f222..29b1070 100644
> >>>> --- a/cpus.c
> >>>> +++ b/cpus.c
> >>>> @@ -254,6 +254,10 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
> >>>>      pthread_sigmask(SIG_BLOCK, NULL, &set);
> >>>>      sigdelset(&set, SIG_IPI);
> >>>>      sigdelset(&set, SIGBUS);
> >>>> +#ifndef CONFIG_IOTHREAD
> >>>> +    sigdelset(&set, SIGIO);
> >>>> +    sigdelset(&set, SIGALRM);
> >>>> +#endif
> >>>
> >>> I'd prefer separate qemu_kvm_init_cpu_signals in the !IOTHREAD
> >>> section.
> >>
> >> You mean to duplicate qemu_kvm_init_cpu_signals for both configurations?
> > 
> > Yes, so to avoid #ifdefs spread.
> 
> Would exchange some #ifdefs against ifndef _WIN32. Haven't measured the
> delta though.
> 
> > 
> >>>> +
> >>>> +#ifndef CONFIG_IOTHREAD
> >>>> +    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
> >>>> +        qemu_notify_event();
> >>>> +    }
> >>>> +#endif
> >>>
> >>> Why is this necessary?
> >>>
> >>> You should break out of cpu_exec_all if there's a pending alarm (see
> >>> qemu_alarm_pending()).
> >>
> >> qemu_alarm_pending() is not true until the signal is actually taken. The
> >> alarm handler sets the required flags.
> > 
> > Right. What i mean is you need to execute the signal handler inside
> > cpu_exec_all loop (so that alarm pending is set).
> > 
> > So, if there is a SIGALRM pending, qemu_run_timers has highest
> > priority, not vcpu execution.
> 
> We leave the vcpu loop (thanks to notify_event), process the signal in
> the event loop and run the timer handler. This pattern is IMO less
> invasive to the existing code, specifically as it is about to die
> long-term anyway.

You'll probably see poor timer behaviour on smp guests without iothread
enabled.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
  2011-02-01 14:10             ` [Qemu-devel] " Marcelo Tosatti
@ 2011-02-01 14:21               ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-02-01 14:21 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Avi Kivity, kvm, qemu-devel, Stefan Hajnoczi

On 2011-02-01 15:10, Marcelo Tosatti wrote:
> On Tue, Feb 01, 2011 at 02:58:02PM +0100, Jan Kiszka wrote:
>> On 2011-02-01 14:48, Marcelo Tosatti wrote:
>>> On Tue, Feb 01, 2011 at 02:32:38PM +0100, Jan Kiszka wrote:
>>>> On 2011-02-01 13:47, Marcelo Tosatti wrote:
>>>>> On Thu, Jan 27, 2011 at 02:09:58PM +0100, Jan Kiszka wrote:
>>>>>> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
>>>>>> checking for exit_request on vcpu entry and timer signals arriving
>>>>>> before KVM starts to catch them. Plug it by blocking both timer related
>>>>>> signals also on !CONFIG_IOTHREAD and process those via signalfd.
>>>>>>
>>>>>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>>>>>> CC: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
>>>>>> ---
>>>>>>  cpus.c |   18 ++++++++++++++++++
>>>>>>  1 files changed, 18 insertions(+), 0 deletions(-)
>>>>>>
>>>>>> diff --git a/cpus.c b/cpus.c
>>>>>> index fc3f222..29b1070 100644
>>>>>> --- a/cpus.c
>>>>>> +++ b/cpus.c
>>>>>> @@ -254,6 +254,10 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
>>>>>>      pthread_sigmask(SIG_BLOCK, NULL, &set);
>>>>>>      sigdelset(&set, SIG_IPI);
>>>>>>      sigdelset(&set, SIGBUS);
>>>>>> +#ifndef CONFIG_IOTHREAD
>>>>>> +    sigdelset(&set, SIGIO);
>>>>>> +    sigdelset(&set, SIGALRM);
>>>>>> +#endif
>>>>>
>>>>> I'd prefer separate qemu_kvm_init_cpu_signals in the !IOTHREAD
>>>>> section.
>>>>
>>>> You mean to duplicate qemu_kvm_init_cpu_signals for both configurations?
>>>
>>> Yes, so to avoid #ifdefs spread.
>>
>> Would exchange some #ifdefs against ifndef _WIN32. Haven't measured the
>> delta though.
>>
>>>
>>>>>> +
>>>>>> +#ifndef CONFIG_IOTHREAD
>>>>>> +    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
>>>>>> +        qemu_notify_event();
>>>>>> +    }
>>>>>> +#endif
>>>>>
>>>>> Why is this necessary?
>>>>>
>>>>> You should break out of cpu_exec_all if there's a pending alarm (see
>>>>> qemu_alarm_pending()).
>>>>
>>>> qemu_alarm_pending() is not true until the signal is actually taken. The
>>>> alarm handler sets the required flags.
>>>
>>> Right. What i mean is you need to execute the signal handler inside
>>> cpu_exec_all loop (so that alarm pending is set).
>>>
>>> So, if there is a SIGALRM pending, qemu_run_timers has highest
>>> priority, not vcpu execution.
>>
>> We leave the vcpu loop (thanks to notify_event), process the signal in
>> the event loop and run the timer handler. This pattern is IMO less
>> invasive to the existing code, specifically as it is about to die
>> long-term anyway.
> 
> You'll probably see poor timer behaviour on smp guests without iothread
> enabled.
> 

Still checking, but that would mean the notification mechanism is broken
anyway: If IO events do not force us to process them quickly, we already
suffer from latencies in SMP mode.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
@ 2011-02-01 14:21               ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-02-01 14:21 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Stefan Hajnoczi, Avi Kivity, kvm, qemu-devel

On 2011-02-01 15:10, Marcelo Tosatti wrote:
> On Tue, Feb 01, 2011 at 02:58:02PM +0100, Jan Kiszka wrote:
>> On 2011-02-01 14:48, Marcelo Tosatti wrote:
>>> On Tue, Feb 01, 2011 at 02:32:38PM +0100, Jan Kiszka wrote:
>>>> On 2011-02-01 13:47, Marcelo Tosatti wrote:
>>>>> On Thu, Jan 27, 2011 at 02:09:58PM +0100, Jan Kiszka wrote:
>>>>>> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
>>>>>> checking for exit_request on vcpu entry and timer signals arriving
>>>>>> before KVM starts to catch them. Plug it by blocking both timer related
>>>>>> signals also on !CONFIG_IOTHREAD and process those via signalfd.
>>>>>>
>>>>>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>>>>>> CC: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
>>>>>> ---
>>>>>>  cpus.c |   18 ++++++++++++++++++
>>>>>>  1 files changed, 18 insertions(+), 0 deletions(-)
>>>>>>
>>>>>> diff --git a/cpus.c b/cpus.c
>>>>>> index fc3f222..29b1070 100644
>>>>>> --- a/cpus.c
>>>>>> +++ b/cpus.c
>>>>>> @@ -254,6 +254,10 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
>>>>>>      pthread_sigmask(SIG_BLOCK, NULL, &set);
>>>>>>      sigdelset(&set, SIG_IPI);
>>>>>>      sigdelset(&set, SIGBUS);
>>>>>> +#ifndef CONFIG_IOTHREAD
>>>>>> +    sigdelset(&set, SIGIO);
>>>>>> +    sigdelset(&set, SIGALRM);
>>>>>> +#endif
>>>>>
>>>>> I'd prefer separate qemu_kvm_init_cpu_signals in the !IOTHREAD
>>>>> section.
>>>>
>>>> You mean to duplicate qemu_kvm_init_cpu_signals for both configurations?
>>>
>>> Yes, so to avoid #ifdefs spread.
>>
>> Would exchange some #ifdefs against ifndef _WIN32. Haven't measured the
>> delta though.
>>
>>>
>>>>>> +
>>>>>> +#ifndef CONFIG_IOTHREAD
>>>>>> +    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
>>>>>> +        qemu_notify_event();
>>>>>> +    }
>>>>>> +#endif
>>>>>
>>>>> Why is this necessary?
>>>>>
>>>>> You should break out of cpu_exec_all if there's a pending alarm (see
>>>>> qemu_alarm_pending()).
>>>>
>>>> qemu_alarm_pending() is not true until the signal is actually taken. The
>>>> alarm handler sets the required flags.
>>>
>>> Right. What i mean is you need to execute the signal handler inside
>>> cpu_exec_all loop (so that alarm pending is set).
>>>
>>> So, if there is a SIGALRM pending, qemu_run_timers has highest
>>> priority, not vcpu execution.
>>
>> We leave the vcpu loop (thanks to notify_event), process the signal in
>> the event loop and run the timer handler. This pattern is IMO less
>> invasive to the existing code, specifically as it is about to die
>> long-term anyway.
> 
> You'll probably see poor timer behaviour on smp guests without iothread
> enabled.
> 

Still checking, but that would mean the notification mechanism is broken
anyway: If IO events do not force us to process them quickly, we already
suffer from latencies in SMP mode.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
  2011-02-01 14:21               ` [Qemu-devel] " Jan Kiszka
@ 2011-02-01 14:37                 ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-02-01 14:37 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Avi Kivity, kvm, qemu-devel, Stefan Hajnoczi

On 2011-02-01 15:21, Jan Kiszka wrote:
> On 2011-02-01 15:10, Marcelo Tosatti wrote:
>> On Tue, Feb 01, 2011 at 02:58:02PM +0100, Jan Kiszka wrote:
>>> On 2011-02-01 14:48, Marcelo Tosatti wrote:
>>>> On Tue, Feb 01, 2011 at 02:32:38PM +0100, Jan Kiszka wrote:
>>>>> On 2011-02-01 13:47, Marcelo Tosatti wrote:
>>>>>> On Thu, Jan 27, 2011 at 02:09:58PM +0100, Jan Kiszka wrote:
>>>>>>> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
>>>>>>> checking for exit_request on vcpu entry and timer signals arriving
>>>>>>> before KVM starts to catch them. Plug it by blocking both timer related
>>>>>>> signals also on !CONFIG_IOTHREAD and process those via signalfd.
>>>>>>>
>>>>>>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>>>>>>> CC: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
>>>>>>> ---
>>>>>>>  cpus.c |   18 ++++++++++++++++++
>>>>>>>  1 files changed, 18 insertions(+), 0 deletions(-)
>>>>>>>
>>>>>>> diff --git a/cpus.c b/cpus.c
>>>>>>> index fc3f222..29b1070 100644
>>>>>>> --- a/cpus.c
>>>>>>> +++ b/cpus.c
>>>>>>> @@ -254,6 +254,10 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
>>>>>>>      pthread_sigmask(SIG_BLOCK, NULL, &set);
>>>>>>>      sigdelset(&set, SIG_IPI);
>>>>>>>      sigdelset(&set, SIGBUS);
>>>>>>> +#ifndef CONFIG_IOTHREAD
>>>>>>> +    sigdelset(&set, SIGIO);
>>>>>>> +    sigdelset(&set, SIGALRM);
>>>>>>> +#endif
>>>>>>
>>>>>> I'd prefer separate qemu_kvm_init_cpu_signals in the !IOTHREAD
>>>>>> section.
>>>>>
>>>>> You mean to duplicate qemu_kvm_init_cpu_signals for both configurations?
>>>>
>>>> Yes, so to avoid #ifdefs spread.
>>>
>>> Would exchange some #ifdefs against ifndef _WIN32. Haven't measured the
>>> delta though.
>>>
>>>>
>>>>>>> +
>>>>>>> +#ifndef CONFIG_IOTHREAD
>>>>>>> +    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
>>>>>>> +        qemu_notify_event();
>>>>>>> +    }
>>>>>>> +#endif
>>>>>>
>>>>>> Why is this necessary?
>>>>>>
>>>>>> You should break out of cpu_exec_all if there's a pending alarm (see
>>>>>> qemu_alarm_pending()).
>>>>>
>>>>> qemu_alarm_pending() is not true until the signal is actually taken. The
>>>>> alarm handler sets the required flags.
>>>>
>>>> Right. What i mean is you need to execute the signal handler inside
>>>> cpu_exec_all loop (so that alarm pending is set).
>>>>
>>>> So, if there is a SIGALRM pending, qemu_run_timers has highest
>>>> priority, not vcpu execution.
>>>
>>> We leave the vcpu loop (thanks to notify_event), process the signal in
>>> the event loop and run the timer handler. This pattern is IMO less
>>> invasive to the existing code, specifically as it is about to die
>>> long-term anyway.
>>
>> You'll probably see poor timer behaviour on smp guests without iothread
>> enabled.
>>
> 
> Still checking, but that would mean the notification mechanism is broken
> anyway: If IO events do not force us to process them quickly, we already
> suffer from latencies in SMP mode.

Maybe a regression caused by the iothread introduction: we need to break
out of the cpu loop via global exit_request when there is an IO event
pending. Fixing this will also heal the above issue.

Sigh, we need to get rid of those two implementations and focus all
reviewing and testing on one. I bet there are still more corner cases
sleeping somewhere.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
@ 2011-02-01 14:37                 ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-02-01 14:37 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Stefan Hajnoczi, Avi Kivity, kvm, qemu-devel

On 2011-02-01 15:21, Jan Kiszka wrote:
> On 2011-02-01 15:10, Marcelo Tosatti wrote:
>> On Tue, Feb 01, 2011 at 02:58:02PM +0100, Jan Kiszka wrote:
>>> On 2011-02-01 14:48, Marcelo Tosatti wrote:
>>>> On Tue, Feb 01, 2011 at 02:32:38PM +0100, Jan Kiszka wrote:
>>>>> On 2011-02-01 13:47, Marcelo Tosatti wrote:
>>>>>> On Thu, Jan 27, 2011 at 02:09:58PM +0100, Jan Kiszka wrote:
>>>>>>> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
>>>>>>> checking for exit_request on vcpu entry and timer signals arriving
>>>>>>> before KVM starts to catch them. Plug it by blocking both timer related
>>>>>>> signals also on !CONFIG_IOTHREAD and process those via signalfd.
>>>>>>>
>>>>>>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>>>>>>> CC: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
>>>>>>> ---
>>>>>>>  cpus.c |   18 ++++++++++++++++++
>>>>>>>  1 files changed, 18 insertions(+), 0 deletions(-)
>>>>>>>
>>>>>>> diff --git a/cpus.c b/cpus.c
>>>>>>> index fc3f222..29b1070 100644
>>>>>>> --- a/cpus.c
>>>>>>> +++ b/cpus.c
>>>>>>> @@ -254,6 +254,10 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
>>>>>>>      pthread_sigmask(SIG_BLOCK, NULL, &set);
>>>>>>>      sigdelset(&set, SIG_IPI);
>>>>>>>      sigdelset(&set, SIGBUS);
>>>>>>> +#ifndef CONFIG_IOTHREAD
>>>>>>> +    sigdelset(&set, SIGIO);
>>>>>>> +    sigdelset(&set, SIGALRM);
>>>>>>> +#endif
>>>>>>
>>>>>> I'd prefer separate qemu_kvm_init_cpu_signals in the !IOTHREAD
>>>>>> section.
>>>>>
>>>>> You mean to duplicate qemu_kvm_init_cpu_signals for both configurations?
>>>>
>>>> Yes, so to avoid #ifdefs spread.
>>>
>>> Would exchange some #ifdefs against ifndef _WIN32. Haven't measured the
>>> delta though.
>>>
>>>>
>>>>>>> +
>>>>>>> +#ifndef CONFIG_IOTHREAD
>>>>>>> +    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
>>>>>>> +        qemu_notify_event();
>>>>>>> +    }
>>>>>>> +#endif
>>>>>>
>>>>>> Why is this necessary?
>>>>>>
>>>>>> You should break out of cpu_exec_all if there's a pending alarm (see
>>>>>> qemu_alarm_pending()).
>>>>>
>>>>> qemu_alarm_pending() is not true until the signal is actually taken. The
>>>>> alarm handler sets the required flags.
>>>>
>>>> Right. What i mean is you need to execute the signal handler inside
>>>> cpu_exec_all loop (so that alarm pending is set).
>>>>
>>>> So, if there is a SIGALRM pending, qemu_run_timers has highest
>>>> priority, not vcpu execution.
>>>
>>> We leave the vcpu loop (thanks to notify_event), process the signal in
>>> the event loop and run the timer handler. This pattern is IMO less
>>> invasive to the existing code, specifically as it is about to die
>>> long-term anyway.
>>
>> You'll probably see poor timer behaviour on smp guests without iothread
>> enabled.
>>
> 
> Still checking, but that would mean the notification mechanism is broken
> anyway: If IO events do not force us to process them quickly, we already
> suffer from latencies in SMP mode.

Maybe a regression caused by the iothread introduction: we need to break
out of the cpu loop via global exit_request when there is an IO event
pending. Fixing this will also heal the above issue.

Sigh, we need to get rid of those two implementations and focus all
reviewing and testing on one. I bet there are still more corner cases
sleeping somewhere.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
  2011-02-01 14:37                 ` [Qemu-devel] " Jan Kiszka
@ 2011-02-01 14:45                   ` Jan Kiszka
  -1 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-02-01 14:45 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Avi Kivity, kvm, qemu-devel, Stefan Hajnoczi

On 2011-02-01 15:37, Jan Kiszka wrote:
> On 2011-02-01 15:21, Jan Kiszka wrote:
>> On 2011-02-01 15:10, Marcelo Tosatti wrote:
>>> On Tue, Feb 01, 2011 at 02:58:02PM +0100, Jan Kiszka wrote:
>>>> On 2011-02-01 14:48, Marcelo Tosatti wrote:
>>>>> On Tue, Feb 01, 2011 at 02:32:38PM +0100, Jan Kiszka wrote:
>>>>>> On 2011-02-01 13:47, Marcelo Tosatti wrote:
>>>>>>> On Thu, Jan 27, 2011 at 02:09:58PM +0100, Jan Kiszka wrote:
>>>>>>>> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
>>>>>>>> checking for exit_request on vcpu entry and timer signals arriving
>>>>>>>> before KVM starts to catch them. Plug it by blocking both timer related
>>>>>>>> signals also on !CONFIG_IOTHREAD and process those via signalfd.
>>>>>>>>
>>>>>>>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>>>>>>>> CC: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
>>>>>>>> ---
>>>>>>>>  cpus.c |   18 ++++++++++++++++++
>>>>>>>>  1 files changed, 18 insertions(+), 0 deletions(-)
>>>>>>>>
>>>>>>>> diff --git a/cpus.c b/cpus.c
>>>>>>>> index fc3f222..29b1070 100644
>>>>>>>> --- a/cpus.c
>>>>>>>> +++ b/cpus.c
>>>>>>>> @@ -254,6 +254,10 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
>>>>>>>>      pthread_sigmask(SIG_BLOCK, NULL, &set);
>>>>>>>>      sigdelset(&set, SIG_IPI);
>>>>>>>>      sigdelset(&set, SIGBUS);
>>>>>>>> +#ifndef CONFIG_IOTHREAD
>>>>>>>> +    sigdelset(&set, SIGIO);
>>>>>>>> +    sigdelset(&set, SIGALRM);
>>>>>>>> +#endif
>>>>>>>
>>>>>>> I'd prefer separate qemu_kvm_init_cpu_signals in the !IOTHREAD
>>>>>>> section.
>>>>>>
>>>>>> You mean to duplicate qemu_kvm_init_cpu_signals for both configurations?
>>>>>
>>>>> Yes, so to avoid #ifdefs spread.
>>>>
>>>> Would exchange some #ifdefs against ifndef _WIN32. Haven't measured the
>>>> delta though.
>>>>
>>>>>
>>>>>>>> +
>>>>>>>> +#ifndef CONFIG_IOTHREAD
>>>>>>>> +    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
>>>>>>>> +        qemu_notify_event();
>>>>>>>> +    }
>>>>>>>> +#endif
>>>>>>>
>>>>>>> Why is this necessary?
>>>>>>>
>>>>>>> You should break out of cpu_exec_all if there's a pending alarm (see
>>>>>>> qemu_alarm_pending()).
>>>>>>
>>>>>> qemu_alarm_pending() is not true until the signal is actually taken. The
>>>>>> alarm handler sets the required flags.
>>>>>
>>>>> Right. What i mean is you need to execute the signal handler inside
>>>>> cpu_exec_all loop (so that alarm pending is set).
>>>>>
>>>>> So, if there is a SIGALRM pending, qemu_run_timers has highest
>>>>> priority, not vcpu execution.
>>>>
>>>> We leave the vcpu loop (thanks to notify_event), process the signal in
>>>> the event loop and run the timer handler. This pattern is IMO less
>>>> invasive to the existing code, specifically as it is about to die
>>>> long-term anyway.
>>>
>>> You'll probably see poor timer behaviour on smp guests without iothread
>>> enabled.
>>>
>>
>> Still checking, but that would mean the notification mechanism is broken
>> anyway: If IO events do not force us to process them quickly, we already
>> suffer from latencies in SMP mode.
> 
> Maybe a regression caused by the iothread introduction:

I take it back, the issue is actually much older.

> we need to break
> out of the cpu loop via global exit_request when there is an IO event
> pending. Fixing this will also heal the above issue.
> 
> Sigh, we need to get rid of those two implementations and focus all
> reviewing and testing on one. I bet there are still more corner cases
> sleeping somewhere.
> 
> Jan
> 

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [Qemu-devel] Re: [PATCH 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
@ 2011-02-01 14:45                   ` Jan Kiszka
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Kiszka @ 2011-02-01 14:45 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Stefan Hajnoczi, Avi Kivity, kvm, qemu-devel

On 2011-02-01 15:37, Jan Kiszka wrote:
> On 2011-02-01 15:21, Jan Kiszka wrote:
>> On 2011-02-01 15:10, Marcelo Tosatti wrote:
>>> On Tue, Feb 01, 2011 at 02:58:02PM +0100, Jan Kiszka wrote:
>>>> On 2011-02-01 14:48, Marcelo Tosatti wrote:
>>>>> On Tue, Feb 01, 2011 at 02:32:38PM +0100, Jan Kiszka wrote:
>>>>>> On 2011-02-01 13:47, Marcelo Tosatti wrote:
>>>>>>> On Thu, Jan 27, 2011 at 02:09:58PM +0100, Jan Kiszka wrote:
>>>>>>>> Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
>>>>>>>> checking for exit_request on vcpu entry and timer signals arriving
>>>>>>>> before KVM starts to catch them. Plug it by blocking both timer related
>>>>>>>> signals also on !CONFIG_IOTHREAD and process those via signalfd.
>>>>>>>>
>>>>>>>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>>>>>>>> CC: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
>>>>>>>> ---
>>>>>>>>  cpus.c |   18 ++++++++++++++++++
>>>>>>>>  1 files changed, 18 insertions(+), 0 deletions(-)
>>>>>>>>
>>>>>>>> diff --git a/cpus.c b/cpus.c
>>>>>>>> index fc3f222..29b1070 100644
>>>>>>>> --- a/cpus.c
>>>>>>>> +++ b/cpus.c
>>>>>>>> @@ -254,6 +254,10 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
>>>>>>>>      pthread_sigmask(SIG_BLOCK, NULL, &set);
>>>>>>>>      sigdelset(&set, SIG_IPI);
>>>>>>>>      sigdelset(&set, SIGBUS);
>>>>>>>> +#ifndef CONFIG_IOTHREAD
>>>>>>>> +    sigdelset(&set, SIGIO);
>>>>>>>> +    sigdelset(&set, SIGALRM);
>>>>>>>> +#endif
>>>>>>>
>>>>>>> I'd prefer separate qemu_kvm_init_cpu_signals in the !IOTHREAD
>>>>>>> section.
>>>>>>
>>>>>> You mean to duplicate qemu_kvm_init_cpu_signals for both configurations?
>>>>>
>>>>> Yes, so to avoid #ifdefs spread.
>>>>
>>>> Would exchange some #ifdefs against ifndef _WIN32. Haven't measured the
>>>> delta though.
>>>>
>>>>>
>>>>>>>> +
>>>>>>>> +#ifndef CONFIG_IOTHREAD
>>>>>>>> +    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
>>>>>>>> +        qemu_notify_event();
>>>>>>>> +    }
>>>>>>>> +#endif
>>>>>>>
>>>>>>> Why is this necessary?
>>>>>>>
>>>>>>> You should break out of cpu_exec_all if there's a pending alarm (see
>>>>>>> qemu_alarm_pending()).
>>>>>>
>>>>>> qemu_alarm_pending() is not true until the signal is actually taken. The
>>>>>> alarm handler sets the required flags.
>>>>>
>>>>> Right. What i mean is you need to execute the signal handler inside
>>>>> cpu_exec_all loop (so that alarm pending is set).
>>>>>
>>>>> So, if there is a SIGALRM pending, qemu_run_timers has highest
>>>>> priority, not vcpu execution.
>>>>
>>>> We leave the vcpu loop (thanks to notify_event), process the signal in
>>>> the event loop and run the timer handler. This pattern is IMO less
>>>> invasive to the existing code, specifically as it is about to die
>>>> long-term anyway.
>>>
>>> You'll probably see poor timer behaviour on smp guests without iothread
>>> enabled.
>>>
>>
>> Still checking, but that would mean the notification mechanism is broken
>> anyway: If IO events do not force us to process them quickly, we already
>> suffer from latencies in SMP mode.
> 
> Maybe a regression caused by the iothread introduction:

I take it back, the issue is actually much older.

> we need to break
> out of the cpu loop via global exit_request when there is an IO event
> pending. Fixing this will also heal the above issue.
> 
> Sigh, we need to get rid of those two implementations and focus all
> reviewing and testing on one. I bet there are still more corner cases
> sleeping somewhere.
> 
> Jan
> 

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

end of thread, other threads:[~2011-02-01 14:45 UTC | newest]

Thread overview: 146+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-27 13:09 [PATCH 00/22] [uq/master] Patch queue, part II Jan Kiszka
2011-01-27 13:09 ` [Qemu-devel] " Jan Kiszka
2011-01-27 13:09 ` [PATCH 01/22] Prevent abortion on multiple VCPU kicks Jan Kiszka
2011-01-27 13:09   ` [Qemu-devel] " Jan Kiszka
2011-01-31  9:44   ` Avi Kivity
2011-01-31  9:44     ` [Qemu-devel] " Avi Kivity
2011-01-31 11:19     ` Jan Kiszka
2011-01-31 11:19       ` [Qemu-devel] " Jan Kiszka
2011-01-31 13:16       ` Avi Kivity
2011-01-31 13:16         ` [Qemu-devel] " Avi Kivity
2011-01-27 13:09 ` [PATCH 02/22] Stop current VCPU on synchronous reset requests Jan Kiszka
2011-01-27 13:09   ` [Qemu-devel] " Jan Kiszka
2011-01-27 13:09 ` [PATCH 03/22] Process vmstop requests in IO thread Jan Kiszka
2011-01-27 13:09   ` [Qemu-devel] " Jan Kiszka
2011-01-27 13:09 ` [PATCH 04/22] Leave inner main_loop faster on pending requests Jan Kiszka
2011-01-27 13:09   ` [Qemu-devel] " Jan Kiszka
2011-01-31  9:52   ` Avi Kivity
2011-01-31  9:52     ` [Qemu-devel] " Avi Kivity
2011-01-31 11:22     ` Jan Kiszka
2011-01-31 11:22       ` [Qemu-devel] " Jan Kiszka
2011-01-31 13:17       ` Avi Kivity
2011-01-31 13:17         ` [Qemu-devel] " Avi Kivity
2011-01-31 14:32         ` Jan Kiszka
2011-01-31 14:32           ` [Qemu-devel] " Jan Kiszka
2011-01-27 13:09 ` [PATCH 05/22] kvm: Report proper error on GET_VCPU_MMAP_SIZE failures Jan Kiszka
2011-01-27 13:09   ` [Qemu-devel] " Jan Kiszka
2011-01-27 13:09 ` [PATCH 06/22] kvm: Drop redundant kvm_enabled from kvm_cpu_thread_fn Jan Kiszka
2011-01-27 13:09   ` [Qemu-devel] " Jan Kiszka
2011-01-27 13:09 ` [PATCH 07/22] kvm: Handle kvm_init_vcpu errors Jan Kiszka
2011-01-27 13:09   ` [Qemu-devel] " Jan Kiszka
2011-01-27 13:09 ` [PATCH 08/22] kvm: Provide sigbus services arch-independently Jan Kiszka
2011-01-27 13:09   ` [Qemu-devel] " Jan Kiszka
2011-01-27 16:39   ` Paolo Bonzini
2011-01-27 16:39     ` [Qemu-devel] " Paolo Bonzini
2011-01-30 14:51   ` Alexander Graf
2011-01-30 14:51     ` [Qemu-devel] " Alexander Graf
2011-01-27 13:09 ` [PATCH 09/22] Refactor signal setup functions in cpus.c Jan Kiszka
2011-01-27 13:09   ` [Qemu-devel] " Jan Kiszka
2011-01-27 13:09 ` [PATCH 10/22] kvm: Set up signal mask also for !CONFIG_IOTHREAD Jan Kiszka
2011-01-27 13:09   ` [Qemu-devel] " Jan Kiszka
2011-01-28  8:08   ` Paolo Bonzini
2011-01-28  8:08     ` [Qemu-devel] " Paolo Bonzini
2011-01-27 13:09 ` [PATCH 11/22] kvm: Refactor qemu_kvm_eat_signals Jan Kiszka
2011-01-27 13:09   ` [Qemu-devel] " Jan Kiszka
2011-01-27 13:09 ` [PATCH 12/22] kvm: Call qemu_kvm_eat_signals also under !CONFIG_IOTHREAD Jan Kiszka
2011-01-27 13:09   ` [Qemu-devel] " Jan Kiszka
2011-01-28  8:09   ` Paolo Bonzini
2011-01-28  8:09     ` [Qemu-devel] " Paolo Bonzini
2011-02-01 12:38   ` Marcelo Tosatti
2011-02-01 12:38     ` [Qemu-devel] " Marcelo Tosatti
2011-02-01 12:49     ` Marcelo Tosatti
2011-02-01 12:49       ` [Qemu-devel] " Marcelo Tosatti
2011-02-01 13:21     ` Jan Kiszka
2011-02-01 13:21       ` [Qemu-devel] " Jan Kiszka
2011-01-27 13:09 ` [PATCH 13/22] Set up signalfd " Jan Kiszka
2011-01-27 13:09   ` [Qemu-devel] " Jan Kiszka
2011-01-28  8:11   ` Paolo Bonzini
2011-01-28  8:11     ` [Qemu-devel] " Paolo Bonzini
2011-01-27 13:09 ` [PATCH 14/22] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD Jan Kiszka
2011-01-27 13:09   ` [Qemu-devel] " Jan Kiszka
2011-01-27 14:20   ` [PATCH v2 " Jan Kiszka
2011-01-27 14:20     ` [Qemu-devel] " Jan Kiszka
2011-01-27 14:33     ` [PATCH v3 " Jan Kiszka
2011-01-27 14:33       ` [Qemu-devel] " Jan Kiszka
2011-01-31 10:03       ` Avi Kivity
2011-01-31 10:03         ` [Qemu-devel] " Avi Kivity
2011-01-31 11:27         ` Jan Kiszka
2011-01-31 11:27           ` [Qemu-devel] " Jan Kiszka
2011-01-31 12:13           ` Stefan Hajnoczi
2011-01-31 12:13             ` Stefan Hajnoczi
2011-01-31 12:18             ` Jan Kiszka
2011-01-31 12:18               ` Jan Kiszka
2011-01-31 13:35               ` Stefan Hajnoczi
2011-01-31 13:35                 ` Stefan Hajnoczi
2011-01-31 13:22           ` Avi Kivity
2011-01-31 13:22             ` [Qemu-devel] " Avi Kivity
2011-01-31 14:31             ` Jan Kiszka
2011-01-31 14:31               ` [Qemu-devel] " Jan Kiszka
2011-01-31 16:30               ` Avi Kivity
2011-01-31 16:30                 ` [Qemu-devel] " Avi Kivity
2011-02-01 12:47   ` [PATCH " Marcelo Tosatti
2011-02-01 12:47     ` [Qemu-devel] " Marcelo Tosatti
2011-02-01 13:32     ` Jan Kiszka
2011-02-01 13:32       ` [Qemu-devel] " Jan Kiszka
2011-02-01 13:48       ` Marcelo Tosatti
2011-02-01 13:48         ` [Qemu-devel] " Marcelo Tosatti
2011-02-01 13:58         ` Jan Kiszka
2011-02-01 13:58           ` [Qemu-devel] " Jan Kiszka
2011-02-01 14:10           ` Marcelo Tosatti
2011-02-01 14:10             ` [Qemu-devel] " Marcelo Tosatti
2011-02-01 14:21             ` Jan Kiszka
2011-02-01 14:21               ` [Qemu-devel] " Jan Kiszka
2011-02-01 14:37               ` Jan Kiszka
2011-02-01 14:37                 ` [Qemu-devel] " Jan Kiszka
2011-02-01 14:45                 ` Jan Kiszka
2011-02-01 14:45                   ` [Qemu-devel] " Jan Kiszka
2011-01-27 13:09 ` [PATCH 15/22] kvm: Add MCE signal support for !CONFIG_IOTHREAD Jan Kiszka
2011-01-27 13:09   ` [Qemu-devel] " Jan Kiszka
2011-01-27 13:10 ` [PATCH 16/22] Introduce VCPU self-signaling service Jan Kiszka
2011-01-27 13:10   ` [Qemu-devel] " Jan Kiszka
2011-02-01 13:14   ` Marcelo Tosatti
2011-02-01 13:14     ` [Qemu-devel] " Marcelo Tosatti
2011-02-01 13:33     ` Jan Kiszka
2011-02-01 13:33       ` [Qemu-devel] " Jan Kiszka
2011-02-01 13:50       ` Marcelo Tosatti
2011-02-01 13:50         ` [Qemu-devel] " Marcelo Tosatti
2011-02-01 13:59         ` Jan Kiszka
2011-02-01 13:59           ` [Qemu-devel] " Jan Kiszka
2011-01-27 13:10 ` [PATCH 17/22] kvm: Move irqchip event processing out of inner loop Jan Kiszka
2011-01-27 13:10   ` [Qemu-devel] " Jan Kiszka
2011-01-31 10:08   ` Avi Kivity
2011-01-31 10:08     ` [Qemu-devel] " Avi Kivity
2011-01-31 11:36     ` Jan Kiszka
2011-01-31 11:36       ` [Qemu-devel] " Jan Kiszka
2011-01-31 13:04       ` Jan Kiszka
2011-01-31 13:04         ` [Qemu-devel] " Jan Kiszka
2011-01-31 15:40         ` Jan Kiszka
2011-01-31 15:40           ` [Qemu-devel] " Jan Kiszka
2011-01-31 16:38           ` Gleb Natapov
2011-01-31 16:38             ` [Qemu-devel] " Gleb Natapov
2011-01-31 16:41             ` Jan Kiszka
2011-01-31 16:41               ` [Qemu-devel] " Jan Kiszka
2011-01-31 16:45               ` Jan Kiszka
2011-01-31 16:45                 ` [Qemu-devel] " Jan Kiszka
2011-01-31 16:50               ` Gleb Natapov
2011-01-31 16:50                 ` [Qemu-devel] " Gleb Natapov
2011-01-31 16:52                 ` Jan Kiszka
2011-01-31 16:52                   ` [Qemu-devel] " Jan Kiszka
2011-01-31 16:56                   ` Gleb Natapov
2011-01-31 16:56                     ` [Qemu-devel] " Gleb Natapov
2011-01-31 18:06                     ` [PATCH v2 17&18/22] kvm: Unconditionally reenter kernel after IO exits Jan Kiszka
2011-01-31 18:06                       ` [Qemu-devel] " Jan Kiszka
2011-01-27 13:10 ` [PATCH 18/22] " Jan Kiszka
2011-01-27 13:10   ` [Qemu-devel] " Jan Kiszka
2011-01-27 13:10 ` [PATCH 19/22] kvm: Remove static return code of kvm_handle_io Jan Kiszka
2011-01-27 13:10   ` [Qemu-devel] " Jan Kiszka
2011-01-27 13:10 ` [PATCH 20/22] kvm: Leave kvm_cpu_exec directly after KVM_EXIT_SHUTDOWN Jan Kiszka
2011-01-27 13:10   ` [Qemu-devel] " Jan Kiszka
2011-01-27 13:10 ` [PATCH 21/22] Refactor kvm&tcg function names in cpus.c Jan Kiszka
2011-01-27 13:10   ` [Qemu-devel] " Jan Kiszka
2011-01-27 13:10 ` [PATCH 22/22] Fix a few coding style violations " Jan Kiszka
2011-01-27 13:10   ` [Qemu-devel] " Jan Kiszka
2011-01-31 10:12 ` [PATCH 00/22] [uq/master] Patch queue, part II Avi Kivity
2011-01-31 10:12   ` [Qemu-devel] " Avi Kivity
2011-01-31 12:03   ` Jan Kiszka
2011-01-31 12:03     ` [Qemu-devel] " Jan Kiszka

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.