From nobody Sat Jul 25 16:53:44 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 545B729D264; Thu, 16 Jul 2026 00:28:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784161706; cv=none; b=gIwLhTWFREeBdPjkRIZzPYde35VHRlUFJwZwvw9Ekc0EMYipQmzmtvYkSOzAo5SCe/+tOBgdhNveRtk/Wma7ncxzf7fdhZUrA2klCjjHLOHop4L07VGAnal7+zNevseElTB6XwARkJecyDujPaUlMnu6poMjEp+zM5Ig7BSq7Hs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784161706; c=relaxed/simple; bh=FtEA8Zj2G3mxt0eUOqFJ/FvL1Poe/zy9hd8F2gKa4ac=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=b/n5wI4YGgTH79J8BB2/RTlhtEIvLqxVWDHtFK3/0/jqiYhWjm2VFvB6/O2AAO3C53vO1QngSWsm1m99czz9n38cUthAbffVAe7Lt6wh9IFkdvEaPK+ZuY7xSPi05ObLXqVUof/1BJDdwRI0zHA1U9y46naG7R3mWDXxjmt7550= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MHWs+qWE; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MHWs+qWE" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 12D6A1F000E9; Thu, 16 Jul 2026 00:28:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1784161705; bh=EETxFP0D7dYMA03aJTLn94vN1cl3zTd6Fd052SBDZns=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=MHWs+qWEOBSCu7dmx2ziUBPjYEEiK4uxvqwF3mahn9jazB2Uv5D7P4vzoqsTAClVR +4DXzp3VVTbgnmlXO6eua7VUcKVzaJF9dlrdRChH5DdQ9/7bOgUYkqaf16g295O5Wh v180+vzYZM33su3lUREpWr1NbBTSMiNA+Wsvm3kgBnWGrSVvSlD/9i5Y/9h6uAEWBU Fiuu6g0rWZ0aHD1B8qP3lDuKbghxgS1ml1Q2LIlE9dmrfd88/djjj2z5quKgmvxKaz +PhXR4M4qDeRciftexZmePzEfZFFiMqz/YBYR4fWnKj57rllwZv28BXwq4/n3Wjr2w tZtaJ1NvnxRbA== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id DF0F1CE0569; Wed, 15 Jul 2026 17:28:24 -0700 (PDT) From: "Paul E. McKenney" To: rcu@vger.kernel.org Cc: linux-kernel@vger.kernel.org, kernel-team@meta.com, rostedt@goodmis.org, =?UTF-8?q?Onur=20=C3=96zkan?= , Gary Guo , Alice Ryhl , Boqun Feng , "Paul E . McKenney" Subject: [PATCH 1/6] srcu: make init_srcu_struct() consistently wrap __init_srcu_struct() Date: Wed, 15 Jul 2026 17:28:18 -0700 Message-Id: <20260716002823.12176-1-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Onur =C3=96zkan Restructure the SRCU initialization functions so it always follows one direction: init_srcu_struct() -> __init_srcu_struct() -> lockdep or generic This uses the same wrapper style as mutex. It avoids the old confusing style where init_srcu_struct() and __init_srcu_struct() called each other in different configs. It also helps Rust side to have simpler helper for SRCU initialization. Signed-off-by: Onur =C3=96zkan Reviewed-by: Gary Guo Reviewed-by: Alice Ryhl Reviewed-by: Boqun Feng Signed-off-by: Paul E. McKenney --- include/linux/srcu.h | 29 ++++++++++++++++++++--------- kernel/rcu/srcutiny.c | 12 ++++++------ kernel/rcu/srcutree.c | 11 ++++++----- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/include/linux/srcu.h b/include/linux/srcu.h index a54ce9e808b92c..c5ab7df6fe5c70 100644 --- a/include/linux/srcu.h +++ b/include/linux/srcu.h @@ -25,20 +25,19 @@ context_lock_struct(srcu_struct, __reentrant_ctx_lock); =20 #ifdef CONFIG_DEBUG_LOCK_ALLOC =20 -int __init_srcu_struct(struct srcu_struct *ssp, const char *name, struct l= ock_class_key *key); +int init_srcu_struct_lockdep(struct srcu_struct *ssp, const char *name, + struct lock_class_key *key); +static inline int __init_srcu_struct(struct srcu_struct *ssp, const char *= name, + struct lock_class_key *key) +{ + return init_srcu_struct_lockdep(ssp, name, key); +} #ifndef CONFIG_TINY_SRCU int __init_srcu_struct_fast(struct srcu_struct *ssp, const char *name, str= uct lock_class_key *key); int __init_srcu_struct_fast_updown(struct srcu_struct *ssp, const char *na= me, struct lock_class_key *key); #endif // #ifndef CONFIG_TINY_SRCU =20 -#define init_srcu_struct(ssp) \ -({ \ - static struct lock_class_key __srcu_key; \ - \ - __init_srcu_struct((ssp), #ssp, &__srcu_key); \ -}) - #define init_srcu_struct_fast(ssp) \ ({ \ static struct lock_class_key __srcu_key; \ @@ -56,7 +55,12 @@ int __init_srcu_struct_fast_updown(struct srcu_struct *s= sp, const char *name, #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); +int init_srcu_struct_generic(struct srcu_struct *ssp); +static inline int __init_srcu_struct(struct srcu_struct *ssp, const char *= name, + struct lock_class_key *key) +{ + return init_srcu_struct_generic(ssp); +} #ifndef CONFIG_TINY_SRCU int init_srcu_struct_fast(struct srcu_struct *ssp); int init_srcu_struct_fast_updown(struct srcu_struct *ssp); @@ -65,6 +69,13 @@ int init_srcu_struct_fast_updown(struct srcu_struct *ssp= ); #define __SRCU_DEP_MAP_INIT(srcu_name) #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */ =20 +#define init_srcu_struct(ssp) \ +({ \ + static struct lock_class_key __srcu_key; \ + \ + __init_srcu_struct((ssp), #ssp, &__srcu_key); \ +}) + /* Values for SRCU Tree srcu_data ->srcu_reader_flavor, but also used by r= cutorture. */ #define SRCU_READ_FLAVOR_NORMAL 0x1 // srcu_read_lock(). #define SRCU_READ_FLAVOR_NMI 0x2 // srcu_read_lock_nmisafe(). diff --git a/kernel/rcu/srcutiny.c b/kernel/rcu/srcutiny.c index a2e2d516e51b9d..47d48ed318483a 100644 --- a/kernel/rcu/srcutiny.c +++ b/kernel/rcu/srcutiny.c @@ -48,31 +48,31 @@ static int init_srcu_struct_fields(struct srcu_struct *= ssp) =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_lockdep(struct srcu_struct *ssp, const char *name, + struct 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); } -EXPORT_SYMBOL_GPL(__init_srcu_struct); +EXPORT_SYMBOL_GPL(init_srcu_struct_lockdep); =20 #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ =20 /* - * init_srcu_struct - initialize a sleep-RCU structure + * init_srcu_struct_generic - initialize a 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(struct srcu_struct *ssp) +int init_srcu_struct_generic(struct srcu_struct *ssp) { return init_srcu_struct_fields(ssp); } -EXPORT_SYMBOL_GPL(init_srcu_struct); +EXPORT_SYMBOL_GPL(init_srcu_struct_generic); =20 #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */ =20 diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c index 7c2f7cc131f7ae..56c5db5c29a09b 100644 --- a/kernel/rcu/srcutree.c +++ b/kernel/rcu/srcutree.c @@ -266,12 +266,13 @@ __init_srcu_struct_common(struct srcu_struct *ssp, co= nst char *name, struct lock return init_srcu_struct_fields(ssp, false); } =20 -int __init_srcu_struct(struct srcu_struct *ssp, const char *name, struct l= ock_class_key *key) +int init_srcu_struct_lockdep(struct srcu_struct *ssp, const char *name, + struct lock_class_key *key) { ssp->srcu_reader_flavor =3D 0; return __init_srcu_struct_common(ssp, name, key); } -EXPORT_SYMBOL_GPL(__init_srcu_struct); +EXPORT_SYMBOL_GPL(init_srcu_struct_lockdep); =20 int __init_srcu_struct_fast(struct srcu_struct *ssp, const char *name, str= uct lock_class_key *key) { @@ -291,7 +292,7 @@ EXPORT_SYMBOL_GPL(__init_srcu_struct_fast_updown); #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ =20 /** - * init_srcu_struct - initialize a sleep-RCU structure + * init_srcu_struct_generic - initialize a sleep-RCU structure * @ssp: structure to initialize. * * Use this in place of DEFINE_SRCU() and DEFINE_STATIC_SRCU() @@ -301,12 +302,12 @@ EXPORT_SYMBOL_GPL(__init_srcu_struct_fast_updown); * to any other function. Each srcu_struct represents a separate domain * of SRCU protection. */ -int init_srcu_struct(struct srcu_struct *ssp) +int init_srcu_struct_generic(struct srcu_struct *ssp) { ssp->srcu_reader_flavor =3D 0; return init_srcu_struct_fields(ssp, false); } -EXPORT_SYMBOL_GPL(init_srcu_struct); +EXPORT_SYMBOL_GPL(init_srcu_struct_generic); =20 /** * init_srcu_struct_fast - initialize a fast-reader sleep-RCU structure --=20 2.40.1 From nobody Sat Jul 25 16:53:44 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 5462F2BDC0E; Thu, 16 Jul 2026 00:28:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784161706; cv=none; b=mdsm1m2MAafOvigbxBrO5EHyikjBHfKVu+Bls1iSz9FiEwsj1oMkV9GL5rraLN2gVMiKZ0Vzm6VeQdsd5sgoslSKOWW1rnyUlnVKRowLbSj0+ZZ9JmyR1fzuS0ZRutkpnWQytGIzt6VcYp9/2tdc6HWXwnA6ymb/BsOOtmlwub8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784161706; c=relaxed/simple; bh=+HYh5TWo+jZqzQyJt7hUZ8rs2CoiXqjr6mKGvkYHPIs=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=I7BzI3tKyrCeqXS153VWhm1NPKG08tpP58Rwpyr2+/YzPbLrqiMQLq6vLu/83XvzouGNl6gw/MTbJVipVbsvUurZtMRjYg98O3jfJ9utpcq+vNyIihosMtSKbLYHfUzLjnEPbSnfUFBqTTyxB5ZhgiN1s0TMw4UX0mGkUziN6Lw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GuHWoaWL; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="GuHWoaWL" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 18D921F00A3A; Thu, 16 Jul 2026 00:28:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1784161705; bh=0G/9lixuEcp8q2iCYDzp4XsrGAmvKvdV//8mCb/bJqE=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=GuHWoaWLQu27woEyUzKnS6HxUYTPAnbQXGY3emFC7Oz6lKMCe3vLD2KWWxmiDEvDc xa0Bl2XuFEeYP2u5h9MKf8KFkJ1cmZ0C6OPufaj0Oce5wiRw8OLwMeWgnzm0+SQKAH ZSwCoAuig27MVpjg6mygeOYVqyMmDhNIZKXIe3+0ZF2bjC7MGE/80+U0E6I3nbbxFZ E4X4UqcRGBtVYBuS/zCsWk7oPGi/9SpeSq+GeP1MWfTvngK5TZ5T0jVnB38WTPKKiK rvKCC+vjupQi+v+GKrZH3s2iooQnmOwtZ4tkqECI3gtjX4TpDbU0uOSVi922khxIb8 fVeNwhGttmhBA== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id E2284CE0B87; Wed, 15 Jul 2026 17:28:24 -0700 (PDT) From: "Paul E. McKenney" To: rcu@vger.kernel.org Cc: linux-kernel@vger.kernel.org, kernel-team@meta.com, rostedt@goodmis.org, =?UTF-8?q?Onur=20=C3=96zkan?= , Gary Guo , Alice Ryhl , Boqun Feng , "Paul E . McKenney" Subject: [PATCH 2/6] rust: helpers: add SRCU helpers Date: Wed, 15 Jul 2026 17:28:19 -0700 Message-Id: <20260716002823.12176-2-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Onur =C3=96zkan Add helper wrappers for SRCU functions that are exposed to Rust through generated bindings. Signed-off-by: Onur =C3=96zkan Reviewed-by: Gary Guo Reviewed-by: Alice Ryhl Reviewed-by: Boqun Feng Signed-off-by: Paul E. McKenney --- rust/helpers/helpers.c | 1 + rust/helpers/srcu.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 rust/helpers/srcu.c diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c index 998e31052e6601..35954f38ff6a4e 100644 --- a/rust/helpers/helpers.c +++ b/rust/helpers/helpers.c @@ -91,6 +91,7 @@ #include "slab.c" #include "spinlock.c" #include "string.c" +#include "srcu.c" #include "sync.c" #include "task.c" #include "time.c" diff --git a/rust/helpers/srcu.c b/rust/helpers/srcu.c new file mode 100644 index 00000000000000..225b3bf9334a8f --- /dev/null +++ b/rust/helpers/srcu.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include + +__rust_helper int rust_helper_init_srcu_struct_with_key(struct srcu_struct= *ssp, + const char *name, + struct lock_class_key *key) +{ + return __init_srcu_struct(ssp, name, key); +} + +__rust_helper int rust_helper_srcu_read_lock(struct srcu_struct *ssp) +{ + return srcu_read_lock(ssp); +} + +__rust_helper void rust_helper_srcu_read_unlock(struct srcu_struct *ssp, i= nt idx) +{ + srcu_read_unlock(ssp, idx); +} + +__rust_helper void rust_helper_srcu_barrier(struct srcu_struct *ssp) +{ + srcu_barrier(ssp); +} + +__rust_helper void rust_helper_synchronize_srcu_expedited(struct srcu_stru= ct *ssp) +{ + synchronize_srcu_expedited(ssp); +} --=20 2.40.1 From nobody Sat Jul 25 16:53:44 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 547582C3266; Thu, 16 Jul 2026 00:28:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784161706; cv=none; b=d4tgzw6wbTWIvbGs47r7WgWjGHVbTZJoVzwb0yo6yzSwFr6xaq51IafWEjkvr9N5xepNjbjCYQCk8TX3sncH9J1jGQDwz7xb5H9J9nV5NDvFBBg97YEtIVv4eyXb80nYoKuRjC1cypDzvC2Tr42UYtzi4XASjI4HNAHxm0c+Z5g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784161706; c=relaxed/simple; bh=DAzb2m/7miFS5XR1FZuYt4bqoy8kzvl8fLX8KcIiac4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=IZ3XmPJRO/g4d3qwT3HCtk0JhGfcWr+KM7XCCTGN65u7SW2GgMIA/sTNeDpvifXfK56eoszjZ+f/deqsyTJCEaRvgQ5kU33WXiiH4jlIkZQNpPa4Bmi4tjbPubC/z9Vh2skKGF4DfmQE+SGn3uaCpjjULm8dUXaTeinb4gOg4ZA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QNlF3KY3; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="QNlF3KY3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 26E0B1F00A3D; Thu, 16 Jul 2026 00:28:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1784161705; bh=pfeHP0fbIsrYBGfIrCHqM34QGuxpIOI7yFuxHP5WPOQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=QNlF3KY3wmaEzQ7Z+u4PvDk9zJ5AfeTe9JCiyA8NdssU04joZ3gOof04ICwxXpkQx 8mTaTs+reV20a0+W8H7RktEWhLLPbz2V/E7FTIbA1dXxJQzslAfV5fSfz/nxXxtcPe Q8mTWtPAAlIqtU12FE7lLQS84PWphl0DTTDnlnOm2TePjD3EyL92db6fIGlzaN2/JY Q2CdPbykfyHkToEaGGPpAx9wmvnbp0AT2r4dfnl2XHwLI5UiBWZY7OPrcccl/TKkoA 1eqe5TLbqzGXU+pSJAjfLgUkAmd2dZGXzsOBRyNodJCc05hsQPxVWvp3FXk+AoZBKt 1XGc0vPUV7QUw== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id E5352CE0B8B; Wed, 15 Jul 2026 17:28:24 -0700 (PDT) From: "Paul E. McKenney" To: rcu@vger.kernel.org Cc: linux-kernel@vger.kernel.org, kernel-team@meta.com, rostedt@goodmis.org, =?UTF-8?q?Onur=20=C3=96zkan?= , Gary Guo , Alice Ryhl , Boqun Feng , "Paul E . McKenney" Subject: [PATCH 3/6] srcu: expose srcu_readers_active() Date: Wed, 15 Jul 2026 17:28:20 -0700 Message-Id: <20260716002823.12176-3-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Onur =C3=96zkan This is needed by rust/helpers/srcu.c which now adds rust_helper_srcu_readers_active() as a wrapper around the SRCU helper for Rust callers. To achive this: 1- Move the srcu_readers_active() implementation from "kernel/rcu/srcutree.c" to "include/linux/srcutree.h". 2- Implement a matching srcu_readers_active() in "include/linux/srcutiny.h" and use it on the existing open-coded WARN_ON() check in cleanup_srcu_struct(). Signed-off-by: Onur =C3=96zkan Reviewed-by: Gary Guo Reviewed-by: Alice Ryhl Reviewed-by: Boqun Feng Signed-off-by: Paul E. McKenney --- include/linux/srcutiny.h | 13 +++++++++++++ include/linux/srcutree.h | 24 ++++++++++++++++++++++++ kernel/rcu/srcutiny.c | 2 +- kernel/rcu/srcutree.c | 25 ------------------------- rust/helpers/srcu.c | 5 +++++ 5 files changed, 43 insertions(+), 26 deletions(-) diff --git a/include/linux/srcutiny.h b/include/linux/srcutiny.h index 905b629e8fa38e..fbcf13bc12d15e 100644 --- a/include/linux/srcutiny.h +++ b/include/linux/srcutiny.h @@ -154,4 +154,17 @@ static inline void srcu_torture_stats_print(struct src= u_struct *ssp, data_race(READ_ONCE(ssp->srcu_idx_max))); } =20 +/** + * srcu_readers_active - returns true if there are readers. and false othe= rwise. + * @ssp: which srcu_struct to count active readers (holding srcu_read_lock= ). + * + * Note that this is not an atomic primitive, and can therefore suffer + * severe errors when invoked on an active srcu_struct. That said, it + * can be useful as an error check at cleanup time. + */ +static inline bool srcu_readers_active(struct srcu_struct *ssp) +{ + return READ_ONCE(ssp->srcu_lock_nesting[0]) || READ_ONCE(ssp->srcu_lock_n= esting[1]); +} + #endif diff --git a/include/linux/srcutree.h b/include/linux/srcutree.h index fd1a9270cb9a81..75e54e4f963fac 100644 --- a/include/linux/srcutree.h +++ b/include/linux/srcutree.h @@ -374,4 +374,28 @@ static inline void srcu_check_read_flavor(struct srcu_= struct *ssp, int read_flav __srcu_check_read_flavor(ssp, read_flavor); } =20 +/** + * srcu_readers_active - returns true if there are readers. and false othe= rwise. + * @ssp: which srcu_struct to count active readers (holding srcu_read_lock= ). + * + * Note that this is not an atomic primitive, and can therefore suffer + * severe errors when invoked on an active srcu_struct. That said, it + * can be useful as an error check at cleanup time. + */ +static inline bool srcu_readers_active(struct srcu_struct *ssp) +{ + int cpu; + unsigned long sum =3D 0; + + for_each_possible_cpu(cpu) { + struct srcu_data *sdp =3D per_cpu_ptr(ssp->sda, cpu); + + sum +=3D atomic_long_read(&sdp->srcu_ctrs[0].srcu_locks); + sum +=3D atomic_long_read(&sdp->srcu_ctrs[1].srcu_locks); + sum -=3D atomic_long_read(&sdp->srcu_ctrs[0].srcu_unlocks); + sum -=3D atomic_long_read(&sdp->srcu_ctrs[1].srcu_unlocks); + } + return sum; +} + #endif diff --git a/kernel/rcu/srcutiny.c b/kernel/rcu/srcutiny.c index 47d48ed318483a..558ba8d316db6c 100644 --- a/kernel/rcu/srcutiny.c +++ b/kernel/rcu/srcutiny.c @@ -85,7 +85,7 @@ EXPORT_SYMBOL_GPL(init_srcu_struct_generic); */ void cleanup_srcu_struct(struct srcu_struct *ssp) { - WARN_ON(ssp->srcu_lock_nesting[0] || ssp->srcu_lock_nesting[1]); + WARN_ON(srcu_readers_active(ssp)); irq_work_sync(&ssp->srcu_irq_work); flush_work(&ssp->srcu_work); WARN_ON(ssp->srcu_gp_running); diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c index 56c5db5c29a09b..4a00e90e17fc07 100644 --- a/kernel/rcu/srcutree.c +++ b/kernel/rcu/srcutree.c @@ -599,31 +599,6 @@ static bool srcu_readers_active_idx_check(struct srcu_= struct *ssp, int idx) return srcu_readers_lock_idx(ssp, idx, did_gp, unlocks); } =20 -/** - * srcu_readers_active - returns true if there are readers. and false - * otherwise - * @ssp: which srcu_struct to count active readers (holding srcu_read_lock= ). - * - * Note that this is not an atomic primitive, and can therefore suffer - * severe errors when invoked on an active srcu_struct. That said, it - * can be useful as an error check at cleanup time. - */ -static bool srcu_readers_active(struct srcu_struct *ssp) -{ - int cpu; - unsigned long sum =3D 0; - - for_each_possible_cpu(cpu) { - struct srcu_data *sdp =3D per_cpu_ptr(ssp->sda, cpu); - - sum +=3D atomic_long_read(&sdp->srcu_ctrs[0].srcu_locks); - sum +=3D atomic_long_read(&sdp->srcu_ctrs[1].srcu_locks); - sum -=3D atomic_long_read(&sdp->srcu_ctrs[0].srcu_unlocks); - sum -=3D atomic_long_read(&sdp->srcu_ctrs[1].srcu_unlocks); - } - return sum; -} - /* * We use an adaptive strategy for synchronize_srcu() and especially for * synchronize_srcu_expedited(). We spin for a fixed time period diff --git a/rust/helpers/srcu.c b/rust/helpers/srcu.c index 225b3bf9334a8f..1a2f563640e001 100644 --- a/rust/helpers/srcu.c +++ b/rust/helpers/srcu.c @@ -9,6 +9,11 @@ __rust_helper int rust_helper_init_srcu_struct_with_key(st= ruct srcu_struct *ssp, return __init_srcu_struct(ssp, name, key); } =20 +__rust_helper bool rust_helper_srcu_readers_active(struct srcu_struct *ssp) +{ + return srcu_readers_active(ssp); +} + __rust_helper int rust_helper_srcu_read_lock(struct srcu_struct *ssp) { return srcu_read_lock(ssp); --=20 2.40.1 From nobody Sat Jul 25 16:53:44 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 546E12C2374; Thu, 16 Jul 2026 00:28:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784161706; cv=none; b=tI40DpEYBdU1gPEFWhxmJjqdvxIbZEsv1UWHTbVbOm2r1Apew4lN6+uyhjAeJUGam0uOo1sLUOnLTRTgSoOhMqLZY8zDuVyzasEP7snnI4yGssKmJpNc/r1jGptx6/HwCm5HGR9mMkOkWcZiYjwPBUuUQoifHvg5O5Fto+ymgBE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784161706; c=relaxed/simple; bh=gM5/MbENEbPAhb2e7y6j6iUd8I63P4tzQhAe4VLAljI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=H9ATlTrYWZV0iYn8X9pPxUUIpM72fKw/RltdTKqYRMZhQU+mTi+no3aEslTREXRFoTqgBUwJ7qNj72Rn9LoRc45zqEz72gBAk67ac14GYj73DRmetW8pwipz6POL/z4ka1U3jcsGBNkvhPQ6F3JFtD9RMAwQseAGvploaqDjz3Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=TtSRxN9s; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="TtSRxN9s" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2C9F41F00AC4; Thu, 16 Jul 2026 00:28:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1784161705; bh=HUVQixphC9JGVDQM6tFRacUMj/muhYJGp39Yy1ENlE4=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=TtSRxN9sHt/hI5Nylsb5vsKXX0Q1joWE8bvtH4IXWHnsr5DXIoi2rIwGzTXsDkJp6 2xza4v3eLlBAuUuCklVVv7jjJwbswVM4KPwIVJHYgiim6n8I5jG1SlcR+yLgtuqlcG YHxTVUE8sYs1onWsyeg7G3U3ILbj7DBcCaA34mO2IiRcvt3X5lR2Gn3aVPMU9eZSe2 LfPh7dp52xZHMHYUIHgFJY1ZA5ecTyIC8xyQJULauW2UZEM45JE0u26PJgT5iBddyN nD1TMDPejtm1nj1fHFCKiAoUjF+zKP3taBrgCjgVMFa4aFUtdaLGI80mmg142k9ROI SwusseoEoUUUw== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id E8019CE0C44; Wed, 15 Jul 2026 17:28:24 -0700 (PDT) From: "Paul E. McKenney" To: rcu@vger.kernel.org Cc: linux-kernel@vger.kernel.org, kernel-team@meta.com, rostedt@goodmis.org, =?UTF-8?q?Onur=20=C3=96zkan?= , Gary Guo , Alice Ryhl , Boqun Feng , "Paul E . McKenney" Subject: [PATCH 4/6] rust: sync: add SRCU abstraction Date: Wed, 15 Jul 2026 17:28:21 -0700 Message-Id: <20260716002823.12176-4-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Onur =C3=96zkan Add a Rust abstraction for sleepable RCU (SRCU), backed by C srcu_struct. Provide FFI helpers and a safe wrapper with a guard-based API for read-side critical sections. Cleanup is handled via `PinnedDrop`. It first checks for active read-side sections and emits a warning if any guards were leaked. In that case, it waits in `synchronize_srcu()` rather than risking a UAF by freeing the `srcu_struct` that is still reachable from the C side. It then uses `srcu_barrier()` to drain pending callbacks before finally calling `cleanup_srcu_struct()`. Signed-off-by: Onur =C3=96zkan Reviewed-by: Gary Guo Reviewed-by: Alice Ryhl Reviewed-by: Boqun Feng Signed-off-by: Paul E. McKenney --- rust/kernel/sync.rs | 2 + rust/kernel/sync/srcu.rs | 171 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 rust/kernel/sync/srcu.rs diff --git a/rust/kernel/sync.rs b/rust/kernel/sync.rs index 993dbf2caa0e3b..0d6a5f1300c3b2 100644 --- a/rust/kernel/sync.rs +++ b/rust/kernel/sync.rs @@ -21,6 +21,7 @@ pub mod rcu; mod refcount; mod set_once; +pub mod srcu; =20 pub use arc::{Arc, ArcBorrow, UniqueArc}; pub use completion::Completion; @@ -31,6 +32,7 @@ pub use locked_by::LockedBy; pub use refcount::Refcount; pub use set_once::SetOnce; +pub use srcu::Srcu; =20 /// Represents a lockdep class. /// diff --git a/rust/kernel/sync/srcu.rs b/rust/kernel/sync/srcu.rs new file mode 100644 index 00000000000000..723e5e277fd641 --- /dev/null +++ b/rust/kernel/sync/srcu.rs @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Sleepable read-copy update (SRCU) support. +//! +//! C header: [`include/linux/srcu.h`](srctree/include/linux/srcu.h) + +use crate::{ + bindings, + error::to_result, + prelude::*, + sync::LockClassKey, + types::{ + NotThreadSafe, + Opaque, // + }, +}; + +use pin_init::pin_data; + +/// Creates an [`Srcu`] initialiser with the given name and a newly-create= d lock class. +#[doc(hidden)] +#[macro_export] +macro_rules! new_srcu { + ($($name:literal)?) =3D> { + $crate::sync::Srcu::new($crate::optional_name!($($name)?), $crate:= :static_lock_class!()) + }; +} +pub use new_srcu; + +/// Sleepable read-copy update primitive. +/// +/// SRCU readers may sleep while holding the read-side guard. +/// +/// The destructor waits for active readers and callbacks, so it may sleep. +/// If a read-side guard has been leaked, dropping an [`Srcu`] may never r= eturn. +/// +/// # Invariants +/// +/// This represents a valid `struct srcu_struct` initialized by the C SRCU= API +/// and it remains pinned and valid until the pinned destructor runs. +#[repr(transparent)] +#[pin_data(PinnedDrop)] +pub struct Srcu { + #[pin] + inner: Opaque, +} + +impl Srcu { + /// Creates a new SRCU instance. + #[inline] + pub fn new(name: &'static CStr, key: Pin<&'static LockClassKey>) -> im= pl PinInit { + try_pin_init!(Self { + // INVARIANT: On success, the C initializer creates a valid `s= rcu_struct` and + // it remains pinned until `PinnedDrop` runs. + inner <- Opaque::try_ffi_init(|ptr: *mut bindings::srcu_struct= | { + // SAFETY: `ptr` points to valid uninitialised memory for = a `srcu_struct`. + to_result(unsafe { + bindings::init_srcu_struct_with_key(ptr, name.as_char_= ptr(), key.as_ptr()) + }) + }), + }) + } + + /// Enters an SRCU read-side critical section. + /// + /// Leaking the returned [`Guard`] leaves the SRCU read-side critical + /// section active and makes `drop` sleep forever. + #[inline] + pub fn read_lock(&self) -> Guard<'_> { + // SAFETY: By the type invariants, `self` contains a valid `struct= srcu_struct`. + let idx =3D unsafe { bindings::srcu_read_lock(self.inner.get()) }; + + // INVARIANT: `idx` was returned by `srcu_read_lock()` for this `S= rcu`. + Guard { + srcu: self, + idx, + _not_send: NotThreadSafe, + } + } + + /// Waits until all pre-existing SRCU readers have completed. + #[inline] + pub fn synchronize(&self) { + // SAFETY: By the type invariants, `self` contains a valid `struct= srcu_struct`. + unsafe { bindings::synchronize_srcu(self.inner.get()) }; + } + + /// Waits until all pre-existing SRCU readers have completed, expedite= d. + /// + /// This requests a lower-latency grace period than [`Srcu::synchroniz= e`] typically + /// at the cost of higher system-wide overhead. Prefer [`Srcu::synchro= nize`] by default + /// and use this variant only when reducing reset or teardown latency = is more important + /// than the extra cost. + #[inline] + pub fn synchronize_expedited(&self) { + // SAFETY: By the type invariants, `self` contains a valid `struct= srcu_struct`. + unsafe { bindings::synchronize_srcu_expedited(self.inner.get()) }; + } +} + +#[pinned_drop] +impl PinnedDrop for Srcu { + fn drop(self: Pin<&mut Self>) { + let ptr =3D self.inner.get(); + + if crate::warn_on!( + // SAFETY: By the type invariants, `self` contains a valid and= pinned `struct srcu_struct` + // and `srcu_readers_active()` only checks the active reader c= ount. + unsafe { bindings::srcu_readers_active(ptr) } + ) { + // `cleanup_srcu_struct()` may return early if there are still= active readers. + // This should only happen if a guard was leaked with `mem::fo= rget`, which is + // "WRONG" code and may cause a UAF because Rust will free the= `srcu_struct` + // while it is still referenced from the C side (e.g. by `call= _srcu()` callbacks). + // + // Another consequence of leaking guards is that `call_srcu()`= callbacks will + // never run because the grace period can never complete due t= o permanently + // active readers (i.e. leaked guards). + // + // If this ever happens, that means the guard was leaked by mi= stake and the + // caller must fix the bug. Sleeping here is intentional and l= ess harmful + // than risking a UAF. + // + // SAFETY: By the type invariants, `self` contains a valid and= pinned + // `struct srcu_struct`. + unsafe { bindings::synchronize_srcu(ptr) }; + } + + // Ensure all SRCU callbacks have been finished before freeing. + // SAFETY: By the type invariants, `self` contains a valid and pin= ned `struct srcu_struct`. + unsafe { bindings::srcu_barrier(ptr) }; + + // SAFETY: By the type invariants, `self` contains a valid and pin= ned `struct srcu_struct`. + unsafe { bindings::cleanup_srcu_struct(ptr) }; + } +} + +// SAFETY: `srcu_struct` may be shared and used across threads. +unsafe impl Send for Srcu {} +// SAFETY: `srcu_struct` may be shared and used concurrently. +unsafe impl Sync for Srcu {} + +/// Guard for an active SRCU read-side critical section on a particular [`= Srcu`]. +/// +/// Leaking this guard with [`core::mem::forget`] leaves the SRCU read-side +/// critical section active and makes dropping the associated [`Srcu`] sle= ep forever. +/// +/// # Invariants +/// +/// `idx` is the index returned by `srcu_read_lock()` for `srcu`. +#[must_use =3D "if unused, the lock will be immediately unlocked"] +pub struct Guard<'a> { + srcu: &'a Srcu, + idx: i32, + _not_send: NotThreadSafe, +} + +impl Guard<'_> { + /// Explicitly releases the SRCU read-side critical section. + #[inline] + pub fn unlock(self) {} +} + +impl Drop for Guard<'_> { + #[inline] + fn drop(&mut self) { + // SAFETY: `Guard` is only constructible through `Srcu::read_lock(= )`, + // which returns a valid index for the SRCU instance. + unsafe { bindings::srcu_read_unlock(self.srcu.inner.get(), self.id= x) }; + } +} --=20 2.40.1 From nobody Sat Jul 25 16:53:44 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 A0D642D0C72; Thu, 16 Jul 2026 00:28:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784161706; cv=none; b=S0QrwguevuYfIchy/iLZCQfy/yNDG2kE7y+qg+/9RZlviVe8Sr2tIMZws7yoqNHgNi+xVJhgDnc3ZIGqCw+99fomBWppyK4s52A5/3wCVC5LffTa/iqROvj8NNHAK4/0rDYNQBGs15P6vEEjq8WiHUIHcGBDYt0NZopxBc23RBw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784161706; c=relaxed/simple; bh=V0x8JStixbHIDW1+MuKIrVTSSR4cEbuv60JF37lPlrM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=kIjfMBuuXCTgMJNYC7fndpvv1bPK9C3MwZcFU/01YormPrsKIHekUH4hkHNTyUFp3UgovetNazzAfR+/7fbt+iRcaSoodq88HyH2ERSwgGhxKmIT3t8Udbw/JrMQC2h+QXfPYyhInn85jSbV4LBPiGPWIqVHePeFH3ZNOUKrAqc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=J5UzqIBW; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="J5UzqIBW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 402441F00ACA; Thu, 16 Jul 2026 00:28:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1784161705; bh=d7NMfMQsKZsM/KnMYq77Vza78BqqJ7HTg6z4nOU+Rvk=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=J5UzqIBWwo6Ql78SlH2aFsBf9z2rk24QUWLmWgpOe85Jjm0lacHOBbxjb9+YWBAGF HH+E9w1ZSu7hhDMxEiAdSVfXhnQ0R/P31g5Z1+FXcmxcLfWySqXjlCjV8YBf88vVBB XZLPUxRS6FkJipTjXcDat3jZonuseGpQzFtbStG+dKDKA14t5fYV1ll1cw48vuG7F0 9ARBMsWzxKGvAUh9HJx65GuYO8r5zsZWzvh30tlwAjVMeCfxwSY16ivJM6PK4UIAi5 X/zLYG1RU0k+KgeZ53q0tdGccCtDm8cWo80MS4lmvwp2vb7dq63AIr5LGFvcIuJYHK ZKSY5kedOmXgQ== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id EA724CE0C57; Wed, 15 Jul 2026 17:28:24 -0700 (PDT) From: "Paul E. McKenney" To: rcu@vger.kernel.org Cc: linux-kernel@vger.kernel.org, kernel-team@meta.com, rostedt@goodmis.org, =?UTF-8?q?Onur=20=C3=96zkan?= , Alice Ryhl , Boqun Feng , "Paul E . McKenney" Subject: [PATCH 5/6] MAINTAINERS: add Rust SRCU files to SRCU entry Date: Wed, 15 Jul 2026 17:28:22 -0700 Message-Id: <20260716002823.12176-5-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Onur =C3=96zkan Include Rust side implementation files to the SRCU maintainer entry. Signed-off-by: Onur =C3=96zkan Reviewed-by: Alice Ryhl Reviewed-by: Boqun Feng Signed-off-by: Paul E. McKenney --- MAINTAINERS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 806bd2d80d1535..b6ef971ee40856 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -24933,6 +24933,7 @@ SLEEPABLE READ-COPY UPDATE (SRCU) M: Lai Jiangshan M: "Paul E. McKenney" M: Josh Triplett +M: Onur =C3=96zkan (RUST) R: Steven Rostedt R: Mathieu Desnoyers L: rcu@vger.kernel.org @@ -24941,6 +24942,8 @@ W: http://www.rdrop.com/users/paulmck/RCU/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/rcu/linux.git rcu/dev F: include/linux/srcu*.h F: kernel/rcu/srcu*.c +F: rust/helpers/srcu.c +F: rust/kernel/sync/srcu.rs =20 SMACK SECURITY MODULE M: Casey Schaufler --=20 2.40.1 From nobody Sat Jul 25 16:53:44 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 ADD9B2D322E; Thu, 16 Jul 2026 00:28:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784161707; cv=none; b=OcagkJ5AIK9L5Ggx+9hdbHE69S2AVybpBGEyT5YruT8R394WLhdsM0enufy81zZc9IsgBf0fj9+mDwtqoWo6x9lqWXmvIBA42quWWkPkGQBxJaR8wjHxk/NjbryUrNhORer9IjDg1HmZup3nO87gevSGLDMgqhfFIpudGXPrYXU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784161707; c=relaxed/simple; bh=Rl00XC1ehwn2H9cCcEJlBpQZhGpGhXrtCG4dWtCYznY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=lpIBfIg7Hl7xNqHeMMBKhQRnz3THTr3egxnwI0NPNWdNctPMXV0NmrRHC5bb+ZkiZxvfHdhYR11kiTWFDzQwAXORYAC9XNQDR6UcSImE3YD1Cp52Kx97lrJ8YYUdxGzBsa2TfPWuWBepyHCsOrs0PcnevcAOVcnJfzyfbxycLvw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=EKUNvPA1; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="EKUNvPA1" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 51C991F00A3E; Thu, 16 Jul 2026 00:28:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1784161705; bh=cck7VcezaFz+NOrwA1nANKOT+K8ZYsRsfJL4fBsY8Vk=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=EKUNvPA13JogXK5F+ZpqTPHn7szWb2HqkvEtWGO962B+mmTAXk/Om+HmVZoWsfDwv WQlpTV0vrOT97yzNSyDRwLLISfWX9muWXikpwqfc59xkhwbGCWpEpGmfvy9AC4YO+C kmHZHCHEJAPaERX3a0YF/H8rY1jU/GWo+27sRc8mUihUxoX9zR1qfUDfQ4ii1umQ2Q maK+uJnoxo8GKgUs74IqlX3suUXtscJGMIBaUrKLYJWhCJf6VDnUWq1+DpHfmxq84c eiwyhs0SnQ9dDMIo+kcXq1JQHJDX6XPQF2lNpyRVg6M1sMgSipINY7COY6T/xEBxJb bd34N1ErRhtjQ== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id ED06FCE0D3B; Wed, 15 Jul 2026 17:28:24 -0700 (PDT) From: "Paul E. McKenney" To: rcu@vger.kernel.org Cc: linux-kernel@vger.kernel.org, kernel-team@meta.com, rostedt@goodmis.org, Zqiang , "Paul E . McKenney" Subject: [PATCH 6/6] srcu: Queue sdp->work when the delay timer is successfully deleted Date: Wed, 15 Jul 2026 17:28:23 -0700 Message-Id: <20260716002823.12176-6-paulmck@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: References: 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" From: Zqiang In the cleanup_srcu_struct() function, when iterating over per-cpu's srcu_data, timer_delete_sync(&sdp->delay_work) is called to cancel the delayed work before doing flush_work(&sdp->work). However, suppose that timer_delete_sync() returns 1, which means that it successfully deleted an pending timer before it had a chance to fire. But this also means that the sdp->work will not be queued, so that the subsequent flush_work(&sdp->work) will returns immediately without waiting for anything. Taken together, all of this means that any recently queued SRCU callbacks to not be invoked, which can result in memory leaks, hangs, or worse. Fix this by checking the return value of timer_delete_sync(), if it returns 1, explicitly queue sdp->work so that the callbacks will be invoked and the following flush_work() will correctly wait for all of those callbacks to finish executing. Signed-off-by: Zqiang Signed-off-by: Paul E. McKenney --- kernel/rcu/srcutree.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c index 4a00e90e17fc07..8b4e7783bdc963 100644 --- a/kernel/rcu/srcutree.c +++ b/kernel/rcu/srcutree.c @@ -701,7 +701,11 @@ void cleanup_srcu_struct(struct srcu_struct *ssp) for_each_possible_cpu(cpu) { struct srcu_data *sdp =3D per_cpu_ptr(ssp->sda, cpu); =20 - timer_delete_sync(&sdp->delay_work); + // Call srcu_barrier() before this cleanup_srcu_struct() + // to avoid triggering this WARN_ON(). + if (WARN_ON(timer_delete_sync(&sdp->delay_work)) && + rcu_cpu_beenfullyonline(sdp->cpu)) + queue_work_on(sdp->cpu, rcu_gp_wq, &sdp->work); flush_work(&sdp->work); if (WARN_ON(rcu_segcblist_n_cbs(&sdp->srcu_cblist))) return; /* Forgot srcu_barrier(), so just leak it! */ --=20 2.40.1