aboutsummaryrefslogtreecommitdiff
path: root/util/rcu.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-08-08 16:32:54 +0100
committerPeter Maydell <peter.maydell@linaro.org>2017-08-08 16:32:54 +0100
commite42590c22a3b88f1cfcb7288f477b38200f5ae8c (patch)
tree5c6a0aea5a298d207f0fb4d04859380bbc113704 /util/rcu.c
parent53b080fa83c35d22cc94c730346fb2c53138d786 (diff)
parentf5048cb7517348a20ba202e435e1006a8f5001cf (diff)
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* --help/--version improvements (Eric) * GCC 7 workaround (Greg) * Small SCSI fix (Hannes) * SSE 4.1 fix (Joseph) * RCU deadlock fix (myself) # gpg: Signature made Tue 08 Aug 2017 16:28:56 BST # gpg: using RSA key 0xBFFBD25F78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: maint: Include bug-reporting info in --help output qga: Give more --version information qemu-io: Give more --version information qemu-img: Sort sub-command names in --help target/i386: set rip_offset for some SSE4.1 instructions scsi: clarify sense codes for LUN0 emulation kvm: workaround build break on gcc-7.1.1 / fedora26 Revert "rcu: do not create thread in pthread_atfork callback" rcu: completely disable pthread_atfork callbacks as soon as possible Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'util/rcu.c')
-rw-r--r--util/rcu.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/util/rcu.c b/util/rcu.c
index 9adc5e4a36..ca5a63e36a 100644
--- a/util/rcu.c
+++ b/util/rcu.c
@@ -318,30 +318,54 @@ static void rcu_init_complete(void)
rcu_register_thread();
}
+static int atfork_depth = 1;
+
+void rcu_enable_atfork(void)
+{
+ atfork_depth++;
+}
+
+void rcu_disable_atfork(void)
+{
+ atfork_depth--;
+}
+
#ifdef CONFIG_POSIX
static void rcu_init_lock(void)
{
+ if (atfork_depth < 1) {
+ return;
+ }
+
qemu_mutex_lock(&rcu_sync_lock);
qemu_mutex_lock(&rcu_registry_lock);
}
static void rcu_init_unlock(void)
{
+ if (atfork_depth < 1) {
+ return;
+ }
+
qemu_mutex_unlock(&rcu_registry_lock);
qemu_mutex_unlock(&rcu_sync_lock);
}
-#endif
-void rcu_after_fork(void)
+static void rcu_init_child(void)
{
+ if (atfork_depth < 1) {
+ return;
+ }
+
memset(&registry, 0, sizeof(registry));
rcu_init_complete();
}
+#endif
static void __attribute__((__constructor__)) rcu_init(void)
{
#ifdef CONFIG_POSIX
- pthread_atfork(rcu_init_lock, rcu_init_unlock, rcu_init_unlock);
+ pthread_atfork(rcu_init_lock, rcu_init_unlock, rcu_init_child);
#endif
rcu_init_complete();
}