Patchwork [RFC,10/13] rcu: report quiescent states

login
register
mail settings
Submitter Paolo Bonzini
Date Aug. 15, 2011, 9:08 p.m.
Message ID <1313442520-12062-11-git-send-email-pbonzini@redhat.com>
Download mbox | patch
Permalink /patch/110100/
State New
Headers show

Comments

Paolo Bonzini - Aug. 15, 2011, 9:08 p.m.
Our flavor of RCU requires threads to communicate when they are going
offline for extended periods of time on a condition variable, or waiting
for I/O, or executing guest code.  Add markers to this end.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 cpus.c     |   12 ++++++++++++
 kvm-all.c  |    3 +++
 os-win32.c |    3 +++
 vl.c       |    4 ++++
 4 files changed, 22 insertions(+), 0 deletions(-)

Patch

diff --git a/cpus.c b/cpus.c
index 73e17a1..d29b8cd 100644
--- a/cpus.c
+++ b/cpus.c
@@ -32,6 +32,7 @@ 
 #include "kvm.h"
 
 #include "qemu-thread.h"
+#include "rcu.h"
 #include "cpus.h"
 
 #ifndef _WIN32
@@ -712,7 +713,9 @@  void run_on_cpu(CPUState *env, void (*func)(void *data), void *data)
     while (!wi.done) {
         CPUState *self_env = cpu_single_env;
 
+        rcu_thread_offline();
         qemu_cond_wait(&qemu_work_cond, &qemu_global_mutex);
+        rcu_thread_online();
         cpu_single_env = self_env;
     }
 }
@@ -753,13 +756,16 @@  static void qemu_tcg_wait_io_event(void)
        /* Start accounting real time to the virtual clock if the CPUs
           are idle.  */
         qemu_clock_warp(vm_clock);
+        rcu_thread_offline();
         qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex);
     }
 
     while (iothread_requesting_mutex) {
+        rcu_thread_offline();
         qemu_cond_wait(&qemu_io_proceeded_cond, &qemu_global_mutex);
     }
 
+    rcu_thread_online();
     for (env = first_cpu; env != NULL; env = env->next_cpu) {
         qemu_wait_io_event_common(env);
     }
@@ -768,9 +774,11 @@  static void qemu_tcg_wait_io_event(void)
 static void qemu_kvm_wait_io_event(CPUState *env)
 {
     while (cpu_thread_is_idle(env)) {
+        rcu_thread_offline();
         qemu_cond_wait(env->halt_cond, &qemu_global_mutex);
     }
 
+    rcu_thread_online();
     qemu_kvm_eat_signals(env);
     qemu_wait_io_event_common(env);
 }
@@ -780,6 +788,7 @@  static void *qemu_kvm_cpu_thread_fn(void *arg)
     CPUState *env = arg;
     int r;
 
+    rcu_register_thread();
     qemu_mutex_lock(&qemu_global_mutex);
     qemu_thread_get_self(env->thread);
     env->thread_id = qemu_get_thread_id();
@@ -818,6 +827,7 @@  static void *qemu_tcg_cpu_thread_fn(void *arg)
 {
     CPUState *env = arg;
 
+    rcu_register_thread();
     qemu_tcg_init_cpu_signals();
     qemu_thread_get_self(env->thread);
 
@@ -941,7 +951,9 @@  void pause_all_vcpus(void)
     }
 
     while (!all_vcpus_paused()) {
+        rcu_thread_offline();
         qemu_cond_wait(&qemu_pause_cond, &qemu_global_mutex);
+        rcu_thread_online();
         penv = first_cpu;
         while (penv) {
             qemu_cpu_kick(penv);
diff --git a/kvm-all.c b/kvm-all.c
index b9c172b..840f260 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -22,6 +22,7 @@ 
 
 #include "qemu-common.h"
 #include "qemu-barrier.h"
+#include "rcu.h"
 #include "sysemu.h"
 #include "hw/hw.h"
 #include "gdbstub.h"
@@ -952,7 +953,9 @@  int kvm_cpu_exec(CPUState *env)
         cpu_single_env = NULL;
         qemu_mutex_unlock_iothread();
 
+        rcu_thread_offline();
         run_ret = kvm_vcpu_ioctl(env, KVM_RUN, 0);
+        rcu_thread_online();
 
         qemu_mutex_lock_iothread();
         cpu_single_env = env;
diff --git a/os-win32.c b/os-win32.c
index b6652af..eab4418 100644
--- a/os-win32.c
+++ b/os-win32.c
@@ -32,6 +32,7 @@ 
 #include "config-host.h"
 #include "sysemu.h"
 #include "qemu-options.h"
+#include "rcu.h"
 
 /***********************************************************/
 /* Functions missing in mingw */
@@ -141,7 +142,9 @@  void os_host_main_loop_wait(int *timeout)
         WaitObjects *w = &wait_objects;
 
         qemu_mutex_unlock_iothread();
+        rcu_thread_offline();
         ret = WaitForMultipleObjects(w->num, w->events, FALSE, *timeout);
+        rcu_thread_online();
         qemu_mutex_lock_iothread();
         if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
             if (w->func[ret - WAIT_OBJECT_0])
diff --git a/vl.c b/vl.c
index c714127..6854036 100644
--- a/vl.c
+++ b/vl.c
@@ -131,6 +131,7 @@  int main(int argc, char **argv)
 #include "console.h"
 #include "sysemu.h"
 #include "gdbstub.h"
+#include "rcu.h"
 #include "qemu-timer.h"
 #include "qemu-char.h"
 #include "cache-utils.h"
@@ -1350,7 +1351,9 @@  void main_loop_wait(int nonblocking)
     slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
 
     qemu_mutex_unlock_iothread();
+    rcu_thread_offline();
     ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
+    rcu_thread_online();
     qemu_mutex_lock_iothread();
 
     qemu_iohandler_poll(&rfds, &wfds, &xfds, ret);
@@ -2113,6 +2116,7 @@  int main(int argc, char **argv, char **envp)
 
     QLIST_INIT (&vm_change_state_head);
     os_setup_early_signal_handling();
+    rcu_register_thread();
 
     module_call_init(MODULE_INIT_MACHINE);
     machine = find_default_machine();