From nobody Tue Apr 30 16:10:14 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 150186547797085.1826550683802; Fri, 4 Aug 2017 09:51:17 -0700 (PDT) Received: from localhost ([::1]:60147 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ddfoi-0007Hz-DH for importer@patchew.org; Fri, 04 Aug 2017 12:51:16 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55489) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ddfFb-00046X-Ns for qemu-devel@nongnu.org; Fri, 04 Aug 2017 12:15:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ddfFY-0002Yh-Ds for qemu-devel@nongnu.org; Fri, 04 Aug 2017 12:14:59 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59466) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ddfFY-0002YE-4L for qemu-devel@nongnu.org; Fri, 04 Aug 2017 12:14:56 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 317BA20A9B for ; Fri, 4 Aug 2017 16:14:55 +0000 (UTC) Received: from donizetti.redhat.com (ovpn-116-109.ams2.redhat.com [10.36.116.109]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5C5028FBF3; Fri, 4 Aug 2017 16:14:54 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 317BA20A9B Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=pbonzini@redhat.com From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Fri, 4 Aug 2017 18:14:51 +0200 Message-Id: <20170804161452.17413-2-pbonzini@redhat.com> In-Reply-To: <20170804161452.17413-1-pbonzini@redhat.com> References: <20170804161452.17413-1-pbonzini@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Fri, 04 Aug 2017 16:14:55 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 1/2] rcu: completely disable pthread_atfork callbacks as soon as possible X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dgilbert@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Because of -daemonize, system mode QEMU sometimes needs to fork() and keep RCU enabled in the child. However, there is a possible deadlock with synchronize_rcu: - the CPU thread is inside a RCU critical section and wants to take the BQL in order to do MMIO - the monitor thread, which is owning the BQL, calls rcu_init_lock which tries to take the rcu_sync_lock - the call_rcu thread has taken rcu_sync_lock in synchronize_rcu, but synchronize_rcu needs the CPU thread to end the critical section before returning. This cannot happen for user-mode emulation, because it does not have a BQL. To fix it, assume that system mode QEMU only forks in preparation for exec (except when daemonizing) and disable pthread_atfork as soon as the double fork has happened. Reported-by: David Gilbert Signed-off-by: Paolo Bonzini Tested-by: Dr. David Alan Gilbert --- include/qemu/rcu.h | 6 ++++++ util/rcu.c | 20 ++++++++++++++++++++ vl.c | 1 + 3 files changed, 27 insertions(+) diff --git a/include/qemu/rcu.h b/include/qemu/rcu.h index 83ae2808be..c0da9907e8 100644 --- a/include/qemu/rcu.h +++ b/include/qemu/rcu.h @@ -105,6 +105,12 @@ extern void synchronize_rcu(void); */ extern void rcu_register_thread(void); extern void rcu_unregister_thread(void); + +/* + * Support for fork(). fork() support is enabled at startup. + */ +extern void rcu_enable_atfork(void); +extern void rcu_disable_atfork(void); extern void rcu_after_fork(void); =20 struct rcu_head; diff --git a/util/rcu.c b/util/rcu.c index 9adc5e4a36..2142ddd93b 100644 --- a/util/rcu.c +++ b/util/rcu.c @@ -318,15 +318,35 @@ static void rcu_init_complete(void) rcu_register_thread(); } =20 +static int atfork_depth =3D 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); } =20 static void rcu_init_unlock(void) { + if (atfork_depth < 1) { + return; + } + qemu_mutex_unlock(&rcu_registry_lock); qemu_mutex_unlock(&rcu_sync_lock); } diff --git a/vl.c b/vl.c index 99fcfa0442..8967115514 100644 --- a/vl.c +++ b/vl.c @@ -4121,6 +4121,7 @@ int main(int argc, char **argv, char **envp) set_memory_options(&ram_slots, &maxram_size, machine_class); =20 os_daemonize(); + rcu_disable_atfork(); =20 if (pid_file && qemu_create_pidfile(pid_file) !=3D 0) { error_report("could not acquire pid file: %s", strerror(errno)); --=20 2.13.3 From nobody Tue Apr 30 16:10:14 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1501865333928290.89436907060497; Fri, 4 Aug 2017 09:48:53 -0700 (PDT) Received: from localhost ([::1]:59576 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ddfmN-0004Xe-OM for importer@patchew.org; Fri, 04 Aug 2017 12:48:51 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55491) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ddfFb-00046Z-OV for qemu-devel@nongnu.org; Fri, 04 Aug 2017 12:15:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ddfFZ-0002ZY-Ki for qemu-devel@nongnu.org; Fri, 04 Aug 2017 12:14:59 -0400 Received: from mx1.redhat.com ([209.132.183.28]:38970) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ddfFZ-0002Yq-E9 for qemu-devel@nongnu.org; Fri, 04 Aug 2017 12:14:57 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6FB26552E9 for ; Fri, 4 Aug 2017 16:14:56 +0000 (UTC) Received: from donizetti.redhat.com (ovpn-116-109.ams2.redhat.com [10.36.116.109]) by smtp.corp.redhat.com (Postfix) with ESMTP id 806998FBF0; Fri, 4 Aug 2017 16:14:55 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 6FB26552E9 Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=pbonzini@redhat.com From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Fri, 4 Aug 2017 18:14:52 +0200 Message-Id: <20170804161452.17413-3-pbonzini@redhat.com> In-Reply-To: <20170804161452.17413-1-pbonzini@redhat.com> References: <20170804161452.17413-1-pbonzini@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Fri, 04 Aug 2017 16:14:56 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 2/2] Revert "rcu: do not create thread in pthread_atfork callback" X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dgilbert@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This reverts commit a59629fcc6f603e19b516dc08f75334e5c480bd0. This is not needed anymore because the IOThread mutex is not "magic" anymore (need not kick the CPU thread) and also because fork callbacks are only enabled at the very beginning of QEMU's execution. Signed-off-by: Paolo Bonzini --- include/qemu/rcu.h | 1 - linux-user/syscall.c | 1 - os-posix.c | 2 -- util/rcu.c | 10 +++++++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/qemu/rcu.h b/include/qemu/rcu.h index c0da9907e8..f19413d649 100644 --- a/include/qemu/rcu.h +++ b/include/qemu/rcu.h @@ -111,7 +111,6 @@ extern void rcu_unregister_thread(void); */ extern void rcu_enable_atfork(void); extern void rcu_disable_atfork(void); -extern void rcu_after_fork(void); =20 struct rcu_head; typedef void RCUCBFunc(struct rcu_head *head); diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 54343c06be..9b6364a266 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -6354,7 +6354,6 @@ static int do_fork(CPUArchState *env, unsigned int fl= ags, abi_ulong newsp, ret =3D fork(); if (ret =3D=3D 0) { /* Child Process. */ - rcu_after_fork(); cpu_clone_regs(env, newsp); fork_end(1); /* There is a race condition here. The parent process could diff --git a/os-posix.c b/os-posix.c index c6ddb7d830..92e9d85215 100644 --- a/os-posix.c +++ b/os-posix.c @@ -34,7 +34,6 @@ #include "sysemu/sysemu.h" #include "net/slirp.h" #include "qemu-options.h" -#include "qemu/rcu.h" #include "qemu/error-report.h" #include "qemu/log.h" #include "qemu/cutils.h" @@ -249,7 +248,6 @@ void os_daemonize(void) signal(SIGTSTP, SIG_IGN); signal(SIGTTOU, SIG_IGN); signal(SIGTTIN, SIG_IGN); - rcu_after_fork(); } } =20 diff --git a/util/rcu.c b/util/rcu.c index 2142ddd93b..ca5a63e36a 100644 --- a/util/rcu.c +++ b/util/rcu.c @@ -350,18 +350,22 @@ static void rcu_init_unlock(void) qemu_mutex_unlock(&rcu_registry_lock); qemu_mutex_unlock(&rcu_sync_lock); } -#endif =20 -void rcu_after_fork(void) +static void rcu_init_child(void) { + if (atfork_depth < 1) { + return; + } + memset(®istry, 0, sizeof(registry)); rcu_init_complete(); } +#endif =20 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(); } --=20 2.13.3