From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-sn1nam02on0094.outbound.protection.outlook.com ([104.47.36.94]:35040 "EHLO NAM02-SN1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S932536AbeDIAe6 (ORCPT ); Sun, 8 Apr 2018 20:34:58 -0400 From: Sasha Levin To: "stable@vger.kernel.org" , "linux-kernel@vger.kernel.org" CC: "Paul E. McKenney" , Sasha Levin Subject: [PATCH AUTOSEL for 4.4 008/162] rcu: Make synchronize_rcu_mult() check for duplicates Date: Mon, 9 Apr 2018 00:27:48 +0000 Message-ID: <20180409002738.163941-8-alexander.levin@microsoft.com> References: <20180409002738.163941-1-alexander.levin@microsoft.com> In-Reply-To: <20180409002738.163941-1-alexander.levin@microsoft.com> Content-Language: en-US Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Sender: stable-owner@vger.kernel.org List-ID: From: "Paul E. McKenney" [ Upstream commit 68ab0b4263224157f4d0c0e42854169a183d7534 ] Currently, doing synchronize_rcu_mult(call_rcu, call_rcu) might (or might not) wait for two RCU grace periods. One approach is of course "don't do that!", but in CONFIG_PREEMPT=3Dn kernels, synchronize_rcu_mult(call_rcu, call_rcu_sched) does exactly that. This results in an ugly #ifdef in sched_cpu_deactivate(). This commit therefore makes __wait_rcu_gp() check for duplicates, which in turn allows duplicates to be passed to synchronize_rcu_mult() without risk of waiting twice on the same type of grace period. Signed-off-by: Paul E. McKenney Signed-off-by: Sasha Levin --- kernel/rcu/update.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c index 5f748c5a40f0..d98acb903325 100644 --- a/kernel/rcu/update.c +++ b/kernel/rcu/update.c @@ -324,6 +324,7 @@ void __wait_rcu_gp(bool checktiny, int n, call_rcu_func= _t *crcu_array, struct rcu_synchronize *rs_array) { int i; + int j; =20 /* Initialize and register callbacks for each flavor specified. */ for (i =3D 0; i < n; i++) { @@ -335,7 +336,11 @@ void __wait_rcu_gp(bool checktiny, int n, call_rcu_fun= c_t *crcu_array, } init_rcu_head_on_stack(&rs_array[i].head); init_completion(&rs_array[i].completion); - (crcu_array[i])(&rs_array[i].head, wakeme_after_rcu); + for (j =3D 0; j < i; j++) + if (crcu_array[j] =3D=3D crcu_array[i]) + break; + if (j =3D=3D i) + (crcu_array[i])(&rs_array[i].head, wakeme_after_rcu); } =20 /* Wait for all callbacks to be invoked. */ @@ -344,7 +349,11 @@ void __wait_rcu_gp(bool checktiny, int n, call_rcu_fun= c_t *crcu_array, (crcu_array[i] =3D=3D call_rcu || crcu_array[i] =3D=3D call_rcu_bh)) continue; - wait_for_completion(&rs_array[i].completion); + for (j =3D 0; j < i; j++) + if (crcu_array[j] =3D=3D crcu_array[i]) + break; + if (j =3D=3D i) + wait_for_completion(&rs_array[i].completion); destroy_rcu_head_on_stack(&rs_array[i].head); } } --=20 2.15.1