From patchwork Mon Mar 10 18:38:01 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Paul E. McKenney" X-Patchwork-Id: 14010540 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 60BC223314B; Mon, 10 Mar 2025 18:38:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741631892; cv=none; b=m+TRRHB+aGz5fIEyw9YGgPbmZDSyprzrmhzOckeiO8bN1gye8PeBo4gXETj38TgP1vWRpDBhDHVfCrjE7IFo9DvRSdaTqCbie0rYb/4D94R6MGloUTcKYJj/q3LnWN9QUEXD+cSZmzI4fFrbjD2P8OzN81VPaLmh8j5PYi1MXIU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741631892; c=relaxed/simple; bh=77AYLHKjJDUAxlPSNSjE5Yx8FldJR4VJKjnY8y5KFC8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=glNHExND8i3Wmunv00L1lTO64p3H52iZ74ivssblO0yHsk1bV/oBlbeAiVE2Xgg4LKMGW6/D//3+9qiVvTBwJMqo6eGGMdUvNRa3SLCL4ptmnZz1Qb8O7XPluGIknzYyp4EnEjIjZztRCP8prmIWv3drIqyz20EJ1Ji/On6rGCA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=W8NzDphX; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="W8NzDphX" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D2665C4CEE5; Mon, 10 Mar 2025 18:38:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1741631891; bh=77AYLHKjJDUAxlPSNSjE5Yx8FldJR4VJKjnY8y5KFC8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=W8NzDphXo/nNkSy2eE9KbOus63p6o6k/4t1IVYntijYbmyxZJlVJ2lX3dtAU41WeM OLLR6SREBaAvk1MWsGMqCErLVHdM/CmaJ9Vj+Vif2CHNER9hb3BuZTCJeDQgpVP4xw JwHYOM9emfgViENCO1xd6Ijvjt0zFjGcNogIRWaQ8WNGjKVURkhWttDS8qRXyvafUA HInMTI/wluAjpPCG5O7v7FcGCpDRptgfQrTKTR7EMRmirja357w7S+TlHYX/7+N2dP UqIymHEnO86xnuKklz9D6sqf12qlLVA0iTAiXqLc67ombhVHtYM1/c19ST1Hm1gN+3 WNOMrYvdWpCHg== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 8DBAACE079A; Mon, 10 Mar 2025 11:38:11 -0700 (PDT) From: "Paul E. McKenney" To: rcu@vger.kernel.org Cc: linux-kernel@vger.kernel.org, kernel-team@meta.com, rostedt@goodmis.org, "Paul E. McKenney" Subject: [PATCH 1/9] rcutorture: Make srcu_lockdep.sh check kernel Kconfig Date: Mon, 10 Mar 2025 11:38:01 -0700 Message-Id: <20250310183809.3576320-1-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <4bf081c8-9299-4ee3-b337-d5b751cef6be@paulmck-laptop> References: <4bf081c8-9299-4ee3-b337-d5b751cef6be@paulmck-laptop> Precedence: bulk X-Mailing-List: rcu@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The srcu_lockdep.sh currently blindly trusts the rcutorture SRCU-P scenario to build its kernel with lockdep enabled. Of course, this dependency might not be obvious to someone rebalancing SRCU scenarios. This commit therefore adds code to srcu_lockdep.sh that verifies that the .config file has lockdep enabled. Signed-off-by: Paul E. McKenney --- .../testing/selftests/rcutorture/bin/srcu_lockdep.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/rcutorture/bin/srcu_lockdep.sh b/tools/testing/selftests/rcutorture/bin/srcu_lockdep.sh index 2db12c5cad9c6..b94f6d3445c6c 100755 --- a/tools/testing/selftests/rcutorture/bin/srcu_lockdep.sh +++ b/tools/testing/selftests/rcutorture/bin/srcu_lockdep.sh @@ -39,8 +39,9 @@ do shift done -err= nerrs=0 + +# Test lockdep's handling of deadlocks. for d in 0 1 do for t in 0 1 2 @@ -52,6 +53,12 @@ do tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration 5s --configs "SRCU-P" --kconfig "CONFIG_FORCE_NEED_SRCU_NMI_SAFE=y" --bootargs "rcutorture.test_srcu_lockdep=$val rcutorture.reader_flavor=0x2" --trust-make --datestamp "$ds/$val" > "$T/kvm.sh.out" 2>&1 ret=$? mv "$T/kvm.sh.out" "$RCUTORTURE/res/$ds/$val" + if ! grep -q '^CONFIG_PROVE_LOCKING=y' .config + then + echo "rcu_torture_init_srcu_lockdep:Error: CONFIG_PROVE_LOCKING disabled in rcutorture SRCU-P scenario" + nerrs=$((nerrs+1)) + err=1 + fi if test "$d" -ne 0 && test "$ret" -eq 0 then err=1 @@ -71,6 +78,8 @@ do done done done + +# Set up exit code. if test "$nerrs" -ne 0 then exit 1 From patchwork Mon Mar 10 18:38:02 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Paul E. McKenney" X-Patchwork-Id: 14010538 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 60CA9233D89; Mon, 10 Mar 2025 18:38:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741631892; cv=none; b=Y2A8vS+azGcA1vEf+GAL7ak2j9iJznJwKdhNbwYWdl7yin+tr5ChyVU2eyBw685yACU0dOfww+jXsKf0YiaTv5gWxrBus2aijzEBhkf3JidSC9voBWH12zICFM9fmMJ5rToMmlccBv5tVFpCR/jmxo3MaHCtNkTQtFnoDm/QPjc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741631892; c=relaxed/simple; bh=Vh4wzubR/QtoBshTTizJkq+P2DARWdEyUI69hQkMTBQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=F/YPnSXhh3udKnJQAVzVu++jPc/drtDAPrHOHcRLx1YZbiGbii1eJKvF0ltD96kYH3tyf4TjVRBJqGvzLmvbHau0HzG4QGB/hF8fr7eSXmIACjFW/C1N2nzIK5eNc7oRzjG8Ki8ut3SriYXT6+6sNPo3WEhqm0XGKDETB3vEjuY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lIqZxU0+; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="lIqZxU0+" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EB252C4CEEC; Mon, 10 Mar 2025 18:38:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1741631892; bh=Vh4wzubR/QtoBshTTizJkq+P2DARWdEyUI69hQkMTBQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lIqZxU0+NmS41KTNQVcszhGvzIkJ/3r2qDeO3gIgrJi7s8GE5voOo68A4eiq5gW3C PO/SOFQccUXXqjvR2OmYC84/CMOcd429ovhjVy2mlqb+mQefD9gudfXelCjlhOokfD lx1L4jB14j+v7IqaJLBTAZffrZxr2gUKd6vkoZZQtpcp1m+G8mxIizoPYaDWurjvYq TEm/2o70WiqyISkzMWzcybYUddv2hAHQKHeClK8stAqKNyCY9mkDQQoVCot8xQI6cG fcNToPt3pqqz4mQMTeS8Y0FZiPHCOm/ov4XFKfgZ8OtbcKaWiKMxU45zeU4fOBaa+l Hf7L6MGZgWalA== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 90F72CE07A0; Mon, 10 Mar 2025 11:38:11 -0700 (PDT) From: "Paul E. McKenney" To: rcu@vger.kernel.org Cc: linux-kernel@vger.kernel.org, kernel-team@meta.com, rostedt@goodmis.org, "Paul E. McKenney" Subject: [PATCH 2/9] rcutorture: Make srcu_lockdep.sh check reader-conflict handling Date: Mon, 10 Mar 2025 11:38:02 -0700 Message-Id: <20250310183809.3576320-2-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <4bf081c8-9299-4ee3-b337-d5b751cef6be@paulmck-laptop> References: <4bf081c8-9299-4ee3-b337-d5b751cef6be@paulmck-laptop> Precedence: bulk X-Mailing-List: rcu@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Mixing different flavors of RCU readers is forbidden, for example, you should not use srcu_read_lock() and srcu_read_lock_nmisafe() on the same srcu_struct structure. There are checks for this, but these checks are not tested on a regular basis. This commit therefore adds such tests to srcu_lockdep.sh. Signed-off-by: Paul E. McKenney --- .../selftests/rcutorture/bin/srcu_lockdep.sh | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tools/testing/selftests/rcutorture/bin/srcu_lockdep.sh b/tools/testing/selftests/rcutorture/bin/srcu_lockdep.sh index b94f6d3445c6c..208be7d09a612 100755 --- a/tools/testing/selftests/rcutorture/bin/srcu_lockdep.sh +++ b/tools/testing/selftests/rcutorture/bin/srcu_lockdep.sh @@ -79,6 +79,37 @@ do done done +# Test lockdep-enabled testing of mixed SRCU readers. +for val in 0x1 0xf +do + err= + tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration 5s --configs "SRCU-P" --kconfig "CONFIG_FORCE_NEED_SRCU_NMI_SAFE=y" --bootargs "rcutorture.reader_flavor=$val" --trust-make --datestamp "$ds/$val" > "$T/kvm.sh.out" 2>&1 + ret=$? + mv "$T/kvm.sh.out" "$RCUTORTURE/res/$ds/$val" + if ! grep -q '^CONFIG_PROVE_LOCKING=y' .config + then + echo "rcu_torture_init_srcu_lockdep:Error: CONFIG_PROVE_LOCKING disabled in rcutorture SRCU-P scenario" + nerrs=$((nerrs+1)) + err=1 + fi + if test "$val" -eq 0xf && test "$ret" -eq 0 + then + err=1 + echo -n Unexpected success for > "$RCUTORTURE/res/$ds/$val/kvm.sh.err" + fi + if test "$val" -eq 0x1 && test "$ret" -ne 0 + then + err=1 + echo -n Unexpected failure for > "$RCUTORTURE/res/$ds/$val/kvm.sh.err" + fi + if test -n "$err" + then + grep "rcu_torture_init_srcu_lockdep: test_srcu_lockdep = " "$RCUTORTURE/res/$ds/$val/SRCU-P/console.log" | sed -e 's/^.*rcu_torture_init_srcu_lockdep://' >> "$RCUTORTURE/res/$ds/$val/kvm.sh.err" + cat "$RCUTORTURE/res/$ds/$val/kvm.sh.err" + nerrs=$((nerrs+1)) + fi +done + # Set up exit code. if test "$nerrs" -ne 0 then From patchwork Mon Mar 10 18:38:03 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Paul E. McKenney" X-Patchwork-Id: 14010542 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 60C4423371B; Mon, 10 Mar 2025 18:38:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741631892; cv=none; b=Mw9t2gYg4l+/eiMJcUv2SPKpRX0EDm4xuftUQtjcPN+Bue89xtSkws0b47FYgt9qgURrEFakvwDXCabs4mQkv1AX6hYCLSYaBBvV7tM8VkZueHW9HwtzEhrwFWiuYF+DqzMkglYsWAuwTwB1KaF5LpNM64uSdx7RfPW+Izqw0rs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741631892; c=relaxed/simple; bh=4Ai2javJFGPUL16QmZ1bVGq4ISa/G87CeO9P6yL8XAA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=XfXarZPHvont1hsWv1+0dDo2GdMVJkjY8TmoWxfNxG3KzFolZZXD80mdeQwiq38v2yAcMzXk7gLQHi3tHkoWUhOXvWkAt4V+dOB0q4UsrmT2KvO4Yl8FbxKCHOiHPQlmz+UVVoOeCKV3lJo8LIWBXtkd3L5UelbHWSNd3ySM/Bw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BDLfrHwY; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="BDLfrHwY" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 088C2C4CEED; Mon, 10 Mar 2025 18:38:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1741631892; bh=4Ai2javJFGPUL16QmZ1bVGq4ISa/G87CeO9P6yL8XAA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BDLfrHwY9Sq+4Ui+ov+x/egSmKtmvuabz93XYo8ran771CSegTtBoLASxK7wk2mpY CyChnfpcTjvC3zV+J2bjPfxhTP8JWjqPlE/Z3gUetzJiw82smcLnS1RjGBEciwftn7 UXyjE/oETR3RKg2wA+3ZPa8/Rmpkc3nlxZW/bDjcdlu20NmFMb/SZwUbad4ZGf6hUT +e1KK3+i9mRmrgMO5aFgRNj1OvWC6S1WkmPbiUiyuJf1zST989GdWt6ahDMy410jXC UjVPSP4tWzYpSgIQd6caKXjZQpcXHeWtfiLdd4hSOvujIJSikjIjTdgN99MahqOm1J wTUH341zOdkLA== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 93AD0CE0F65; Mon, 10 Mar 2025 11:38:11 -0700 (PDT) From: "Paul E. McKenney" To: rcu@vger.kernel.org Cc: linux-kernel@vger.kernel.org, kernel-team@meta.com, rostedt@goodmis.org, "Paul E. McKenney" Subject: [PATCH 3/9] rcutorture: Split out beginning and end from rcu_torture_one_read() Date: Mon, 10 Mar 2025 11:38:03 -0700 Message-Id: <20250310183809.3576320-3-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <4bf081c8-9299-4ee3-b337-d5b751cef6be@paulmck-laptop> References: <4bf081c8-9299-4ee3-b337-d5b751cef6be@paulmck-laptop> Precedence: bulk X-Mailing-List: rcu@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The rcu_torture_one_read() function is designed for RCU readers that are confined to a task, such that a single thread of control extends from the beginning of a given RCU read-side critical section to its end. This does not suffice for things like srcu_down_read() and srcu_up_read(), where the critical section might start at task level and end in a timer handler. This commit therefore creates separate init_rcu_torture_one_read_state(), rcu_torture_one_read_start(), and rcu_torture_one_read_end() functions, along with a rcu_torture_one_read_state structure to coordinate their actions. These will be used to create tests for srcu_down_read() and friends. One caution: The caller to rcu_torture_one_read_start() must enter the initial read-side critical section prior to the call. This enables use of non-standard primitives such as srcu_down_read() while still using the same validation code. --- kernel/rcu/rcutorture.c | 124 ++++++++++++++++++++++++++-------------- 1 file changed, 81 insertions(+), 43 deletions(-) diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 65095664f5c5b..b0e96df636226 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -2164,53 +2164,70 @@ rcutorture_loop_extend(int *readstate, bool insoftirq, struct torture_random_sta return &rtrsp[j]; } -/* - * Do one read-side critical section, returning false if there was - * no data to read. Can be invoked both from process context and - * from a timer handler. - */ -static bool rcu_torture_one_read(struct torture_random_state *trsp, long myid) -{ - bool checkpolling = !(torture_random(trsp) & 0xfff); +struct rcu_torture_one_read_state { + bool checkpolling; unsigned long cookie; struct rcu_gp_oldstate cookie_full; - int i; unsigned long started; - unsigned long completed; - int newstate; struct rcu_torture *p; - int pipe_count; - bool preempted = false; - int readstate = 0; - struct rt_read_seg rtseg[RCUTORTURE_RDR_MAX_SEGS] = { { 0 } }; - struct rt_read_seg *rtrsp = &rtseg[0]; - struct rt_read_seg *rtrsp1; + int readstate; + struct rt_read_seg rtseg[RCUTORTURE_RDR_MAX_SEGS]; + struct rt_read_seg *rtrsp; unsigned long long ts; +}; - WARN_ON_ONCE(!rcu_is_watching()); - newstate = rcutorture_extend_mask(readstate, trsp); - rcutorture_one_extend(&readstate, newstate, myid < 0, trsp, rtrsp++); - if (checkpolling) { +static void init_rcu_torture_one_read_state(struct rcu_torture_one_read_state *rtorsp, + struct torture_random_state *trsp) +{ + memset(rtorsp, 0, sizeof(*rtorsp)); + rtorsp->checkpolling = !(torture_random(trsp) & 0xfff); + rtorsp->rtrsp = &rtorsp->rtseg[0]; +} + +/* + * Set up the first segment of a series of overlapping read-side + * critical sections. The caller must have actually initiated the + * outermost read-side critical section. + */ +static bool rcu_torture_one_read_start(struct rcu_torture_one_read_state *rtorsp, + struct torture_random_state *trsp, long myid) +{ + if (rtorsp->checkpolling) { if (cur_ops->get_gp_state && cur_ops->poll_gp_state) - cookie = cur_ops->get_gp_state(); + rtorsp->cookie = cur_ops->get_gp_state(); if (cur_ops->get_gp_state_full && cur_ops->poll_gp_state_full) - cur_ops->get_gp_state_full(&cookie_full); + cur_ops->get_gp_state_full(&rtorsp->cookie_full); } - started = cur_ops->get_gp_seq(); - ts = rcu_trace_clock_local(); - p = rcu_dereference_check(rcu_torture_current, + rtorsp->started = cur_ops->get_gp_seq(); + rtorsp->ts = rcu_trace_clock_local(); + rtorsp->p = rcu_dereference_check(rcu_torture_current, !cur_ops->readlock_held || cur_ops->readlock_held()); - if (p == NULL) { + if (rtorsp->p == NULL) { /* Wait for rcu_torture_writer to get underway */ - rcutorture_one_extend(&readstate, 0, myid < 0, trsp, rtrsp); + rcutorture_one_extend(&rtorsp->readstate, 0, myid < 0, trsp, rtorsp->rtrsp); return false; } - if (p->rtort_mbtest == 0) + if (rtorsp->p->rtort_mbtest == 0) atomic_inc(&n_rcu_torture_mberror); - rcu_torture_reader_do_mbchk(myid, p, trsp); - rtrsp = rcutorture_loop_extend(&readstate, myid < 0, trsp, rtrsp); + rcu_torture_reader_do_mbchk(myid, rtorsp->p, trsp); + return true; +} + +/* + * Complete the last segment of a series of overlapping read-side + * critical sections and check for errors. + */ +static void rcu_torture_one_read_end(struct rcu_torture_one_read_state *rtorsp, + struct torture_random_state *trsp, long myid) +{ + int i; + unsigned long completed; + int pipe_count; + bool preempted = false; + struct rt_read_seg *rtrsp1; + preempt_disable(); - pipe_count = READ_ONCE(p->rtort_pipe_count); + pipe_count = READ_ONCE(rtorsp->p->rtort_pipe_count); if (pipe_count > RCU_TORTURE_PIPE_LEN) { // Should not happen in a correct RCU implementation, // happens quite often for torture_type=busted. @@ -2218,28 +2235,28 @@ static bool rcu_torture_one_read(struct torture_random_state *trsp, long myid) } completed = cur_ops->get_gp_seq(); if (pipe_count > 1) { - do_trace_rcu_torture_read(cur_ops->name, &p->rtort_rcu, - ts, started, completed); + do_trace_rcu_torture_read(cur_ops->name, &rtorsp->p->rtort_rcu, + rtorsp->ts, rtorsp->started, completed); rcu_ftrace_dump(DUMP_ALL); } __this_cpu_inc(rcu_torture_count[pipe_count]); - completed = rcutorture_seq_diff(completed, started); + completed = rcutorture_seq_diff(completed, rtorsp->started); if (completed > RCU_TORTURE_PIPE_LEN) { /* Should not happen, but... */ completed = RCU_TORTURE_PIPE_LEN; } __this_cpu_inc(rcu_torture_batch[completed]); preempt_enable(); - if (checkpolling) { + if (rtorsp->checkpolling) { if (cur_ops->get_gp_state && cur_ops->poll_gp_state) - WARN_ONCE(cur_ops->poll_gp_state(cookie), + WARN_ONCE(cur_ops->poll_gp_state(rtorsp->cookie), "%s: Cookie check 2 failed %s(%d) %lu->%lu\n", __func__, rcu_torture_writer_state_getname(), rcu_torture_writer_state, - cookie, cur_ops->get_gp_state()); + rtorsp->cookie, cur_ops->get_gp_state()); if (cur_ops->get_gp_state_full && cur_ops->poll_gp_state_full) - WARN_ONCE(cur_ops->poll_gp_state_full(&cookie_full), + WARN_ONCE(cur_ops->poll_gp_state_full(&rtorsp->cookie_full), "%s: Cookie check 6 failed %s(%d) online %*pbl\n", __func__, rcu_torture_writer_state_getname(), @@ -2248,21 +2265,42 @@ static bool rcu_torture_one_read(struct torture_random_state *trsp, long myid) } if (cur_ops->reader_blocked) preempted = cur_ops->reader_blocked(); - rcutorture_one_extend(&readstate, 0, myid < 0, trsp, rtrsp); - WARN_ON_ONCE(readstate); + rcutorture_one_extend(&rtorsp->readstate, 0, myid < 0, trsp, rtorsp->rtrsp); + WARN_ON_ONCE(rtorsp->readstate); // This next splat is expected behavior if leakpointer, especially // for CONFIG_RCU_STRICT_GRACE_PERIOD=y kernels. - WARN_ON_ONCE(leakpointer && READ_ONCE(p->rtort_pipe_count) > 1); + WARN_ON_ONCE(leakpointer && READ_ONCE(rtorsp->p->rtort_pipe_count) > 1); /* If error or close call, record the sequence of reader protections. */ if ((pipe_count > 1 || completed > 1) && !xchg(&err_segs_recorded, 1)) { i = 0; - for (rtrsp1 = &rtseg[0]; rtrsp1 < rtrsp; rtrsp1++) + for (rtrsp1 = &rtorsp->rtseg[0]; rtrsp1 < rtorsp->rtrsp; rtrsp1++) err_segs[i++] = *rtrsp1; rt_read_nsegs = i; rt_read_preempted = preempted; } +} +/* + * Do one read-side critical section, returning false if there was + * no data to read. Can be invoked both from process context and + * from a timer handler. + */ +static bool rcu_torture_one_read(struct torture_random_state *trsp, long myid) +{ + int newstate; + struct rcu_torture_one_read_state rtors; + + WARN_ON_ONCE(!rcu_is_watching()); + init_rcu_torture_one_read_state(&rtors, trsp); + newstate = rcutorture_extend_mask(rtors.readstate, trsp); + rcutorture_one_extend(&rtors.readstate, newstate, myid < 0, trsp, rtors.rtrsp++); + if (!rcu_torture_one_read_start(&rtors, trsp, myid)) { + rcutorture_one_extend(&rtors.readstate, 0, myid < 0, trsp, rtors.rtrsp); + return false; + } + rtors.rtrsp = rcutorture_loop_extend(&rtors.readstate, myid < 0, trsp, rtors.rtrsp); + rcu_torture_one_read_end(&rtors, trsp, myid); return true; } From patchwork Mon Mar 10 18:38:04 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Paul E. McKenney" X-Patchwork-Id: 14010539 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 60AE617A2E8; Mon, 10 Mar 2025 18:38:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741631892; cv=none; b=PZ3UXwsgDVutX94B3gCq7Ayvz+UzcpA9fAbvxqJKwoC1ZpNCz6PLmQ5N6trif7E4zPngsX8waBM+cNgCFLiHEUp8RPBAHj/nnYHn5SK9SfDmTf5DV3OA6tqgq9f00Zh4+mzDUBonCIdX0JYlv3zmn9s7fl/KNaICjUjgwdygrhQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741631892; c=relaxed/simple; bh=9sDMN4XZIcJRgoHQjxyZQce37ueUrgjbAHGywNbSEVo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=AFln4PKVY1BNA+BXy42b0gdijN46TcGfTb/bQKd6GDEcskUQZ/1p1VVbuVjY76jDMqM9IdmuSzjR/6iGqUE9w9pgbKL4/ouH3t1KU+uHQP1kvnlMKnP5urQHWKYJXqHd6cQ3FkdFm0p/OiRG3VUIlXYiy/7m3KFWBkjtye8zpYM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kBraPChY; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="kBraPChY" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1A07AC4CEF0; Mon, 10 Mar 2025 18:38:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1741631892; bh=9sDMN4XZIcJRgoHQjxyZQce37ueUrgjbAHGywNbSEVo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kBraPChYmnALx5Y2wGL+tBRbECOLIs4TW2P4nZbpnFuKeO0FqxNljMlOuYV2vLPHR 8Qt756opii3LzhM9xrENH5OcEPorhFasrFb9rD/tSvfbU6jFUSlJOF6CjAslNFutlj 2z3xfeyQHn5DXbqDIttpaWgv48iQxsvUNFeyq2cxhik5AAbkMXruBV0NCRYxQctU+e WlJgXodlSLRsulWx/imFSqlIRIFcQxnv0vBClkr2B4hEx8dIo96d08Ofhsju3QQNPQ jgYb7O86WCqCvE/4zhxuUfmLulnGz1T9oAl0GRIhBInAd6/XPBVqPYsn2EfD0l6Nj2 sX442rE1AfN4g== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 9663DCE1163; Mon, 10 Mar 2025 11:38:11 -0700 (PDT) From: "Paul E. McKenney" To: rcu@vger.kernel.org Cc: linux-kernel@vger.kernel.org, kernel-team@meta.com, rostedt@goodmis.org, "Paul E. McKenney" , Sebastian Andrzej Siewior Subject: [PATCH 4/9] rcutorture: Make torture.sh --do-rt use CONFIG_PREEMPT_RT Date: Mon, 10 Mar 2025 11:38:04 -0700 Message-Id: <20250310183809.3576320-4-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <4bf081c8-9299-4ee3-b337-d5b751cef6be@paulmck-laptop> References: <4bf081c8-9299-4ee3-b337-d5b751cef6be@paulmck-laptop> Precedence: bulk X-Mailing-List: rcu@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The torture.sh --do-rt command-line parameter is intended to mimic -rt kernels. Now that CONFIG_PREEMPT_RT is upstream, this commit makes this mimicking more precise. Note that testing of RCU priority boosting is disabled in favor of forward-progress testing of RCU callbacks. If it turns out to be possible to make kernels built with CONFIG_PREEMPT_RT=y to tolerate testing of both, both will be enabled. Signed-off-by: Paul E. McKenney Cc: Sebastian Andrzej Siewior --- tools/testing/selftests/rcutorture/bin/torture.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/rcutorture/bin/torture.sh b/tools/testing/selftests/rcutorture/bin/torture.sh index 0447c4a00cc4d..9cabe505585ea 100755 --- a/tools/testing/selftests/rcutorture/bin/torture.sh +++ b/tools/testing/selftests/rcutorture/bin/torture.sh @@ -448,13 +448,17 @@ fi if test "$do_rt" = "yes" then + # In both runs, disable testing of RCU priority boosting because + # -rt doesn't like its interaction with testing of callback + # flooding. + # With all post-boot grace periods forced to normal. - torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000 rcupdate.rcu_normal=1" - torture_set "rcurttorture" tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration "$duration_rcutorture" --configs "TREE03" --trust-make + torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000 rcutorture.test_boost=0 rcupdate.rcu_normal=1" + torture_set "rcurttorture" tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration "$duration_rcutorture" --configs "TREE03" --kconfig "CONFIG_PREEMPT_LAZY=n CONFIG_PREEMPT_RT=y CONFIG_EXPERT=y" --trust-make # With all post-boot grace periods forced to expedited. - torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000 rcupdate.rcu_expedited=1" - torture_set "rcurttorture-exp" tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration "$duration_rcutorture" --configs "TREE03" --trust-make + torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000 rcutorture.test_boost=0 rcupdate.rcu_expedited=1" + torture_set "rcurttorture-exp" tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration "$duration_rcutorture" --configs "TREE03" --kconfig "CONFIG_PREEMPT_LAZY=n CONFIG_PREEMPT_RT=y CONFIG_EXPERT=y" --trust-make fi if test "$do_srcu_lockdep" = "yes" From patchwork Mon Mar 10 18:38:05 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Paul E. McKenney" X-Patchwork-Id: 14010541 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 60B5E22FF4E; Mon, 10 Mar 2025 18:38:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741631892; cv=none; b=KUXzCkoTVcrKKo3qo8efZ0PJ77fAmTWjNqZuLLz8l1KuSQaczmLxa8w9i/VLsecmBmLRCoVEP9Nkq1hyUxbdD40q3oP1O7677MQrroMD9epLN83wo9c1Wu+wGdroexmlGm28fcCkZ0So/mmwEeYDezKqgnyz2eUp3tv9T81eLdk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741631892; c=relaxed/simple; bh=PxckqoCCMs7XJtMT3z9A1/wSVHGdWWHIAtmoQbk4RO8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=pzIq6wt6+aFdfjajgX2CPrUNKWQoP9Lxau5WZr4cPfZhEJ6gbbA8n/ON66Gih6DDnO1Mw9VRpVmT6Cu063ay72fAy2W2su2TOolLo3oAOA7Dzssjr38fUcqmRHWWHbtfMuFATr3zZ4LN0QptW193INiHeGl+37qphudLsrqV/2A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=n3BC1LhX; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="n3BC1LhX" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 11CB0C4CEEF; Mon, 10 Mar 2025 18:38:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1741631892; bh=PxckqoCCMs7XJtMT3z9A1/wSVHGdWWHIAtmoQbk4RO8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=n3BC1LhXEPTWHoUTWtGsapV4HPR0hYKuNWU5bc3y5NoCco6YBopmisbtyF9+pvjIU xrJg1Zj43NEPbrrCPsXFmrrShAxKNQOvGazVmxDeEe+yS5hOKdoiEHyC5rWm85Rpik Vr7fcNFOnVU3VG4Nq0L1GzFZ6fPBIz9hq9NYFrN/Urv+CjMvlx3sLSAdHwpHfntCb+ DukE65pewF56GBIRWsF/6D/nn8zteKMZjCxI1AqgFB0x+j8nQNWSfYRez5ilpd7uuQ tVUgNTATSxmVyZ/poGnY2XZnmY4hvnFAGHEqbLhxMnPsPGy3sok39W8tvmlU1LiZVk i/HKsLdLlDlGw== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 9944BCE130D; Mon, 10 Mar 2025 11:38:11 -0700 (PDT) From: "Paul E. McKenney" To: rcu@vger.kernel.org Cc: linux-kernel@vger.kernel.org, kernel-team@meta.com, rostedt@goodmis.org, "Paul E. McKenney" Subject: [PATCH 5/9] rcutorture: Add tests for SRCU up/down reader primitives Date: Mon, 10 Mar 2025 11:38:05 -0700 Message-Id: <20250310183809.3576320-5-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <4bf081c8-9299-4ee3-b337-d5b751cef6be@paulmck-laptop> References: <4bf081c8-9299-4ee3-b337-d5b751cef6be@paulmck-laptop> Precedence: bulk X-Mailing-List: rcu@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This commit adds a new rcutorture.n_up_down kernel boot parameter that specifies the number of outstanding SRCU up/down readers, which begin in kthread context and end in an hrtimer handler. There is a new kthread ("rcu_torture_updown") that scans an per-reader array looking for elements whose readers have ended. This kthread sleeps between one and two milliseconds between consecutive scans. [ paulmck: Apply kernel test robot feedback. ] Signed-off-by: Paul E. McKenney --- kernel/rcu/rcutorture.c | 227 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 208 insertions(+), 19 deletions(-) diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index b0e96df636226..6afcd33e724ba 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -55,22 +55,24 @@ MODULE_DESCRIPTION("Read-Copy Update module-based torture test facility"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Paul E. McKenney and Josh Triplett "); -/* Bits for ->extendables field, extendables param, and related definitions. */ -#define RCUTORTURE_RDR_SHIFT_1 8 /* Put SRCU index in upper bits. */ -#define RCUTORTURE_RDR_MASK_1 (0xff << RCUTORTURE_RDR_SHIFT_1) -#define RCUTORTURE_RDR_SHIFT_2 16 /* Put SRCU index in upper bits. */ -#define RCUTORTURE_RDR_MASK_2 (0xff << RCUTORTURE_RDR_SHIFT_2) -#define RCUTORTURE_RDR_BH 0x01 /* Extend readers by disabling bh. */ -#define RCUTORTURE_RDR_IRQ 0x02 /* ... disabling interrupts. */ -#define RCUTORTURE_RDR_PREEMPT 0x04 /* ... disabling preemption. */ -#define RCUTORTURE_RDR_RBH 0x08 /* ... rcu_read_lock_bh(). */ -#define RCUTORTURE_RDR_SCHED 0x10 /* ... rcu_read_lock_sched(). */ -#define RCUTORTURE_RDR_RCU_1 0x20 /* ... entering another RCU reader. */ -#define RCUTORTURE_RDR_RCU_2 0x40 /* ... entering another RCU reader. */ -#define RCUTORTURE_RDR_NBITS 7 /* Number of bits defined above. */ -#define RCUTORTURE_MAX_EXTEND \ +// Bits for ->extendables field, extendables param, and related definitions. +#define RCUTORTURE_RDR_SHIFT_1 8 // Put SRCU index in upper bits. +#define RCUTORTURE_RDR_MASK_1 (0xff << RCUTORTURE_RDR_SHIFT_1) +#define RCUTORTURE_RDR_SHIFT_2 16 // Put SRCU index in upper bits. +#define RCUTORTURE_RDR_MASK_2 (0xff << RCUTORTURE_RDR_SHIFT_2) +#define RCUTORTURE_RDR_BH 0x01 // Extend readers by disabling bh. +#define RCUTORTURE_RDR_IRQ 0x02 // ... disabling interrupts. +#define RCUTORTURE_RDR_PREEMPT 0x04 // ... disabling preemption. +#define RCUTORTURE_RDR_RBH 0x08 // ... rcu_read_lock_bh(). +#define RCUTORTURE_RDR_SCHED 0x10 // ... rcu_read_lock_sched(). +#define RCUTORTURE_RDR_RCU_1 0x20 // ... entering another RCU reader. +#define RCUTORTURE_RDR_RCU_2 0x40 // ... entering another RCU reader. +#define RCUTORTURE_RDR_UPDOWN 0x80 // ... up-read from task, down-read from timer. + // Note: Manual start, automatic end. +#define RCUTORTURE_RDR_NBITS 8 // Number of bits defined above. +#define RCUTORTURE_MAX_EXTEND \ (RCUTORTURE_RDR_BH | RCUTORTURE_RDR_IRQ | RCUTORTURE_RDR_PREEMPT | \ - RCUTORTURE_RDR_RBH | RCUTORTURE_RDR_SCHED) + RCUTORTURE_RDR_RBH | RCUTORTURE_RDR_SCHED) // Intentionally omit RCUTORTURE_RDR_UPDOWN. #define RCUTORTURE_RDR_ALLBITS \ (RCUTORTURE_MAX_EXTEND | RCUTORTURE_RDR_RCU_1 | RCUTORTURE_RDR_RCU_2 | \ RCUTORTURE_RDR_MASK_1 | RCUTORTURE_RDR_MASK_2) @@ -110,6 +112,7 @@ torture_param(bool, gp_sync, false, "Use synchronous GP wait primitives"); torture_param(int, irqreader, 1, "Allow RCU readers from irq handlers"); torture_param(int, leakpointer, 0, "Leak pointer dereferences from readers"); torture_param(int, n_barrier_cbs, 0, "# of callbacks/kthreads for barrier testing"); +torture_param(int, n_up_down, 32, "# of concurrent up/down hrtimer-based RCU readers"); torture_param(int, nfakewriters, 4, "Number of RCU fake writer threads"); torture_param(int, nreaders, -1, "Number of RCU reader threads"); torture_param(int, object_debug, 0, "Enable debug-object double call_rcu() testing"); @@ -152,6 +155,7 @@ static int nrealfakewriters; static struct task_struct *writer_task; static struct task_struct **fakewriter_tasks; static struct task_struct **reader_tasks; +static struct task_struct *updown_task; static struct task_struct **nocb_tasks; static struct task_struct *stats_task; static struct task_struct *fqs_task; @@ -374,6 +378,8 @@ struct rcu_torture_ops { void (*readunlock)(int idx); int (*readlock_held)(void); // lockdep. int (*readlock_nesting)(void); // actual nesting, if available, -1 if not. + int (*down_read)(void); + void (*up_read)(int idx); unsigned long (*get_gp_seq)(void); unsigned long (*gp_diff)(unsigned long new, unsigned long old); void (*deferred_free)(struct rcu_torture *p); @@ -421,6 +427,7 @@ struct rcu_torture_ops { int no_pi_lock; int debug_objects; int start_poll_irqsoff; + int have_up_down; const char *name; }; @@ -754,6 +761,50 @@ static int torture_srcu_read_lock_held(void) return srcu_read_lock_held(srcu_ctlp); } +static bool srcu_torture_have_up_down(void) +{ + int rf = reader_flavor; + + if (!rf) + rf = SRCU_READ_FLAVOR_NORMAL; + return !!(cur_ops->have_up_down & rf); +} + +static int srcu_torture_down_read(void) +{ + int idx; + struct srcu_ctr __percpu *scp; + + WARN_ON_ONCE(reader_flavor & ~SRCU_READ_FLAVOR_ALL); + WARN_ON_ONCE(reader_flavor & (reader_flavor - 1)); + + if ((reader_flavor & SRCU_READ_FLAVOR_NORMAL) || !(reader_flavor & SRCU_READ_FLAVOR_ALL)) { + idx = srcu_down_read(srcu_ctlp); + WARN_ON_ONCE(idx & ~0x1); + return idx; + } + if (reader_flavor & SRCU_READ_FLAVOR_FAST) { + scp = srcu_down_read_fast(srcu_ctlp); + idx = __srcu_ptr_to_ctr(srcu_ctlp, scp); + WARN_ON_ONCE(idx & ~0x1); + return idx << 3; + } + WARN_ON_ONCE(1); + return 0; +} + +static void srcu_torture_up_read(int idx) +{ + WARN_ON_ONCE((reader_flavor && (idx & ~reader_flavor)) || (!reader_flavor && (idx & ~0x1))); + if (reader_flavor & SRCU_READ_FLAVOR_FAST) + srcu_up_read_fast(srcu_ctlp, __srcu_ctr_to_ptr(srcu_ctlp, (idx & 0x8) >> 3)); + else if ((reader_flavor & SRCU_READ_FLAVOR_NORMAL) || + !(reader_flavor & SRCU_READ_FLAVOR_ALL)) + srcu_up_read(srcu_ctlp, idx & 0x1); + else + WARN_ON_ONCE(1); +} + static unsigned long srcu_torture_completed(void) { return srcu_batches_completed(srcu_ctlp); @@ -811,6 +862,8 @@ static struct rcu_torture_ops srcu_ops = { .readlock = srcu_torture_read_lock, .read_delay = srcu_read_delay, .readunlock = srcu_torture_read_unlock, + .down_read = srcu_torture_down_read, + .up_read = srcu_torture_up_read, .readlock_held = torture_srcu_read_lock_held, .get_gp_seq = srcu_torture_completed, .gp_diff = rcu_seq_diff, @@ -831,6 +884,8 @@ static struct rcu_torture_ops srcu_ops = { .irq_capable = 1, .no_pi_lock = IS_ENABLED(CONFIG_TINY_SRCU), .debug_objects = 1, + .have_up_down = IS_ENABLED(CONFIG_TINY_SRCU) + ? 0 : SRCU_READ_FLAVOR_NORMAL | SRCU_READ_FLAVOR_FAST, .name = "srcu" }; @@ -856,6 +911,8 @@ static struct rcu_torture_ops srcud_ops = { .read_delay = srcu_read_delay, .readunlock = srcu_torture_read_unlock, .readlock_held = torture_srcu_read_lock_held, + .down_read = srcu_torture_down_read, + .up_read = srcu_torture_up_read, .get_gp_seq = srcu_torture_completed, .gp_diff = rcu_seq_diff, .deferred_free = srcu_torture_deferred_free, @@ -875,6 +932,8 @@ static struct rcu_torture_ops srcud_ops = { .irq_capable = 1, .no_pi_lock = IS_ENABLED(CONFIG_TINY_SRCU), .debug_objects = 1, + .have_up_down = IS_ENABLED(CONFIG_TINY_SRCU) + ? 0 : SRCU_READ_FLAVOR_NORMAL | SRCU_READ_FLAVOR_FAST, .name = "srcud" }; @@ -1985,7 +2044,7 @@ static void rcutorture_one_extend(int *readstate, int newstate, bool insoftirq, first = idxold1 == 0; WARN_ON_ONCE(idxold2 < 0); - WARN_ON_ONCE(idxold2 & ~RCUTORTURE_RDR_ALLBITS); + WARN_ON_ONCE(idxold2 & ~(RCUTORTURE_RDR_ALLBITS | RCUTORTURE_RDR_UPDOWN)); rcutorture_one_extend_check("before change", idxold1, statesnew, statesold, insoftirq); rtrsp->rt_readstate = newstate; @@ -2061,6 +2120,11 @@ static void rcutorture_one_extend(int *readstate, int newstate, bool insoftirq, if (lockit) raw_spin_unlock_irqrestore(¤t->pi_lock, flags); } + if (statesold & RCUTORTURE_RDR_UPDOWN) { + cur_ops->up_read((idxold1 & RCUTORTURE_RDR_MASK_1) >> RCUTORTURE_RDR_SHIFT_1); + WARN_ON_ONCE(idxnew1 != -1); + idxold1 = 0; + } /* Delay if neither beginning nor end and there was a change. */ if ((statesnew || statesold) && *readstate && newstate) @@ -2201,7 +2265,8 @@ static bool rcu_torture_one_read_start(struct rcu_torture_one_read_state *rtorsp rtorsp->started = cur_ops->get_gp_seq(); rtorsp->ts = rcu_trace_clock_local(); rtorsp->p = rcu_dereference_check(rcu_torture_current, - !cur_ops->readlock_held || cur_ops->readlock_held()); + !cur_ops->readlock_held || cur_ops->readlock_held() || + (rtorsp->readstate & RCUTORTURE_RDR_UPDOWN)); if (rtorsp->p == NULL) { /* Wait for rcu_torture_writer to get underway */ rcutorture_one_extend(&rtorsp->readstate, 0, myid < 0, trsp, rtorsp->rtrsp); @@ -2370,6 +2435,123 @@ rcu_torture_reader(void *arg) return 0; } +struct rcu_torture_one_read_state_updown { + struct hrtimer rtorsu_hrt; + bool rtorsu_inuse; + struct torture_random_state rtorsu_trs; + struct rcu_torture_one_read_state rtorsu_rtors; +}; + +static struct rcu_torture_one_read_state_updown *updownreaders; +static DEFINE_TORTURE_RANDOM(rcu_torture_updown_rand); +static int rcu_torture_updown(void *arg); + +static enum hrtimer_restart rcu_torture_updown_hrt(struct hrtimer *hrtp) +{ + struct rcu_torture_one_read_state_updown *rtorsup; + + rtorsup = container_of(hrtp, struct rcu_torture_one_read_state_updown, rtorsu_hrt); + rcu_torture_one_read_end(&rtorsup->rtorsu_rtors, &rtorsup->rtorsu_trs, -1); + smp_store_release(&rtorsup->rtorsu_inuse, false); + return HRTIMER_NORESTART; +} + +static int rcu_torture_updown_init(void) +{ + int i; + struct torture_random_state *rand = &rcu_torture_updown_rand; + int ret; + + if (n_up_down < 0) + return 0; + if (!srcu_torture_have_up_down()) { + VERBOSE_TOROUT_STRING("rcu_torture_updown_init: Disabling up/down reader tests due to lack of primitives"); + return 0; + } + updownreaders = kcalloc(n_up_down, sizeof(*updownreaders), GFP_KERNEL); + if (!updownreaders) { + VERBOSE_TOROUT_STRING("rcu_torture_updown_init: Out of memory, disabling up/down reader tests"); + return -ENOMEM; + } + for (i = 0; i < n_up_down; i++) { + init_rcu_torture_one_read_state(&updownreaders[i].rtorsu_rtors, rand); + hrtimer_init(&updownreaders[i].rtorsu_hrt, CLOCK_MONOTONIC, + HRTIMER_MODE_REL | HRTIMER_MODE_SOFT); + updownreaders[i].rtorsu_hrt.function = rcu_torture_updown_hrt; + torture_random_init(&updownreaders[i].rtorsu_trs); + init_rcu_torture_one_read_state(&updownreaders[i].rtorsu_rtors, + &updownreaders[i].rtorsu_trs); + } + ret = torture_create_kthread(rcu_torture_updown, rand, updown_task); + if (ret) { + kfree(updownreaders); + updownreaders = NULL; + } + return ret; +} + +static void rcu_torture_updown_cleanup(void) +{ + struct rcu_torture_one_read_state_updown *rtorsup; + + for (rtorsup = updownreaders; rtorsup < &updownreaders[n_up_down]; rtorsup++) { + if (!smp_load_acquire(&rtorsup->rtorsu_inuse)) + continue; + (void)hrtimer_cancel(&rtorsup->rtorsu_hrt); + WARN_ON_ONCE(rtorsup->rtorsu_inuse); + + } + kfree(updownreaders); + updownreaders = NULL; +} + +/* + * RCU torture up/down reader kthread, starting RCU readers in kthread + * context and ending them in hrtimer handlers. Otherwise similar to + * rcu_torture_reader(). + */ +static int +rcu_torture_updown(void *arg) +{ + int idx; + int rawidx; + struct rcu_torture_one_read_state_updown *rtorsup; + ktime_t t; + + VERBOSE_TOROUT_STRING("rcu_torture_updown task started"); + do { + for (rtorsup = updownreaders; rtorsup < &updownreaders[n_up_down]; rtorsup++) { + if (torture_must_stop()) + break; + if (smp_load_acquire(&rtorsup->rtorsu_inuse)) + continue; + init_rcu_torture_one_read_state(&rtorsup->rtorsu_rtors, + &rtorsup->rtorsu_trs); + rawidx = cur_ops->down_read(); + idx = (rawidx << RCUTORTURE_RDR_SHIFT_1) & RCUTORTURE_RDR_MASK_1; + rtorsup->rtorsu_rtors.readstate = idx | RCUTORTURE_RDR_UPDOWN; + rtorsup->rtorsu_rtors.rtrsp++; + if (!rcu_torture_one_read_start(&rtorsup->rtorsu_rtors, + &rtorsup->rtorsu_trs, -1)) { + cur_ops->up_read(rawidx); + schedule_timeout_idle(HZ); + continue; + } + smp_store_release(&rtorsup->rtorsu_inuse, true); + t = torture_random(&rtorsup->rtorsu_trs) & 0xfffff; // One per million. + if (t < 10 * 1000) + t = 200 * 1000 * 1000; + hrtimer_start(&rtorsup->rtorsu_hrt, t, + HRTIMER_MODE_REL | HRTIMER_MODE_SOFT); + } + torture_hrtimeout_ms(1, 1000, &rcu_torture_updown_rand); + stutter_wait("rcu_torture_updown"); + } while (!torture_must_stop()); + rcu_torture_updown_cleanup(); + torture_kthread_stopping("rcu_torture_updown"); + return 0; +} + /* * Randomly Toggle CPUs' callback-offload state. This uses hrtimers to * increase race probabilities and fuzzes the interval between toggling. @@ -2620,7 +2802,7 @@ rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, const char *tag) "reader_flavor=%x " "nocbs_nthreads=%d nocbs_toggle=%d " "test_nmis=%d " - "preempt_duration=%d preempt_interval=%d\n", + "preempt_duration=%d preempt_interval=%d n_up_down=%d\n", torture_type, tag, nrealreaders, nrealfakewriters, stat_interval, verbose, test_no_idle_hz, shuffle_interval, stutter, irqreader, fqs_duration, fqs_holdoff, fqs_stutter, @@ -2634,7 +2816,7 @@ rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, const char *tag) reader_flavor, nocbs_nthreads, nocbs_toggle, test_nmis, - preempt_duration, preempt_interval); + preempt_duration, preempt_interval, n_up_down); } static int rcutorture_booster_cleanup(unsigned int cpu) @@ -3686,6 +3868,10 @@ rcu_torture_cleanup(void) nocb_tasks = NULL; } + if (updown_task) { + torture_stop_kthread(rcu_torture_updown, updown_task); + updown_task = NULL; + } if (reader_tasks) { for (i = 0; i < nrealreaders; i++) torture_stop_kthread(rcu_torture_reader, @@ -4216,6 +4402,9 @@ rcu_torture_init(void) if (torture_init_error(firsterr)) goto unwind; } + firsterr = rcu_torture_updown_init(); + if (torture_init_error(firsterr)) + goto unwind; nrealnocbers = nocbs_nthreads; if (WARN_ON(nrealnocbers < 0)) nrealnocbers = 1; From patchwork Mon Mar 10 18:38:06 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Paul E. McKenney" X-Patchwork-Id: 14010545 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B476D235C1B; Mon, 10 Mar 2025 18:38:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741631892; cv=none; b=X7KV6RHTqXEgePnMnnW0KFAPCXlBWwmSmuKaHDtT4sM10TmFHBN5IK2YUIiXbuh4qw9RtCnNd0X5qamyKNN4MNOD8MDeJeiyYJ3TF6keYLVeLBMC6dOiHH0XzAnn+i7z6pVFKUc1HWjWq/E3qpXusJXF+RgdqXcM29/NBYPv3AQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741631892; c=relaxed/simple; bh=49ZKHlT4AKvojbmFQ6+D5rEHUXLvNqqx95V8uLPi97Q=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=SbdxzTctrUp+HjZZMd7UbIsUUvo5lVH+sGOoK/uiC6iW6wbV4T5p+71C34LmKZahKMOQnBIU5BtDYWDQAxXAcduIqijVHJRCBWUgQEULGl7M8ziMzI5JbC6q8Ya3I1phv7INi0+sEG0B9AG+JJcvTU5FaqPEtLLzbDJ7Es4TjIE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=XZmXgrdt; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="XZmXgrdt" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 40C74C4CEF4; Mon, 10 Mar 2025 18:38:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1741631892; bh=49ZKHlT4AKvojbmFQ6+D5rEHUXLvNqqx95V8uLPi97Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XZmXgrdt2IRncH8gy5bmLRP1PCYQsge8OnMpR457h++6qRy7xYC4Xmh2q7oumyOze PhL2B11T54IGa1zfHm2dqg6/8XFjdFTmJJ9yWp1TOWR8LiXPRsQpDW034BPVP0j7GT coKk9otC75zJKWdp9Y0V7tvj8IL9j7KwHgNVZOU48ElHPeOFbd/uBPw6pIGhTV6ZZG T6I2rVWwMk0cGWpKjawpI4i2twDfAPfRhjWSUkVxftmy+KErWdHN+ctksR1vYA7PpL TQI2RKascocarRIV2AIxD7vXqNQ+2QwC6fmgGPF7kAjY3M36uKh3b9gjG5+hSacLRY ZedIMH5VzlsBw== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 9BB38CE1312; Mon, 10 Mar 2025 11:38:11 -0700 (PDT) From: "Paul E. McKenney" To: rcu@vger.kernel.org Cc: linux-kernel@vger.kernel.org, kernel-team@meta.com, rostedt@goodmis.org, "Paul E. McKenney" Subject: [PATCH 6/9] rcutorture: Pull rcu_torture_updown() loop body into new function Date: Mon, 10 Mar 2025 11:38:06 -0700 Message-Id: <20250310183809.3576320-6-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <4bf081c8-9299-4ee3-b337-d5b751cef6be@paulmck-laptop> References: <4bf081c8-9299-4ee3-b337-d5b751cef6be@paulmck-laptop> Precedence: bulk X-Mailing-List: rcu@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This is strictly a code-movement commit, pulling that part of the rcu_torture_updown() function's loop body that processes one rcu_torture_one_read_state_updown structure into a new rcu_torture_updown_one() function. The checks for the end of the torture test and the current structure being in use remain in the rcu_torture_updown() function. Signed-off-by: Paul E. McKenney --- kernel/rcu/rcutorture.c | 46 ++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 6afcd33e724ba..6d808c70349c4 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -2505,6 +2505,30 @@ static void rcu_torture_updown_cleanup(void) updownreaders = NULL; } +// Do one reader for rcu_torture_updown(). +static void rcu_torture_updown_one(struct rcu_torture_one_read_state_updown *rtorsup) +{ + int idx; + int rawidx; + ktime_t t; + + init_rcu_torture_one_read_state(&rtorsup->rtorsu_rtors, &rtorsup->rtorsu_trs); + rawidx = cur_ops->down_read(); + idx = (rawidx << RCUTORTURE_RDR_SHIFT_1) & RCUTORTURE_RDR_MASK_1; + rtorsup->rtorsu_rtors.readstate = idx | RCUTORTURE_RDR_UPDOWN; + rtorsup->rtorsu_rtors.rtrsp++; + if (!rcu_torture_one_read_start(&rtorsup->rtorsu_rtors, &rtorsup->rtorsu_trs, -1)) { + cur_ops->up_read(rawidx); + schedule_timeout_idle(HZ); + return; + } + smp_store_release(&rtorsup->rtorsu_inuse, true); + t = torture_random(&rtorsup->rtorsu_trs) & 0xfffff; // One per million. + if (t < 10 * 1000) + t = 200 * 1000 * 1000; + hrtimer_start(&rtorsup->rtorsu_hrt, t, HRTIMER_MODE_REL | HRTIMER_MODE_SOFT); +} + /* * RCU torture up/down reader kthread, starting RCU readers in kthread * context and ending them in hrtimer handlers. Otherwise similar to @@ -2513,10 +2537,7 @@ static void rcu_torture_updown_cleanup(void) static int rcu_torture_updown(void *arg) { - int idx; - int rawidx; struct rcu_torture_one_read_state_updown *rtorsup; - ktime_t t; VERBOSE_TOROUT_STRING("rcu_torture_updown task started"); do { @@ -2525,24 +2546,7 @@ rcu_torture_updown(void *arg) break; if (smp_load_acquire(&rtorsup->rtorsu_inuse)) continue; - init_rcu_torture_one_read_state(&rtorsup->rtorsu_rtors, - &rtorsup->rtorsu_trs); - rawidx = cur_ops->down_read(); - idx = (rawidx << RCUTORTURE_RDR_SHIFT_1) & RCUTORTURE_RDR_MASK_1; - rtorsup->rtorsu_rtors.readstate = idx | RCUTORTURE_RDR_UPDOWN; - rtorsup->rtorsu_rtors.rtrsp++; - if (!rcu_torture_one_read_start(&rtorsup->rtorsu_rtors, - &rtorsup->rtorsu_trs, -1)) { - cur_ops->up_read(rawidx); - schedule_timeout_idle(HZ); - continue; - } - smp_store_release(&rtorsup->rtorsu_inuse, true); - t = torture_random(&rtorsup->rtorsu_trs) & 0xfffff; // One per million. - if (t < 10 * 1000) - t = 200 * 1000 * 1000; - hrtimer_start(&rtorsup->rtorsu_hrt, t, - HRTIMER_MODE_REL | HRTIMER_MODE_SOFT); + rcu_torture_updown_one(rtorsup); } torture_hrtimeout_ms(1, 1000, &rcu_torture_updown_rand); stutter_wait("rcu_torture_updown"); From patchwork Mon Mar 10 18:38:07 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Paul E. McKenney" X-Patchwork-Id: 14010546 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B469C235C15; Mon, 10 Mar 2025 18:38:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741631892; cv=none; b=kG8uT+feaHi946U2e03WUGTMxMwyqhvukZZSyBbOVVbmeAJSZY6zpA9x25JzA4Td0xGPiZiTznYUvc1NNXkuAETDac5seX96rQ2kG5SYR2IotYPX0mhx8dpiwVa0NmQSboBz28dTHhclrzUM8zP8OSXBBb03jhXWPV48A8MJCsk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741631892; c=relaxed/simple; bh=58Vf7rQ9Ye1ZnF11F3AKbtRYHEgqBK/0woCbX8EkJYc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=PpmjGXXxM+v6eMhWruYiWy+ubudGLpn+4hYans6jD2VcmtSZJeplHCtrzro8xLLUStdZ394b/uDXWIKsQc41Eel/NMdvkmIwNeiP8UyWunM1Wm1hX7V8Ric0XOu7GdO6R4SfbOpF+IyHpwlvUFWhTixlWOMXn21GUc73XfMSC8I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=P5m6LcCY; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="P5m6LcCY" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4D084C4CEF6; Mon, 10 Mar 2025 18:38:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1741631892; bh=58Vf7rQ9Ye1ZnF11F3AKbtRYHEgqBK/0woCbX8EkJYc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=P5m6LcCY0fMTsbvQBiYf/XRYgqwdq8ytPquDE20krnwpOaMuDoNA3pU22YsjdDDnZ qZXcgvsjhtD+gBnQ8yDYjS4VS6fjlWdJl6rB5AULiAk+z6VU7XRZ1Erge+x3cg8QZ+ EauQkjvmZHffohcA36ck217NllK1h3t+XMzy//q5dO28AHqw8Z0xOpCEv0PyyYc3q5 n0KfEYbJrbBQVyMkmn23Msfg6NKF0jum/ogCx79YAMGx8lSCX2c4/IsjUyGDzJXMq9 ezhz6fIZr5+49jOKebZnnkMOlyezx6eL3B/CSfbVT/+86jhNLL1nOIKIHKNXep3/VQ /4JxIbu5B11ww== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 9EE36CE1389; Mon, 10 Mar 2025 11:38:11 -0700 (PDT) From: "Paul E. McKenney" To: rcu@vger.kernel.org Cc: linux-kernel@vger.kernel.org, kernel-team@meta.com, rostedt@goodmis.org, "Paul E. McKenney" Subject: [PATCH 7/9] rcutorture: Comment invocations of tick_dep_set_task() Date: Mon, 10 Mar 2025 11:38:07 -0700 Message-Id: <20250310183809.3576320-7-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <4bf081c8-9299-4ee3-b337-d5b751cef6be@paulmck-laptop> References: <4bf081c8-9299-4ee3-b337-d5b751cef6be@paulmck-laptop> Precedence: bulk X-Mailing-List: rcu@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The rcu_torture_reader() and rcu_torture_fwd_prog_cr() functions run CPU-bound for extended periods of time (tens or even hundreds of milliseconds), so they invoke tick_dep_set_task() and tick_dep_clear_task() to ensure that the scheduling-clock tick helps move grace periods forward. So why doesn't rcu_torture_fwd_prog_nr() also invoke tick_dep_set_task() and tick_dep_clear_task()? Because the point of this function is to test RCU's ability to (eventually) force grace periods forward even when the tick has been disabled during long CPU-bound kernel execution. Signed-off-by: Paul E. McKenney --- kernel/rcu/rcutorture.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 6d808c70349c4..3042a7950fe23 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -2410,7 +2410,7 @@ rcu_torture_reader(void *arg) set_user_nice(current, MAX_NICE); if (irqreader && cur_ops->irq_capable) timer_setup_on_stack(&t, rcu_torture_timer, 0); - tick_dep_set_task(current, TICK_DEP_BIT_RCU); + tick_dep_set_task(current, TICK_DEP_BIT_RCU); // CPU bound, so need tick. do { if (irqreader && cur_ops->irq_capable) { if (!timer_pending(&t)) @@ -3260,7 +3260,7 @@ static void rcu_torture_fwd_prog_cr(struct rcu_fwd *rfp) cver = READ_ONCE(rcu_torture_current_version); gps = cur_ops->get_gp_seq(); rfp->rcu_launder_gp_seq_start = gps; - tick_dep_set_task(current, TICK_DEP_BIT_RCU); + tick_dep_set_task(current, TICK_DEP_BIT_RCU); // CPU bound, so need tick. while (time_before(jiffies, stopat) && !shutdown_time_arrived() && !READ_ONCE(rcu_fwd_emergency_stop) && !torture_must_stop()) { From patchwork Mon Mar 10 18:38:08 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Paul E. McKenney" X-Patchwork-Id: 14010543 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9E90B235BFB; Mon, 10 Mar 2025 18:38:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741631892; cv=none; b=TBtqlsZ/jVEit+CTRPE6+9+/MHwxu415MNDRFvRy28gWIaq8WI8aud0BLnytFWazzNxMyQUKIStJHhU5l055PZJhKQ89b0RKwjYU1WdOzN25hgqqLqXBP2MXxSZuK6xVu7e8w6HTNRcgNEZpbBorhuzAowbjarM8nuphvx00DSM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741631892; c=relaxed/simple; bh=XGyE/kRVLYcAJNHHvwpu1f6JtOQ0/1fOq4byrIOVY8g=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=OxsucVfkxnDxKUpIvgFYcUCWhuafKaCBk+u7/cR62w5cfLrgDpd45uruCSDPLwOLE0HFcNHf83+q27fopmDYG3vIsFQVpH0DsmTGg2Jpbzz3o4kHMS0hXLXExQU4Ty4ytxC76j26YbqjuqqLTtMf/wTbEo/RB5tB5IRxfjQxSRg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Ncnk7M0d; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Ncnk7M0d" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 56EE8C4CEEE; Mon, 10 Mar 2025 18:38:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1741631892; bh=XGyE/kRVLYcAJNHHvwpu1f6JtOQ0/1fOq4byrIOVY8g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Ncnk7M0dS5KvBjxInNT6aMpPKgBYP+9CQ/G9hX3gDwSKJpeEyzw0nI7j7TJmb/Kdg /p5TBgLXCGbO6UoNxkwEeWc5puODCKLGH/0RX8gmCc75CBnI+G8ZS9EngrQnksjzCk LkSLirC3iloAb+YIl4F6+qOS1pMUfwRuGFzzdszLg6bDJ/UtI6wJstrRt/5sJtOKDd 79fzyR2vrydwmWJXSQoDq5Pls+/2VCWF0liCnbFr09q2oPWPrZpVEg7R59AfMBupuD rCGA4oHvLKoMzFH34XwK3DPRsJWnTig1FjH0B3Paq0zeIzoIE7A/SP3FRsEAYyNNTl KA9TThUhpR46g== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id A07C1CE13D4; Mon, 10 Mar 2025 11:38:11 -0700 (PDT) From: "Paul E. McKenney" To: rcu@vger.kernel.org Cc: linux-kernel@vger.kernel.org, kernel-team@meta.com, rostedt@goodmis.org, "Paul E. McKenney" Subject: [PATCH 8/9] rcutorture: Complain if an ->up_read() is delayed more than 10 seconds Date: Mon, 10 Mar 2025 11:38:08 -0700 Message-Id: <20250310183809.3576320-8-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <4bf081c8-9299-4ee3-b337-d5b751cef6be@paulmck-laptop> References: <4bf081c8-9299-4ee3-b337-d5b751cef6be@paulmck-laptop> Precedence: bulk X-Mailing-List: rcu@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The down/up SRCU reader testing uses an hrtimer handler to exit the SRCU read-side critical section. This might be delayed, and if delayed for too long, it can prevent the rcutorture run from completing. This commit therefore complains if the hrtimer handler is delayed for more than ten seconds. Signed-off-by: Paul E. McKenney --- kernel/rcu/rcutorture.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 3042a7950fe23..fcdd6271f435c 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -2438,6 +2438,7 @@ rcu_torture_reader(void *arg) struct rcu_torture_one_read_state_updown { struct hrtimer rtorsu_hrt; bool rtorsu_inuse; + unsigned long rtorsu_j; struct torture_random_state rtorsu_trs; struct rcu_torture_one_read_state rtorsu_rtors; }; @@ -2522,6 +2523,7 @@ static void rcu_torture_updown_one(struct rcu_torture_one_read_state_updown *rto schedule_timeout_idle(HZ); return; } + rtorsup->rtorsu_j = jiffies; smp_store_release(&rtorsup->rtorsu_inuse, true); t = torture_random(&rtorsup->rtorsu_trs) & 0xfffff; // One per million. if (t < 10 * 1000) @@ -2544,8 +2546,10 @@ rcu_torture_updown(void *arg) for (rtorsup = updownreaders; rtorsup < &updownreaders[n_up_down]; rtorsup++) { if (torture_must_stop()) break; - if (smp_load_acquire(&rtorsup->rtorsu_inuse)) + if (smp_load_acquire(&rtorsup->rtorsu_inuse)) { + WARN_ON_ONCE(time_after(jiffies, rtorsup->rtorsu_j + 10 * HZ)); continue; + } rcu_torture_updown_one(rtorsup); } torture_hrtimeout_ms(1, 1000, &rcu_torture_updown_rand); From patchwork Mon Mar 10 18:38:09 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Paul E. McKenney" X-Patchwork-Id: 14010544 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B470C235C17; Mon, 10 Mar 2025 18:38:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741631892; cv=none; b=KW5LOMuP9XxIPEjr/MDgxvanYEsMr9NMsghvMZd+b63pqSwiyYeg2cJSgnSzcp7qt/UBEnQXSHc7/aq4SoLoUDyZESU9231e3nfrblEg4FQgvMOI6R5t7CIl7S+K0Tnb2GO8yuUuRgP5DM72AdZ5e5mFLIbjj0bnKYfcX5PaC7c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741631892; c=relaxed/simple; bh=QrzgNx2Z70ZJkhKYaYpwPppmFmFzg0Cl6Eu7C/Gx3I4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=i5IPCCSCfqcOlcRdNaFidrCBdD5B6zOTsgyiiinjc2Zzmfs1ZDuLUoZA+ygHKiToXwRikAZNqwAvsmBnmJiNqKxF7JrvxnkEHQFj+imRazlfnXnmEiXvBAbcYFi50nG4gIrtb570pUr6g6WtOklPDpnEhW3dg/larohwemWu9og= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=WWVJpd4g; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="WWVJpd4g" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5CAB9C4CEF8; Mon, 10 Mar 2025 18:38:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1741631892; bh=QrzgNx2Z70ZJkhKYaYpwPppmFmFzg0Cl6Eu7C/Gx3I4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WWVJpd4gfZAsWYAH/445Byydyr7Y6Zu/60orVuDF33qiM+GaqvOSpGD2yjXJpVXG4 YMSrrHgGDT/EezO81Uac7KxCAT1xn8Um8WZ2Z/J+6TP+njkDu2x+JAwO3KGwZ7a3Wo n80hL4dKaSTclcHQV56praekKaUPCg4eMi9eOA2GVndB3QgVOC5LX7rmp5Lb1QJ/38 qqz+vfLrnVbEioKwzuYt4b+Vk4wvyXtyc9J87bmiN7ijPHN73XQbH11fX3uGKkCnQC dV/RZf3D/uw+nu4gemX+UU+4o6P0oQcTJNe28E/qNqstg/1aMTz6jChnNz/3hcQVCT PlEwZnNVw7qCA== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id A2F70CE1482; Mon, 10 Mar 2025 11:38:11 -0700 (PDT) From: "Paul E. McKenney" To: rcu@vger.kernel.org Cc: linux-kernel@vger.kernel.org, kernel-team@meta.com, rostedt@goodmis.org, "Paul E. McKenney" , kernel test robot Subject: [PATCH 9/9] rcutorture: Check for ->up_read() without matching ->down_read() Date: Mon, 10 Mar 2025 11:38:09 -0700 Message-Id: <20250310183809.3576320-9-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <4bf081c8-9299-4ee3-b337-d5b751cef6be@paulmck-laptop> References: <4bf081c8-9299-4ee3-b337-d5b751cef6be@paulmck-laptop> Precedence: bulk X-Mailing-List: rcu@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This commit creates counters in the rcu_torture_one_read_state_updown structure that check for a call to ->up_read() that lacks a matching call to ->down_read(). While in the area, add end-of-run cleanup code that prevents calls to rcu_torture_updown_hrt() from happening after the test has moved on. Yes, the srcu_barrier() at the end of the test will wait for them, but this could result in confusing states, statistics, and diagnostic information. So explicitly wait for them before we get to the end-of-test output. [ paulmck: Apply kernel test robot feedback. ] Signed-off-by: Paul E. McKenney Tested-by: kernel test robot --- kernel/rcu/rcutorture.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index fcdd6271f435c..a0786b3c223be 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -2439,6 +2439,8 @@ struct rcu_torture_one_read_state_updown { struct hrtimer rtorsu_hrt; bool rtorsu_inuse; unsigned long rtorsu_j; + unsigned long rtorsu_ndowns; + unsigned long rtorsu_nups; struct torture_random_state rtorsu_trs; struct rcu_torture_one_read_state rtorsu_rtors; }; @@ -2453,6 +2455,8 @@ static enum hrtimer_restart rcu_torture_updown_hrt(struct hrtimer *hrtp) rtorsup = container_of(hrtp, struct rcu_torture_one_read_state_updown, rtorsu_hrt); rcu_torture_one_read_end(&rtorsup->rtorsu_rtors, &rtorsup->rtorsu_trs, -1); + WARN_ONCE(rtorsup->rtorsu_nups >= rtorsup->rtorsu_ndowns, "%s: Up without matching down #%zu.\n", __func__, rtorsup - updownreaders); + rtorsup->rtorsu_nups++; smp_store_release(&rtorsup->rtorsu_inuse, false); return HRTIMER_NORESTART; } @@ -2499,7 +2503,12 @@ static void rcu_torture_updown_cleanup(void) if (!smp_load_acquire(&rtorsup->rtorsu_inuse)) continue; (void)hrtimer_cancel(&rtorsup->rtorsu_hrt); - WARN_ON_ONCE(rtorsup->rtorsu_inuse); + if (WARN_ON_ONCE(rtorsup->rtorsu_inuse)) { + rcu_torture_one_read_end(&rtorsup->rtorsu_rtors, &rtorsup->rtorsu_trs, -1); + WARN_ONCE(rtorsup->rtorsu_nups >= rtorsup->rtorsu_ndowns, "%s: Up without matching down #%zu.\n", __func__, rtorsup - updownreaders); + rtorsup->rtorsu_nups++; + smp_store_release(&rtorsup->rtorsu_inuse, false); + } } kfree(updownreaders); @@ -2515,11 +2524,14 @@ static void rcu_torture_updown_one(struct rcu_torture_one_read_state_updown *rto init_rcu_torture_one_read_state(&rtorsup->rtorsu_rtors, &rtorsup->rtorsu_trs); rawidx = cur_ops->down_read(); + rtorsup->rtorsu_ndowns++; idx = (rawidx << RCUTORTURE_RDR_SHIFT_1) & RCUTORTURE_RDR_MASK_1; rtorsup->rtorsu_rtors.readstate = idx | RCUTORTURE_RDR_UPDOWN; rtorsup->rtorsu_rtors.rtrsp++; if (!rcu_torture_one_read_start(&rtorsup->rtorsu_rtors, &rtorsup->rtorsu_trs, -1)) { cur_ops->up_read(rawidx); + rtorsup->rtorsu_nups++; + WARN_ONCE(rtorsup->rtorsu_nups >= rtorsup->rtorsu_ndowns, "%s: Up without matching down #%zu.\n", __func__, rtorsup - updownreaders); schedule_timeout_idle(HZ); return; }