|
@@ -28,6 +28,7 @@
|
|
|
#include "sysemu/tcg.h"
|
|
|
#include "sysemu/replay.h"
|
|
|
#include "qemu/main-loop.h"
|
|
|
+#include "qemu/notify.h"
|
|
|
#include "qemu/guest-random.h"
|
|
|
#include "exec/exec-all.h"
|
|
|
#include "hw/boards.h"
|
|
@@ -35,6 +36,26 @@
|
|
|
#include "tcg-accel-ops.h"
|
|
|
#include "tcg-accel-ops-mttcg.h"
|
|
|
|
|
|
+typedef struct MttcgForceRcuNotifier {
|
|
|
+ Notifier notifier;
|
|
|
+ CPUState *cpu;
|
|
|
+} MttcgForceRcuNotifier;
|
|
|
+
|
|
|
+static void do_nothing(CPUState *cpu, run_on_cpu_data d)
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+static void mttcg_force_rcu(Notifier *notify, void *data)
|
|
|
+{
|
|
|
+ CPUState *cpu = container_of(notify, MttcgForceRcuNotifier, notifier)->cpu;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Called with rcu_registry_lock held, using async_run_on_cpu() ensures
|
|
|
+ * that there are no deadlocks.
|
|
|
+ */
|
|
|
+ async_run_on_cpu(cpu, do_nothing, RUN_ON_CPU_NULL);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* In the multi-threaded case each vCPU has its own thread. The TLS
|
|
|
* variable current_cpu can be used deep in the code to find the
|
|
@@ -43,12 +64,16 @@
|
|
|
|
|
|
static void *mttcg_cpu_thread_fn(void *arg)
|
|
|
{
|
|
|
+ MttcgForceRcuNotifier force_rcu;
|
|
|
CPUState *cpu = arg;
|
|
|
|
|
|
assert(tcg_enabled());
|
|
|
g_assert(!icount_enabled());
|
|
|
|
|
|
rcu_register_thread();
|
|
|
+ force_rcu.notifier.notify = mttcg_force_rcu;
|
|
|
+ force_rcu.cpu = cpu;
|
|
|
+ rcu_add_force_rcu_notifier(&force_rcu.notifier);
|
|
|
tcg_register_thread();
|
|
|
|
|
|
qemu_mutex_lock_iothread();
|
|
@@ -100,6 +125,7 @@ static void *mttcg_cpu_thread_fn(void *arg)
|
|
|
|
|
|
tcg_cpus_destroy(cpu);
|
|
|
qemu_mutex_unlock_iothread();
|
|
|
+ rcu_remove_force_rcu_notifier(&force_rcu.notifier);
|
|
|
rcu_unregister_thread();
|
|
|
return NULL;
|
|
|
}
|