From nobody Wed Oct 1 20:32:42 2025 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 5D09C255E53; Wed, 1 Oct 2025 14:48:37 +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=1759330117; cv=none; b=Jm9rN4H+W5/wRAZ/UyWixcDA+LeAAkFpH691D0PSRjLX6Xte+93bFT5ZA5AK4xzycDKizrRdVUZUe/3EKxj23cHCcb8rBmhNVsKZDlGE3xGx8H1fi1puW7kffZWNH4w760ZNkMnFJRIsUab9/tAYeSR85IYFgkooxzOyz815rqI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759330117; c=relaxed/simple; bh=yBaOC5W3nSd5obx3kTATstlLARGhR3bToCH6Ph5k7XI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=WsQkFSUXIc9AC2arXn2caTFBy0KqLnB1Do0c5poTIVDT7AsmMgQHZIspxawzCwUcA02+BoBIaPT11oUEN8wVkW00O90m7uSMJBZKwlBAChYnKS++QS3ENcRwiIJVixprsRFNNPKQX6dlODm3tAkVAtj1iurEg3u8Bmb8l6dLZWU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=aF2moIKC; 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="aF2moIKC" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D3CFEC4AF09; Wed, 1 Oct 2025 14:48:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1759330117; bh=yBaOC5W3nSd5obx3kTATstlLARGhR3bToCH6Ph5k7XI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aF2moIKCka1hqUOXop3oQvxhAKe/BXCPx97xVp/mE9ItMG3K/h+i/ghzX318Kp6As f2AY2VJN/xjcCd8BG5j9zp+GZURLFUj51FIOU1RYuxvMFIzFF3WbL63/8GqIBKM3Zb hCGXUech9tW2fVynOHA9Arn1KlJi9wWTpk2yypz5GIpeTiY9oXPBRjpm2iJJy+OQIZ dag7ZwMkLsbF3dh1nGH7dRmurEzY1AxARUl4NViJUNs3yb/wshRGm/4BdIXed3B8Er FGx//8qafCnETh0L00oT3Z+gZdprXDdFm+2SPeeF/e1rS/1KhnwXfwYMODCvSwha/x Twe7h2badvVeA== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 5FDC8CE0F80; Wed, 1 Oct 2025 07:48:34 -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 , Zqiang Subject: [PATCH v2 01/21] srcu: Permit Tiny SRCU srcu_read_unlock() with interrupts disabled Date: Wed, 1 Oct 2025 07:48:12 -0700 Message-Id: <20251001144832.631770-1-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> References: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The current Tiny SRCU implementation of srcu_read_unlock() awakens the grace-period processing when exiting the outermost SRCU read-side critical section. However, not all Linux-kernel configurations and contexts permit swake_up_one() to be invoked while interrupts are disabled, and this can result in indefinitely extended SRCU grace periods. This commit therefore only invokes swake_up_one() when interrupts are enabled, and introduces polling to the grace-period workqueue handler. Reported-by: kernel test robot Reported-by: Zqiang Closes: https://lore.kernel.org/oe-lkp/202508261642.b15eefbb-lkp@intel.com Signed-off-by: Paul E. McKenney --- kernel/rcu/srcutiny.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/kernel/rcu/srcutiny.c b/kernel/rcu/srcutiny.c index e3b64a5e0ec7e1..3450c3751ef7ad 100644 --- a/kernel/rcu/srcutiny.c +++ b/kernel/rcu/srcutiny.c @@ -106,15 +106,15 @@ void __srcu_read_unlock(struct srcu_struct *ssp, int = idx) newval =3D READ_ONCE(ssp->srcu_lock_nesting[idx]) - 1; WRITE_ONCE(ssp->srcu_lock_nesting[idx], newval); preempt_enable(); - if (!newval && READ_ONCE(ssp->srcu_gp_waiting) && in_task()) + if (!newval && READ_ONCE(ssp->srcu_gp_waiting) && in_task() && !irqs_disa= bled()) swake_up_one(&ssp->srcu_wq); } EXPORT_SYMBOL_GPL(__srcu_read_unlock); =20 /* * Workqueue handler to drive one grace period and invoke any callbacks - * that become ready as a result. Single-CPU and !PREEMPTION operation - * means that we get away with murder on synchronization. ;-) + * that become ready as a result. Single-CPU operation and preemption + * disabling mean that we get away with murder on synchronization. ;-) */ void srcu_drive_gp(struct work_struct *wp) { @@ -141,7 +141,12 @@ void srcu_drive_gp(struct work_struct *wp) WRITE_ONCE(ssp->srcu_idx, ssp->srcu_idx + 1); WRITE_ONCE(ssp->srcu_gp_waiting, true); /* srcu_read_unlock() wakes! */ preempt_enable(); - swait_event_exclusive(ssp->srcu_wq, !READ_ONCE(ssp->srcu_lock_nesting[idx= ])); + do { + // Deadlock issues prevent __srcu_read_unlock() from + // doing an unconditional wakeup, so polling is required. + swait_event_timeout_exclusive(ssp->srcu_wq, + !READ_ONCE(ssp->srcu_lock_nesting[idx]), HZ / 10); + } while (READ_ONCE(ssp->srcu_lock_nesting[idx])); preempt_disable(); // Needed for PREEMPT_LAZY WRITE_ONCE(ssp->srcu_gp_waiting, false); /* srcu_read_unlock() cheap. */ WRITE_ONCE(ssp->srcu_idx, ssp->srcu_idx + 1); --=20 2.40.1 From nobody Wed Oct 1 20:32:42 2025 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 CB31A277CBF; Wed, 1 Oct 2025 14:48:37 +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=1759330117; cv=none; b=sT0OKd4rMwMdF6SnGEkk+PJHDowoM/pU4LziQjvNRjo+ja+TW5GiF7asyK7UZp9CiZR4law/soaNXl49ZMxvWnGtRKjDjzPxTj77RSfShiJxbRD/vLYRQ8riJ5MTiqZsjKEykE1IJMXui/IYgyjteyIGVllRZY2pYcP65OAHHZM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759330117; c=relaxed/simple; bh=GuWZgmScxYz8wlLiDZ3hGcnxOt0ZVDLS+1O/In+1EiI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=OxqSZ/rirE7jvJPl47LRQi5UaSZ7AUj1FxlEc8Ux7gCQA3413imy/mQPaC/l1bfRS7PRE+aFKrT3q5czR355Z9+7dakvH7MW4fiPn91GQ7U2K4/rxbxKmGTxn3OeFp4lOclEQYKt0hQxhF8++iQQbUQwQN2gjZiW+7GfJ/Xurzk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=c/g1Mtkn; 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="c/g1Mtkn" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 37121C116D0; Wed, 1 Oct 2025 14:48:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1759330117; bh=GuWZgmScxYz8wlLiDZ3hGcnxOt0ZVDLS+1O/In+1EiI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=c/g1Mtkn5L1D09sfNkCRYMXwnY+/Aimprq31eRxVGX129g8z5VplT0oETko4AHfaD yDFTXtVrl9CMKkZP9+HzZeLzT06EKFK1lU5Ny7b8cS3ZjJ5Q6iHuX+whCarvxgb8pj yZGCFnI1KQG8hg6MhHJWkNZv9xpkwFWjKx2g0pkUSsMNHV/TWykjybJYy42ShtLcwT 8yYvrUvxKn7q7AVkn0gBZJ1PpuIzvroc8svcdIWFQubWoeEToV5OesDD2VdCQ6Wvmf eZdecdY/RUDV+rawCGcd5OOcefv/i8byjQ1d9Sdet4gAoSkN4BImWpKeGnf1Cfer6x fNqpXvRzGgJcQ== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 64C0DCE1067; Wed, 1 Oct 2025 07:48:34 -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 , Andrii Nakryiko , Alexei Starovoitov , Peter Zijlstra , bpf@vger.kernel.org Subject: [PATCH v2 02/21] rcu: Re-implement RCU Tasks Trace in terms of SRCU-fast Date: Wed, 1 Oct 2025 07:48:13 -0700 Message-Id: <20251001144832.631770-2-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> References: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This commit saves more than 500 lines of RCU code by re-implementing RCU Tasks Trace in terms of SRCU-fast. Follow-up work will remove more code that does not cause problems by its presence, but that is no longer required. This variant places smp_mb() in rcu_read_{,un}lock_trace(), which will be removed on common-case architectures in a later commit. [ paulmck: Apply kernel test robot, Boqun Feng, and Zqiang feedback. ] [ paulmck: Split out Tiny SRCU fixes per Andrii Nakryiko feedback. ] Signed-off-by: Paul E. McKenney Tested-by: kernel test robot Cc: Andrii Nakryiko Cc: Alexei Starovoitov Cc: Peter Zijlstra Cc: --- include/linux/rcupdate_trace.h | 107 ++++-- include/linux/sched.h | 1 + kernel/rcu/tasks.h | 617 +-------------------------------- 3 files changed, 95 insertions(+), 630 deletions(-) diff --git a/include/linux/rcupdate_trace.h b/include/linux/rcupdate_trace.h index e6c44eb428ab63..3f46cbe6700038 100644 --- a/include/linux/rcupdate_trace.h +++ b/include/linux/rcupdate_trace.h @@ -12,28 +12,28 @@ #include #include =20 -extern struct lockdep_map rcu_trace_lock_map; +#ifdef CONFIG_TASKS_TRACE_RCU +extern struct srcu_struct rcu_tasks_trace_srcu_struct; +#endif // #ifdef CONFIG_TASKS_TRACE_RCU =20 -#ifdef CONFIG_DEBUG_LOCK_ALLOC +#if defined(CONFIG_DEBUG_LOCK_ALLOC) && defined(CONFIG_TASKS_TRACE_RCU) =20 static inline int rcu_read_lock_trace_held(void) { - return lock_is_held(&rcu_trace_lock_map); + return srcu_read_lock_held(&rcu_tasks_trace_srcu_struct); } =20 -#else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ +#else // #if defined(CONFIG_DEBUG_LOCK_ALLOC) && defined(CONFIG_TASKS_TRAC= E_RCU) =20 static inline int rcu_read_lock_trace_held(void) { return 1; } =20 -#endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */ +#endif // #else // #if defined(CONFIG_DEBUG_LOCK_ALLOC) && defined(CONFIG_= TASKS_TRACE_RCU) =20 #ifdef CONFIG_TASKS_TRACE_RCU =20 -void rcu_read_unlock_trace_special(struct task_struct *t); - /** * rcu_read_lock_trace - mark beginning of RCU-trace read-side critical se= ction * @@ -50,12 +50,14 @@ static inline void rcu_read_lock_trace(void) { struct task_struct *t =3D current; =20 - WRITE_ONCE(t->trc_reader_nesting, READ_ONCE(t->trc_reader_nesting) + 1); - barrier(); - if (IS_ENABLED(CONFIG_TASKS_TRACE_RCU_READ_MB) && - t->trc_reader_special.b.need_mb) - smp_mb(); // Pairs with update-side barriers - rcu_lock_acquire(&rcu_trace_lock_map); + if (t->trc_reader_nesting++) { + // In case we interrupted a Tasks Trace RCU reader. + rcu_try_lock_acquire(&rcu_tasks_trace_srcu_struct.dep_map); + return; + } + barrier(); // nesting before scp to protect against interrupt handler. + t->trc_reader_scp =3D srcu_read_lock_fast(&rcu_tasks_trace_srcu_struct); + smp_mb(); // Placeholder for more selective ordering } =20 /** @@ -69,26 +71,75 @@ static inline void rcu_read_lock_trace(void) */ static inline void rcu_read_unlock_trace(void) { - int nesting; + struct srcu_ctr __percpu *scp; struct task_struct *t =3D current; =20 - rcu_lock_release(&rcu_trace_lock_map); - nesting =3D READ_ONCE(t->trc_reader_nesting) - 1; - barrier(); // Critical section before disabling. - // Disable IPI-based setting of .need_qs. - WRITE_ONCE(t->trc_reader_nesting, INT_MIN + nesting); - if (likely(!READ_ONCE(t->trc_reader_special.s)) || nesting) { - WRITE_ONCE(t->trc_reader_nesting, nesting); - return; // We assume shallow reader nesting. - } - WARN_ON_ONCE(nesting !=3D 0); - rcu_read_unlock_trace_special(t); + smp_mb(); // Placeholder for more selective ordering + scp =3D t->trc_reader_scp; + barrier(); // scp before nesting to protect against interrupt handler. + if (!--t->trc_reader_nesting) + srcu_read_unlock_fast(&rcu_tasks_trace_srcu_struct, scp); + else + srcu_lock_release(&rcu_tasks_trace_srcu_struct.dep_map); +} + +/** + * call_rcu_tasks_trace() - Queue a callback trace task-based grace period + * @rhp: structure to be used for queueing the RCU updates. + * @func: actual callback function to be invoked after the grace period + * + * The callback function will be invoked some time after a trace rcu-tasks + * grace period elapses, in other words after all currently executing + * trace rcu-tasks read-side critical sections have completed. These + * read-side critical sections are delimited by calls to rcu_read_lock_tra= ce() + * and rcu_read_unlock_trace(). + * + * See the description of call_rcu() for more detailed information on + * memory ordering guarantees. + */ +static inline void call_rcu_tasks_trace(struct rcu_head *rhp, rcu_callback= _t func) +{ + call_srcu(&rcu_tasks_trace_srcu_struct, rhp, func); +} + +/** + * synchronize_rcu_tasks_trace - wait for a trace rcu-tasks grace period + * + * Control will return to the caller some time after a trace rcu-tasks + * grace period has elapsed, in other words after all currently executing + * trace rcu-tasks read-side critical sections have elapsed. These read-si= de + * critical sections are delimited by calls to rcu_read_lock_trace() + * and rcu_read_unlock_trace(). + * + * This is a very specialized primitive, intended only for a few uses in + * tracing and other situations requiring manipulation of function preambl= es + * and profiling hooks. The synchronize_rcu_tasks_trace() function is not + * (yet) intended for heavy use from multiple CPUs. + * + * See the description of synchronize_rcu() for more detailed information + * on memory ordering guarantees. + */ +static inline void synchronize_rcu_tasks_trace(void) +{ + synchronize_srcu(&rcu_tasks_trace_srcu_struct); } =20 -void call_rcu_tasks_trace(struct rcu_head *rhp, rcu_callback_t func); -void synchronize_rcu_tasks_trace(void); -void rcu_barrier_tasks_trace(void); +/** + * rcu_barrier_tasks_trace - Wait for in-flight call_rcu_tasks_trace() cal= lbacks. + * + * Note that rcu_barrier_tasks_trace() is not obligated to actually wait, + * for example, if there are no pending callbacks. + */ +static inline void rcu_barrier_tasks_trace(void) +{ + srcu_barrier(&rcu_tasks_trace_srcu_struct); +} + +// Placeholders to enable stepwise transition. +void rcu_tasks_trace_get_gp_data(int *flags, unsigned long *gp_seq); +void __init rcu_tasks_trace_suppress_unused(void); struct task_struct *get_rcu_tasks_trace_gp_kthread(void); + #else /* * The BPF JIT forms these addresses even when it doesn't call these diff --git a/include/linux/sched.h b/include/linux/sched.h index 2b272382673d62..89d3646155525f 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -939,6 +939,7 @@ struct task_struct { =20 #ifdef CONFIG_TASKS_TRACE_RCU int trc_reader_nesting; + struct srcu_ctr __percpu *trc_reader_scp; int trc_ipi_to_cpu; union rcu_special trc_reader_special; struct list_head trc_holdout_list; diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h index 2dc044fd126eb0..418fa242cf0288 100644 --- a/kernel/rcu/tasks.h +++ b/kernel/rcu/tasks.h @@ -718,7 +718,6 @@ static void __init rcu_tasks_bootup_oddness(void) #endif /* #ifdef CONFIG_TASKS_TRACE_RCU */ } =20 - /* Dump out rcutorture-relevant state common to all RCU-tasks flavors. */ static void show_rcu_tasks_generic_gp_kthread(struct rcu_tasks *rtp, char = *s) { @@ -803,7 +802,7 @@ static void rcu_tasks_torture_stats_print_generic(struc= t rcu_tasks *rtp, char *t =20 static void exit_tasks_rcu_finish_trace(struct task_struct *t); =20 -#if defined(CONFIG_TASKS_RCU) || defined(CONFIG_TASKS_TRACE_RCU) +#if defined(CONFIG_TASKS_RCU) =20 //////////////////////////////////////////////////////////////////////// // @@ -898,7 +897,7 @@ static void rcu_tasks_wait_gp(struct rcu_tasks *rtp) rtp->postgp_func(rtp); } =20 -#endif /* #if defined(CONFIG_TASKS_RCU) || defined(CONFIG_TASKS_TRACE_RCU)= */ +#endif /* #if defined(CONFIG_TASKS_RCU) */ =20 #ifdef CONFIG_TASKS_RCU =20 @@ -1453,94 +1452,23 @@ EXPORT_SYMBOL_GPL(rcu_tasks_rude_get_gp_data); // // Tracing variant of Tasks RCU. This variant is designed to be used // to protect tracing hooks, including those of BPF. This variant -// therefore: -// -// 1. Has explicit read-side markers to allow finite grace periods -// in the face of in-kernel loops for PREEMPT=3Dn builds. -// -// 2. Protects code in the idle loop, exception entry/exit, and -// CPU-hotplug code paths, similar to the capabilities of SRCU. -// -// 3. Avoids expensive read-side instructions, having overhead similar -// to that of Preemptible RCU. -// -// There are of course downsides. For example, the grace-period code -// can send IPIs to CPUs, even when those CPUs are in the idle loop or -// in nohz_full userspace. If needed, these downsides can be at least -// partially remedied. -// -// Perhaps most important, this variant of RCU does not affect the vanilla -// flavors, rcu_preempt and rcu_sched. The fact that RCU Tasks Trace -// readers can operate from idle, offline, and exception entry/exit in no -// way allows rcu_preempt and rcu_sched readers to also do so. -// -// The implementation uses rcu_tasks_wait_gp(), which relies on function -// pointers in the rcu_tasks structure. The rcu_spawn_tasks_trace_kthread= () -// function sets these function pointers up so that rcu_tasks_wait_gp() -// invokes these functions in this order: -// -// rcu_tasks_trace_pregp_step(): -// Disables CPU hotplug, adds all currently executing tasks to the -// holdout list, then checks the state of all tasks that blocked -// or were preempted within their current RCU Tasks Trace read-side -// critical section, adding them to the holdout list if appropriate. -// Finally, this function re-enables CPU hotplug. -// The ->pertask_func() pointer is NULL, so there is no per-task processin= g. -// rcu_tasks_trace_postscan(): -// Invokes synchronize_rcu() to wait for late-stage exiting tasks -// to finish exiting. -// check_all_holdout_tasks_trace(), repeatedly until holdout list is empty: -// Scans the holdout list, attempting to identify a quiescent state -// for each task on the list. If there is a quiescent state, the -// corresponding task is removed from the holdout list. Once this -// list is empty, the grace period has completed. -// rcu_tasks_trace_postgp(): -// Provides the needed full memory barrier and does debug checks. -// -// The exit_tasks_rcu_finish_trace() synchronizes with exiting tasks. -// -// Pre-grace-period update-side code is ordered before the grace period -// via the ->cbs_lock and barriers in rcu_tasks_kthread(). Pre-grace-peri= od -// read-side code is ordered before the grace period by atomic operations -// on .b.need_qs flag of each task involved in this process, or by schedul= er -// context-switch ordering (for locked-down non-running readers). - -// The lockdep state must be outside of #ifdef to be useful. -#ifdef CONFIG_DEBUG_LOCK_ALLOC -static struct lock_class_key rcu_lock_trace_key; -struct lockdep_map rcu_trace_lock_map =3D - STATIC_LOCKDEP_MAP_INIT("rcu_read_lock_trace", &rcu_lock_trace_key); -EXPORT_SYMBOL_GPL(rcu_trace_lock_map); -#endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ +// is implemented via a straightforward mapping onto SRCU-fast. =20 #ifdef CONFIG_TASKS_TRACE_RCU =20 -// Record outstanding IPIs to each CPU. No point in sending two... -static DEFINE_PER_CPU(bool, trc_ipi_to_cpu); - -// The number of detections of task quiescent state relying on -// heavyweight readers executing explicit memory barriers. -static unsigned long n_heavy_reader_attempts; -static unsigned long n_heavy_reader_updates; -static unsigned long n_heavy_reader_ofl_updates; -static unsigned long n_trc_holdouts; +DEFINE_SRCU(rcu_tasks_trace_srcu_struct); +EXPORT_SYMBOL_GPL(rcu_tasks_trace_srcu_struct); =20 -void call_rcu_tasks_trace(struct rcu_head *rhp, rcu_callback_t func); -DEFINE_RCU_TASKS(rcu_tasks_trace, rcu_tasks_wait_gp, call_rcu_tasks_trace, - "RCU Tasks Trace"); - -/* Load from ->trc_reader_special.b.need_qs with proper ordering. */ -static u8 rcu_ld_need_qs(struct task_struct *t) +// Placeholder to suppress build errors through transition period. +void __init rcu_tasks_trace_suppress_unused(void) { - smp_mb(); // Enforce full grace-period ordering. - return smp_load_acquire(&t->trc_reader_special.b.need_qs); -} - -/* Store to ->trc_reader_special.b.need_qs with proper ordering. */ -static void rcu_st_need_qs(struct task_struct *t, u8 v) -{ - smp_store_release(&t->trc_reader_special.b.need_qs, v); - smp_mb(); // Enforce full grace-period ordering. + show_rcu_tasks_generic_gp_kthread(NULL, NULL); + rcu_spawn_tasks_kthread_generic(NULL); + synchronize_rcu_tasks_generic(NULL); + call_rcu_tasks_generic(NULL, NULL, NULL); + call_rcu_tasks_iw_wakeup(NULL); + cblist_init_generic(NULL); + rcu_tasks_torture_stats_print_generic(NULL, NULL, NULL, NULL); } =20 /* @@ -1555,321 +1483,12 @@ u8 rcu_trc_cmpxchg_need_qs(struct task_struct *t, = u8 old, u8 new) } EXPORT_SYMBOL_GPL(rcu_trc_cmpxchg_need_qs); =20 -/* - * If we are the last reader, signal the grace-period kthread. - * Also remove from the per-CPU list of blocked tasks. - */ -void rcu_read_unlock_trace_special(struct task_struct *t) -{ - unsigned long flags; - struct rcu_tasks_percpu *rtpcp; - union rcu_special trs; - - // Open-coded full-word version of rcu_ld_need_qs(). - smp_mb(); // Enforce full grace-period ordering. - trs =3D smp_load_acquire(&t->trc_reader_special); - - if (IS_ENABLED(CONFIG_TASKS_TRACE_RCU_READ_MB) && t->trc_reader_special.b= .need_mb) - smp_mb(); // Pairs with update-side barriers. - // Update .need_qs before ->trc_reader_nesting for irq/NMI handlers. - if (trs.b.need_qs =3D=3D (TRC_NEED_QS_CHECKED | TRC_NEED_QS)) { - u8 result =3D rcu_trc_cmpxchg_need_qs(t, TRC_NEED_QS_CHECKED | TRC_NEED_= QS, - TRC_NEED_QS_CHECKED); - - WARN_ONCE(result !=3D trs.b.need_qs, "%s: result =3D %d", __func__, resu= lt); - } - if (trs.b.blocked) { - rtpcp =3D per_cpu_ptr(rcu_tasks_trace.rtpcpu, t->trc_blkd_cpu); - raw_spin_lock_irqsave_rcu_node(rtpcp, flags); - list_del_init(&t->trc_blkd_node); - WRITE_ONCE(t->trc_reader_special.b.blocked, false); - raw_spin_unlock_irqrestore_rcu_node(rtpcp, flags); - } - WRITE_ONCE(t->trc_reader_nesting, 0); -} -EXPORT_SYMBOL_GPL(rcu_read_unlock_trace_special); - /* Add a newly blocked reader task to its CPU's list. */ void rcu_tasks_trace_qs_blkd(struct task_struct *t) { - unsigned long flags; - struct rcu_tasks_percpu *rtpcp; - - local_irq_save(flags); - rtpcp =3D this_cpu_ptr(rcu_tasks_trace.rtpcpu); - raw_spin_lock_rcu_node(rtpcp); // irqs already disabled - t->trc_blkd_cpu =3D smp_processor_id(); - if (!rtpcp->rtp_blkd_tasks.next) - INIT_LIST_HEAD(&rtpcp->rtp_blkd_tasks); - list_add(&t->trc_blkd_node, &rtpcp->rtp_blkd_tasks); - WRITE_ONCE(t->trc_reader_special.b.blocked, true); - raw_spin_unlock_irqrestore_rcu_node(rtpcp, flags); } EXPORT_SYMBOL_GPL(rcu_tasks_trace_qs_blkd); =20 -/* Add a task to the holdout list, if it is not already on the list. */ -static void trc_add_holdout(struct task_struct *t, struct list_head *bhp) -{ - if (list_empty(&t->trc_holdout_list)) { - get_task_struct(t); - list_add(&t->trc_holdout_list, bhp); - n_trc_holdouts++; - } -} - -/* Remove a task from the holdout list, if it is in fact present. */ -static void trc_del_holdout(struct task_struct *t) -{ - if (!list_empty(&t->trc_holdout_list)) { - list_del_init(&t->trc_holdout_list); - put_task_struct(t); - n_trc_holdouts--; - } -} - -/* IPI handler to check task state. */ -static void trc_read_check_handler(void *t_in) -{ - int nesting; - struct task_struct *t =3D current; - struct task_struct *texp =3D t_in; - - // If the task is no longer running on this CPU, leave. - if (unlikely(texp !=3D t)) - goto reset_ipi; // Already on holdout list, so will check later. - - // If the task is not in a read-side critical section, and - // if this is the last reader, awaken the grace-period kthread. - nesting =3D READ_ONCE(t->trc_reader_nesting); - if (likely(!nesting)) { - rcu_trc_cmpxchg_need_qs(t, 0, TRC_NEED_QS_CHECKED); - goto reset_ipi; - } - // If we are racing with an rcu_read_unlock_trace(), try again later. - if (unlikely(nesting < 0)) - goto reset_ipi; - - // Get here if the task is in a read-side critical section. - // Set its state so that it will update state for the grace-period - // kthread upon exit from that critical section. - rcu_trc_cmpxchg_need_qs(t, 0, TRC_NEED_QS | TRC_NEED_QS_CHECKED); - -reset_ipi: - // Allow future IPIs to be sent on CPU and for task. - // Also order this IPI handler against any later manipulations of - // the intended task. - smp_store_release(per_cpu_ptr(&trc_ipi_to_cpu, smp_processor_id()), false= ); // ^^^ - smp_store_release(&texp->trc_ipi_to_cpu, -1); // ^^^ -} - -/* Callback function for scheduler to check locked-down task. */ -static int trc_inspect_reader(struct task_struct *t, void *bhp_in) -{ - struct list_head *bhp =3D bhp_in; - int cpu =3D task_cpu(t); - int nesting; - bool ofl =3D cpu_is_offline(cpu); - - if (task_curr(t) && !ofl) { - // If no chance of heavyweight readers, do it the hard way. - if (!IS_ENABLED(CONFIG_TASKS_TRACE_RCU_READ_MB)) - return -EINVAL; - - // If heavyweight readers are enabled on the remote task, - // we can inspect its state despite its currently running. - // However, we cannot safely change its state. - n_heavy_reader_attempts++; - // Check for "running" idle tasks on offline CPUs. - if (!rcu_watching_zero_in_eqs(cpu, &t->trc_reader_nesting)) - return -EINVAL; // No quiescent state, do it the hard way. - n_heavy_reader_updates++; - nesting =3D 0; - } else { - // The task is not running, so C-language access is safe. - nesting =3D t->trc_reader_nesting; - WARN_ON_ONCE(ofl && task_curr(t) && (t !=3D idle_task(task_cpu(t)))); - if (IS_ENABLED(CONFIG_TASKS_TRACE_RCU_READ_MB) && ofl) - n_heavy_reader_ofl_updates++; - } - - // If not exiting a read-side critical section, mark as checked - // so that the grace-period kthread will remove it from the - // holdout list. - if (!nesting) { - rcu_trc_cmpxchg_need_qs(t, 0, TRC_NEED_QS_CHECKED); - return 0; // In QS, so done. - } - if (nesting < 0) - return -EINVAL; // Reader transitioning, try again later. - - // The task is in a read-side critical section, so set up its - // state so that it will update state upon exit from that critical - // section. - if (!rcu_trc_cmpxchg_need_qs(t, 0, TRC_NEED_QS | TRC_NEED_QS_CHECKED)) - trc_add_holdout(t, bhp); - return 0; -} - -/* Attempt to extract the state for the specified task. */ -static void trc_wait_for_one_reader(struct task_struct *t, - struct list_head *bhp) -{ - int cpu; - - // If a previous IPI is still in flight, let it complete. - if (smp_load_acquire(&t->trc_ipi_to_cpu) !=3D -1) // Order IPI - return; - - // The current task had better be in a quiescent state. - if (t =3D=3D current) { - rcu_trc_cmpxchg_need_qs(t, 0, TRC_NEED_QS_CHECKED); - WARN_ON_ONCE(READ_ONCE(t->trc_reader_nesting)); - return; - } - - // Attempt to nail down the task for inspection. - get_task_struct(t); - if (!task_call_func(t, trc_inspect_reader, bhp)) { - put_task_struct(t); - return; - } - put_task_struct(t); - - // If this task is not yet on the holdout list, then we are in - // an RCU read-side critical section. Otherwise, the invocation of - // trc_add_holdout() that added it to the list did the necessary - // get_task_struct(). Either way, the task cannot be freed out - // from under this code. - - // If currently running, send an IPI, either way, add to list. - trc_add_holdout(t, bhp); - if (task_curr(t) && - time_after(jiffies + 1, rcu_tasks_trace.gp_start + rcu_task_ipi_delay= )) { - // The task is currently running, so try IPIing it. - cpu =3D task_cpu(t); - - // If there is already an IPI outstanding, let it happen. - if (per_cpu(trc_ipi_to_cpu, cpu) || t->trc_ipi_to_cpu >=3D 0) - return; - - per_cpu(trc_ipi_to_cpu, cpu) =3D true; - t->trc_ipi_to_cpu =3D cpu; - rcu_tasks_trace.n_ipis++; - if (smp_call_function_single(cpu, trc_read_check_handler, t, 0)) { - // Just in case there is some other reason for - // failure than the target CPU being offline. - WARN_ONCE(1, "%s(): smp_call_function_single() failed for CPU: %d\n", - __func__, cpu); - rcu_tasks_trace.n_ipis_fails++; - per_cpu(trc_ipi_to_cpu, cpu) =3D false; - t->trc_ipi_to_cpu =3D -1; - } - } -} - -/* - * Initialize for first-round processing for the specified task. - * Return false if task is NULL or already taken care of, true otherwise. - */ -static bool rcu_tasks_trace_pertask_prep(struct task_struct *t, bool notse= lf) -{ - // During early boot when there is only the one boot CPU, there - // is no idle task for the other CPUs. Also, the grace-period - // kthread is always in a quiescent state. In addition, just return - // if this task is already on the list. - if (unlikely(t =3D=3D NULL) || (t =3D=3D current && notself) || !list_emp= ty(&t->trc_holdout_list)) - return false; - - rcu_st_need_qs(t, 0); - t->trc_ipi_to_cpu =3D -1; - return true; -} - -/* Do first-round processing for the specified task. */ -static void rcu_tasks_trace_pertask(struct task_struct *t, struct list_hea= d *hop) -{ - if (rcu_tasks_trace_pertask_prep(t, true)) - trc_wait_for_one_reader(t, hop); -} - -/* Initialize for a new RCU-tasks-trace grace period. */ -static void rcu_tasks_trace_pregp_step(struct list_head *hop) -{ - LIST_HEAD(blkd_tasks); - int cpu; - unsigned long flags; - struct rcu_tasks_percpu *rtpcp; - struct task_struct *t; - - // There shouldn't be any old IPIs, but... - for_each_possible_cpu(cpu) - WARN_ON_ONCE(per_cpu(trc_ipi_to_cpu, cpu)); - - // Disable CPU hotplug across the CPU scan for the benefit of - // any IPIs that might be needed. This also waits for all readers - // in CPU-hotplug code paths. - cpus_read_lock(); - - // These rcu_tasks_trace_pertask_prep() calls are serialized to - // allow safe access to the hop list. - for_each_online_cpu(cpu) { - rcu_read_lock(); - // Note that cpu_curr_snapshot() picks up the target - // CPU's current task while its runqueue is locked with - // an smp_mb__after_spinlock(). This ensures that either - // the grace-period kthread will see that task's read-side - // critical section or the task will see the updater's pre-GP - // accesses. The trailing smp_mb() in cpu_curr_snapshot() - // does not currently play a role other than simplify - // that function's ordering semantics. If these simplified - // ordering semantics continue to be redundant, that smp_mb() - // might be removed. - t =3D cpu_curr_snapshot(cpu); - if (rcu_tasks_trace_pertask_prep(t, true)) - trc_add_holdout(t, hop); - rcu_read_unlock(); - cond_resched_tasks_rcu_qs(); - } - - // Only after all running tasks have been accounted for is it - // safe to take care of the tasks that have blocked within their - // current RCU tasks trace read-side critical section. - for_each_possible_cpu(cpu) { - rtpcp =3D per_cpu_ptr(rcu_tasks_trace.rtpcpu, cpu); - raw_spin_lock_irqsave_rcu_node(rtpcp, flags); - list_splice_init(&rtpcp->rtp_blkd_tasks, &blkd_tasks); - while (!list_empty(&blkd_tasks)) { - rcu_read_lock(); - t =3D list_first_entry(&blkd_tasks, struct task_struct, trc_blkd_node); - list_del_init(&t->trc_blkd_node); - list_add(&t->trc_blkd_node, &rtpcp->rtp_blkd_tasks); - raw_spin_unlock_irqrestore_rcu_node(rtpcp, flags); - rcu_tasks_trace_pertask(t, hop); - rcu_read_unlock(); - raw_spin_lock_irqsave_rcu_node(rtpcp, flags); - } - raw_spin_unlock_irqrestore_rcu_node(rtpcp, flags); - cond_resched_tasks_rcu_qs(); - } - - // Re-enable CPU hotplug now that the holdout list is populated. - cpus_read_unlock(); -} - -/* - * Do intermediate processing between task and holdout scans. - */ -static void rcu_tasks_trace_postscan(struct list_head *hop) -{ - // Wait for late-stage exiting tasks to finish exiting. - // These might have passed the call to exit_tasks_rcu_finish(). - - // If you remove the following line, update rcu_trace_implies_rcu_gp()!!! - synchronize_rcu(); - // Any tasks that exit after this point will set - // TRC_NEED_QS_CHECKED in ->trc_reader_special.b.need_qs. -} - /* Communicate task state back to the RCU tasks trace stall warning reques= t. */ struct trc_stall_chk_rdr { int nesting; @@ -1877,241 +1496,39 @@ struct trc_stall_chk_rdr { u8 needqs; }; =20 -static int trc_check_slow_task(struct task_struct *t, void *arg) -{ - struct trc_stall_chk_rdr *trc_rdrp =3D arg; - - if (task_curr(t) && cpu_online(task_cpu(t))) - return false; // It is running, so decline to inspect it. - trc_rdrp->nesting =3D READ_ONCE(t->trc_reader_nesting); - trc_rdrp->ipi_to_cpu =3D READ_ONCE(t->trc_ipi_to_cpu); - trc_rdrp->needqs =3D rcu_ld_need_qs(t); - return true; -} - -/* Show the state of a task stalling the current RCU tasks trace GP. */ -static void show_stalled_task_trace(struct task_struct *t, bool *firstrepo= rt) -{ - int cpu; - struct trc_stall_chk_rdr trc_rdr; - bool is_idle_tsk =3D is_idle_task(t); - - if (*firstreport) { - pr_err("INFO: rcu_tasks_trace detected stalls on tasks:\n"); - *firstreport =3D false; - } - cpu =3D task_cpu(t); - if (!task_call_func(t, trc_check_slow_task, &trc_rdr)) - pr_alert("P%d: %c%c\n", - t->pid, - ".I"[t->trc_ipi_to_cpu >=3D 0], - ".i"[is_idle_tsk]); - else - pr_alert("P%d: %c%c%c%c nesting: %d%c%c cpu: %d%s\n", - t->pid, - ".I"[trc_rdr.ipi_to_cpu >=3D 0], - ".i"[is_idle_tsk], - ".N"[cpu >=3D 0 && tick_nohz_full_cpu(cpu)], - ".B"[!!data_race(t->trc_reader_special.b.blocked)], - trc_rdr.nesting, - " !CN"[trc_rdr.needqs & 0x3], - " ?"[trc_rdr.needqs > 0x3], - cpu, cpu_online(cpu) ? "" : "(offline)"); - sched_show_task(t); -} - -/* List stalled IPIs for RCU tasks trace. */ -static void show_stalled_ipi_trace(void) -{ - int cpu; - - for_each_possible_cpu(cpu) - if (per_cpu(trc_ipi_to_cpu, cpu)) - pr_alert("\tIPI outstanding to CPU %d\n", cpu); -} - -/* Do one scan of the holdout list. */ -static void check_all_holdout_tasks_trace(struct list_head *hop, - bool needreport, bool *firstreport) -{ - struct task_struct *g, *t; - - // Disable CPU hotplug across the holdout list scan for IPIs. - cpus_read_lock(); - - list_for_each_entry_safe(t, g, hop, trc_holdout_list) { - // If safe and needed, try to check the current task. - if (READ_ONCE(t->trc_ipi_to_cpu) =3D=3D -1 && - !(rcu_ld_need_qs(t) & TRC_NEED_QS_CHECKED)) - trc_wait_for_one_reader(t, hop); - - // If check succeeded, remove this task from the list. - if (smp_load_acquire(&t->trc_ipi_to_cpu) =3D=3D -1 && - rcu_ld_need_qs(t) =3D=3D TRC_NEED_QS_CHECKED) - trc_del_holdout(t); - else if (needreport) - show_stalled_task_trace(t, firstreport); - cond_resched_tasks_rcu_qs(); - } - - // Re-enable CPU hotplug now that the holdout list scan has completed. - cpus_read_unlock(); - - if (needreport) { - if (*firstreport) - pr_err("INFO: rcu_tasks_trace detected stalls? (Late IPI?)\n"); - show_stalled_ipi_trace(); - } -} - -static void rcu_tasks_trace_empty_fn(void *unused) -{ -} - -/* Wait for grace period to complete and provide ordering. */ -static void rcu_tasks_trace_postgp(struct rcu_tasks *rtp) -{ - int cpu; - - // Wait for any lingering IPI handlers to complete. Note that - // if a CPU has gone offline or transitioned to userspace in the - // meantime, all IPI handlers should have been drained beforehand. - // Yes, this assumes that CPUs process IPIs in order. If that ever - // changes, there will need to be a recheck and/or timed wait. - for_each_online_cpu(cpu) - if (WARN_ON_ONCE(smp_load_acquire(per_cpu_ptr(&trc_ipi_to_cpu, cpu)))) - smp_call_function_single(cpu, rcu_tasks_trace_empty_fn, NULL, 1); - - smp_mb(); // Caller's code must be ordered after wakeup. - // Pairs with pretty much every ordering primitive. -} - /* Report any needed quiescent state for this exiting task. */ static void exit_tasks_rcu_finish_trace(struct task_struct *t) { - union rcu_special trs =3D READ_ONCE(t->trc_reader_special); - - rcu_trc_cmpxchg_need_qs(t, 0, TRC_NEED_QS_CHECKED); - WARN_ON_ONCE(READ_ONCE(t->trc_reader_nesting)); - if (WARN_ON_ONCE(rcu_ld_need_qs(t) & TRC_NEED_QS || trs.b.blocked)) - rcu_read_unlock_trace_special(t); - else - WRITE_ONCE(t->trc_reader_nesting, 0); -} - -/** - * call_rcu_tasks_trace() - Queue a callback trace task-based grace period - * @rhp: structure to be used for queueing the RCU updates. - * @func: actual callback function to be invoked after the grace period - * - * The callback function will be invoked some time after a trace rcu-tasks - * grace period elapses, in other words after all currently executing - * trace rcu-tasks read-side critical sections have completed. These - * read-side critical sections are delimited by calls to rcu_read_lock_tra= ce() - * and rcu_read_unlock_trace(). - * - * See the description of call_rcu() for more detailed information on - * memory ordering guarantees. - */ -void call_rcu_tasks_trace(struct rcu_head *rhp, rcu_callback_t func) -{ - call_rcu_tasks_generic(rhp, func, &rcu_tasks_trace); -} -EXPORT_SYMBOL_GPL(call_rcu_tasks_trace); - -/** - * synchronize_rcu_tasks_trace - wait for a trace rcu-tasks grace period - * - * Control will return to the caller some time after a trace rcu-tasks - * grace period has elapsed, in other words after all currently executing - * trace rcu-tasks read-side critical sections have elapsed. These read-si= de - * critical sections are delimited by calls to rcu_read_lock_trace() - * and rcu_read_unlock_trace(). - * - * This is a very specialized primitive, intended only for a few uses in - * tracing and other situations requiring manipulation of function preambl= es - * and profiling hooks. The synchronize_rcu_tasks_trace() function is not - * (yet) intended for heavy use from multiple CPUs. - * - * See the description of synchronize_rcu() for more detailed information - * on memory ordering guarantees. - */ -void synchronize_rcu_tasks_trace(void) -{ - RCU_LOCKDEP_WARN(lock_is_held(&rcu_trace_lock_map), "Illegal synchronize_= rcu_tasks_trace() in RCU Tasks Trace read-side critical section"); - synchronize_rcu_tasks_generic(&rcu_tasks_trace); } -EXPORT_SYMBOL_GPL(synchronize_rcu_tasks_trace); - -/** - * rcu_barrier_tasks_trace - Wait for in-flight call_rcu_tasks_trace() cal= lbacks. - * - * Although the current implementation is guaranteed to wait, it is not - * obligated to, for example, if there are no pending callbacks. - */ -void rcu_barrier_tasks_trace(void) -{ - rcu_barrier_tasks_generic(&rcu_tasks_trace); -} -EXPORT_SYMBOL_GPL(rcu_barrier_tasks_trace); =20 int rcu_tasks_trace_lazy_ms =3D -1; module_param(rcu_tasks_trace_lazy_ms, int, 0444); =20 static int __init rcu_spawn_tasks_trace_kthread(void) { - if (IS_ENABLED(CONFIG_TASKS_TRACE_RCU_READ_MB)) { - rcu_tasks_trace.gp_sleep =3D HZ / 10; - rcu_tasks_trace.init_fract =3D HZ / 10; - } else { - rcu_tasks_trace.gp_sleep =3D HZ / 200; - if (rcu_tasks_trace.gp_sleep <=3D 0) - rcu_tasks_trace.gp_sleep =3D 1; - rcu_tasks_trace.init_fract =3D HZ / 200; - if (rcu_tasks_trace.init_fract <=3D 0) - rcu_tasks_trace.init_fract =3D 1; - } - if (rcu_tasks_trace_lazy_ms >=3D 0) - rcu_tasks_trace.lazy_jiffies =3D msecs_to_jiffies(rcu_tasks_trace_lazy_m= s); - rcu_tasks_trace.pregp_func =3D rcu_tasks_trace_pregp_step; - rcu_tasks_trace.postscan_func =3D rcu_tasks_trace_postscan; - rcu_tasks_trace.holdouts_func =3D check_all_holdout_tasks_trace; - rcu_tasks_trace.postgp_func =3D rcu_tasks_trace_postgp; - rcu_spawn_tasks_kthread_generic(&rcu_tasks_trace); return 0; } =20 #if !defined(CONFIG_TINY_RCU) void show_rcu_tasks_trace_gp_kthread(void) { - char buf[64]; - - snprintf(buf, sizeof(buf), "N%lu h:%lu/%lu/%lu", - data_race(n_trc_holdouts), - data_race(n_heavy_reader_ofl_updates), - data_race(n_heavy_reader_updates), - data_race(n_heavy_reader_attempts)); - show_rcu_tasks_generic_gp_kthread(&rcu_tasks_trace, buf); } EXPORT_SYMBOL_GPL(show_rcu_tasks_trace_gp_kthread); =20 void rcu_tasks_trace_torture_stats_print(char *tt, char *tf) { - rcu_tasks_torture_stats_print_generic(&rcu_tasks_trace, tt, tf, ""); } EXPORT_SYMBOL_GPL(rcu_tasks_trace_torture_stats_print); #endif // !defined(CONFIG_TINY_RCU) =20 struct task_struct *get_rcu_tasks_trace_gp_kthread(void) { - return rcu_tasks_trace.kthread_ptr; + return NULL; } EXPORT_SYMBOL_GPL(get_rcu_tasks_trace_gp_kthread); =20 void rcu_tasks_trace_get_gp_data(int *flags, unsigned long *gp_seq) { - *flags =3D 0; - *gp_seq =3D rcu_seq_current(&rcu_tasks_trace.tasks_gp_seq); } EXPORT_SYMBOL_GPL(rcu_tasks_trace_get_gp_data); =20 @@ -2251,10 +1668,6 @@ void __init tasks_cblist_init_generic(void) #ifdef CONFIG_TASKS_RUDE_RCU cblist_init_generic(&rcu_tasks_rude); #endif - -#ifdef CONFIG_TASKS_TRACE_RCU - cblist_init_generic(&rcu_tasks_trace); -#endif } =20 static int __init rcu_init_tasks_generic(void) --=20 2.40.1 From nobody Wed Oct 1 20:32:42 2025 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 5D0232550D4; Wed, 1 Oct 2025 14:48:37 +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=1759330117; cv=none; b=ezpM+OzqX+Qv/Kwz4NHzis3SRaRVUovudGP/grPxE85mDCUQi/KtlhBVNdd2v8tvy8vkQsD86hRr4QfFAKJox7s6DR31rLsyBqMDFbUfNOSf9Fi8hc9hPMUti+LKcg9yegeSGsMiarXXWvbsUPLpJgljhZ020A0ACQ90gAebPtU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759330117; c=relaxed/simple; bh=gORzw/K5miRE/rNReHV1tjj65oo9eOSliJxhQHUaXtc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=m8ogYNaBFCWfeq8RdEdTVEKjsFXgO5HfK+B8HdnHJcTwIrEY7LzXkW/DteGC+eq89/UdpqwMjLom9VqLMw+YJeiY8DpuAq8jJmZY2aWUIWwn9qGghsR4HkW7igb3INlvRVl37O4Ycs2E17+GPK5UGTgMvYeIu7Otg9me2ixoAXw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=TAjk6kgo; 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="TAjk6kgo" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CBA60C4CEF1; Wed, 1 Oct 2025 14:48:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1759330117; bh=gORzw/K5miRE/rNReHV1tjj65oo9eOSliJxhQHUaXtc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TAjk6kgoN0vOc2F0MkIZtzNr7hH4kTxjfAyN/4fVnEOvFSXXNfHvbBtn1rXkw5DjZ YXNsEI/ph4XsHnjkmHjPryT3fASSsNefGPzmPJ1EHwqrWrpm82yhlUB8lKMGlZIIXN kQsF8svNELpG7AUexB8v1tTConjdElRG9zjdyJ3j7TUZ7YhUK1gVKh0mFS+qYoqXU6 lEJM58sgpLQZBoEs3/kaZwYHDbCFMguvdHZ2LCeVAnApaW1uC4U32eJRzcXGbHv6bO dL2iI7gfjXo4EFMMfaSkiYZEiAj0ozo/qDJOeooxunJ9bzaexSDHVxR+867XQC1p1R zALpxcOb3+CNQ== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 677A3CE10DB; Wed, 1 Oct 2025 07:48:34 -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" , Frederic Weisbecker , Andrii Nakryiko , Alexei Starovoitov , Peter Zijlstra , bpf@vger.kernel.org Subject: [PATCH v2 03/21] context_tracking: Remove rcu_task_trace_heavyweight_{enter,exit}() Date: Wed, 1 Oct 2025 07:48:14 -0700 Message-Id: <20251001144832.631770-3-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> References: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Because SRCU-fast does not use IPIs for its grace periods, there is no need for real-time workloads to switch to an IPI-free mode, and there is in turn no need for either rcu_task_trace_heavyweight_enter() or rcu_task_trace_heavyweight_exit(). This commit therefore removes them. Signed-off-by: Paul E. McKenney Cc: Frederic Weisbecker Cc: Andrii Nakryiko Cc: Alexei Starovoitov Cc: Peter Zijlstra Cc: --- kernel/context_tracking.c | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/kernel/context_tracking.c b/kernel/context_tracking.c index fb5be6e9b423f2..a743e7ffa6c00f 100644 --- a/kernel/context_tracking.c +++ b/kernel/context_tracking.c @@ -54,24 +54,6 @@ static __always_inline void rcu_task_enter(void) #endif /* #if defined(CONFIG_TASKS_RCU) && defined(CONFIG_NO_HZ_FULL) */ } =20 -/* Turn on heavyweight RCU tasks trace readers on kernel exit. */ -static __always_inline void rcu_task_trace_heavyweight_enter(void) -{ -#ifdef CONFIG_TASKS_TRACE_RCU - if (IS_ENABLED(CONFIG_TASKS_TRACE_RCU_READ_MB)) - current->trc_reader_special.b.need_mb =3D true; -#endif /* #ifdef CONFIG_TASKS_TRACE_RCU */ -} - -/* Turn off heavyweight RCU tasks trace readers on kernel entry. */ -static __always_inline void rcu_task_trace_heavyweight_exit(void) -{ -#ifdef CONFIG_TASKS_TRACE_RCU - if (IS_ENABLED(CONFIG_TASKS_TRACE_RCU_READ_MB)) - current->trc_reader_special.b.need_mb =3D false; -#endif /* #ifdef CONFIG_TASKS_TRACE_RCU */ -} - /* * Record entry into an extended quiescent state. This is only to be * called when not already in an extended quiescent state, that is, @@ -85,7 +67,6 @@ static noinstr void ct_kernel_exit_state(int offset) * critical sections, and we also must force ordering with the * next idle sojourn. */ - rcu_task_trace_heavyweight_enter(); // Before CT state update! // RCU is still watching. Better not be in extended quiescent state! WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && !rcu_is_watching_curr_cp= u()); (void)ct_state_inc(offset); @@ -108,7 +89,6 @@ static noinstr void ct_kernel_enter_state(int offset) */ seq =3D ct_state_inc(offset); // RCU is now watching. Better not be in an extended quiescent state! - rcu_task_trace_heavyweight_exit(); // After CT state update! WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && !(seq & CT_RCU_WATCHING)= ); } =20 --=20 2.40.1 From nobody Wed Oct 1 20:32:42 2025 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 9D550259CBD; Wed, 1 Oct 2025 14:48:37 +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=1759330117; cv=none; b=PQQxZxHjbTQZP3FSpM3En4ZByQt2CaNMUXZeOxED65V8ZR88595tI4vZnsEEJ13SJzAOkdHVN8h0U0epkJhBa94hsw+qbk5+CDQXh+050LcfANubYck9dzbQjVzpGX4uXgpJRE5bVxTjcL/4IErOwWY2ukbs7b0MvWnB7N67RG8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759330117; c=relaxed/simple; bh=zC2jQuHnhQLXYOXbzbMX2xSQ36GfWdKCHr/v1rDApwM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=B9sKqTcuNiodANezFGUiYMIfLXyK9rbVkZejrKryP9+7CG8nFgDpKmaY/PNCZXcUXQ1MUQ0/s+x38C+UUp0WOnIUMDeWNFwH3mec4yqyTuQUCqaKNFgJ2kxZt/Ji03rUi9IRiqAgNYXk+B/LlYpBfOoXi+0fGVlwf4zgz8ddSCc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=TH7/EZiU; 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="TH7/EZiU" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D1A44C4CEFA; Wed, 1 Oct 2025 14:48:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1759330117; bh=zC2jQuHnhQLXYOXbzbMX2xSQ36GfWdKCHr/v1rDApwM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TH7/EZiUdVbE5CBtyeS+f4EKfAkK0pUNGXWMcvD1G1p8P3LEZ4flJKc+p6iWyEx+7 FVNdfk976UWT6x4qfJz9MgAtYPYJ6WXRCOda2tuMjwujEgl0PsXa1XjTg88MWvAHaY klJTWfgasuGSC0KDWtXdk8MS9GJW2QlABeDAfgvfUKowNJFoYxCqZv+NWLcPsE/F0I 5JcgpZUOoyPqAgt5EzHu4uMJYBa2G2V8Up3JTbXaKOflrRD6BaLzPSqxYyAThBPl4d 4bLfeJEznF17ai5yscID5KIgnw+Njy5H5EOMABq7PA56zuczbKXPLt90tY8L0UbbCE AbYk/pJTJyMNw== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 6A57CCE1109; Wed, 1 Oct 2025 07:48:34 -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" , Andrii Nakryiko , Alexei Starovoitov , Peter Zijlstra , bpf@vger.kernel.org Subject: [PATCH v2 04/21] rcu: Clean up after the SRCU-fastification of RCU Tasks Trace Date: Wed, 1 Oct 2025 07:48:15 -0700 Message-Id: <20251001144832.631770-4-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> References: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Now that RCU Tasks Trace has been re-implemented in terms of SRCU-fast, the ->trc_ipi_to_cpu, ->trc_blkd_cpu, ->trc_blkd_node, ->trc_holdout_list, and ->trc_reader_special task_struct fields are no longer used. In addition, the rcu_tasks_trace_qs(), rcu_tasks_trace_qs_blkd(), exit_tasks_rcu_finish_trace(), and rcu_spawn_tasks_trace_kthread(), show_rcu_tasks_trace_gp_kthread(), rcu_tasks_trace_get_gp_data(), rcu_tasks_trace_torture_stats_print(), and get_rcu_tasks_trace_gp_kthread() functions and all the other functions that they invoke are no longer used. Also, the TRC_NEED_QS and TRC_NEED_QS_CHECKED CPP macros are no longer used. Neither are the rcu_tasks_trace_lazy_ms and rcu_task_ipi_delay rcupdate module parameters and the TASKS_TRACE_RCU_READ_MB Kconfig option. This commit therefore removes all of them. [ paulmck: Apply Alexei Starovoitov feedback. ] Signed-off-by: Paul E. McKenney Cc: Andrii Nakryiko Cc: Alexei Starovoitov Cc: Peter Zijlstra Cc: --- .../admin-guide/kernel-parameters.txt | 15 ---- include/linux/rcupdate.h | 31 +------- include/linux/rcupdate_trace.h | 2 - include/linux/sched.h | 5 -- init/init_task.c | 3 - kernel/fork.c | 3 - kernel/rcu/Kconfig | 18 ----- kernel/rcu/rcu.h | 9 --- kernel/rcu/rcuscale.c | 7 -- kernel/rcu/rcutorture.c | 2 - kernel/rcu/tasks.h | 79 +------------------ .../selftests/rcutorture/configs/rcu/TRACE01 | 1 - .../selftests/rcutorture/configs/rcu/TRACE02 | 1 - 13 files changed, 2 insertions(+), 174 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentatio= n/admin-guide/kernel-parameters.txt index 747a55abf4946b..40fc198bed4db9 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -6078,13 +6078,6 @@ dynamically) adjusted. This parameter is intended for use in testing. =20 - rcupdate.rcu_task_ipi_delay=3D [KNL] - Set time in jiffies during which RCU tasks will - avoid sending IPIs, starting with the beginning - of a given grace period. Setting a large - number avoids disturbing real-time workloads, - but lengthens grace periods. - rcupdate.rcu_task_lazy_lim=3D [KNL] Number of callbacks on a given CPU that will cancel laziness on that CPU. Use -1 to disable @@ -6128,14 +6121,6 @@ of zero will disable batching. Batching is always disabled for synchronize_rcu_tasks(). =20 - rcupdate.rcu_tasks_trace_lazy_ms=3D [KNL] - Set timeout in milliseconds RCU Tasks - Trace asynchronous callback batching for - call_rcu_tasks_trace(). A negative value - will take the default. A value of zero will - disable batching. Batching is always disabled - for synchronize_rcu_tasks_trace(). - rcupdate.rcu_self_test=3D [KNL] Run the RCU early boot self tests =20 diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 120536f4c6eb1d..2237c56d32417b 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -175,36 +175,7 @@ void rcu_tasks_torture_stats_print(char *tt, char *tf); # define synchronize_rcu_tasks synchronize_rcu # endif =20 -# ifdef CONFIG_TASKS_TRACE_RCU -// Bits for ->trc_reader_special.b.need_qs field. -#define TRC_NEED_QS 0x1 // Task needs a quiescent state. -#define TRC_NEED_QS_CHECKED 0x2 // Task has been checked for needing quie= scent state. - -u8 rcu_trc_cmpxchg_need_qs(struct task_struct *t, u8 old, u8 new); -void rcu_tasks_trace_qs_blkd(struct task_struct *t); - -# define rcu_tasks_trace_qs(t) \ - do { \ - int ___rttq_nesting =3D READ_ONCE((t)->trc_reader_nesting); \ - \ - if (unlikely(READ_ONCE((t)->trc_reader_special.b.need_qs) =3D=3D TRC_NEE= D_QS) && \ - likely(!___rttq_nesting)) { \ - rcu_trc_cmpxchg_need_qs((t), TRC_NEED_QS, TRC_NEED_QS_CHECKED); \ - } else if (___rttq_nesting && ___rttq_nesting !=3D INT_MIN && \ - !READ_ONCE((t)->trc_reader_special.b.blocked)) { \ - rcu_tasks_trace_qs_blkd(t); \ - } \ - } while (0) -void rcu_tasks_trace_torture_stats_print(char *tt, char *tf); -# else -# define rcu_tasks_trace_qs(t) do { } while (0) -# endif - -#define rcu_tasks_qs(t, preempt) \ -do { \ - rcu_tasks_classic_qs((t), (preempt)); \ - rcu_tasks_trace_qs(t); \ -} while (0) +#define rcu_tasks_qs(t, preempt) rcu_tasks_classic_qs((t), (preempt)) =20 # ifdef CONFIG_TASKS_RUDE_RCU void synchronize_rcu_tasks_rude(void); diff --git a/include/linux/rcupdate_trace.h b/include/linux/rcupdate_trace.h index 3f46cbe6700038..0bd47f12ecd17b 100644 --- a/include/linux/rcupdate_trace.h +++ b/include/linux/rcupdate_trace.h @@ -136,9 +136,7 @@ static inline void rcu_barrier_tasks_trace(void) } =20 // Placeholders to enable stepwise transition. -void rcu_tasks_trace_get_gp_data(int *flags, unsigned long *gp_seq); void __init rcu_tasks_trace_suppress_unused(void); -struct task_struct *get_rcu_tasks_trace_gp_kthread(void); =20 #else /* diff --git a/include/linux/sched.h b/include/linux/sched.h index 89d3646155525f..577fafd22a0e6f 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -940,11 +940,6 @@ struct task_struct { #ifdef CONFIG_TASKS_TRACE_RCU int trc_reader_nesting; struct srcu_ctr __percpu *trc_reader_scp; - int trc_ipi_to_cpu; - union rcu_special trc_reader_special; - struct list_head trc_holdout_list; - struct list_head trc_blkd_node; - int trc_blkd_cpu; #endif /* #ifdef CONFIG_TASKS_TRACE_RCU */ =20 struct sched_info sched_info; diff --git a/init/init_task.c b/init/init_task.c index e557f622bd9061..0c075f3cc8fc5a 100644 --- a/init/init_task.c +++ b/init/init_task.c @@ -165,9 +165,6 @@ struct task_struct init_task __aligned(L1_CACHE_BYTES) = =3D { #endif #ifdef CONFIG_TASKS_TRACE_RCU .trc_reader_nesting =3D 0, - .trc_reader_special.s =3D 0, - .trc_holdout_list =3D LIST_HEAD_INIT(init_task.trc_holdout_list), - .trc_blkd_node =3D LIST_HEAD_INIT(init_task.trc_blkd_node), #endif #ifdef CONFIG_CPUSETS .mems_allowed_seq =3D SEQCNT_SPINLOCK_ZERO(init_task.mems_allowed_seq, diff --git a/kernel/fork.c b/kernel/fork.c index af673856499dca..5686d50b62cfaf 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1780,9 +1780,6 @@ static inline void rcu_copy_process(struct task_struc= t *p) #endif /* #ifdef CONFIG_TASKS_RCU */ #ifdef CONFIG_TASKS_TRACE_RCU p->trc_reader_nesting =3D 0; - p->trc_reader_special.s =3D 0; - INIT_LIST_HEAD(&p->trc_holdout_list); - INIT_LIST_HEAD(&p->trc_blkd_node); #endif /* #ifdef CONFIG_TASKS_TRACE_RCU */ } =20 diff --git a/kernel/rcu/Kconfig b/kernel/rcu/Kconfig index ceaf6594f634cd..54b4c4aa553a4a 100644 --- a/kernel/rcu/Kconfig +++ b/kernel/rcu/Kconfig @@ -313,24 +313,6 @@ config RCU_NOCB_CPU_CB_BOOST Say Y here if you want to set RT priority for offloading kthreads. Say N here if you are building a !PREEMPT_RT kernel and are unsure. =20 -config TASKS_TRACE_RCU_READ_MB - bool "Tasks Trace RCU readers use memory barriers in user and idle" - depends on RCU_EXPERT && TASKS_TRACE_RCU - default PREEMPT_RT || NR_CPUS < 8 - help - Use this option to further reduce the number of IPIs sent - to CPUs executing in userspace or idle during tasks trace - RCU grace periods. Given that a reasonable setting of - the rcupdate.rcu_task_ipi_delay kernel boot parameter - eliminates such IPIs for many workloads, proper setting - of this Kconfig option is important mostly for aggressive - real-time installations and for battery-powered devices, - hence the default chosen above. - - Say Y here if you hate IPIs. - Say N here if you hate read-side memory barriers. - Take the default if you are unsure. - config RCU_LAZY bool "RCU callback lazy invocation functionality" depends on RCU_NOCB_CPU diff --git a/kernel/rcu/rcu.h b/kernel/rcu/rcu.h index 9cf01832a6c3d1..dc5d614b372c1e 100644 --- a/kernel/rcu/rcu.h +++ b/kernel/rcu/rcu.h @@ -544,10 +544,6 @@ struct task_struct *get_rcu_tasks_rude_gp_kthread(void= ); void rcu_tasks_rude_get_gp_data(int *flags, unsigned long *gp_seq); #endif // # ifdef CONFIG_TASKS_RUDE_RCU =20 -#ifdef CONFIG_TASKS_TRACE_RCU -void rcu_tasks_trace_get_gp_data(int *flags, unsigned long *gp_seq); -#endif - #ifdef CONFIG_TASKS_RCU_GENERIC void tasks_cblist_init_generic(void); #else /* #ifdef CONFIG_TASKS_RCU_GENERIC */ @@ -673,11 +669,6 @@ void show_rcu_tasks_rude_gp_kthread(void); #else static inline void show_rcu_tasks_rude_gp_kthread(void) {} #endif -#if !defined(CONFIG_TINY_RCU) && defined(CONFIG_TASKS_TRACE_RCU) -void show_rcu_tasks_trace_gp_kthread(void); -#else -static inline void show_rcu_tasks_trace_gp_kthread(void) {} -#endif =20 #ifdef CONFIG_TINY_RCU static inline bool rcu_cpu_beenfullyonline(int cpu) { return true; } diff --git a/kernel/rcu/rcuscale.c b/kernel/rcu/rcuscale.c index b521d04559927a..17d038e26b65de 100644 --- a/kernel/rcu/rcuscale.c +++ b/kernel/rcu/rcuscale.c @@ -400,11 +400,6 @@ static void tasks_trace_scale_read_unlock(int idx) rcu_read_unlock_trace(); } =20 -static void rcu_tasks_trace_scale_stats(void) -{ - rcu_tasks_trace_torture_stats_print(scale_type, SCALE_FLAG); -} - static struct rcu_scale_ops tasks_tracing_ops =3D { .ptype =3D RCU_TASKS_FLAVOR, .init =3D rcu_sync_scale_init, @@ -416,8 +411,6 @@ static struct rcu_scale_ops tasks_tracing_ops =3D { .gp_barrier =3D rcu_barrier_tasks_trace, .sync =3D synchronize_rcu_tasks_trace, .exp_sync =3D synchronize_rcu_tasks_trace, - .rso_gp_kthread =3D get_rcu_tasks_trace_gp_kthread, - .stats =3D IS_ENABLED(CONFIG_TINY_RCU) ? NULL : rcu_tasks_trace_scale_st= ats, .name =3D "tasks-tracing" }; =20 diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 72619e5e8549dc..485fa822b6a753 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -1130,8 +1130,6 @@ static struct rcu_torture_ops tasks_tracing_ops =3D { .exp_sync =3D synchronize_rcu_tasks_trace, .call =3D call_rcu_tasks_trace, .cb_barrier =3D rcu_barrier_tasks_trace, - .gp_kthread_dbg =3D show_rcu_tasks_trace_gp_kthread, - .get_gp_data =3D rcu_tasks_trace_get_gp_data, .cbflood_max =3D 50000, .irq_capable =3D 1, .slow_gps =3D 1, diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h index 418fa242cf0288..fd1fe80ddde484 100644 --- a/kernel/rcu/tasks.h +++ b/kernel/rcu/tasks.h @@ -161,11 +161,6 @@ static void tasks_rcu_exit_srcu_stall(struct timer_lis= t *unused); static DEFINE_TIMER(tasks_rcu_exit_srcu_stall_timer, tasks_rcu_exit_srcu_s= tall); #endif =20 -/* Avoid IPIing CPUs early in the grace period. */ -#define RCU_TASK_IPI_DELAY (IS_ENABLED(CONFIG_TASKS_TRACE_RCU_READ_MB) ? H= Z / 2 : 0) -static int rcu_task_ipi_delay __read_mostly =3D RCU_TASK_IPI_DELAY; -module_param(rcu_task_ipi_delay, int, 0644); - /* Control stall timeouts. Disable with <=3D 0, otherwise jiffies till st= all. */ #define RCU_TASK_BOOT_STALL_TIMEOUT (HZ * 30) #define RCU_TASK_STALL_TIMEOUT (HZ * 60 * 10) @@ -800,8 +795,6 @@ static void rcu_tasks_torture_stats_print_generic(struc= t rcu_tasks *rtp, char *t =20 #endif // #ifndef CONFIG_TINY_RCU =20 -static void exit_tasks_rcu_finish_trace(struct task_struct *t); - #if defined(CONFIG_TASKS_RCU) =20 //////////////////////////////////////////////////////////////////////// @@ -1321,13 +1314,11 @@ void exit_tasks_rcu_finish(void) raw_spin_lock_irqsave_rcu_node(rtpcp, flags); list_del_init(&t->rcu_tasks_exit_list); raw_spin_unlock_irqrestore_rcu_node(rtpcp, flags); - - exit_tasks_rcu_finish_trace(t); } =20 #else /* #ifdef CONFIG_TASKS_RCU */ void exit_tasks_rcu_start(void) { } -void exit_tasks_rcu_finish(void) { exit_tasks_rcu_finish_trace(current); } +void exit_tasks_rcu_finish(void) { } #endif /* #else #ifdef CONFIG_TASKS_RCU */ =20 #ifdef CONFIG_TASKS_RUDE_RCU @@ -1471,69 +1462,6 @@ void __init rcu_tasks_trace_suppress_unused(void) rcu_tasks_torture_stats_print_generic(NULL, NULL, NULL, NULL); } =20 -/* - * Do a cmpxchg() on ->trc_reader_special.b.need_qs, allowing for - * the four-byte operand-size restriction of some platforms. - * - * Returns the old value, which is often ignored. - */ -u8 rcu_trc_cmpxchg_need_qs(struct task_struct *t, u8 old, u8 new) -{ - return cmpxchg(&t->trc_reader_special.b.need_qs, old, new); -} -EXPORT_SYMBOL_GPL(rcu_trc_cmpxchg_need_qs); - -/* Add a newly blocked reader task to its CPU's list. */ -void rcu_tasks_trace_qs_blkd(struct task_struct *t) -{ -} -EXPORT_SYMBOL_GPL(rcu_tasks_trace_qs_blkd); - -/* Communicate task state back to the RCU tasks trace stall warning reques= t. */ -struct trc_stall_chk_rdr { - int nesting; - int ipi_to_cpu; - u8 needqs; -}; - -/* Report any needed quiescent state for this exiting task. */ -static void exit_tasks_rcu_finish_trace(struct task_struct *t) -{ -} - -int rcu_tasks_trace_lazy_ms =3D -1; -module_param(rcu_tasks_trace_lazy_ms, int, 0444); - -static int __init rcu_spawn_tasks_trace_kthread(void) -{ - return 0; -} - -#if !defined(CONFIG_TINY_RCU) -void show_rcu_tasks_trace_gp_kthread(void) -{ -} -EXPORT_SYMBOL_GPL(show_rcu_tasks_trace_gp_kthread); - -void rcu_tasks_trace_torture_stats_print(char *tt, char *tf) -{ -} -EXPORT_SYMBOL_GPL(rcu_tasks_trace_torture_stats_print); -#endif // !defined(CONFIG_TINY_RCU) - -struct task_struct *get_rcu_tasks_trace_gp_kthread(void) -{ - return NULL; -} -EXPORT_SYMBOL_GPL(get_rcu_tasks_trace_gp_kthread); - -void rcu_tasks_trace_get_gp_data(int *flags, unsigned long *gp_seq) -{ -} -EXPORT_SYMBOL_GPL(rcu_tasks_trace_get_gp_data); - -#else /* #ifdef CONFIG_TASKS_TRACE_RCU */ -static void exit_tasks_rcu_finish_trace(struct task_struct *t) { } #endif /* #else #ifdef CONFIG_TASKS_TRACE_RCU */ =20 #ifndef CONFIG_TINY_RCU @@ -1541,7 +1469,6 @@ void show_rcu_tasks_gp_kthreads(void) { show_rcu_tasks_classic_gp_kthread(); show_rcu_tasks_rude_gp_kthread(); - show_rcu_tasks_trace_gp_kthread(); } #endif /* #ifndef CONFIG_TINY_RCU */ =20 @@ -1680,10 +1607,6 @@ static int __init rcu_init_tasks_generic(void) rcu_spawn_tasks_rude_kthread(); #endif =20 -#ifdef CONFIG_TASKS_TRACE_RCU - rcu_spawn_tasks_trace_kthread(); -#endif - // Run the self-tests. rcu_tasks_initiate_self_tests(); =20 diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TRACE01 b/tools= /testing/selftests/rcutorture/configs/rcu/TRACE01 index 85b407467454a2..18efab346381a4 100644 --- a/tools/testing/selftests/rcutorture/configs/rcu/TRACE01 +++ b/tools/testing/selftests/rcutorture/configs/rcu/TRACE01 @@ -10,5 +10,4 @@ CONFIG_PROVE_LOCKING=3Dn #CHECK#CONFIG_PROVE_RCU=3Dn CONFIG_FORCE_TASKS_TRACE_RCU=3Dy #CHECK#CONFIG_TASKS_TRACE_RCU=3Dy -CONFIG_TASKS_TRACE_RCU_READ_MB=3Dy CONFIG_RCU_EXPERT=3Dy diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TRACE02 b/tools= /testing/selftests/rcutorture/configs/rcu/TRACE02 index 9003c56cd76484..8da390e8282977 100644 --- a/tools/testing/selftests/rcutorture/configs/rcu/TRACE02 +++ b/tools/testing/selftests/rcutorture/configs/rcu/TRACE02 @@ -9,6 +9,5 @@ CONFIG_PROVE_LOCKING=3Dy #CHECK#CONFIG_PROVE_RCU=3Dy CONFIG_FORCE_TASKS_TRACE_RCU=3Dy #CHECK#CONFIG_TASKS_TRACE_RCU=3Dy -CONFIG_TASKS_TRACE_RCU_READ_MB=3Dn CONFIG_RCU_EXPERT=3Dy CONFIG_DEBUG_OBJECTS=3Dy --=20 2.40.1 From nobody Wed Oct 1 20:32:42 2025 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 5D104256C76; Wed, 1 Oct 2025 14:48:37 +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=1759330117; cv=none; b=JRqyEWNuFUCXvL/n8i0PEAjdBD3HGnN+3DwW2agbOwzOdgiRChoA0xwgUZJN5IwN14HraOa3AV8SVCFOlmeLJ37N+PlUTrzPSmPiHzQngTFLFXlX9+VNLTKEezRclJR2+sXxHK6206pWnjhVt4EJ065Tf51fdYDUzJ+oi11AteI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759330117; c=relaxed/simple; bh=7msjYfr0Kv43ez5IZwT7gg8cr4MufUyBGd2HMG5qBx8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=j6GGeTtIszPKUif5hi8to23yt0tIIledmq7CLPvE5xxgASkNeACS4x2QBEvRWXYLskyYm5LFcNvmqHSvnmWHXy3x5p05fHLXzN0tH2H8rYrc4Pn988B48hZraxhUzhhvQVoQCVmGaBtHbUgibjlNDFRmnxtFpRd+d75EbNVu+qc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=vBxNV/QM; 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="vBxNV/QM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CF4B1C4CEF9; Wed, 1 Oct 2025 14:48:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1759330117; bh=7msjYfr0Kv43ez5IZwT7gg8cr4MufUyBGd2HMG5qBx8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vBxNV/QMK3vrkwVsCv58npjpNtxaxi9C1UgimyViknw3CkgkMAKUtbOozk/UQjZZB isDTKH3+aR5bW1A7SEfrKPqBdUx0r1NglQFOBQ2mRJxbAbDZ1vPJ2jITkt2S99jDPc BSSeNhT0cTRRi837jqXcYFsxzlwrY/C55foKsghvcNfFTN+tTb6keR5UuwPHpyXGIR ZtKyVWpBhDF3PKFVcDjrcaP3d8D34Kgl1DVH7yOYZVmQkNZKypauFeluAfkJTSZ8YM KF08WxneuP8tBIvfXIxuHqWappUwfeV+rK5ke+XHyIfW/+r36LxLZa7m/LYs3wpsI4 4f7FeHPISw3gw== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 6D3F4CE1148; Wed, 1 Oct 2025 07:48:34 -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" , Andrii Nakryiko , Alexei Starovoitov , Peter Zijlstra , bpf@vger.kernel.org Subject: [PATCH v2 05/21] rcu: Move rcu_tasks_trace_srcu_struct out of #ifdef CONFIG_TASKS_RCU_GENERIC Date: Wed, 1 Oct 2025 07:48:16 -0700 Message-Id: <20251001144832.631770-5-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> References: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Moving the rcu_tasks_trace_srcu_struct structure instance out from under the CONFIG_TASKS_RCU_GENERIC Kconfig option permits the CONFIG_TASKS_TRACE_RCU Kconfig option to stop enabling this CONFIG_TASKS_RCU_GENERIC Kconfig option. This commit also therefore makes it so. Signed-off-by: Paul E. McKenney Cc: Andrii Nakryiko Cc: Alexei Starovoitov Cc: Peter Zijlstra Cc: --- kernel/rcu/Kconfig | 2 +- kernel/rcu/tasks.h | 38 +++++++++++++------------------------- 2 files changed, 14 insertions(+), 26 deletions(-) diff --git a/kernel/rcu/Kconfig b/kernel/rcu/Kconfig index 54b4c4aa553a4a..73a6cc364628b5 100644 --- a/kernel/rcu/Kconfig +++ b/kernel/rcu/Kconfig @@ -82,7 +82,7 @@ config NEED_SRCU_NMI_SAFE def_bool HAVE_NMI && !ARCH_HAS_NMI_SAFE_THIS_CPU_OPS && !TINY_SRCU =20 config TASKS_RCU_GENERIC - def_bool TASKS_RCU || TASKS_RUDE_RCU || TASKS_TRACE_RCU + def_bool TASKS_RCU || TASKS_RUDE_RCU help This option enables generic infrastructure code supporting task-based RCU implementations. Not for manual selection. diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h index fd1fe80ddde484..833e180db744f2 100644 --- a/kernel/rcu/tasks.h +++ b/kernel/rcu/tasks.h @@ -1439,31 +1439,6 @@ EXPORT_SYMBOL_GPL(rcu_tasks_rude_get_gp_data); =20 #endif /* #ifdef CONFIG_TASKS_RUDE_RCU */ =20 -//////////////////////////////////////////////////////////////////////// -// -// Tracing variant of Tasks RCU. This variant is designed to be used -// to protect tracing hooks, including those of BPF. This variant -// is implemented via a straightforward mapping onto SRCU-fast. - -#ifdef CONFIG_TASKS_TRACE_RCU - -DEFINE_SRCU(rcu_tasks_trace_srcu_struct); -EXPORT_SYMBOL_GPL(rcu_tasks_trace_srcu_struct); - -// Placeholder to suppress build errors through transition period. -void __init rcu_tasks_trace_suppress_unused(void) -{ - show_rcu_tasks_generic_gp_kthread(NULL, NULL); - rcu_spawn_tasks_kthread_generic(NULL); - synchronize_rcu_tasks_generic(NULL); - call_rcu_tasks_generic(NULL, NULL, NULL); - call_rcu_tasks_iw_wakeup(NULL); - cblist_init_generic(NULL); - rcu_tasks_torture_stats_print_generic(NULL, NULL, NULL, NULL); -} - -#endif /* #else #ifdef CONFIG_TASKS_TRACE_RCU */ - #ifndef CONFIG_TINY_RCU void show_rcu_tasks_gp_kthreads(void) { @@ -1617,3 +1592,16 @@ core_initcall(rcu_init_tasks_generic); #else /* #ifdef CONFIG_TASKS_RCU_GENERIC */ static inline void rcu_tasks_bootup_oddness(void) {} #endif /* #else #ifdef CONFIG_TASKS_RCU_GENERIC */ + +#ifdef CONFIG_TASKS_TRACE_RCU + +//////////////////////////////////////////////////////////////////////// +// +// Tracing variant of Tasks RCU. This variant is designed to be used +// to protect tracing hooks, including those of BPF. This variant +// is implemented via a straightforward mapping onto SRCU-fast. + +DEFINE_SRCU(rcu_tasks_trace_srcu_struct); +EXPORT_SYMBOL_GPL(rcu_tasks_trace_srcu_struct); + +#endif /* #else #ifdef CONFIG_TASKS_TRACE_RCU */ --=20 2.40.1 From nobody Wed Oct 1 20:32:42 2025 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 D58BF303A24; Wed, 1 Oct 2025 14:48:39 +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=1759330119; cv=none; b=MYFJca6n4XXdDRclYler1zcxuMf2lZl2AogGPFS9qJ4+xnKZZTqxNfhFsAQBbPigLN4h8Wr/+XIdpIyy2sRAIUJDna4mRAxr6M+53CtkjR6jbzuEq/5735sEeyxEw92E8uURAyqP2DtBS+8bVd8NSgVpGgviIOgc/QHlAtJz39U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759330119; c=relaxed/simple; bh=iKeiZMJ0ulhBekBtlRCePhWmJOVL8l8/TB0NfJOhkCE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=RH23mOK0qQBLWm+zT/3Qs9J/RQgY/JU3yeTKj/VF6JlgoLAiuFs+F4XDH5pPMd046nzAVF7uvzyIAGrFJuNWrHzmibWLD8ev18gPy72tBcFy80kuGt4xPACuk29exq6G4IzDXqyJnxCvxQg3O8d6/nfZwCmBFjPdnevuz6kRp60= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=qrC+zIU2; 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="qrC+zIU2" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5FE56C4CEFA; Wed, 1 Oct 2025 14:48:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1759330119; bh=iKeiZMJ0ulhBekBtlRCePhWmJOVL8l8/TB0NfJOhkCE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qrC+zIU2Xv1YYDU5cBFWUDH8QhtVwbSpaiuWqdIQb/UY9gDUKVRANLQh+RS9W/W+I LJj4gYRh/0C4K47ggkRe3/lmL9wzmvZbz5JiM1hMOoIsgOHc846r04W7oMQb3n84MS aAWjhzntL/bO5QJo1mG9BwKR84pQ2KCfRL/1/h6ehmNwu6j5fpl44loIrWiKI6E1b3 z2nV74NMIFt4wL8ocFJa1B9eM3gtAriawI0QKE4Kb61P1OPrUILTBwzwOwlmo5pZUt sudLKucfZYa5aiT2plZrEqPwANn7myo35b1Io1QEo5/CiNu0TEw4pW0BurWF28auKA a1LwvYQ66tTzA== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 6FD28CE1160; Wed, 1 Oct 2025 07:48:34 -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" , Andrii Nakryiko , Alexei Starovoitov , Peter Zijlstra , bpf@vger.kernel.org Subject: [PATCH v2 06/21] srcu: Create an srcu_expedite_current() function Date: Wed, 1 Oct 2025 07:48:17 -0700 Message-Id: <20251001144832.631770-6-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> References: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This commit creates an srcu_expedite_current() function that expedites the current (and possibly the next) SRCU grace period for the specified srcu_struct structure. This functionality will be inherited by RCU Tasks Trace courtesy of its mapping to SRCU fast. If the current SRCU grace period is already waiting, that wait will complete before the expediting takes effect. If there is no SRCU grace period in flight, this function might well create one. [ paulmck: Apply Zqiang feedback for PREEMPT_RT use. ] Signed-off-by: Paul E. McKenney Cc: Andrii Nakryiko Cc: Alexei Starovoitov Cc: Peter Zijlstra Cc: --- include/linux/srcutiny.h | 1 + include/linux/srcutree.h | 8 ++++++ kernel/rcu/srcutree.c | 58 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/include/linux/srcutiny.h b/include/linux/srcutiny.h index 51ce25f07930ee..3bfbd44cb1b37d 100644 --- a/include/linux/srcutiny.h +++ b/include/linux/srcutiny.h @@ -103,6 +103,7 @@ static inline void srcu_barrier(struct srcu_struct *ssp) synchronize_srcu(ssp); } =20 +static inline void srcu_expedite_current(struct srcu_struct *ssp) { } #define srcu_check_read_flavor(ssp, read_flavor) do { } while (0) #define srcu_check_read_flavor_force(ssp, read_flavor) do { } while (0) =20 diff --git a/include/linux/srcutree.h b/include/linux/srcutree.h index 42098e0fa0b7dd..93ad18acd6d02d 100644 --- a/include/linux/srcutree.h +++ b/include/linux/srcutree.h @@ -42,6 +42,8 @@ struct srcu_data { struct timer_list delay_work; /* Delay for CB invoking */ struct work_struct work; /* Context for CB invoking. */ struct rcu_head srcu_barrier_head; /* For srcu_barrier() use. */ + struct rcu_head srcu_ec_head; /* For srcu_expedite_current() use. */ + int srcu_ec_state; /* State for srcu_expedite_current(). */ struct srcu_node *mynode; /* Leaf srcu_node. */ unsigned long grpmask; /* Mask for leaf srcu_node */ /* ->srcu_data_have_cbs[]. */ @@ -135,6 +137,11 @@ struct srcu_struct { #define SRCU_STATE_SCAN1 1 #define SRCU_STATE_SCAN2 2 =20 +/* Values for srcu_expedite_current() state (->srcu_ec_state). */ +#define SRCU_EC_IDLE 0 +#define SRCU_EC_PENDING 1 +#define SRCU_EC_REPOST 2 + /* * Values for initializing gp sequence fields. Higher values allow wrap ar= ounds to * occur earlier. @@ -210,6 +217,7 @@ struct srcu_struct { int __srcu_read_lock(struct srcu_struct *ssp) __acquires(ssp); void synchronize_srcu_expedited(struct srcu_struct *ssp); void srcu_barrier(struct srcu_struct *ssp); +void srcu_expedite_current(struct srcu_struct *ssp); void srcu_torture_stats_print(struct srcu_struct *ssp, char *tt, char *tf); =20 // Converts a per-CPU pointer to an ->srcu_ctrs[] array element to that diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c index 1ff94b76d91f15..38b440b0b0c80b 100644 --- a/kernel/rcu/srcutree.c +++ b/kernel/rcu/srcutree.c @@ -1688,6 +1688,64 @@ void srcu_barrier(struct srcu_struct *ssp) } EXPORT_SYMBOL_GPL(srcu_barrier); =20 +/* Callback for srcu_expedite_current() usage. */ +static void srcu_expedite_current_cb(struct rcu_head *rhp) +{ + unsigned long flags; + bool needcb =3D false; + struct srcu_data *sdp =3D container_of(rhp, struct srcu_data, srcu_ec_hea= d); + + spin_lock_irqsave_sdp_contention(sdp, &flags); + if (sdp->srcu_ec_state =3D=3D SRCU_EC_IDLE) { + WARN_ON_ONCE(1); + } else if (sdp->srcu_ec_state =3D=3D SRCU_EC_PENDING) { + sdp->srcu_ec_state =3D SRCU_EC_IDLE; + } else { + WARN_ON_ONCE(sdp->srcu_ec_state !=3D SRCU_EC_REPOST); + sdp->srcu_ec_state =3D SRCU_EC_PENDING; + needcb =3D true; + } + spin_unlock_irqrestore_rcu_node(sdp, flags); + // If needed, requeue ourselves as an expedited SRCU callback. + if (needcb) + __call_srcu(sdp->ssp, &sdp->srcu_ec_head, srcu_expedite_current_cb, fals= e); +} + +/** + * srcu_expedite_current - Expedite the current SRCU grace period + * @ssp: srcu_struct to expedite. + * + * Cause the current SRCU grace period to become expedited. The grace + * period following the current one might also be expedited. If there is + * no current grace period, one might be created. If the current grace + * period is currently sleeping, that sleep will complete before expediting + * will take effect. + */ +void srcu_expedite_current(struct srcu_struct *ssp) +{ + unsigned long flags; + bool needcb =3D false; + struct srcu_data *sdp; + + migrate_disable(); + sdp =3D this_cpu_ptr(ssp->sda); + spin_lock_irqsave_sdp_contention(sdp, &flags); + if (sdp->srcu_ec_state =3D=3D SRCU_EC_IDLE) { + sdp->srcu_ec_state =3D SRCU_EC_PENDING; + needcb =3D true; + } else if (sdp->srcu_ec_state =3D=3D SRCU_EC_PENDING) { + sdp->srcu_ec_state =3D SRCU_EC_REPOST; + } else { + WARN_ON_ONCE(sdp->srcu_ec_state !=3D SRCU_EC_REPOST); + } + spin_unlock_irqrestore_rcu_node(sdp, flags); + // If needed, queue an expedited SRCU callback. + if (needcb) + __call_srcu(ssp, &sdp->srcu_ec_head, srcu_expedite_current_cb, false); + migrate_enable(); +} +EXPORT_SYMBOL_GPL(srcu_expedite_current); + /** * srcu_batches_completed - return batches completed. * @ssp: srcu_struct on which to report batch completion. --=20 2.40.1 From nobody Wed Oct 1 20:32:42 2025 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 D573D303A20; Wed, 1 Oct 2025 14:48:39 +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=1759330119; cv=none; b=P4DNL9TfJJeBXZ25N7nv6nWDMpgf/BCmaVoYgwdrAC9HtVB01QegqY6xn71AwibXAao7GPslYMbxHrt/f/YPxTlZQJA+WPM46QAJ8LK23c3xRlzExIeJlM1muaHledyekp8uQaeds6sxt3wVMtUi9Js92exZz/TNYgWDwkgoga8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759330119; c=relaxed/simple; bh=H2Rpde2Lnzmi1rrKiEk9cEd+o18Lx4S73RaemLuL/J0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=VzUXnmYtoVH0AmIl/2Yuk9ZEOZTc4H/GjrfGtWyHcy6ecL24bXRqqhaTtSQhIp4hROrX2DhT14wvZMpI4x8sdqfKMrOJPruqL7/jEANa6CsnFjspPWMdvPA+e8oAnPWh2EJey8gVBbaiB60rYzDHDb134rxTMHjY0DAbrCEW+Fk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=r76KOMt3; 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="r76KOMt3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 53212C4CEFC; Wed, 1 Oct 2025 14:48:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1759330119; bh=H2Rpde2Lnzmi1rrKiEk9cEd+o18Lx4S73RaemLuL/J0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=r76KOMt33iJbGQvvJTCb2tOk0tL1Zg7UZS6SE6LrL8QWR1m5koA5xspEnh9nc5Zj/ h4RmJ7pIhFP/VP9nbsk2MrzRyyHIv50HhLUYFmwdpZs+G9kaWKSMvZDaSMhZmy7ghz O17qTPZKhprfs/Kr20/n0lBDksxg2RDEQaLhhiI3ahcx8c1rb6KAZOgw3hyGGsWPmg r/myOGTYt02w8oimpWnsEnNZ2nFDJX9kAvFvIEnp2cjO1HUDtLHatOn8uapDYzBJIn nk7I98MWEnGWiq/vurOXIBuDl/KvXJWAwU3PlTVt5Z+TOakTrExR45I9fZWoAnXxGt RfnaNmlZm/HXA== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 72A28CE11BD; Wed, 1 Oct 2025 07:48:34 -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" , Andrii Nakryiko , Alexei Starovoitov , Peter Zijlstra , bpf@vger.kernel.org Subject: [PATCH v2 07/21] rcutorture: Test srcu_expedite_current() Date: Wed, 1 Oct 2025 07:48:18 -0700 Message-Id: <20251001144832.631770-7-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> References: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This commit adds a ->exp_current member to the rcu_torture_ops structure to test the srcu_expedite_current() function. Signed-off-by: Paul E. McKenney Cc: Andrii Nakryiko Cc: Alexei Starovoitov Cc: Peter Zijlstra Cc: --- kernel/rcu/rcutorture.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 485fa822b6a753..64803d09fc733a 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -389,6 +389,7 @@ struct rcu_torture_ops { void (*deferred_free)(struct rcu_torture *p); void (*sync)(void); void (*exp_sync)(void); + void (*exp_current)(void); unsigned long (*get_gp_state_exp)(void); unsigned long (*start_gp_poll_exp)(void); void (*start_gp_poll_exp_full)(struct rcu_gp_oldstate *rgosp); @@ -857,6 +858,11 @@ static void srcu_torture_synchronize_expedited(void) synchronize_srcu_expedited(srcu_ctlp); } =20 +static void srcu_torture_expedite_current(void) +{ + srcu_expedite_current(srcu_ctlp); +} + static struct rcu_torture_ops srcu_ops =3D { .ttype =3D SRCU_FLAVOR, .init =3D rcu_sync_torture_init, @@ -871,6 +877,7 @@ static struct rcu_torture_ops srcu_ops =3D { .deferred_free =3D srcu_torture_deferred_free, .sync =3D srcu_torture_synchronize, .exp_sync =3D srcu_torture_synchronize_expedited, + .exp_current =3D srcu_torture_expedite_current, .same_gp_state =3D same_state_synchronize_srcu, .get_comp_state =3D get_completed_synchronize_srcu, .get_gp_state =3D srcu_torture_get_gp_state, @@ -919,6 +926,7 @@ static struct rcu_torture_ops srcud_ops =3D { .deferred_free =3D srcu_torture_deferred_free, .sync =3D srcu_torture_synchronize, .exp_sync =3D srcu_torture_synchronize_expedited, + .exp_current =3D srcu_torture_expedite_current, .same_gp_state =3D same_state_synchronize_srcu, .get_comp_state =3D get_completed_synchronize_srcu, .get_gp_state =3D srcu_torture_get_gp_state, @@ -1698,6 +1706,8 @@ rcu_torture_writer(void *arg) ulo[i] =3D cur_ops->get_comp_state(); gp_snap =3D cur_ops->start_gp_poll(); rcu_torture_writer_state =3D RTWS_POLL_WAIT; + if (cur_ops->exp_current && !torture_random(&rand) % 0xff) + cur_ops->exp_current(); while (!cur_ops->poll_gp_state(gp_snap)) { gp_snap1 =3D cur_ops->get_gp_state(); for (i =3D 0; i < ulo_size; i++) @@ -1718,6 +1728,8 @@ rcu_torture_writer(void *arg) cur_ops->get_comp_state_full(&rgo[i]); cur_ops->start_gp_poll_full(&gp_snap_full); rcu_torture_writer_state =3D RTWS_POLL_WAIT_FULL; + if (cur_ops->exp_current && !torture_random(&rand) % 0xff) + cur_ops->exp_current(); while (!cur_ops->poll_gp_state_full(&gp_snap_full)) { cur_ops->get_gp_state_full(&gp_snap1_full); for (i =3D 0; i < rgo_size; i++) --=20 2.40.1 From nobody Wed Oct 1 20:32:42 2025 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 D57B9303A21; Wed, 1 Oct 2025 14:48:39 +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=1759330119; cv=none; b=MVNP40sLZgVTTC/s6muF/TcnBqetVQPEu2rVEC8eusREzh8BJG7qy8GcrO4wezZtk23mRJsN0zzdWejZJ7I6S/ruARjjAzd8fBvYAOAatRYJUihy5Eru2AhcGzq1Sqaey88eVep8UBJeet8Gn17rrY9xrUp4urnIlYaBHdXpM2g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759330119; c=relaxed/simple; bh=MKbdfKwt7gETlTpQcusETrFaTqFUQmuaJ62gW5Sy6jg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=pS+Qm/6szNEVDIBVoMvR0xxpwoiba8pKZ/nWECk1Pz0WofeJnwY8mktDTdNMMfkK8TY32t/3uNsIsB/NTP4qbYmkAWfJBhBlnqN8UepeSKg7FqGQwYv0wa8TQTcwlXHfxx/i8U6OxIQPJjSadz2O0Q4qNavkVqMKXjYjqIyMDdE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RJ2bspef; 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="RJ2bspef" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 52C7BC4CEF5; Wed, 1 Oct 2025 14:48:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1759330119; bh=MKbdfKwt7gETlTpQcusETrFaTqFUQmuaJ62gW5Sy6jg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RJ2bspefEOoYwaLOhz3VsRwtSg17mm5cx1VGVIVZwh+9T+JW8vY+CHTpvzIyJgCLY NjbjoDdFaN3acRpjF8dTMH0jFZ49dINaNrR1tpT1O89GSwxlMNqqaLsW20+2H2VIX0 mJjQN+3VGdOMAc6b0WIz2Njblhij4gug9zp2dQORwZt8+c9vTDHfmQO6CpfmUn+pkr S8aa/+SXpgEy2GHmgclekOOX8Q0snV0xiCAaPbpM5JzbpETTGGLthR5k3HPpnqGvjO g0abQWr1iPK/SJw/QFr0/ymsdTEK02sbV1sYAgelvSplrVVotbUnt5U9QqcWK01+j1 EvQPOYwqlBjHw== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 75647CE125B; Wed, 1 Oct 2025 07:48:34 -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" , Andrii Nakryiko , Alexei Starovoitov , Peter Zijlstra , bpf@vger.kernel.org Subject: [PATCH v2 08/21] rcu: Add noinstr-fast rcu_read_{,un}lock_tasks_trace() APIs Date: Wed, 1 Oct 2025 07:48:19 -0700 Message-Id: <20251001144832.631770-8-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> References: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When expressing RCU Tasks Trace in terms of SRCU-fast, it was necessary to keep a nesting count and per-CPU srcu_ctr structure pointer in the task_struct structure, which is slow to access. But an alternative is to instead make rcu_read_lock_tasks_trace() and rcu_read_unlock_tasks_trace(), which match the underlying SRCU-fast semantics, avoiding the task_struct accesses. When all callers have switched to the new API, the previous rcu_read_lock_trace() and rcu_read_unlock_trace() APIs will be removed. The rcu_read_{,un}lock_{,tasks_}trace() functions need to use smp_mb() only if invoked where RCU is not watching, that is, from locations where a call to rcu_is_watching() would return false. In architectures that define the ARCH_WANTS_NO_INSTR Kconfig option, use of noinstr and friends ensures that tracing happens only where RCU is watching, so those architectures can dispense entirely with the read-side calls to smp_mb(). Other architectures include these read-side calls by default, but in many installations there might be either larger than average tolerance for risk, prohibition of removing tracing on a running system, or careful review and approval of removing of tracing. Such installations can build their kernels with CONFIG_TASKS_TRACE_RCU_NO_MB=3Dy to avoid those read-side calls to smp_mb(), thus accepting responsibility for run-time removal of tracing from code regions that RCU is not watching. Those wishing to disable read-side memory barriers for an entire architecture can select this TASKS_TRACE_RCU_NO_MB Kconfig option, hence the polarity. [ paulmck: Apply Peter Zijlstra feedback. ] Signed-off-by: Paul E. McKenney Cc: Andrii Nakryiko Cc: Alexei Starovoitov Cc: Peter Zijlstra Cc: --- include/linux/rcupdate_trace.h | 65 +++++++++++++++++++++++++++++----- kernel/rcu/Kconfig | 23 ++++++++++++ kernel/rcu/tasks.h | 7 +++- 3 files changed, 86 insertions(+), 9 deletions(-) diff --git a/include/linux/rcupdate_trace.h b/include/linux/rcupdate_trace.h index 0bd47f12ecd17b..f47ba9c074601c 100644 --- a/include/linux/rcupdate_trace.h +++ b/include/linux/rcupdate_trace.h @@ -34,6 +34,53 @@ static inline int rcu_read_lock_trace_held(void) =20 #ifdef CONFIG_TASKS_TRACE_RCU =20 +/** + * rcu_read_lock_tasks_trace - mark beginning of RCU-trace read-side criti= cal section + * + * When synchronize_rcu_tasks_trace() is invoked by one task, then that + * task is guaranteed to block until all other tasks exit their read-side + * critical sections. Similarly, if call_rcu_trace() is invoked on one + * task while other tasks are within RCU read-side critical sections, + * invocation of the corresponding RCU callback is deferred until after + * the all the other tasks exit their critical sections. + * + * For more details, please see the documentation for + * srcu_read_lock_fast(). For a description of how implicit RCU + * readers provide the needed ordering for architectures defining the + * ARCH_WANTS_NO_INSTR Kconfig option (and thus promising never to trace + * code where RCU is not watching), please see the __srcu_read_lock_fast() + * (non-kerneldoc) header comment. Otherwise, the smp_mb() below provided + * the needed ordering. + */ +static inline struct srcu_ctr __percpu *rcu_read_lock_tasks_trace(void) +{ + struct srcu_ctr __percpu *ret =3D __srcu_read_lock_fast(&rcu_tasks_trace_= srcu_struct); + + rcu_try_lock_acquire(&rcu_tasks_trace_srcu_struct.dep_map); + if (!IS_ENABLED(CONFIG_TASKS_TRACE_RCU_NO_MB)) + smp_mb(); // Provide ordering on noinstr-incomplete architectures. + return ret; +} + +/** + * rcu_read_unlock_tasks_trace - mark end of RCU-trace read-side critical = section + * @scp: return value from corresponding rcu_read_lock_tasks_trace(). + * + * Pairs with the preceding call to rcu_read_lock_tasks_trace() that + * returned the value passed in via scp. + * + * For more details, please see the documentation for rcu_read_unlock(). + * For memory-ordering information, please see the header comment for the + * rcu_read_lock_tasks_trace() function. + */ +static inline void rcu_read_unlock_tasks_trace(struct srcu_ctr __percpu *s= cp) +{ + if (!IS_ENABLED(CONFIG_TASKS_TRACE_RCU_NO_MB)) + smp_mb(); // Provide ordering on noinstr-incomplete architectures. + __srcu_read_unlock_fast(&rcu_tasks_trace_srcu_struct, scp); + srcu_lock_release(&rcu_tasks_trace_srcu_struct.dep_map); +} + /** * rcu_read_lock_trace - mark beginning of RCU-trace read-side critical se= ction * @@ -50,14 +97,15 @@ static inline void rcu_read_lock_trace(void) { struct task_struct *t =3D current; =20 + rcu_try_lock_acquire(&rcu_tasks_trace_srcu_struct.dep_map); if (t->trc_reader_nesting++) { // In case we interrupted a Tasks Trace RCU reader. - rcu_try_lock_acquire(&rcu_tasks_trace_srcu_struct.dep_map); return; } barrier(); // nesting before scp to protect against interrupt handler. - t->trc_reader_scp =3D srcu_read_lock_fast(&rcu_tasks_trace_srcu_struct); - smp_mb(); // Placeholder for more selective ordering + t->trc_reader_scp =3D __srcu_read_lock_fast(&rcu_tasks_trace_srcu_struct); + if (!IS_ENABLED(CONFIG_TASKS_TRACE_RCU_NO_MB)) + smp_mb(); // Placeholder for more selective ordering } =20 /** @@ -74,13 +122,14 @@ static inline void rcu_read_unlock_trace(void) struct srcu_ctr __percpu *scp; struct task_struct *t =3D current; =20 - smp_mb(); // Placeholder for more selective ordering scp =3D t->trc_reader_scp; barrier(); // scp before nesting to protect against interrupt handler. - if (!--t->trc_reader_nesting) - srcu_read_unlock_fast(&rcu_tasks_trace_srcu_struct, scp); - else - srcu_lock_release(&rcu_tasks_trace_srcu_struct.dep_map); + if (!--t->trc_reader_nesting) { + if (!IS_ENABLED(CONFIG_TASKS_TRACE_RCU_NO_MB)) + smp_mb(); // Placeholder for more selective ordering + __srcu_read_unlock_fast(&rcu_tasks_trace_srcu_struct, scp); + } + srcu_lock_release(&rcu_tasks_trace_srcu_struct.dep_map); } =20 /** diff --git a/kernel/rcu/Kconfig b/kernel/rcu/Kconfig index 73a6cc364628b5..6a319e2926589f 100644 --- a/kernel/rcu/Kconfig +++ b/kernel/rcu/Kconfig @@ -142,6 +142,29 @@ config TASKS_TRACE_RCU default n select IRQ_WORK =20 +config TASKS_TRACE_RCU_NO_MB + bool "Override RCU Tasks Trace inclusion of read-side memory barriers" + depends on RCU_EXPERT && TASKS_TRACE_RCU + default ARCH_WANTS_NO_INSTR + help + This option prevents the use of read-side memory barriers in + rcu_read_lock_tasks_trace() and rcu_read_unlock_tasks_trace() + even in kernels built with CONFIG_ARCH_WANTS_NO_INSTR=3Dn, that is, + in kernels that do not have noinstr set up in entry/exit code. + By setting this option, you are promising to carefully review + use of ftrace, BPF, and friends to ensure that no tracing + operation is attached to a function that runs in that portion + of the entry/exit code that RCU does not watch, that is, + where rcu_is_watching() returns false. Alternatively, you + might choose to never remove traces except by rebooting. + + Those wishing to disable read-side memory barriers for an entire + architecture can select this Kconfig option, hence the polarity. + + Say Y here if you need speed and will review use of tracing. + Say N here for certain esoteric testing of RCU itself. + Take the default if you are unsure. + config RCU_STALL_COMMON def_bool TREE_RCU help diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h index 833e180db744f2..bf1226834c9423 100644 --- a/kernel/rcu/tasks.h +++ b/kernel/rcu/tasks.h @@ -1600,8 +1600,13 @@ static inline void rcu_tasks_bootup_oddness(void) {} // Tracing variant of Tasks RCU. This variant is designed to be used // to protect tracing hooks, including those of BPF. This variant // is implemented via a straightforward mapping onto SRCU-fast. +// DEFINE_SRCU_FAST() is required because rcu_read_lock_trace() must +// use __srcu_read_lock_fast() in order to bypass the rcu_is_watching() +// checks in kernels built with CONFIG_TASKS_TRACE_RCU_NO_MB=3Dn, which al= so +// bypasses the srcu_check_read_flavor_force() that would otherwise mark +// rcu_tasks_trace_srcu_struct as needing SRCU-fast readers. =20 -DEFINE_SRCU(rcu_tasks_trace_srcu_struct); +DEFINE_SRCU_FAST(rcu_tasks_trace_srcu_struct); EXPORT_SYMBOL_GPL(rcu_tasks_trace_srcu_struct); =20 #endif /* #else #ifdef CONFIG_TASKS_TRACE_RCU */ --=20 2.40.1 From nobody Wed Oct 1 20:32:42 2025 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 D5849303A22; Wed, 1 Oct 2025 14:48:39 +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=1759330119; cv=none; b=L8DRqrXcZl3iLSgbf+6qnf5KnS+LWT/lgTa8iB94dekx+esV7ADOD/G/Wj6x6FEeYLwUAJAfJIWuRaCTbvh512gh/ZUpcOlCOeZhoDWrsvIxjUXcoKppSdFmfpdFADD02HxXweFA90GeGWslXOVtorR6vq07GZ2imnv9vuAQe1k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759330119; c=relaxed/simple; bh=1LD05Jje7JY4+QRieuy7/gMogSMrNyvAzrT45QnCY+Y=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ZNj9sR1Z4d7xQZ3CXzTsL0GqLeISETsOKavRBgUNqNhcn0lLVNaq4yxt6ZtiMd5VM9ueV7pwmLh8AsTgfyZuB9MvASTNq4Hdg5NKJhzn9YVfirJ6OlzRRHVMDgpq6B/dPvOtWsdXBGc8yC/Ss1mNFps4mfhGVMcYGwuZUKJ7pgQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fGwYKN9Q; 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="fGwYKN9Q" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5E97BC4CEF9; Wed, 1 Oct 2025 14:48:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1759330119; bh=1LD05Jje7JY4+QRieuy7/gMogSMrNyvAzrT45QnCY+Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fGwYKN9Q2GnrQ2++a4QBcrC3JPlemY5oGyYqbWqaBzOHRdf872rSKrTknDuOrFqFU GdmkAG9gc4Wa7ziRv40WAdYo1fuFXLWHlXgcW6AOTeqroznLCqh6pg+K/GYgAfM+pt aTM9mm7TJZ2t8SmUSx+4L1XRs2JfEIIwRFHwHi4pPw4If76NvCtiIf9WlSAVymvRtZ 9lKLptiLH0IeLPO6MZ9uhZhTMLk42z04sWlAu093AjCMO3GsnaJkQTDfIkLNUgBHU1 966/Z4x4yC2aLM2aubQKW0gHam6dClRefZ3nAlxeqa2oXGWp3DBiqyGpgNRe5RburP J6gNWXMb3+MOw== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 77EBBCE12C3; Wed, 1 Oct 2025 07:48:34 -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" , Andrii Nakryiko , Alexei Starovoitov , Peter Zijlstra , bpf@vger.kernel.org Subject: [PATCH v2 09/21] rcu: Update Requirements.rst for RCU Tasks Trace Date: Wed, 1 Oct 2025 07:48:20 -0700 Message-Id: <20251001144832.631770-9-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> References: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This commit updates the documentation to declare that RCU Tasks Trace is implemented as a thin wrapper around SRCU-fast. Signed-off-by: Paul E. McKenney Cc: Andrii Nakryiko Cc: Alexei Starovoitov Cc: Peter Zijlstra Cc: --- .../RCU/Design/Requirements/Requirements.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Documentation/RCU/Design/Requirements/Requirements.rst b/Docum= entation/RCU/Design/Requirements/Requirements.rst index f24b3c0b9b0dc6..4a116d7a564edc 100644 --- a/Documentation/RCU/Design/Requirements/Requirements.rst +++ b/Documentation/RCU/Design/Requirements/Requirements.rst @@ -2779,12 +2779,12 @@ Tasks Trace RCU ~~~~~~~~~~~~~~~ =20 Some forms of tracing need to sleep in readers, but cannot tolerate -SRCU's read-side overhead, which includes a full memory barrier in both -srcu_read_lock() and srcu_read_unlock(). This need is handled by a -Tasks Trace RCU that uses scheduler locking and IPIs to synchronize with -readers. Real-time systems that cannot tolerate IPIs may build their -kernels with ``CONFIG_TASKS_TRACE_RCU_READ_MB=3Dy``, which avoids the IPIs= at -the expense of adding full memory barriers to the read-side primitives. +SRCU's read-side overhead, which includes a full memory barrier in +both srcu_read_lock() and srcu_read_unlock(). This need is handled by +a Tasks Trace RCU API implemented as thin wrappers around SRCU-fast, +which avoids the read-side memory barriers, at least for architectures +that apply noinstr to kernel entry/exit code (or that build with +``CONFIG_TASKS_TRACE_RCU_NO_MB=3Dy``. =20 The tasks-trace-RCU API is also reasonably compact, consisting of rcu_read_lock_trace(), rcu_read_unlock_trace(), --=20 2.40.1 From nobody Wed Oct 1 20:32:42 2025 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 1405F303C8B; Wed, 1 Oct 2025 14:48:40 +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=1759330120; cv=none; b=tbsfOXySrYzRcMvjjgvEU7oTWY9a0M7Ggw3R//0zoxD//Xr4kB9lOTEx08j9S9hWZMd/r5W3ok3MePs4xDFpDKYkgY6EhvHT9SYTww1QnCLmt4FAnFtzYL0lUfdB7sZjmngm7K9cIf+RlJ7pRYwHW9zRA50jIvqRiIMH73iCBE4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759330120; c=relaxed/simple; bh=B7b7Gx1mcM4EGN2sMoC77cGW6QCZYuX1KTpiyMpYpx8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=f8c9P+GO/8N08akBy/MOOjSx5LJIsh+ZhgPwTI0LsBALFNWrzGpI2b6amNKApTe7nMTK6MZQ5nte+xNLcb0CQhaq2eW3MOdq2evwgjWcQRW2Yk3yV+ntHcjNL6SwdmH2pEs0rLtdEp4403/Gz9dQ7l/QJNPygVD3qtK7++3jnVk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Dlvg7uXA; 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="Dlvg7uXA" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7EAD2C4CEFE; Wed, 1 Oct 2025 14:48:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1759330119; bh=B7b7Gx1mcM4EGN2sMoC77cGW6QCZYuX1KTpiyMpYpx8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Dlvg7uXAg5rWZQQ4kDnogLgvbX+Lp0+tarH4OhgI5HhhEyZh92TTtccnO7MZW/wvS vRUMu4h31lTdZzhC/Usv4YHo3KEhi6QlGuT2ALJFTHGLlkkE3td2Sx8O0xOUi5Yshr MTiUdSolUxQ5JRDI70nkw2u++7rSVHA4DEKl7GeJWwsCI0LymePhEs4Irhjt/plA+m 9gPaPY1cKB/Xqg6FgTt9VbhbJJoHz+BB0c0km+HeRSIw7ki5pLxQ/mVuiGNbgOs25P 20kHq34ia3nZ0DRcXCUebnWb+jlMLLNnK/rUCfe57gric6TtxtcJqbDYdufai/8thK GJAlbs4dWrYYA== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 7AA38CE12CD; Wed, 1 Oct 2025 07:48:34 -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" , Joe Perches , Andy Whitcroft , Dwaipayan Ray , Lukas Bulwahn , Andrii Nakryiko , Alexei Starovoitov , Peter Zijlstra , bpf@vger.kernel.org Subject: [PATCH v2 10/21] checkpatch: Deprecate rcu_read_{,un}lock_trace() Date: Wed, 1 Oct 2025 07:48:21 -0700 Message-Id: <20251001144832.631770-10-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> References: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Uses of rcu_read_lock_trace() and rcu_read_unlock_trace() are better served by the new rcu_read_lock_tasks_trace() and rcu_read_unlock_tasks_trace() APIs. Therefore, mark the old APIs as deprecated. Signed-off-by: Paul E. McKenney Acked-by: Joe Perches Cc: Andy Whitcroft Cc: Dwaipayan Ray Cc: Lukas Bulwahn Cc: Andrii Nakryiko Cc: Alexei Starovoitov Cc: Peter Zijlstra Cc: --- scripts/checkpatch.pl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index e722dd6fa8ef3d..3bb7d35a5cfcba 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -860,6 +860,8 @@ our %deprecated_apis =3D ( "kunmap" =3D> "kunmap_local", "kmap_atomic" =3D> "kmap_local_page", "kunmap_atomic" =3D> "kunmap_local", + "rcu_read_lock_trace" =3D> "rcu_read_lock_tasks_trace", + "rcu_read_unlock_trace" =3D> "rcu_read_unlock_tasks_trace", ); =20 #Create a search pattern for all these strings to speed up a loop below --=20 2.40.1 From nobody Wed Oct 1 20:32:42 2025 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 1E842303C9F; Wed, 1 Oct 2025 14:48:39 +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=1759330120; cv=none; b=M/JWSkNhrqb+TWjaKWZNiWfjm6+RtykTwOLmtu4P8QlnsiJLigkuDQmd1r6JtwsrFP0TG1QqVll58cDg9hbWkJBNfHc2xlFiGBf+D6+7FyyJjtZm+SmCbqhmi8A15QPCGff5tiBaBGXW3xsAKGMIRzBj8r0Nb6JBA0XEt7LHDrg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759330120; c=relaxed/simple; bh=KsyAiYK2BbMqGVso6WNz3IqAqctiHCv1RlmZwiUylvk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Mp+T3/7lkZdiBMItKzKloMpErY+HtZlhnkK8+rS3hv8z2eo+P0iTpsT5IEymICh1zMIU1kIOnp1pUAhDs2zbljmt8LM7uki1/+ySK1PhY2rrqDhOh7+lGF4BiipgdPfIBJOTsze0CF4LnxbuXMuTIiTretHQD3M99vjNRQKhpAY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IOLocjYY; 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="IOLocjYY" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7BB2DC4CEF1; Wed, 1 Oct 2025 14:48:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1759330119; bh=KsyAiYK2BbMqGVso6WNz3IqAqctiHCv1RlmZwiUylvk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IOLocjYYkXFAZXMqryXV0ZEbA/RIlrBIXShFF8/TaQvjQdSePGfozymi1/eawhMy2 P2iH8sz6rt8WFLF5WXu+a2GXKbRuyFeavaHob7MB+B5W/FgkJUrnbdQVHKoEgzBXfb /iCwHdFh7KAZsgae0okgLf6uXOweHfq8LUIgxCsVQaRK+CECLYg0PdXVr2Xk9kqpVy JcFKTX5BkrFVkzNO+ZeNoNT3RqPl9H7uxOVfCH1q3wYgE2LaGuSiO7/xwzFlv958TE FSnMAVGKwgFB2JflQMo7o1m4TaCMU+3xRDm2VamMncgDf1rjcEgKJSvy1m6F8OxV7w z4DtVuH/GBzVQ== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 7D305CE1418; Wed, 1 Oct 2025 07:48:34 -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" , Mathieu Desnoyers , Sebastian Andrzej Siewior , bpf@vger.kernel.org Subject: [PATCH v2 11/21] srcu: Create a DEFINE_SRCU_FAST() Date: Wed, 1 Oct 2025 07:48:22 -0700 Message-Id: <20251001144832.631770-11-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> References: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This commit creates DEFINE_SRCU_FAST() and DEFINE_STATIC_SRCU_FAST() macros that are similar to DEFINE_SRCU() and DEFINE_STATIC_SRCU(), but which create srcu_struct structures that are usable only by readers initiated by srcu_read_lock_fast() and friends. This commit does make DEFINE_SRCU_FAST() available to modules, in which case the per-CPU srcu_data structures are not created at compile time, but rather at module-load time. This means that the >srcu_reader_flavor field of the srcu_data structure is not available. Therefore, this commit instead creates an ->srcu_reader_flavor field in the srcu_struct structure, adds arguments to the DEFINE_SRCU()-related macros to initialize this new field, and extends the checks in the __srcu_check_read_flavor() function to include this new field. This commit also allows dynamically allocated srcu_struct structure to be marked for SRCU-fast readers. It does so by defining a new init_srcu_struct_fast() function that marks the specified srcu_struct structure for use by srcu_read_lock_fast() and friends. Signed-off-by: Paul E. McKenney Cc: Mathieu Desnoyers Cc: Steven Rostedt Cc: Sebastian Andrzej Siewior Cc: --- include/linux/notifier.h | 2 +- include/linux/srcu.h | 16 ++++++++++++++-- include/linux/srcutiny.h | 13 ++++++++++--- include/linux/srcutree.h | 34 +++++++++++++++++++++++----------- kernel/rcu/srcutree.c | 36 ++++++++++++++++++++++++++++++++++-- 5 files changed, 82 insertions(+), 19 deletions(-) diff --git a/include/linux/notifier.h b/include/linux/notifier.h index b42e6473496882..01b6c9d9956f90 100644 --- a/include/linux/notifier.h +++ b/include/linux/notifier.h @@ -109,7 +109,7 @@ extern void srcu_init_notifier_head(struct srcu_notifie= r_head *nh); .mutex =3D __MUTEX_INITIALIZER(name.mutex), \ .head =3D NULL, \ .srcuu =3D __SRCU_USAGE_INIT(name.srcuu), \ - .srcu =3D __SRCU_STRUCT_INIT(name.srcu, name.srcuu, pcpu), \ + .srcu =3D __SRCU_STRUCT_INIT(name.srcu, name.srcuu, pcpu, 0), \ } =20 #define ATOMIC_NOTIFIER_HEAD(name) \ diff --git a/include/linux/srcu.h b/include/linux/srcu.h index ada65b58bc4c5f..26de47820c58cd 100644 --- a/include/linux/srcu.h +++ b/include/linux/srcu.h @@ -25,8 +25,10 @@ struct srcu_struct; =20 #ifdef CONFIG_DEBUG_LOCK_ALLOC =20 -int __init_srcu_struct(struct srcu_struct *ssp, const char *name, - struct lock_class_key *key); +int __init_srcu_struct(struct srcu_struct *ssp, const char *name, struct l= ock_class_key *key); +#ifndef CONFIG_TINY_SRCU +int __init_srcu_struct_fast(struct srcu_struct *ssp, const char *name, str= uct lock_class_key *key); +#endif // #ifndef CONFIG_TINY_SRCU =20 #define init_srcu_struct(ssp) \ ({ \ @@ -35,10 +37,20 @@ int __init_srcu_struct(struct srcu_struct *ssp, const c= har *name, __init_srcu_struct((ssp), #ssp, &__srcu_key); \ }) =20 +#define init_srcu_struct_fast(ssp) \ +({ \ + static struct lock_class_key __srcu_key; \ + \ + __init_srcu_struct_fast((ssp), #ssp, &__srcu_key); \ +}) + #define __SRCU_DEP_MAP_INIT(srcu_name) .dep_map =3D { .name =3D #srcu_name= }, #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ =20 int init_srcu_struct(struct srcu_struct *ssp); +#ifndef CONFIG_TINY_SRCU +int init_srcu_struct_fast(struct srcu_struct *ssp); +#endif // #ifndef CONFIG_TINY_SRCU =20 #define __SRCU_DEP_MAP_INIT(srcu_name) #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */ diff --git a/include/linux/srcutiny.h b/include/linux/srcutiny.h index 3bfbd44cb1b37d..92e6ab53398fc0 100644 --- a/include/linux/srcutiny.h +++ b/include/linux/srcutiny.h @@ -31,7 +31,7 @@ struct srcu_struct { =20 void srcu_drive_gp(struct work_struct *wp); =20 -#define __SRCU_STRUCT_INIT(name, __ignored, ___ignored) \ +#define __SRCU_STRUCT_INIT(name, __ignored, ___ignored, ____ignored) \ { \ .srcu_wq =3D __SWAIT_QUEUE_HEAD_INITIALIZER(name.srcu_wq), \ .srcu_cb_tail =3D &name.srcu_cb_head, \ @@ -44,13 +44,20 @@ void srcu_drive_gp(struct work_struct *wp); * Tree SRCU, which needs some per-CPU data. */ #define DEFINE_SRCU(name) \ - struct srcu_struct name =3D __SRCU_STRUCT_INIT(name, name, name) + struct srcu_struct name =3D __SRCU_STRUCT_INIT(name, name, name, name) #define DEFINE_STATIC_SRCU(name) \ - static struct srcu_struct name =3D __SRCU_STRUCT_INIT(name, name, name) + static struct srcu_struct name =3D __SRCU_STRUCT_INIT(name, name, name, n= ame) +#define DEFINE_SRCU_FAST(name) DEFINE_SRCU(name) +#define DEFINE_STATIC_SRCU_FAST(name) \ + static struct srcu_struct name =3D __SRCU_STRUCT_INIT(name, name, name, n= ame) =20 // Dummy structure for srcu_notifier_head. struct srcu_usage { }; #define __SRCU_USAGE_INIT(name) { } +#define __init_srcu_struct_fast __init_srcu_struct +#ifndef CONFIG_DEBUG_LOCK_ALLOC +#define init_srcu_struct_fast init_srcu_struct +#endif // #ifndef CONFIG_DEBUG_LOCK_ALLOC =20 void synchronize_srcu(struct srcu_struct *ssp); =20 diff --git a/include/linux/srcutree.h b/include/linux/srcutree.h index 93ad18acd6d02d..05400f70baa40a 100644 --- a/include/linux/srcutree.h +++ b/include/linux/srcutree.h @@ -104,6 +104,7 @@ struct srcu_usage { struct srcu_struct { struct srcu_ctr __percpu *srcu_ctrp; struct srcu_data __percpu *sda; /* Per-CPU srcu_data array. */ + u8 srcu_reader_flavor; struct lockdep_map dep_map; struct srcu_usage *srcu_sup; /* Update-side data. */ }; @@ -162,20 +163,21 @@ struct srcu_struct { .work =3D __DELAYED_WORK_INITIALIZER(name.work, NULL, 0), \ } =20 -#define __SRCU_STRUCT_INIT_COMMON(name, usage_name) \ +#define __SRCU_STRUCT_INIT_COMMON(name, usage_name, fast) \ .srcu_sup =3D &usage_name, \ + .srcu_reader_flavor =3D fast, \ __SRCU_DEP_MAP_INIT(name) =20 -#define __SRCU_STRUCT_INIT_MODULE(name, usage_name) \ +#define __SRCU_STRUCT_INIT_MODULE(name, usage_name, fast) \ { \ - __SRCU_STRUCT_INIT_COMMON(name, usage_name) \ + __SRCU_STRUCT_INIT_COMMON(name, usage_name, fast) \ } =20 -#define __SRCU_STRUCT_INIT(name, usage_name, pcpu_name) \ +#define __SRCU_STRUCT_INIT(name, usage_name, pcpu_name, fast) \ { \ .sda =3D &pcpu_name, \ .srcu_ctrp =3D &pcpu_name.srcu_ctrs[0], \ - __SRCU_STRUCT_INIT_COMMON(name, usage_name) \ + __SRCU_STRUCT_INIT_COMMON(name, usage_name, fast) \ } =20 /* @@ -196,23 +198,33 @@ struct srcu_struct { * init_srcu_struct(&my_srcu); * * See include/linux/percpu-defs.h for the rules on per-CPU variables. + * + * DEFINE_SRCU_FAST() creates an srcu_struct and associated structures + * whose readers must be of the SRCU-fast variety. DEFINE_SRCU_FAST() + * cannot be used within modules due to there being no place to + * put the desired ->srcu_reader_flavor value. If in-module use of + * DEFINE_SRCU_FAST() becomes necessary, the srcu_struct structure will + * need to grow in order to store this value. */ #ifdef MODULE -# define __DEFINE_SRCU(name, is_static) \ +# define __DEFINE_SRCU(name, fast, is_static) \ static struct srcu_usage name##_srcu_usage =3D __SRCU_USAGE_INIT(name##_s= rcu_usage); \ - is_static struct srcu_struct name =3D __SRCU_STRUCT_INIT_MODULE(name, nam= e##_srcu_usage); \ + is_static struct srcu_struct name =3D __SRCU_STRUCT_INIT_MODULE(name, nam= e##_srcu_usage, \ + fast); \ extern struct srcu_struct * const __srcu_struct_##name; \ struct srcu_struct * const __srcu_struct_##name \ __section("___srcu_struct_ptrs") =3D &name #else -# define __DEFINE_SRCU(name, is_static) \ +# define __DEFINE_SRCU(name, fast, is_static) \ static DEFINE_PER_CPU(struct srcu_data, name##_srcu_data); \ static struct srcu_usage name##_srcu_usage =3D __SRCU_USAGE_INIT(name##_s= rcu_usage); \ is_static struct srcu_struct name =3D \ - __SRCU_STRUCT_INIT(name, name##_srcu_usage, name##_srcu_data) + __SRCU_STRUCT_INIT(name, name##_srcu_usage, name##_srcu_data, fast) #endif -#define DEFINE_SRCU(name) __DEFINE_SRCU(name, /* not static */) -#define DEFINE_STATIC_SRCU(name) __DEFINE_SRCU(name, static) +#define DEFINE_SRCU(name) __DEFINE_SRCU(name, 0, /* not static */) +#define DEFINE_STATIC_SRCU(name) __DEFINE_SRCU(name, 0, static) +#define DEFINE_SRCU_FAST(name) __DEFINE_SRCU(name, SRCU_READ_FLAVOR_FAST,= /* not static */) +#define DEFINE_STATIC_SRCU_FAST(name) __DEFINE_SRCU(name, SRCU_READ_FLAVOR= _FAST, static) =20 int __srcu_read_lock(struct srcu_struct *ssp) __acquires(ssp); void synchronize_srcu_expedited(struct srcu_struct *ssp); diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c index 38b440b0b0c80b..9869a13b876342 100644 --- a/kernel/rcu/srcutree.c +++ b/kernel/rcu/srcutree.c @@ -286,16 +286,29 @@ static int init_srcu_struct_fields(struct srcu_struct= *ssp, bool is_static) =20 #ifdef CONFIG_DEBUG_LOCK_ALLOC =20 -int __init_srcu_struct(struct srcu_struct *ssp, const char *name, - struct lock_class_key *key) +static int +__init_srcu_struct_common(struct srcu_struct *ssp, const char *name, struc= t lock_class_key *key) { /* Don't re-initialize a lock while it is held. */ debug_check_no_locks_freed((void *)ssp, sizeof(*ssp)); lockdep_init_map(&ssp->dep_map, name, key, 0); return init_srcu_struct_fields(ssp, false); } + +int __init_srcu_struct(struct srcu_struct *ssp, const char *name, struct l= ock_class_key *key) +{ + ssp->srcu_reader_flavor =3D 0; + return __init_srcu_struct_common(ssp, name, key); +} EXPORT_SYMBOL_GPL(__init_srcu_struct); =20 +int __init_srcu_struct_fast(struct srcu_struct *ssp, const char *name, str= uct lock_class_key *key) +{ + ssp->srcu_reader_flavor =3D SRCU_READ_FLAVOR_FAST; + return __init_srcu_struct_common(ssp, name, key); +} +EXPORT_SYMBOL_GPL(__init_srcu_struct_fast); + #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ =20 /** @@ -308,10 +321,26 @@ EXPORT_SYMBOL_GPL(__init_srcu_struct); */ int init_srcu_struct(struct srcu_struct *ssp) { + ssp->srcu_reader_flavor =3D 0; return init_srcu_struct_fields(ssp, false); } EXPORT_SYMBOL_GPL(init_srcu_struct); =20 +/** + * init_srcu_struct_fast - initialize a fast-reader sleep-RCU structure + * @ssp: structure to initialize. + * + * Must invoke this on a given srcu_struct before passing that srcu_struct + * to any other function. Each srcu_struct represents a separate domain + * of SRCU protection. + */ +int init_srcu_struct_fast(struct srcu_struct *ssp) +{ + ssp->srcu_reader_flavor =3D SRCU_READ_FLAVOR_FAST; + return init_srcu_struct_fields(ssp, false); +} +EXPORT_SYMBOL_GPL(init_srcu_struct_fast); + #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */ =20 /* @@ -734,6 +763,9 @@ void __srcu_check_read_flavor(struct srcu_struct *ssp, = int read_flavor) =20 sdp =3D raw_cpu_ptr(ssp->sda); old_read_flavor =3D READ_ONCE(sdp->srcu_reader_flavor); + WARN_ON_ONCE(ssp->srcu_reader_flavor && read_flavor !=3D ssp->srcu_reader= _flavor); + WARN_ON_ONCE(old_read_flavor && ssp->srcu_reader_flavor && + old_read_flavor !=3D ssp->srcu_reader_flavor); if (!old_read_flavor) { old_read_flavor =3D cmpxchg(&sdp->srcu_reader_flavor, 0, read_flavor); if (!old_read_flavor) --=20 2.40.1 From nobody Wed Oct 1 20:32:42 2025 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 17DE5303C8E; Wed, 1 Oct 2025 14:48:40 +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=1759330120; cv=none; b=QEV3Ds1Skz2Z5qkme603le74Vngfyo8S+kcYpCqWLxPxYNNesVfJOdK8TV37p4qyuIH4Yo6Xz0cR7zSj9Nr5oRtpvnq8DFsEPnEvM/NKspv5LngmCdu9xXJ+h3lrFTSgKKS2uetP1vo1jJbFBrTpISZyq0AoCvnnQaJKUNqEFSc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759330120; c=relaxed/simple; bh=tAtrCD0Q6r51wlJ/YZUSgYxDBqaTmpmjPK/LBZzejX4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=KV9topWwSRww8CBGkgoGc63KMF4hWuBjgS2WcfrMcL2WPFJMFxldctzaVt1j74zsonaRzVyDOPEqUU9Zi1GeqgUeSPjk/f3+3JHyc4qvV6HVfT/XTgSY9xvvl7xJrEC4sFQQLx0V7j4npISMZMEhmLf2dz16+L4fWFmj12xkS/Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=csTgdgUS; 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="csTgdgUS" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 94989C4CEFB; Wed, 1 Oct 2025 14:48:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1759330119; bh=tAtrCD0Q6r51wlJ/YZUSgYxDBqaTmpmjPK/LBZzejX4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=csTgdgUSMTy232HN+CTaEbv4J1Xi+gxUOITEFgFKGEAXeTFWSYXivUcBiiaMWKNO6 L/DrANeKLzG55seYzDAUNBzMgZCBMdSdSKaeAloQhD7gZLdRJEiLz7UXBYEoQsQV6O JVVv38BECH+91AugcmcSGEEP+zJ18mnG4mm0IU9pzVtO5r8a1uC6VAjhOlKstZg4kp DCP5cpX5qHOu/G5MeHxZSi72/o6oFozHlGcV7jy5psjJDQFPpSEf1SQo2PodWH7TOz PY2gZxfu0WgF1ZLAzkLWwUgs2I4xZTJyWK2GUY8vORtMj8h0T6NiYht569BeQVDh/H 5QdA796+ihPGQ== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 7FDBECE1427; Wed, 1 Oct 2025 07:48:34 -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" , Andrii Nakryiko , Alexei Starovoitov , Peter Zijlstra , bpf@vger.kernel.org Subject: [PATCH v2 12/21] srcu: Create an rcu_tasks_trace_expedite_current() function Date: Wed, 1 Oct 2025 07:48:23 -0700 Message-Id: <20251001144832.631770-12-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> References: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This commit creates an rcu_tasks_trace_expedite_current() function that expedites the current (and possibly the next) RCU Tasks Trace grace period. If the current RCU Tasks Trace grace period is already waiting, that wait will complete before the expediting takes effect. If there is no RCU Tasks Trace grace period in flight, this function might well create one. Signed-off-by: Paul E. McKenney Cc: Andrii Nakryiko Cc: Alexei Starovoitov Cc: Peter Zijlstra Cc: --- include/linux/rcupdate_trace.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/include/linux/rcupdate_trace.h b/include/linux/rcupdate_trace.h index f47ba9c074601c..cee89e51e45cbb 100644 --- a/include/linux/rcupdate_trace.h +++ b/include/linux/rcupdate_trace.h @@ -184,6 +184,20 @@ static inline void rcu_barrier_tasks_trace(void) srcu_barrier(&rcu_tasks_trace_srcu_struct); } =20 +/** + * rcu_tasks_trace_expedite_current - Expedite the current Tasks Trace RCU= grace period + * + * Cause the current Tasks Trace RCU grace period to become expedited. + * The grace period following the current one might also be expedited. + * If there is no current grace period, one might be created. If the + * current grace period is currently sleeping, that sleep will complete + * before expediting will take effect. + */ +static inline void rcu_tasks_trace_expedite_current(void) +{ + srcu_expedite_current(&rcu_tasks_trace_srcu_struct); +} + // Placeholders to enable stepwise transition. void __init rcu_tasks_trace_suppress_unused(void); =20 --=20 2.40.1 From nobody Wed Oct 1 20:32:42 2025 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 16220303C8D; Wed, 1 Oct 2025 14:48:40 +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=1759330120; cv=none; b=OiaqCvTmsQJoQmqDdRJhe9OUoJqI+rmIT/CpDA989ZpqObifq08AikR3Lmi+Wq1Nqm5aHs11imSawHKvKLF2DTM6ZCNn+jTrrwqRYvLRRrMZlzHunfm1B7RJ+FCh28Fj11XxnzUqr05O+GU5Vzl1Fv5CLRrFHNicF+ux/25eAQU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759330120; c=relaxed/simple; bh=voJ4b6wMLOYakegASPWhkeR8X8Tsr/P1l+3ILgsYDF4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=idOtMMjnAA+/YFUq78kEy7BMSgoqdUotkKOfW1D5a2hMiY2m3yQ/mfiMgYfuusiiBsTZav0zUOay79xAptmDEtYgDNkNoo9tYCfYonasKYKEuBs3kViYNGwStMF05fizdrFiNHvhul7AjfRAPcu31xjhmH2bh1YEfoG+d4vcz3A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=qytJBxiv; 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="qytJBxiv" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9B70EC19421; Wed, 1 Oct 2025 14:48:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1759330119; bh=voJ4b6wMLOYakegASPWhkeR8X8Tsr/P1l+3ILgsYDF4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qytJBxiv1s6olJZLe2hETNHsEYKMrLB29Vkbely3ZSm6YP69cs1k5G+Jfj2CPkW9x HO0vJZrDz+Oyb34tuNNP6de2Wywajwe2IZ8ZyJDOXg5N3PgT4601b5LvuYUIfxMODN 8CAWvGhx3bfeuXVsPtBAqYdVr0iU+eOxqrLNoPabT08gtc/FDpUh3lI+h7mdR/LOzJ 1heSb0BkPIXCSMRUmRV5jztwTOJZ3uxTtGuKIB2rapvmIEc2BGQogLBTCjOIwXO2Ez kZyRoAxGV3lFF2+a7RIgaLaz+LfUshyk0iSKAMsJzXnJCkZvjcWkY8r6V5l/A6PhcW GMTcyPCGvQ8Sg== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 8254FCE1436; Wed, 1 Oct 2025 07:48:34 -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" , Andrii Nakryiko , Alexei Starovoitov , Peter Zijlstra , bpf@vger.kernel.org Subject: [PATCH v2 13/21] rcutorture: Test rcu_tasks_trace_expedite_current() Date: Wed, 1 Oct 2025 07:48:24 -0700 Message-Id: <20251001144832.631770-13-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> References: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This commit adds a ->exp_current member to the tasks_tracing_ops structure to test the rcu_tasks_trace_expedite_current() function. Signed-off-by: Paul E. McKenney Cc: Andrii Nakryiko Cc: Alexei Starovoitov Cc: Peter Zijlstra Cc: --- kernel/rcu/rcutorture.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 64803d09fc733a..2e3806b996a80a 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -1136,6 +1136,7 @@ static struct rcu_torture_ops tasks_tracing_ops =3D { .deferred_free =3D rcu_tasks_tracing_torture_deferred_free, .sync =3D synchronize_rcu_tasks_trace, .exp_sync =3D synchronize_rcu_tasks_trace, + .exp_current =3D rcu_tasks_trace_expedite_current, .call =3D call_rcu_tasks_trace, .cb_barrier =3D rcu_barrier_tasks_trace, .cbflood_max =3D 50000, --=20 2.40.1 From nobody Wed Oct 1 20:32:42 2025 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 957F6304BB3; Wed, 1 Oct 2025 14:48:40 +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=1759330120; cv=none; b=V8TsMS98z9+kTn89/vJsx1bIyZUL/5MNSNAnCWbEUqwhpyQ/RUs5wq7R2qF9bVIBIQFVKuKxh98otJ8k87Zslq1E9inN/kxh5Y+Xq4BkoI1656F1tnjmmAohAXFwSRLzDe7Y1TO6KRp/xzdfy128FX9bdQIUFJNvK6DWAN5QY+U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759330120; c=relaxed/simple; bh=pdnTyZTL7oQ5jSpDQHBWEglBgEqYI4vFkpmgL1RNbu4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=pSs0qUeryIJCE9UIB04zu6SP5jzmtVYUxxp3fCOBZZRQD3QOFoAT2vgUCaUZZnmmWXLeWcHjoshE26ysvyDLERohsKX4VxBkG8CO5QlksHQxuCWj40kedu+J2w8Z1d07i4BzBK/BNVBZHVke65veGWKephk4Dvl/LtJZ43MHYFs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=a0+AuOus; 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="a0+AuOus" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 04578C116D0; Wed, 1 Oct 2025 14:48:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1759330120; bh=pdnTyZTL7oQ5jSpDQHBWEglBgEqYI4vFkpmgL1RNbu4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=a0+AuOus2VUJ6A77QBhQkKFyKvAaLi4uJn0dGy/IzRTbIbqab1b1FwN8OVGNjqMVM L2/BQs39dPyC9L+0+ts8mI9rWqQjaY446jMGc4rLaOi0XRWj+FqnItuoB1IfH4rZjm h+H0c5Rbec4yOh9NECV/ua8m2HxJz3nIfIheRADNI1Ie/8R0eokTS96xebG7cLUuPY Bv40CVHy37zauyt8zywHK3LYEh8nKZHJPr1GurkgXSgXEOVJWqBs10TvccyTa9OMk6 N9hnPpOUNbeiqQEAbKlXi3URVLetqfAgYRDf13NCB8ezhC2WxoEUNYKM/oURba77YZ +HrWs402CM68g== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 8523ACE147E; Wed, 1 Oct 2025 07:48:34 -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" , Mathieu Desnoyers , Sebastian Andrzej Siewior , bpf@vger.kernel.org Subject: [PATCH v2 14/21] srcu: Make grace-period determination use ssp->srcu_reader_flavor Date: Wed, 1 Oct 2025 07:48:25 -0700 Message-Id: <20251001144832.631770-14-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> References: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This commit causes the srcu_readers_unlock_idx() function to take the srcu_struct structure's ->srcu_reader_flavor field into account. This ensures that structures defined via DEFINE_SRCU_FAST( or initialized via init_srcu_struct_fast() have their grace periods use synchronize_srcu() or synchronize_srcu_expedited() instead of smp_mb(), even before the first SRCU reader has been entered. Signed-off-by: Paul E. McKenney Cc: Mathieu Desnoyers Cc: Steven Rostedt Cc: Sebastian Andrzej Siewior Cc: --- kernel/rcu/srcutree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c index 9869a13b876342..c29203b23d1ad7 100644 --- a/kernel/rcu/srcutree.c +++ b/kernel/rcu/srcutree.c @@ -490,7 +490,7 @@ static bool srcu_readers_lock_idx(struct srcu_struct *s= sp, int idx, bool gp, uns static unsigned long srcu_readers_unlock_idx(struct srcu_struct *ssp, int = idx, unsigned long *rdm) { int cpu; - unsigned long mask =3D 0; + unsigned long mask =3D ssp->srcu_reader_flavor; unsigned long sum =3D 0; =20 for_each_possible_cpu(cpu) { --=20 2.40.1 From nobody Wed Oct 1 20:32:42 2025 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 95716304BB2; Wed, 1 Oct 2025 14:48:40 +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=1759330120; cv=none; b=jpQnfe0z/O7pKuRzLT8vuNbltewzv1x4KrHPVAJ3afj7nenCegMxmGyKcNeW8RCJOoKXWyegzFjev0xVHElXt1xvWzVxASD66e9Dt8YhFB/vMnz/kHPedcmixoKbI+KC6ulYeiuG0k15hyl9U1ypccCPeghnTcbaZM2c6fUKuq8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759330120; c=relaxed/simple; bh=M6lQK/a51z9FSyLcsJB4DdYne3vYn3DuAPGWx5z897o=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=XC2dBok36tLUZwYpOfzP85IBUBjo+XGxUVKA+Hz2Ts4WLUTo+7nc5J9Bu4DgEF8IWxrFRJJJyzy8yrnAXAD589VDm1yh1ot0vYMf+cDCOguOjM/M4aPXVLKSPlTTCOD/JYCZuF9A7pOoF2wRwtJJew4d6ULVx3vjIUjHKwh3MI8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pR2M9STP; 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="pR2M9STP" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 04E0BC19423; Wed, 1 Oct 2025 14:48:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1759330120; bh=M6lQK/a51z9FSyLcsJB4DdYne3vYn3DuAPGWx5z897o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pR2M9STPcyv9NFEEZTT+27ROyeObWB77NHAWfHQ6us7no1FuLckHXZdb4ZAIj1BpO iv2/1/dtWhZRs2NK9J7FC/FHVzyJ051TC8fJBs9+WmXXkThuoQkpxWCX/K3JoPxfSW dWzSc207aRBqeTfYTqs8s6b87OtGAlcPz8RcfhfbTqztUl15/pb+H0oemKzKLPdZ9g NAXYNfXfydCLBco3wkjroY0MfZk79fdOqYi0dV2EV/grxZFZyZp9rQ7rbP1ZSSd8rw YCKqW6druRuOaJRTV5mMQAYcMegU0BGzZ0+oAAzZZqo/A+PenER5Sqll3n+FwEfWw9 vgQc55qIB3CiQ== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 87EF6CE14BF; Wed, 1 Oct 2025 07:48:34 -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" , Mathieu Desnoyers , Sebastian Andrzej Siewior , bpf@vger.kernel.org Subject: [PATCH v2 15/21] rcutorture: Exercise DEFINE_STATIC_SRCU_FAST() and init_srcu_struct_fast() Date: Wed, 1 Oct 2025 07:48:26 -0700 Message-Id: <20251001144832.631770-15-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> References: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This commit updates the initialization for the "srcu" and "srcud" torture types to use DEFINE_STATIC_SRCU_FAST() and init_srcu_struct_fast(), respectively, when reader_flavor is equal to SRCU_READ_FLAVOR_FAST. Signed-off-by: Paul E. McKenney Cc: Mathieu Desnoyers Cc: Steven Rostedt Cc: Sebastian Andrzej Siewior Cc: --- kernel/rcu/rcutorture.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 2e3806b996a80a..e859a1ca7dc841 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -692,10 +692,18 @@ static struct rcu_torture_ops rcu_busted_ops =3D { */ =20 DEFINE_STATIC_SRCU(srcu_ctl); +DEFINE_STATIC_SRCU_FAST(srcu_ctlf); static struct srcu_struct srcu_ctld; static struct srcu_struct *srcu_ctlp =3D &srcu_ctl; static struct rcu_torture_ops srcud_ops; =20 +static void srcu_torture_init(void) +{ + rcu_sync_torture_init(); + if (reader_flavor & SRCU_READ_FLAVOR_FAST) + srcu_ctlp =3D &srcu_ctlf; +} + static void srcu_get_gp_data(int *flags, unsigned long *gp_seq) { srcutorture_get_gp_data(srcu_ctlp, flags, gp_seq); @@ -865,7 +873,7 @@ static void srcu_torture_expedite_current(void) =20 static struct rcu_torture_ops srcu_ops =3D { .ttype =3D SRCU_FLAVOR, - .init =3D rcu_sync_torture_init, + .init =3D srcu_torture_init, .readlock =3D srcu_torture_read_lock, .read_delay =3D srcu_read_delay, .readunlock =3D srcu_torture_read_unlock, @@ -897,10 +905,13 @@ static struct rcu_torture_ops srcu_ops =3D { .name =3D "srcu" }; =20 -static void srcu_torture_init(void) +static void srcud_torture_init(void) { rcu_sync_torture_init(); - WARN_ON(init_srcu_struct(&srcu_ctld)); + if (reader_flavor & SRCU_READ_FLAVOR_FAST) + WARN_ON(init_srcu_struct_fast(&srcu_ctld)); + else + WARN_ON(init_srcu_struct(&srcu_ctld)); srcu_ctlp =3D &srcu_ctld; } =20 @@ -913,7 +924,7 @@ static void srcu_torture_cleanup(void) /* As above, but dynamically allocated. */ static struct rcu_torture_ops srcud_ops =3D { .ttype =3D SRCU_FLAVOR, - .init =3D srcu_torture_init, + .init =3D srcud_torture_init, .cleanup =3D srcu_torture_cleanup, .readlock =3D srcu_torture_read_lock, .read_delay =3D srcu_read_delay, --=20 2.40.1 From nobody Wed Oct 1 20:32:42 2025 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 951AD306D58; Wed, 1 Oct 2025 14:48:42 +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=1759330122; cv=none; b=rdlqt6DiRRvBIcWe3/oCETWVnl13PdSLJO1gZGkRyUIGbFU8MLGU5gV8HhmwQMJVW+FsQefZT5B5uyDIqh0NQQ9im54q5w2JAyw4SbvVt02M1Ou2x8SAca6DZiCUiwXZHcMsT9/1hwvFyfLDUqy0EM8JKuQ3pBkR0Ys6rm41pg0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759330122; c=relaxed/simple; bh=XhR9e3hqlUudx27Vubeb4TW2DWMcOEhmyHuKz9F2A/k=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=BJgO1G0Y9+Hs4U9+dBs9JPEhozO0u4kuUl5DET7TmZoqIw6FR7pUnACV80PcT7eCbBflSaMQ5WIIR+O+ebPKDYPvrrob8d6jxKhV757B3v2BrVeDXQY7obR6Rtt+ChJV/j7+Ph0BbqCAFQVZkFoL4Zz/TlyywlXS57i9FbXwZNY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MW4StiLS; 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="MW4StiLS" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0C3B0C4CEF9; Wed, 1 Oct 2025 14:48:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1759330122; bh=XhR9e3hqlUudx27Vubeb4TW2DWMcOEhmyHuKz9F2A/k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MW4StiLSL/ElaVEebubHzd/b/Qn/rurqgM7IolVNzy0msGtcBwyPWp16vYkK98+P6 HEut7n+MEoyw1vL3FS/pa5uCNNowlkBQAgbvZ3BRNpEVl3+e3OxUILaUKQ7KNwlDgi hL0NpeQguVM8OndK4urvj7qw7C7VBhYCp6YJgclHwMq6nVZsUpThV0BqOF+UFPejmX gU7iCPf5GNlNm3hvEwB0TarFQlcZ7W/Z514g0cz64h2aaHX3XLj+hjLdiNIDFGCJL7 TPzb3chsbu5dhxbfalbkFEFIY8e0k0BetFVua+I4UcpMArQUYBKN06/m/4eufpnoUf uFvPZSza+Lr9g== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 8A6C6CE14C4; Wed, 1 Oct 2025 07:48:34 -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" , Mathieu Desnoyers , Sebastian Andrzej Siewior , bpf@vger.kernel.org Subject: [PATCH v2 16/21] refscale: Exercise DEFINE_STATIC_SRCU_FAST() and init_srcu_struct_fast() Date: Wed, 1 Oct 2025 07:48:27 -0700 Message-Id: <20251001144832.631770-16-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> References: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This commit updates the initialization for the "srcu-fast" scale type to use DEFINE_STATIC_SRCU_FAST() when reader_flavor is equal to SRCU_READ_FLAVOR_FAST. Signed-off-by: Paul E. McKenney Cc: Mathieu Desnoyers Cc: Steven Rostedt Cc: Sebastian Andrzej Siewior Cc: --- kernel/rcu/refscale.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/kernel/rcu/refscale.c b/kernel/rcu/refscale.c index 19841704d8f579..ece77f6d055b85 100644 --- a/kernel/rcu/refscale.c +++ b/kernel/rcu/refscale.c @@ -184,6 +184,7 @@ static const struct ref_scale_ops rcu_ops =3D { =20 // Definitions for SRCU ref scale testing. DEFINE_STATIC_SRCU(srcu_refctl_scale); +DEFINE_STATIC_SRCU_FAST(srcu_fast_refctl_scale); static struct srcu_struct *srcu_ctlp =3D &srcu_refctl_scale; =20 static void srcu_ref_scale_read_section(const int nloops) @@ -216,6 +217,12 @@ static const struct ref_scale_ops srcu_ops =3D { .name =3D "srcu" }; =20 +static bool srcu_fast_sync_scale_init(void) +{ + srcu_ctlp =3D &srcu_fast_refctl_scale; + return true; +} + static void srcu_fast_ref_scale_read_section(const int nloops) { int i; @@ -240,7 +247,7 @@ static void srcu_fast_ref_scale_delay_section(const int= nloops, const int udl, c } =20 static const struct ref_scale_ops srcu_fast_ops =3D { - .init =3D rcu_sync_scale_init, + .init =3D srcu_fast_sync_scale_init, .readsection =3D srcu_fast_ref_scale_read_section, .delaysection =3D srcu_fast_ref_scale_delay_section, .name =3D "srcu-fast" --=20 2.40.1 From nobody Wed Oct 1 20:32:42 2025 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 A6A633074AA; Wed, 1 Oct 2025 14:48:42 +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=1759330122; cv=none; b=SknlEzXxg2NcZkqBM1+CG5FOxpPolKuXWFr953OdIxiXcHgBEu/tXFK/PPbk1ucTR0+4MyzdfPBxozVWOOhGGh+EoXqiFbyIHY9/voR77xPioxhjx4BJlz8mUXfyFjbcuEZZAOj4Uu7BN7F7ezNGiGcef3xmaKOkxkhr9pr8hRM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759330122; c=relaxed/simple; bh=LScGsjhQ8gC4uQeaMP9aDvziuKzyoZfiTdtxTzt+6cM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=jXfQ0k2DMF8N5BIGC1LmxrUS2wtJ6a4iCHPraxHTSXVgrc4OEa2g981JZtl277kufXTOIJH+fwC/VVoK0gRBIpg1nlx7z7WFYxbpwQj5Rzyr11Rv+7wGlNlLder/cyRwo5embATJOzq4CNgg4xXtnNeKiEf1R6ak1NtwM17gjUc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=N0djdl6Y; 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="N0djdl6Y" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0D0B0C4AF0C; Wed, 1 Oct 2025 14:48:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1759330122; bh=LScGsjhQ8gC4uQeaMP9aDvziuKzyoZfiTdtxTzt+6cM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=N0djdl6YiJv2vY+1kcyDfo7HXbOY+Pb88LsyZuWnKHI6kgfoBWs08cQyvh8dSQjPs mSbQTRgLMcZEAKMFPKOsgaIafXDDCLbCBXPwP7Eh7B/sCd5fML6sdeQxAnwKE7ZkMk G74P+wzipD+BhOCyT47mly4ECQHYoG55lkNOHGNxmQVvV3Io5u6xkaCFyqq6cwDsQb PeVGbM2y2By7VGNjOWF+f6I8qsw7ujUa6ylQR34NL45WS2vIMerKdZmnt1lsCcM8em EJ5+avfVgbFXnj9844ONMDS6kG2Mq3WNMi9t8/8+Tg5amAfD6XyEYDE8658v3+szXF 0Tlw4Q4tL8Z+g== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 8CF7CCE14DF; Wed, 1 Oct 2025 07:48:34 -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" , Mathieu Desnoyers , Sebastian Andrzej Siewior , bpf@vger.kernel.org Subject: [PATCH v2 17/21] srcu: Require special srcu_struct define/init for SRCU-fast readers Date: Wed, 1 Oct 2025 07:48:28 -0700 Message-Id: <20251001144832.631770-17-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> References: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This commit adds CONFIG_PROVE_RCU=3Dy checking to enforce the new rule that srcu_struct structures passed to srcu_read_lock_fast() and other SRCU-fast read-side markers be either initialized with init_srcu_struct_fast() on the one hand or defined using either DEFINE_SRCU_FAST() or DEFINE_STATIC_SRCU_FAST(). This will enable removal of the non-debug read-side checks from srcu_read_lock_fast() and friends, which on my laptop provides a 25% speedup (which admittedly amounts to about half a nanosecond, but when tracing fastpaths...) Signed-off-by: Paul E. McKenney Cc: Mathieu Desnoyers Cc: Steven Rostedt Cc: Sebastian Andrzej Siewior Cc: --- include/linux/srcu.h | 34 ++++++++++++++++++++++------------ kernel/rcu/srcutree.c | 1 + 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/include/linux/srcu.h b/include/linux/srcu.h index 26de47820c58cd..2982b5a6930fa6 100644 --- a/include/linux/srcu.h +++ b/include/linux/srcu.h @@ -271,17 +271,26 @@ static inline int srcu_read_lock(struct srcu_struct *= ssp) __acquires(ssp) * @ssp: srcu_struct in which to register the new reader. * * Enter an SRCU read-side critical section, but for a light-weight - * smp_mb()-free reader. See srcu_read_lock() for more information. - * - * If srcu_read_lock_fast() is ever used on an srcu_struct structure, - * then none of the other flavors may be used, whether before, during, - * or after. Note that grace-period auto-expediting is disabled for _fast - * srcu_struct structures because auto-expedited grace periods invoke - * synchronize_rcu_expedited(), IPIs and all. - * - * Note that srcu_read_lock_fast() can be invoked only from those contexts - * where RCU is watching, that is, from contexts where it would be legal - * to invoke rcu_read_lock(). Otherwise, lockdep will complain. + * smp_mb()-free reader. See srcu_read_lock() for more information. This + * function is NMI-safe, in a manner similar to srcu_read_lock_nmisafe(). + * + * For srcu_read_lock_fast() to be used on an srcu_struct structure, + * that structure must have been defined using either DEFINE_SRCU_FAST() + * or DEFINE_STATIC_SRCU_FAST() on the one hand or initialized with + * init_srcu_struct_fast() on the other. Such an srcu_struct structure + * cannot be passed to any non-fast variant of srcu_read_{,un}lock() or + * srcu_{down,up}_read(). In kernels built with CONFIG_PROVE_RCU=3Dy, + * __srcu_check_read_flavor() will complain bitterly if you ignore this + * restriction. + * + * Grace-period auto-expediting is disabled for SRCU-fast srcu_struct + * structures because SRCU-fast expedited grace periods invoke + * synchronize_rcu_expedited(), IPIs and all. If you need expedited + * SRCU-fast grace periods, use synchronize_srcu_expedited(). + * + * The srcu_read_lock_fast() function can be invoked only from those + * contexts where RCU is watching, that is, from contexts where it would + * be legal to invoke rcu_read_lock(). Otherwise, lockdep will complain. */ static inline struct srcu_ctr __percpu *srcu_read_lock_fast(struct srcu_st= ruct *ssp) __acquires(ssp) { @@ -317,7 +326,8 @@ static inline struct srcu_ctr __percpu *srcu_read_lock_= fast_notrace(struct srcu_ * srcu_down_read() for more information. * * The same srcu_struct may be used concurrently by srcu_down_read_fast() - * and srcu_read_lock_fast(). + * and srcu_read_lock_fast(). However, the same definition/initialization + * requirements called out for srcu_read_lock_safe() apply. */ static inline struct srcu_ctr __percpu *srcu_down_read_fast(struct srcu_st= ruct *ssp) __acquires(ssp) { diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c index c29203b23d1ad7..2f8aa280911e19 100644 --- a/kernel/rcu/srcutree.c +++ b/kernel/rcu/srcutree.c @@ -766,6 +766,7 @@ void __srcu_check_read_flavor(struct srcu_struct *ssp, = int read_flavor) WARN_ON_ONCE(ssp->srcu_reader_flavor && read_flavor !=3D ssp->srcu_reader= _flavor); WARN_ON_ONCE(old_read_flavor && ssp->srcu_reader_flavor && old_read_flavor !=3D ssp->srcu_reader_flavor); + WARN_ON_ONCE(read_flavor =3D=3D SRCU_READ_FLAVOR_FAST && !ssp->srcu_reade= r_flavor); if (!old_read_flavor) { old_read_flavor =3D cmpxchg(&sdp->srcu_reader_flavor, 0, read_flavor); if (!old_read_flavor) --=20 2.40.1 From nobody Wed Oct 1 20:32:42 2025 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 71470306D40; Wed, 1 Oct 2025 14:48:42 +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=1759330122; cv=none; b=YBHC3Z3lNul/umJy1z72zCA6m8Ra5eDtNbqhtJZFxehCQVYcrAlxd9tMswtgzI8hnFXTLlGWp2ekEgnx0Cza5VwKSIIqKf27kPOCE0KsH7wdMfzUUpi0eTcjvzK9myblUwP+3XCIWfQLFyx7KpTksjCDtsoIvr8yqBIUrRFDS48= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759330122; c=relaxed/simple; bh=h25HXfqFwZPbzPp+0/q7PleMKwW/TXZPNmjI5yN4W8Q=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=gaJCUtoDYHc0XdbY9Y4ZCvjtiVYzx64nx021rOtcyIUGp7LVfOZZaoASkTvn/xAHYoOWMd/YGB/R5fAEv+ZUGMzbDhL5I55hkaiYN16NGVldJfYgLcsxD5IHLvUrVSanRt+3omJKksBGBWXKFHDXMVUgAke4tmylDcAQ1Zth7Rk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=iLCIQ08z; 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="iLCIQ08z" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0CD0FC4CEFB; Wed, 1 Oct 2025 14:48:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1759330122; bh=h25HXfqFwZPbzPp+0/q7PleMKwW/TXZPNmjI5yN4W8Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iLCIQ08z3SlN2WlN4vUVtl0nuhTVvrV6DT78yaGGwFs4MPshPJxuGtQj6Gq10iJT0 A1yZ5/WwCHq1YysHhe7ZR7AgGHW0kJWhjwdm9okrAusdn8p9Lhr29gfoEWcJfjUgxk W3Nla37WhiWgfAetAal7z0U9dVmANGuAM8U1PvLe+tZ9QRqTqw2k3cSd0u0VPocQqI UeWIAv99XsjEzka5J3ywtxg7eJaAWSNraittJN32vWVGtTY7h06v5vTgOjdmWhDAVb 9ukKfRjbrpH4n+/w4p26/3XBglI2KoC4P3F7AOSBUEcXkQQEPtV51MjPc6Znfz/dTM PJcVvAI41/o8Q== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 8F63FCE14F4; Wed, 1 Oct 2025 07:48:34 -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" , Mathieu Desnoyers , Sebastian Andrzej Siewior , bpf@vger.kernel.org Subject: [PATCH v2 18/21] srcu: Make SRCU-fast readers enforce use of SRCU-fast definition/init Date: Wed, 1 Oct 2025 07:48:29 -0700 Message-Id: <20251001144832.631770-18-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> References: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This commit makes CONFIG_PROVE_RCU=3Dy kernels enforce the new rule that srcu_struct structures that are passed to srcu_read_lock_fast() and other SRCU-fast read-side markers be either initialized with init_srcu_struct_fast() on the one hand or defined with DEFINE_SRCU_FAST() or DEFINE_STATIC_SRCU_FAST() on the other. This eliminates the read-side test that was formerly included in srcu_read_lock_fast() and friends, speeding these primitives up by about 25% (admittedly only about half of a nanosecond, but when tracing on fastpaths...) Signed-off-by: Paul E. McKenney Cc: Mathieu Desnoyers Cc: Steven Rostedt Cc: Sebastian Andrzej Siewior Cc: --- include/linux/srcu.h | 6 +++--- include/linux/srcutiny.h | 1 - include/linux/srcutree.h | 16 +--------------- kernel/rcu/tasks.h | 5 ----- 4 files changed, 4 insertions(+), 24 deletions(-) diff --git a/include/linux/srcu.h b/include/linux/srcu.h index 2982b5a6930fa6..41e27c1d917d3e 100644 --- a/include/linux/srcu.h +++ b/include/linux/srcu.h @@ -297,7 +297,7 @@ static inline struct srcu_ctr __percpu *srcu_read_lock_= fast(struct srcu_struct * struct srcu_ctr __percpu *retval; =20 RCU_LOCKDEP_WARN(!rcu_is_watching(), "RCU must be watching srcu_read_lock= _fast()."); - srcu_check_read_flavor_force(ssp, SRCU_READ_FLAVOR_FAST); + srcu_check_read_flavor(ssp, SRCU_READ_FLAVOR_FAST); retval =3D __srcu_read_lock_fast(ssp); rcu_try_lock_acquire(&ssp->dep_map); return retval; @@ -312,7 +312,7 @@ static inline struct srcu_ctr __percpu *srcu_read_lock_= fast_notrace(struct srcu_ { struct srcu_ctr __percpu *retval; =20 - srcu_check_read_flavor_force(ssp, SRCU_READ_FLAVOR_FAST); + srcu_check_read_flavor(ssp, SRCU_READ_FLAVOR_FAST); retval =3D __srcu_read_lock_fast(ssp); return retval; } @@ -333,7 +333,7 @@ static inline struct srcu_ctr __percpu *srcu_down_read_= fast(struct srcu_struct * { WARN_ON_ONCE(IS_ENABLED(CONFIG_PROVE_RCU) && in_nmi()); RCU_LOCKDEP_WARN(!rcu_is_watching(), "RCU must be watching srcu_down_read= _fast()."); - srcu_check_read_flavor_force(ssp, SRCU_READ_FLAVOR_FAST); + srcu_check_read_flavor(ssp, SRCU_READ_FLAVOR_FAST); return __srcu_read_lock_fast(ssp); } =20 diff --git a/include/linux/srcutiny.h b/include/linux/srcutiny.h index 92e6ab53398fc0..1ecc3393fb26be 100644 --- a/include/linux/srcutiny.h +++ b/include/linux/srcutiny.h @@ -112,7 +112,6 @@ static inline void srcu_barrier(struct srcu_struct *ssp) =20 static inline void srcu_expedite_current(struct srcu_struct *ssp) { } #define srcu_check_read_flavor(ssp, read_flavor) do { } while (0) -#define srcu_check_read_flavor_force(ssp, read_flavor) do { } while (0) =20 /* Defined here to avoid size increase for non-torture kernels. */ static inline void srcu_torture_stats_print(struct srcu_struct *ssp, diff --git a/include/linux/srcutree.h b/include/linux/srcutree.h index 05400f70baa40a..fd24ec146af614 100644 --- a/include/linux/srcutree.h +++ b/include/linux/srcutree.h @@ -311,21 +311,7 @@ __srcu_read_unlock_fast(struct srcu_struct *ssp, struc= t srcu_ctr __percpu *scp) =20 void __srcu_check_read_flavor(struct srcu_struct *ssp, int read_flavor); =20 -// Record reader usage even for CONFIG_PROVE_RCU=3Dn kernels. This is -// needed only for flavors that require grace-period smp_mb() calls to be -// promoted to synchronize_rcu(). -static inline void srcu_check_read_flavor_force(struct srcu_struct *ssp, i= nt read_flavor) -{ - struct srcu_data *sdp =3D raw_cpu_ptr(ssp->sda); - - if (likely(READ_ONCE(sdp->srcu_reader_flavor) & read_flavor)) - return; - - // Note that the cmpxchg() in __srcu_check_read_flavor() is fully ordered. - __srcu_check_read_flavor(ssp, read_flavor); -} - -// Record non-_lite() usage only for CONFIG_PROVE_RCU=3Dy kernels. +// Record SRCU-reader usage type only for CONFIG_PROVE_RCU=3Dy kernels. static inline void srcu_check_read_flavor(struct srcu_struct *ssp, int rea= d_flavor) { if (IS_ENABLED(CONFIG_PROVE_RCU)) diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h index bf1226834c9423..76f952196a2921 100644 --- a/kernel/rcu/tasks.h +++ b/kernel/rcu/tasks.h @@ -1600,11 +1600,6 @@ static inline void rcu_tasks_bootup_oddness(void) {} // Tracing variant of Tasks RCU. This variant is designed to be used // to protect tracing hooks, including those of BPF. This variant // is implemented via a straightforward mapping onto SRCU-fast. -// DEFINE_SRCU_FAST() is required because rcu_read_lock_trace() must -// use __srcu_read_lock_fast() in order to bypass the rcu_is_watching() -// checks in kernels built with CONFIG_TASKS_TRACE_RCU_NO_MB=3Dn, which al= so -// bypasses the srcu_check_read_flavor_force() that would otherwise mark -// rcu_tasks_trace_srcu_struct as needing SRCU-fast readers. =20 DEFINE_SRCU_FAST(rcu_tasks_trace_srcu_struct); EXPORT_SYMBOL_GPL(rcu_tasks_trace_srcu_struct); --=20 2.40.1 From nobody Wed Oct 1 20:32:42 2025 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 973F9307487; Wed, 1 Oct 2025 14:48:42 +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=1759330122; cv=none; b=p19SIer6YT+0cmF8o7a4HQhxrP0gR92vVYhzUuo/3EFQAygrFVI2UZxy3rIwJNsehFbq3fxHs3buB1BUWY4lUar5RJWW2u7O3HmAzZyndCKf+MkAQAAUBg6CWmhtANeItm2uKkoxUJiD1hN+XsUZKeQwVIJ2NlAkX2Pqdr27c6U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759330122; c=relaxed/simple; bh=81BLq8+oPnPePeqC2bm5XK2/WvvBNdRPQuuI5LrZL9M=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=H9LdMdhDTjQmebPgaiyv9+IuzIDZQqjsJ5XlIrfAIcnFTDvQYLGwcygkyKMGHYapR39Xi2cVegqv0BXTyJGminYNKJ5o0ptRDNbq017VryyG3HggNK51amwpJ6AruFSC9axhdPz7aXr8IO2YbdLvdZ+aSOspRaepjax17gxYCSU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZV7DNIaW; 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="ZV7DNIaW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0CF1EC4AF0B; Wed, 1 Oct 2025 14:48:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1759330122; bh=81BLq8+oPnPePeqC2bm5XK2/WvvBNdRPQuuI5LrZL9M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZV7DNIaWcrlojWlA3X9ZPb/9vaOqUIRRr/b+Mg643ai0OqJ88s5P/XvBdWIINDEGU 9PcWKT7K9IXv+J950K32IJpGKGfQuHhofS3AvSjIJtabEdNoqua93mjXWNNIceFHbf Q5tNxIRqroWCNYfGdJ0ch72lKFwxAM7Ukr1lEgDyyBJx87m/feF1YP0oQiXHg3Rz49 FeaswbGPbUorsETo4yAk4OsCVbHAGEI7V2vQoSa9t+a7dh+vNBasWOAnANgi6zpDkb RzxvLNh0ccgwN0LqW3HHxGsoc4kfHIL4uRu7fnYTDpPJroipsZI1aBrPZgQsDnK15S Ub9hqLOCzcAWQ== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 92237CE14F5; Wed, 1 Oct 2025 07:48:34 -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" , Mathieu Desnoyers , Sebastian Andrzej Siewior , bpf@vger.kernel.org Subject: [PATCH v2 19/21] doc: Update for SRCU-fast definitions and initialization Date: Wed, 1 Oct 2025 07:48:30 -0700 Message-Id: <20251001144832.631770-19-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> References: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This commit documents the DEFINE_SRCU_FAST(), DEFINE_STATIC_SRCU_FAST(), and init_srcu_struct_fast() API members. Signed-off-by: Paul E. McKenney Cc: Mathieu Desnoyers Cc: Steven Rostedt Cc: Sebastian Andrzej Siewior Cc: --- .../RCU/Design/Requirements/Requirements.rst | 33 ++++++++++--------- Documentation/RCU/checklist.rst | 12 ++++--- Documentation/RCU/whatisRCU.rst | 3 ++ 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/Documentation/RCU/Design/Requirements/Requirements.rst b/Docum= entation/RCU/Design/Requirements/Requirements.rst index 4a116d7a564edc..b5cdbba3ec2e71 100644 --- a/Documentation/RCU/Design/Requirements/Requirements.rst +++ b/Documentation/RCU/Design/Requirements/Requirements.rst @@ -2637,15 +2637,16 @@ synchronize_srcu() for some other domain ``ss1``, a= nd if an that was held across as ``ss``-domain synchronize_srcu(), deadlock would again be possible. Such a deadlock cycle could extend across an arbitrarily large number of different SRCU domains. Again, with great -power comes great responsibility. +power comes great responsibility, though lockdep is now able to detect +this sort of deadlock. =20 -Unlike the other RCU flavors, SRCU read-side critical sections can run -on idle and even offline CPUs. This ability requires that -srcu_read_lock() and srcu_read_unlock() contain memory barriers, -which means that SRCU readers will run a bit slower than would RCU -readers. It also motivates the smp_mb__after_srcu_read_unlock() API, -which, in combination with srcu_read_unlock(), guarantees a full -memory barrier. +Unlike the other RCU flavors, SRCU read-side critical sections can run on +idle and even offline CPUs, with the exception of srcu_read_lock_fast() +and friends. This ability requires that srcu_read_lock() and +srcu_read_unlock() contain memory barriers, which means that SRCU +readers will run a bit slower than would RCU readers. It also motivates +the smp_mb__after_srcu_read_unlock() API, which, in combination with +srcu_read_unlock(), guarantees a full memory barrier. =20 Also unlike other RCU flavors, synchronize_srcu() may **not** be invoked from CPU-hotplug notifiers, due to the fact that SRCU grace @@ -2681,15 +2682,15 @@ run some tests first. SRCU just might need a few ad= justment to deal with that sort of load. Of course, your mileage may vary based on the speed of your CPUs and the size of your memory. =20 -The `SRCU -API `__ +The `SRCU API +`__ includes srcu_read_lock(), srcu_read_unlock(), -srcu_dereference(), srcu_dereference_check(), -synchronize_srcu(), synchronize_srcu_expedited(), -call_srcu(), srcu_barrier(), and srcu_read_lock_held(). It -also includes DEFINE_SRCU(), DEFINE_STATIC_SRCU(), and -init_srcu_struct() APIs for defining and initializing -``srcu_struct`` structures. +srcu_dereference(), srcu_dereference_check(), synchronize_srcu(), +synchronize_srcu_expedited(), call_srcu(), srcu_barrier(), +and srcu_read_lock_held(). It also includes DEFINE_SRCU(), +DEFINE_STATIC_SRCU(), DEFINE_SRCU_FAST(), DEFINE_STATIC_SRCU_FAST(), +init_srcu_struct(), and init_srcu_struct_fast() APIs for defining and +initializing ``srcu_struct`` structures. =20 More recently, the SRCU API has added polling interfaces: =20 diff --git a/Documentation/RCU/checklist.rst b/Documentation/RCU/checklist.= rst index c9bfb2b218e525..4b30f701225fdb 100644 --- a/Documentation/RCU/checklist.rst +++ b/Documentation/RCU/checklist.rst @@ -417,11 +417,13 @@ over a rather long period of time, but improvements a= re always welcome! you should be using RCU rather than SRCU, because RCU is almost always faster and easier to use than is SRCU. =20 - Also unlike other forms of RCU, explicit initialization and - cleanup is required either at build time via DEFINE_SRCU() - or DEFINE_STATIC_SRCU() or at runtime via init_srcu_struct() - and cleanup_srcu_struct(). These last two are passed a - "struct srcu_struct" that defines the scope of a given + Also unlike other forms of RCU, explicit initialization + and cleanup is required either at build time via + DEFINE_SRCU(), DEFINE_STATIC_SRCU(), DEFINE_SRCU_FAST(), + or DEFINE_STATIC_SRCU_FAST() or at runtime via either + init_srcu_struct() or init_srcu_struct_fast() and + cleanup_srcu_struct(). These last three are passed a + `struct srcu_struct` that defines the scope of a given SRCU domain. Once initialized, the srcu_struct is passed to srcu_read_lock(), srcu_read_unlock() synchronize_srcu(), synchronize_srcu_expedited(), and call_srcu(). A given diff --git a/Documentation/RCU/whatisRCU.rst b/Documentation/RCU/whatisRCU.= rst index cf0b0ac9f4636a..a1582bd653d115 100644 --- a/Documentation/RCU/whatisRCU.rst +++ b/Documentation/RCU/whatisRCU.rst @@ -1227,7 +1227,10 @@ SRCU: Initialization/cleanup/ordering:: =20 DEFINE_SRCU DEFINE_STATIC_SRCU + DEFINE_SRCU_FAST // for srcu_read_lock_fast() and friends + DEFINE_STATIC_SRCU_FAST // for srcu_read_lock_fast() and friends init_srcu_struct + init_srcu_struct_fast cleanup_srcu_struct smp_mb__after_srcu_read_unlock =20 --=20 2.40.1 From nobody Wed Oct 1 20:32:42 2025 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 A5C5B3074A6; Wed, 1 Oct 2025 14:48:42 +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=1759330122; cv=none; b=R9duA4foB5zymlbpUlD95rqxfd+Dh1qnigTEoAjuc2kPR4uAPGeEW969wardZTVPFlckf5ApAML6NbqjImmit55pJ2wLbMCojzKBGmVuHVuqHrBXFFLuQLwTHO5Y+UIo1JjZx6DXFiu48rQHEwdMznFsQS5oG/doo6KhtT7Ijgw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759330122; c=relaxed/simple; bh=sjVFcWrDJfqVEdr4Iyjd1Hv55BK3Tses2HzyitawB4I=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=mVq6qBjDMbndIPjYCX2T7bXANLy92K+SAnxdHYf1TbZgPjiWgqEcbszm8/TOBGVT9NIQAfXGEv/Ri/IlIKFZPRc1Ho/mYwPTNXZibs1JZUWXrRlNr4DVZzsDdUrAQDqbujg3/b+GE4v6AkkqDVCYpBEcvIeCmXFuZVdZ6wWse2M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=LIfuwIs3; 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="LIfuwIs3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0CD4AC4AF09; Wed, 1 Oct 2025 14:48:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1759330122; bh=sjVFcWrDJfqVEdr4Iyjd1Hv55BK3Tses2HzyitawB4I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LIfuwIs3aWwSw2fZBWkAnzRnXv+k1JyVpn9nvELRLD+XrCbTp3xJQlVJ5AOQnkn/S N2ZFBKIHueCPm/Q+X3+r3DTeX9DyD5zsBSo4dy3Lhbzv31fUjZPH2Nl96XlZrgFRHd 3wQimfsYFMMPBq9AGaSCktCHONkS53+/pBkX6XGZp8Y4mzBbTQBuBpykezOmq5x1Oo QLZyzF8Rxyo+IUfASIn51sTK0Ztjz77VUOp6ccN7n38yRHqL1P3wbC+MG4rEwh2P3p 2pbtDNlKHomwZsxgYbbxT3xr9sjsaoFT/AhAM90m/uLHjiNCXgYlaJ7ZEEJgBU3l6I OjhDuS5eQ3QFA== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 94B29CE152F; Wed, 1 Oct 2025 07:48:34 -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" , Mathieu Desnoyers , Sebastian Andrzej Siewior , bpf@vger.kernel.org Subject: [PATCH v2 20/21] tracing: Guard __DECLARE_TRACE() use of __DO_TRACE_CALL() with SRCU-fast Date: Wed, 1 Oct 2025 07:48:31 -0700 Message-Id: <20251001144832.631770-20-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> References: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The current use of guard(preempt_notrace)() within __DECLARE_TRACE() to protect invocation of __DO_TRACE_CALL() means that BPF programs attached to tracepoints are non-preemptible. This is unhelpful in real-time systems, whose users apparently wish to use BPF while also achieving low latencies. (Who knew?) One option would be to use preemptible RCU, but this introduces many opportunities for infinite recursion, which many consider to be counterproductive, especially given the relatively small stacks provided by the Linux kernel. These opportunities could be shut down by sufficiently energetic duplication of code, but this sort of thing is considered impolite in some circles. Therefore, use the shiny new SRCU-fast API, which provides somewhat faster readers than those of preemptible RCU, at least on my laptop, where task_struct access is more expensive than access to per-CPU variables. And SRCU fast provides way faster readers than does SRCU, courtesy of being able to avoid the read-side use of smp_mb(). Also, it is quite straightforward to create srcu_read_{,un}lock_fast_notrace() functions. While in the area, SRCU now supports early boot call_srcu(). Therefore, remove the checks that used to avoid such use from rcu_free_old_probes() before this commit was applied: e53244e2c893 ("tracepoint: Remove SRCU protection") The current commit can be thought of as an approximate revert of that commit, with some compensating additions of preemption disabling pointed out by Steven Rostedt (thank you, Steven!). This preemption disabling uses guard(preempt_notrace)(), and while in the area a couple of other use cases were also converted to guards. However, Yonghong Song points out that BPF expects non-sleepable BPF programs to remain on the same CPU, which means that migration must be disabled whenever preemption remains enabled. In addition, non-RT kernels have performance expectations on BPF that would be violated by allowing the BPF programs to be preempted. Therefore, continue to disable preemption in non-RT kernels, and protect the BPF program with both SRCU and migration disabling for RT kernels, and even then only if preemption is not already disabled. [ paulmck: Apply kernel test robot and Yonghong Song feedback. ] Link: https://lore.kernel.org/all/20250613152218.1924093-1-bigeasy@linutron= ix.de/ Signed-off-by: Paul E. McKenney Cc: Mathieu Desnoyers Cc: Steven Rostedt Cc: Sebastian Andrzej Siewior Cc: --- include/linux/tracepoint.h | 45 ++++++++++++++++++++++-------------- include/trace/perf.h | 4 ++-- include/trace/trace_events.h | 4 ++-- kernel/tracepoint.c | 21 ++++++++++++++++- 4 files changed, 52 insertions(+), 22 deletions(-) diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 826ce3f8e1f851..9f8b19cd303acc 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -33,6 +33,8 @@ struct trace_eval_map { =20 #define TRACEPOINT_DEFAULT_PRIO 10 =20 +extern struct srcu_struct tracepoint_srcu; + extern int tracepoint_probe_register(struct tracepoint *tp, void *probe, void *data); extern int @@ -115,7 +117,10 @@ void for_each_tracepoint_in_module(struct module *mod, static inline void tracepoint_synchronize_unregister(void) { synchronize_rcu_tasks_trace(); - synchronize_rcu(); + if (IS_ENABLED(CONFIG_PREEMPT_RT)) + synchronize_srcu(&tracepoint_srcu); + else + synchronize_rcu(); } static inline bool tracepoint_is_faultable(struct tracepoint *tp) { @@ -266,23 +271,29 @@ static inline struct tracepoint *tracepoint_ptr_deref= (tracepoint_ptr_t *p) return static_branch_unlikely(&__tracepoint_##name.key);\ } =20 -#define __DECLARE_TRACE(name, proto, args, cond, data_proto) \ +#define __DECLARE_TRACE(name, proto, args, cond, data_proto) \ __DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), PARAMS(data_pro= to)) \ - static inline void __do_trace_##name(proto) \ - { \ - if (cond) { \ - guard(preempt_notrace)(); \ - __DO_TRACE_CALL(name, TP_ARGS(args)); \ - } \ - } \ - static inline void trace_##name(proto) \ - { \ - if (static_branch_unlikely(&__tracepoint_##name.key)) \ - __do_trace_##name(args); \ - if (IS_ENABLED(CONFIG_LOCKDEP) && (cond)) { \ - WARN_ONCE(!rcu_is_watching(), \ - "RCU not watching for tracepoint"); \ - } \ + static inline void __do_trace_##name(proto) \ + { \ + if (cond) { \ + if (IS_ENABLED(CONFIG_PREEMPT_RT) && preemptible()) { \ + guard(srcu_fast_notrace)(&tracepoint_srcu); \ + guard(migrate)(); \ + __DO_TRACE_CALL(name, TP_ARGS(args)); \ + } else { \ + guard(preempt_notrace)(); \ + __DO_TRACE_CALL(name, TP_ARGS(args)); \ + } \ + } \ + } \ + static inline void trace_##name(proto) \ + { \ + if (static_branch_unlikely(&__tracepoint_##name.key)) \ + __do_trace_##name(args); \ + if (IS_ENABLED(CONFIG_LOCKDEP) && (cond)) { \ + WARN_ONCE(!rcu_is_watching(), \ + "RCU not watching for tracepoint"); \ + } \ } =20 #define __DECLARE_TRACE_SYSCALL(name, proto, args, data_proto) \ diff --git a/include/trace/perf.h b/include/trace/perf.h index a1754b73a8f55b..348ad1d9b5566e 100644 --- a/include/trace/perf.h +++ b/include/trace/perf.h @@ -71,6 +71,7 @@ perf_trace_##call(void *__data, proto) \ u64 __count __attribute__((unused)); \ struct task_struct *__task __attribute__((unused)); \ \ + guard(preempt_notrace)(); \ do_perf_trace_##call(__data, args); \ } =20 @@ -85,9 +86,8 @@ perf_trace_##call(void *__data, proto) \ struct task_struct *__task __attribute__((unused)); \ \ might_fault(); \ - preempt_disable_notrace(); \ + guard(preempt_notrace)(); \ do_perf_trace_##call(__data, args); \ - preempt_enable_notrace(); \ } =20 /* diff --git a/include/trace/trace_events.h b/include/trace/trace_events.h index 4f22136fd4656c..fbc07d353be6b6 100644 --- a/include/trace/trace_events.h +++ b/include/trace/trace_events.h @@ -436,6 +436,7 @@ __DECLARE_EVENT_CLASS(call, PARAMS(proto), PARAMS(args)= , PARAMS(tstruct), \ static notrace void \ trace_event_raw_event_##call(void *__data, proto) \ { \ + guard(preempt_notrace)(); \ do_trace_event_raw_event_##call(__data, args); \ } =20 @@ -447,9 +448,8 @@ static notrace void \ trace_event_raw_event_##call(void *__data, proto) \ { \ might_fault(); \ - preempt_disable_notrace(); \ + guard(preempt_notrace)(); \ do_trace_event_raw_event_##call(__data, args); \ - preempt_enable_notrace(); \ } =20 /* diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c index 62719d2941c900..21bb6779821476 100644 --- a/kernel/tracepoint.c +++ b/kernel/tracepoint.c @@ -25,6 +25,9 @@ enum tp_func_state { extern tracepoint_ptr_t __start___tracepoints_ptrs[]; extern tracepoint_ptr_t __stop___tracepoints_ptrs[]; =20 +DEFINE_SRCU_FAST(tracepoint_srcu); +EXPORT_SYMBOL_GPL(tracepoint_srcu); + enum tp_transition_sync { TP_TRANSITION_SYNC_1_0_1, TP_TRANSITION_SYNC_N_2_1, @@ -34,6 +37,7 @@ enum tp_transition_sync { =20 struct tp_transition_snapshot { unsigned long rcu; + unsigned long srcu_gp; bool ongoing; }; =20 @@ -46,6 +50,7 @@ static void tp_rcu_get_state(enum tp_transition_sync sync) =20 /* Keep the latest get_state snapshot. */ snapshot->rcu =3D get_state_synchronize_rcu(); + snapshot->srcu_gp =3D start_poll_synchronize_srcu(&tracepoint_srcu); snapshot->ongoing =3D true; } =20 @@ -56,6 +61,8 @@ static void tp_rcu_cond_sync(enum tp_transition_sync sync) if (!snapshot->ongoing) return; cond_synchronize_rcu(snapshot->rcu); + if (!poll_state_synchronize_srcu(&tracepoint_srcu, snapshot->srcu_gp)) + synchronize_srcu(&tracepoint_srcu); snapshot->ongoing =3D false; } =20 @@ -101,17 +108,29 @@ static inline void *allocate_probes(int count) return p =3D=3D NULL ? NULL : p->probes; } =20 -static void rcu_free_old_probes(struct rcu_head *head) +static void srcu_free_old_probes(struct rcu_head *head) { kfree(container_of(head, struct tp_probes, rcu)); } =20 +static void rcu_free_old_probes(struct rcu_head *head) +{ + call_srcu(&tracepoint_srcu, head, srcu_free_old_probes); +} + static inline void release_probes(struct tracepoint *tp, struct tracepoint= _func *old) { if (old) { struct tp_probes *tp_probes =3D container_of(old, struct tp_probes, probes[0]); =20 + /* + * Tracepoint probes are protected by either RCU or + * Tasks Trace RCU and also by SRCU. By calling the SRCU + * callback in the [Tasks Trace] RCU callback we cover + * both cases. So let us chain the SRCU and [Tasks Trace] + * RCU callbacks to wait for both grace periods. + */ if (tracepoint_is_faultable(tp)) call_rcu_tasks_trace(&tp_probes->rcu, rcu_free_old_probes); else --=20 2.40.1 From nobody Wed Oct 1 20:32:42 2025 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 954D2306D5F; Wed, 1 Oct 2025 14:48:42 +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=1759330122; cv=none; b=ch4tswwvdUAxPRZ8eF55P2HkG0DHaoZPcLeaJG9yf+UhcKMH/DHdpgAADo3fcsM17fwVMrHjYbV0c7JzCeZv36rdSXAhBxjZuxU70IvX4nZfxY3GE62gWrLMiKt6pQpPgXrmGk/rjw0tZDxSJ1q/jGAjP+hDmS3Og6H7DKw7AMQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759330122; c=relaxed/simple; bh=5+6cap8BHuj7LD+F6jHOG4xWIftMKuTGrdQG1g1VuNA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=DVBZlZcJVIReFHUkLeRIzLlqOv2iKed8tH5TzH6+9vt2BGdpo9R40bpSGMSYyJSIKgu5DgNoi23nmXkeGiIgF25MMO7rL8dbu7QO5HqSC1VYbEQqr0xowCEIcJN+Sp4A+N1wEeyLDJ3/4Voav3Rdq0BdbCenZYQUIhl5q7PDOuc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=f6DwVI9B; 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="f6DwVI9B" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0DB44C4AF0D; Wed, 1 Oct 2025 14:48:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1759330122; bh=5+6cap8BHuj7LD+F6jHOG4xWIftMKuTGrdQG1g1VuNA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=f6DwVI9BxTl3oHt6mA0HcILf8ik6GGSoZ0OLMhSbPeoGtYBlGknaaIg6sYgLEEguR wPtFMJUy87rjzytPd91EVFqoMrnOS0Yw64gp0VE0nDUS2jOQFZNfxQ+u6WeUaJYHN6 dZ1iz9q8Wi+AUUKU7bKpetA+ezX3VJX8XKptL919h58Bgs798QdmpIGLyVsNHi2qdi JtazPj6Fx34F4JOxe1x1gYbpEfNcdMUlbuFiz2iyCaTFjPipUCs42ItPGJCDizjE0x wQERutENschQzUoKLXZLgF0YvesXC6RK02dOW9wfpP8j6z7/hSNkqEJk9WDDgUoFDf JUcGle4fbQ2ZQ== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 970E1CE158E; Wed, 1 Oct 2025 07:48:34 -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" , Leon Hwang , Alexei Starovoitov Subject: [PATCH v2 21/21] rcu: Mark diagnostic functions as notrace Date: Wed, 1 Oct 2025 07:48:32 -0700 Message-Id: <20251001144832.631770-21-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> References: <7fa58961-2dce-4e08-8174-1d1cc592210f@paulmck-laptop> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The rcu_lockdep_current_cpu_online(), rcu_read_lock_sched_held(), rcu_read_lock_held(), rcu_read_lock_bh_held(), rcu_read_lock_any_held() are used by tracing-related code paths, so putting traces on them is unlikely to make anyone happy. This commit therefore marks them all "notrace". Reported-by: Leon Hwang Reported-by: Alexei Starovoitov Signed-off-by: Paul E. McKenney --- kernel/rcu/tree.c | 2 +- kernel/rcu/update.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 31690ffa452afe..8ddd07fed36334 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -4021,7 +4021,7 @@ bool rcu_cpu_online(int cpu) * RCU on an offline processor during initial boot, hence the check for * rcu_scheduler_fully_active. */ -bool rcu_lockdep_current_cpu_online(void) +bool notrace rcu_lockdep_current_cpu_online(void) { struct rcu_data *rdp; bool ret =3D false; diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c index c912b594ba987f..dfeba9b3539508 100644 --- a/kernel/rcu/update.c +++ b/kernel/rcu/update.c @@ -117,7 +117,7 @@ static bool rcu_read_lock_held_common(bool *ret) return false; } =20 -int rcu_read_lock_sched_held(void) +int notrace rcu_read_lock_sched_held(void) { bool ret; =20 @@ -342,7 +342,7 @@ EXPORT_SYMBOL_GPL(debug_lockdep_rcu_enabled); * Note that rcu_read_lock() is disallowed if the CPU is either idle or * offline from an RCU perspective, so check for those as well. */ -int rcu_read_lock_held(void) +int notrace rcu_read_lock_held(void) { bool ret; =20 @@ -367,7 +367,7 @@ EXPORT_SYMBOL_GPL(rcu_read_lock_held); * Note that rcu_read_lock_bh() is disallowed if the CPU is either idle or * offline from an RCU perspective, so check for those as well. */ -int rcu_read_lock_bh_held(void) +int notrace rcu_read_lock_bh_held(void) { bool ret; =20 @@ -377,7 +377,7 @@ int rcu_read_lock_bh_held(void) } EXPORT_SYMBOL_GPL(rcu_read_lock_bh_held); =20 -int rcu_read_lock_any_held(void) +int notrace rcu_read_lock_any_held(void) { bool ret; =20 --=20 2.40.1