Rust for Linux List
 help / color / mirror / Atom feed
* [PATCH v5 0/4] rust: add SRCU abstraction
@ 2026-05-27 17:40 Onur Özkan
  2026-05-27 17:40 ` [PATCH v5 1/4] rust: helpers: add SRCU helpers Onur Özkan
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Onur Özkan @ 2026-05-27 17:40 UTC (permalink / raw)
  To: rcu, rust-for-linux, linux-kernel
  Cc: ojeda, boqun, gary, bjorn3_gh, lossin, a.hindborg, aliceryhl,
	tmgross, dakr, peterz, fujita.tomonori, tamird, jiangshanlai,
	paulmck, josh, rostedt, mathieu.desnoyers, Onur Özkan

The immediate motivation is the Tyr reset infrastructure [1] which needs
to serialize reset sensitive hardware access against reset and teardown
paths. That reset series started to require many independent dependencies
so this SRCU support is split out as a standalone Rust API to keep the
reset series focused on the reset logic and easier to review, rebase and
land.

Changes since v4:

- Exposed srcu_readers_active from C side and wired it to the Rust
  helpers.
- Used srcu_readers_active() in SRCU drop and logged with pr_warn if
  there are leaked guards during the drop.

Changes since v3 (which are for Sashiko notes [2]):

- Added rust helpers for srcu_barrier() and synchronize_srcu_expedited()
  so the abstraction builds with CONFIG_TINY_SRCU, where these are
  static inline functions.
- Added missing INVARIANT comment in Srcu::new() about why the type
  invariants hold after successful initialization.

Changes since v2:

- Removed closure-based API.
- Added #[doc(hidden)] on new_srcu macro.
- Added #[must_use..] on srcu::Guard.
- Improved the clean-up path (PinnedDrop implementation) which
  eventually made read_lock safe with leaked guards.

v2: https://lore.kernel.org/all/20260502162833.34334-1-work@onurozkan.dev

Changes since v1:

- Made the owned SRCU read-side guard API unsafe and added a safe closure
  based helper for callers that do not need to keep the guard. This is to
  avoid UB on the C side cleanup_srcu_struct where the SRCU struct is freed
  while there are still active guards, which can happen if the caller leaks
  the guard e.g., with mem::forget().
- Improved doc comments.

v1: https://lore.kernel.org/all/20260428103437.156236-1-work@onurozkan.dev


[1]: https://lore.kernel.org/all/20260416171728.205141-1-work@onurozkan.dev
[2]: https://sashiko.dev/#/patchset/20260522054228.114814-1-work@onurozkan.dev?part=2


Onur Özkan (4):
  rust: helpers: add SRCU helpers
  srcu: expose srcu_readers_active()
  rust: sync: add SRCU abstraction
  MAINTAINERS: add Rust SRCU files to SRCU entry

 MAINTAINERS              |   3 +
 include/linux/srcu.h     |  29 +++++++
 kernel/rcu/srcutiny.c    |   2 +-
 kernel/rcu/srcutree.c    |  25 ------
 rust/helpers/helpers.c   |   1 +
 rust/helpers/srcu.c      |  39 +++++++++
 rust/kernel/sync.rs      |   2 +
 rust/kernel/sync/srcu.rs | 166 +++++++++++++++++++++++++++++++++++++++
 8 files changed, 241 insertions(+), 26 deletions(-)
 create mode 100644 rust/helpers/srcu.c
 create mode 100644 rust/kernel/sync/srcu.rs

-- 
2.51.2


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v5 1/4] rust: helpers: add SRCU helpers
  2026-05-27 17:40 [PATCH v5 0/4] rust: add SRCU abstraction Onur Özkan
@ 2026-05-27 17:40 ` Onur Özkan
  2026-05-27 23:03   ` Paul E. McKenney
  2026-05-27 17:40 ` [PATCH v5 2/4] srcu: expose srcu_readers_active() Onur Özkan
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 12+ messages in thread
From: Onur Özkan @ 2026-05-27 17:40 UTC (permalink / raw)
  To: rcu, rust-for-linux, linux-kernel
  Cc: ojeda, boqun, gary, bjorn3_gh, lossin, a.hindborg, aliceryhl,
	tmgross, dakr, peterz, fujita.tomonori, tamird, jiangshanlai,
	paulmck, josh, rostedt, mathieu.desnoyers, Onur Özkan

Add helper wrappers for SRCU functions that are exposed to Rust
through generated bindings.

Signed-off-by: Onur Özkan <work@onurozkan.dev>
---
 rust/helpers/helpers.c |  1 +
 rust/helpers/srcu.c    | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+)
 create mode 100644 rust/helpers/srcu.c

diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c
index 625921e27dfb..f3562d3b3888 100644
--- a/rust/helpers/helpers.c
+++ b/rust/helpers/helpers.c
@@ -88,6 +88,7 @@
 #include "signal.c"
 #include "slab.c"
 #include "spinlock.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 000000000000..79dd24a104ef
--- /dev/null
+++ b/rust/helpers/srcu.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/srcu.h>
+
+__rust_helper int rust_helper_init_srcu_struct_with_key(struct srcu_struct *ssp,
+							const char *name,
+							struct lock_class_key *key)
+{
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+	return __init_srcu_struct(ssp, name, key);
+#else /* !CONFIG_DEBUG_LOCK_ALLOC */
+	return init_srcu_struct(ssp);
+#endif /* CONFIG_DEBUG_LOCK_ALLOC */
+}
+
+__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, int 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_struct *ssp)
+{
+	synchronize_srcu_expedited(ssp);
+}
-- 
2.51.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v5 2/4] srcu: expose srcu_readers_active()
  2026-05-27 17:40 [PATCH v5 0/4] rust: add SRCU abstraction Onur Özkan
  2026-05-27 17:40 ` [PATCH v5 1/4] rust: helpers: add SRCU helpers Onur Özkan
@ 2026-05-27 17:40 ` Onur Özkan
  2026-05-27 19:37   ` Boqun Feng
  2026-05-27 17:40 ` [PATCH v5 3/4] rust: sync: add SRCU abstraction Onur Özkan
  2026-05-27 17:40 ` [PATCH v5 4/4] MAINTAINERS: add Rust SRCU files to SRCU entry Onur Özkan
  3 siblings, 1 reply; 12+ messages in thread
From: Onur Özkan @ 2026-05-27 17:40 UTC (permalink / raw)
  To: rcu, rust-for-linux, linux-kernel
  Cc: ojeda, boqun, gary, bjorn3_gh, lossin, a.hindborg, aliceryhl,
	tmgross, dakr, peterz, fujita.tomonori, tamird, jiangshanlai,
	paulmck, josh, rostedt, mathieu.desnoyers, Onur Özkan

Move srcu_readers_active() from kernel/rcu/srcutree.c into
include/linux/srcu.h so it can be reused by Rust SRCU helpers.

Provide a CONFIG_TINY_SRCU implementation in the header as well
so the helper is available regardless of the selected SRCU backend.

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.

Signed-off-by: Onur Özkan <work@onurozkan.dev>
---
 include/linux/srcu.h  | 29 +++++++++++++++++++++++++++++
 kernel/rcu/srcutiny.c |  2 +-
 kernel/rcu/srcutree.c | 25 -------------------------
 rust/helpers/srcu.c   |  5 +++++
 4 files changed, 35 insertions(+), 26 deletions(-)

diff --git a/include/linux/srcu.h b/include/linux/srcu.h
index 81b1938512d5..5ca35efb4536 100644
--- a/include/linux/srcu.h
+++ b/include/linux/srcu.h
@@ -92,6 +92,35 @@ void call_srcu(struct srcu_struct *ssp, struct rcu_head *head,
 void cleanup_srcu_struct(struct srcu_struct *ssp);
 void synchronize_srcu(struct srcu_struct *ssp);
 
+/**
+ * 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 inline bool srcu_readers_active(struct srcu_struct *ssp)
+{
+#ifdef CONFIG_TINY_SRCU
+	return READ_ONCE(ssp->srcu_lock_nesting[0]) || READ_ONCE(ssp->srcu_lock_nesting[1]);
+#else
+	int cpu;
+	unsigned long sum = 0;
+
+	for_each_possible_cpu(cpu) {
+		struct srcu_data *sdp = per_cpu_ptr(ssp->sda, cpu);
+
+		sum += atomic_long_read(&sdp->srcu_ctrs[0].srcu_locks);
+		sum += atomic_long_read(&sdp->srcu_ctrs[1].srcu_locks);
+		sum -= atomic_long_read(&sdp->srcu_ctrs[0].srcu_unlocks);
+		sum -= atomic_long_read(&sdp->srcu_ctrs[1].srcu_unlocks);
+	}
+
+	return sum;
+#endif
+}
+
 #define SRCU_GET_STATE_COMPLETED 0x1
 
 /**
diff --git a/kernel/rcu/srcutiny.c b/kernel/rcu/srcutiny.c
index a2e2d516e51b..5dc26af604bf 100644
--- a/kernel/rcu/srcutiny.c
+++ b/kernel/rcu/srcutiny.c
@@ -85,7 +85,7 @@ EXPORT_SYMBOL_GPL(init_srcu_struct);
  */
 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 0d01cd8c4b4a..b1e97ba2e53f 100644
--- a/kernel/rcu/srcutree.c
+++ b/kernel/rcu/srcutree.c
@@ -598,31 +598,6 @@ static bool srcu_readers_active_idx_check(struct srcu_struct *ssp, int idx)
 	return srcu_readers_lock_idx(ssp, idx, did_gp, unlocks);
 }
 
-/**
- * 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 = 0;
-
-	for_each_possible_cpu(cpu) {
-		struct srcu_data *sdp = per_cpu_ptr(ssp->sda, cpu);
-
-		sum += atomic_long_read(&sdp->srcu_ctrs[0].srcu_locks);
-		sum += atomic_long_read(&sdp->srcu_ctrs[1].srcu_locks);
-		sum -= atomic_long_read(&sdp->srcu_ctrs[0].srcu_unlocks);
-		sum -= 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 79dd24a104ef..fa4b5879dda5 100644
--- a/rust/helpers/srcu.c
+++ b/rust/helpers/srcu.c
@@ -13,6 +13,11 @@ __rust_helper int rust_helper_init_srcu_struct_with_key(struct srcu_struct *ssp,
 #endif /* CONFIG_DEBUG_LOCK_ALLOC */
 }
 
+__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);
-- 
2.51.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v5 3/4] rust: sync: add SRCU abstraction
  2026-05-27 17:40 [PATCH v5 0/4] rust: add SRCU abstraction Onur Özkan
  2026-05-27 17:40 ` [PATCH v5 1/4] rust: helpers: add SRCU helpers Onur Özkan
  2026-05-27 17:40 ` [PATCH v5 2/4] srcu: expose srcu_readers_active() Onur Özkan
@ 2026-05-27 17:40 ` Onur Özkan
  2026-05-27 17:40 ` [PATCH v5 4/4] MAINTAINERS: add Rust SRCU files to SRCU entry Onur Özkan
  3 siblings, 0 replies; 12+ messages in thread
From: Onur Özkan @ 2026-05-27 17:40 UTC (permalink / raw)
  To: rcu, rust-for-linux, linux-kernel
  Cc: ojeda, boqun, gary, bjorn3_gh, lossin, a.hindborg, aliceryhl,
	tmgross, dakr, peterz, fujita.tomonori, tamird, jiangshanlai,
	paulmck, josh, rostedt, mathieu.desnoyers, Onur Özkan

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`, which explicitly drains pending grace
periods and callbacks via `synchronize_srcu` and `srcu_barrier` before
executing `cleanup_srcu_struct` to guarantee memory safety e.g. when there
are leaked guards (via `mem::forget($guard)`).

Signed-off-by: Onur Özkan <work@onurozkan.dev>
---
 rust/kernel/sync.rs      |   2 +
 rust/kernel/sync/srcu.rs | 166 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 168 insertions(+)
 create mode 100644 rust/kernel/sync/srcu.rs

diff --git a/rust/kernel/sync.rs b/rust/kernel/sync.rs
index 993dbf2caa0e..0d6a5f1300c3 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;
 
 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;
 
 /// Represents a lockdep class.
 ///
diff --git a/rust/kernel/sync/srcu.rs b/rust/kernel/sync/srcu.rs
new file mode 100644
index 000000000000..343f00d070c7
--- /dev/null
+++ b/rust/kernel/sync/srcu.rs
@@ -0,0 +1,166 @@
+// 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-created lock class.
+#[doc(hidden)]
+#[macro_export]
+macro_rules! new_srcu {
+    ($($name:literal)?) => {
+        $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 return.
+///
+/// # 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<bindings::srcu_struct>,
+}
+
+impl Srcu {
+    /// Creates a new SRCU instance.
+    #[inline]
+    pub fn new(name: &'static CStr, key: Pin<&'static LockClassKey>) -> impl PinInit<Self, Error> {
+        try_pin_init!(Self {
+            // INVARIANT: On success, the C initializer creates a valid `srcu_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 = unsafe { bindings::srcu_read_lock(self.inner.get()) };
+
+        // INVARIANT: `idx` was returned by `srcu_read_lock()` for this `Srcu`.
+        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, expedited.
+    ///
+    /// This requests a lower-latency grace period than [`Srcu::synchronize`] typically
+    /// at the cost of higher system-wide overhead. Prefer [`Srcu::synchronize`] 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 = self.inner.get();
+
+        // SAFETY: By the type invariants, `self` contains a valid and pinned `struct srcu_struct`
+        // and `srcu_readers_active()` only checks the active reader count.
+        if unsafe { bindings::srcu_readers_active(ptr) } {
+            crate::pr_warn!(
+                "Leaked `Guard` detected while dropping SRCU; drop will block forever.\n"
+            );
+        }
+
+        // `cleanup_srcu_struct()` may return early if readers are still active. Because `Srcu`
+        // owns the embedded `srcu_struct`, returning from `drop` in that state could free memory
+        // that is still referenced by the C side.
+        //
+        // Wait for all readers to complete first. If any `Guard` was leaked, `synchronize_srcu()`
+        // will sleep forever.
+        //
+        // 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 pinned `struct srcu_struct`.
+        unsafe { bindings::srcu_barrier(ptr) };
+
+        // SAFETY: By the type invariants, `self` contains a valid and pinned `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`] sleep forever.
+///
+/// # Invariants
+///
+/// `idx` is the index returned by `srcu_read_lock()` for `srcu`.
+#[must_use = "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.idx) };
+    }
+}
-- 
2.51.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v5 4/4] MAINTAINERS: add Rust SRCU files to SRCU entry
  2026-05-27 17:40 [PATCH v5 0/4] rust: add SRCU abstraction Onur Özkan
                   ` (2 preceding siblings ...)
  2026-05-27 17:40 ` [PATCH v5 3/4] rust: sync: add SRCU abstraction Onur Özkan
@ 2026-05-27 17:40 ` Onur Özkan
  2026-05-27 23:05   ` Paul E. McKenney
  3 siblings, 1 reply; 12+ messages in thread
From: Onur Özkan @ 2026-05-27 17:40 UTC (permalink / raw)
  To: rcu, rust-for-linux, linux-kernel
  Cc: ojeda, boqun, gary, bjorn3_gh, lossin, a.hindborg, aliceryhl,
	tmgross, dakr, peterz, fujita.tomonori, tamird, jiangshanlai,
	paulmck, josh, rostedt, mathieu.desnoyers, Onur Özkan

Include Rust side implementation files to the SRCU maintainer
entry.

Signed-off-by: Onur Özkan <work@onurozkan.dev>
---
 MAINTAINERS | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index e0b307b2108c..7739a435f258 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -24624,6 +24624,7 @@ SLEEPABLE READ-COPY UPDATE (SRCU)
 M:	Lai Jiangshan <jiangshanlai@gmail.com>
 M:	"Paul E. McKenney" <paulmck@kernel.org>
 M:	Josh Triplett <josh@joshtriplett.org>
+M:	Onur Özkan <work@onurozkan.dev> (RUST)
 R:	Steven Rostedt <rostedt@goodmis.org>
 R:	Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
 L:	rcu@vger.kernel.org
@@ -24632,6 +24633,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
 
 SMACK SECURITY MODULE
 M:	Casey Schaufler <casey@schaufler-ca.com>
-- 
2.51.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH v5 2/4] srcu: expose srcu_readers_active()
  2026-05-27 17:40 ` [PATCH v5 2/4] srcu: expose srcu_readers_active() Onur Özkan
@ 2026-05-27 19:37   ` Boqun Feng
  2026-05-27 23:04     ` Paul E. McKenney
  0 siblings, 1 reply; 12+ messages in thread
From: Boqun Feng @ 2026-05-27 19:37 UTC (permalink / raw)
  To: Onur Özkan
  Cc: rcu, rust-for-linux, linux-kernel, ojeda, gary, bjorn3_gh, lossin,
	a.hindborg, aliceryhl, tmgross, dakr, peterz, fujita.tomonori,
	tamird, jiangshanlai, paulmck, josh, rostedt, mathieu.desnoyers

On Wed, May 27, 2026 at 08:40:43PM +0300, Onur Özkan wrote:
> Move srcu_readers_active() from kernel/rcu/srcutree.c into
> include/linux/srcu.h so it can be reused by Rust SRCU helpers.
> 
> Provide a CONFIG_TINY_SRCU implementation in the header as well
> so the helper is available regardless of the selected SRCU backend.
> 
> 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.
> 
> Signed-off-by: Onur Özkan <work@onurozkan.dev>
> ---
>  include/linux/srcu.h  | 29 +++++++++++++++++++++++++++++
>  kernel/rcu/srcutiny.c |  2 +-
>  kernel/rcu/srcutree.c | 25 -------------------------
>  rust/helpers/srcu.c   |  5 +++++
>  4 files changed, 35 insertions(+), 26 deletions(-)
> 
> diff --git a/include/linux/srcu.h b/include/linux/srcu.h
> index 81b1938512d5..5ca35efb4536 100644
> --- a/include/linux/srcu.h
> +++ b/include/linux/srcu.h
> @@ -92,6 +92,35 @@ void call_srcu(struct srcu_struct *ssp, struct rcu_head *head,
>  void cleanup_srcu_struct(struct srcu_struct *ssp);
>  void synchronize_srcu(struct srcu_struct *ssp);
>  
> +/**
> + * 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 inline bool srcu_readers_active(struct srcu_struct *ssp)
> +{
> +#ifdef CONFIG_TINY_SRCU

Having a "#ifdef" in a function body is generally considered as bad code
(I know we have some of these in rust helpers, but helpers are a bit
special and maybe we should clean them up). So could you move this
function into include/linux/srcutiny.h and include/linux/srcutree.h?

Thanks!

Regards,
Boqun

> +	return READ_ONCE(ssp->srcu_lock_nesting[0]) || READ_ONCE(ssp->srcu_lock_nesting[1]);
> +#else
> +	int cpu;
> +	unsigned long sum = 0;
> +
> +	for_each_possible_cpu(cpu) {
> +		struct srcu_data *sdp = per_cpu_ptr(ssp->sda, cpu);
> +
> +		sum += atomic_long_read(&sdp->srcu_ctrs[0].srcu_locks);
> +		sum += atomic_long_read(&sdp->srcu_ctrs[1].srcu_locks);
> +		sum -= atomic_long_read(&sdp->srcu_ctrs[0].srcu_unlocks);
> +		sum -= atomic_long_read(&sdp->srcu_ctrs[1].srcu_unlocks);
> +	}
> +
> +	return sum;
> +#endif
> +}
> +
>  #define SRCU_GET_STATE_COMPLETED 0x1
>  
>  /**
> diff --git a/kernel/rcu/srcutiny.c b/kernel/rcu/srcutiny.c
> index a2e2d516e51b..5dc26af604bf 100644
> --- a/kernel/rcu/srcutiny.c
> +++ b/kernel/rcu/srcutiny.c
> @@ -85,7 +85,7 @@ EXPORT_SYMBOL_GPL(init_srcu_struct);
>   */
>  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 0d01cd8c4b4a..b1e97ba2e53f 100644
> --- a/kernel/rcu/srcutree.c
> +++ b/kernel/rcu/srcutree.c
> @@ -598,31 +598,6 @@ static bool srcu_readers_active_idx_check(struct srcu_struct *ssp, int idx)
>  	return srcu_readers_lock_idx(ssp, idx, did_gp, unlocks);
>  }
>  
> -/**
> - * 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 = 0;
> -
> -	for_each_possible_cpu(cpu) {
> -		struct srcu_data *sdp = per_cpu_ptr(ssp->sda, cpu);
> -
> -		sum += atomic_long_read(&sdp->srcu_ctrs[0].srcu_locks);
> -		sum += atomic_long_read(&sdp->srcu_ctrs[1].srcu_locks);
> -		sum -= atomic_long_read(&sdp->srcu_ctrs[0].srcu_unlocks);
> -		sum -= 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 79dd24a104ef..fa4b5879dda5 100644
> --- a/rust/helpers/srcu.c
> +++ b/rust/helpers/srcu.c
> @@ -13,6 +13,11 @@ __rust_helper int rust_helper_init_srcu_struct_with_key(struct srcu_struct *ssp,
>  #endif /* CONFIG_DEBUG_LOCK_ALLOC */
>  }
>  
> +__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);
> -- 
> 2.51.2
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v5 1/4] rust: helpers: add SRCU helpers
  2026-05-27 17:40 ` [PATCH v5 1/4] rust: helpers: add SRCU helpers Onur Özkan
@ 2026-05-27 23:03   ` Paul E. McKenney
  2026-05-28  6:13     ` Onur Özkan
  2026-05-28  6:23     ` Alice Ryhl
  0 siblings, 2 replies; 12+ messages in thread
From: Paul E. McKenney @ 2026-05-27 23:03 UTC (permalink / raw)
  To: Onur Özkan
  Cc: rcu, rust-for-linux, linux-kernel, ojeda, boqun, gary, bjorn3_gh,
	lossin, a.hindborg, aliceryhl, tmgross, dakr, peterz,
	fujita.tomonori, tamird, jiangshanlai, josh, rostedt,
	mathieu.desnoyers

On Wed, May 27, 2026 at 08:40:42PM +0300, Onur Özkan wrote:
> Add helper wrappers for SRCU functions that are exposed to Rust
> through generated bindings.
> 
> Signed-off-by: Onur Özkan <work@onurozkan.dev>
> ---
>  rust/helpers/helpers.c |  1 +
>  rust/helpers/srcu.c    | 34 ++++++++++++++++++++++++++++++++++
>  2 files changed, 35 insertions(+)
>  create mode 100644 rust/helpers/srcu.c
> 
> diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c
> index 625921e27dfb..f3562d3b3888 100644
> --- a/rust/helpers/helpers.c
> +++ b/rust/helpers/helpers.c
> @@ -88,6 +88,7 @@
>  #include "signal.c"
>  #include "slab.c"
>  #include "spinlock.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 000000000000..79dd24a104ef
> --- /dev/null
> +++ b/rust/helpers/srcu.c
> @@ -0,0 +1,34 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include <linux/srcu.h>
> +
> +__rust_helper int rust_helper_init_srcu_struct_with_key(struct srcu_struct *ssp,
> +							const char *name,
> +							struct lock_class_key *key)
> +{
> +#ifdef CONFIG_DEBUG_LOCK_ALLOC
> +	return __init_srcu_struct(ssp, name, key);
> +#else /* !CONFIG_DEBUG_LOCK_ALLOC */
> +	return init_srcu_struct(ssp);
> +#endif /* CONFIG_DEBUG_LOCK_ALLOC */
> +}

Similar to Boqun's feedback on a later patch, could you please make
these be two functions under the corresponding legs of the existing
CONFIG_DEBUG_LOCK_ALLOC #ifdef in include/linux/srcu.h?  You are including
that file above, so it should work well.

Actually, you could just name thefunction __init_srcu_struct(), use the
existing definition under #ifdef CONFIG_DEBUG_LOCK_ALLOC, and just create
the simple wrapper in the other leg of this #ifdef.  That would be more
aligned with the Linux-kernel coding guidelines and also be less code.

Or is the "rust_helper_" prefix mandatory?  If so, you could make
rust_helper_init_srcu_struct() be a wrapper for __init_srcu_struct()
in this file, then just define __init_srcu_struct() as a wrapper around
init_srcu_struct() in the !CONFIG_DEBUG_LOCK_ALLOC leg of the #ifdef
in include/linux/srcu.h.

As a historical note, I didn't much like this rule 25 years ago, but
tried a new project both ways, and quickly abandoned the one that used
#ifdef with abandon.  So I quickly came around to the Linux-kernel way
of thinking on this particular point, anyway.  ;-)

							Thanx, Paul

> +__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, int 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_struct *ssp)
> +{
> +	synchronize_srcu_expedited(ssp);
> +}
> -- 
> 2.51.2
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v5 2/4] srcu: expose srcu_readers_active()
  2026-05-27 19:37   ` Boqun Feng
@ 2026-05-27 23:04     ` Paul E. McKenney
  0 siblings, 0 replies; 12+ messages in thread
From: Paul E. McKenney @ 2026-05-27 23:04 UTC (permalink / raw)
  To: Boqun Feng
  Cc: Onur Özkan, rcu, rust-for-linux, linux-kernel, ojeda, gary,
	bjorn3_gh, lossin, a.hindborg, aliceryhl, tmgross, dakr, peterz,
	fujita.tomonori, tamird, jiangshanlai, josh, rostedt,
	mathieu.desnoyers

On Wed, May 27, 2026 at 12:37:14PM -0700, Boqun Feng wrote:
> On Wed, May 27, 2026 at 08:40:43PM +0300, Onur Özkan wrote:
> > Move srcu_readers_active() from kernel/rcu/srcutree.c into
> > include/linux/srcu.h so it can be reused by Rust SRCU helpers.
> > 
> > Provide a CONFIG_TINY_SRCU implementation in the header as well
> > so the helper is available regardless of the selected SRCU backend.
> > 
> > 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.
> > 
> > Signed-off-by: Onur Özkan <work@onurozkan.dev>
> > ---
> >  include/linux/srcu.h  | 29 +++++++++++++++++++++++++++++
> >  kernel/rcu/srcutiny.c |  2 +-
> >  kernel/rcu/srcutree.c | 25 -------------------------
> >  rust/helpers/srcu.c   |  5 +++++
> >  4 files changed, 35 insertions(+), 26 deletions(-)
> > 
> > diff --git a/include/linux/srcu.h b/include/linux/srcu.h
> > index 81b1938512d5..5ca35efb4536 100644
> > --- a/include/linux/srcu.h
> > +++ b/include/linux/srcu.h
> > @@ -92,6 +92,35 @@ void call_srcu(struct srcu_struct *ssp, struct rcu_head *head,
> >  void cleanup_srcu_struct(struct srcu_struct *ssp);
> >  void synchronize_srcu(struct srcu_struct *ssp);
> >  
> > +/**
> > + * 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 inline bool srcu_readers_active(struct srcu_struct *ssp)
> > +{
> > +#ifdef CONFIG_TINY_SRCU
> 
> Having a "#ifdef" in a function body is generally considered as bad code
> (I know we have some of these in rust helpers, but helpers are a bit
> special and maybe we should clean them up). So could you move this
> function into include/linux/srcutiny.h and include/linux/srcutree.h?

What Boqun said, please!

							Thanx, Paul

> Thanks!
> 
> Regards,
> Boqun
> 
> > +	return READ_ONCE(ssp->srcu_lock_nesting[0]) || READ_ONCE(ssp->srcu_lock_nesting[1]);
> > +#else
> > +	int cpu;
> > +	unsigned long sum = 0;
> > +
> > +	for_each_possible_cpu(cpu) {
> > +		struct srcu_data *sdp = per_cpu_ptr(ssp->sda, cpu);
> > +
> > +		sum += atomic_long_read(&sdp->srcu_ctrs[0].srcu_locks);
> > +		sum += atomic_long_read(&sdp->srcu_ctrs[1].srcu_locks);
> > +		sum -= atomic_long_read(&sdp->srcu_ctrs[0].srcu_unlocks);
> > +		sum -= atomic_long_read(&sdp->srcu_ctrs[1].srcu_unlocks);
> > +	}
> > +
> > +	return sum;
> > +#endif
> > +}
> > +
> >  #define SRCU_GET_STATE_COMPLETED 0x1
> >  
> >  /**
> > diff --git a/kernel/rcu/srcutiny.c b/kernel/rcu/srcutiny.c
> > index a2e2d516e51b..5dc26af604bf 100644
> > --- a/kernel/rcu/srcutiny.c
> > +++ b/kernel/rcu/srcutiny.c
> > @@ -85,7 +85,7 @@ EXPORT_SYMBOL_GPL(init_srcu_struct);
> >   */
> >  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 0d01cd8c4b4a..b1e97ba2e53f 100644
> > --- a/kernel/rcu/srcutree.c
> > +++ b/kernel/rcu/srcutree.c
> > @@ -598,31 +598,6 @@ static bool srcu_readers_active_idx_check(struct srcu_struct *ssp, int idx)
> >  	return srcu_readers_lock_idx(ssp, idx, did_gp, unlocks);
> >  }
> >  
> > -/**
> > - * 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 = 0;
> > -
> > -	for_each_possible_cpu(cpu) {
> > -		struct srcu_data *sdp = per_cpu_ptr(ssp->sda, cpu);
> > -
> > -		sum += atomic_long_read(&sdp->srcu_ctrs[0].srcu_locks);
> > -		sum += atomic_long_read(&sdp->srcu_ctrs[1].srcu_locks);
> > -		sum -= atomic_long_read(&sdp->srcu_ctrs[0].srcu_unlocks);
> > -		sum -= 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 79dd24a104ef..fa4b5879dda5 100644
> > --- a/rust/helpers/srcu.c
> > +++ b/rust/helpers/srcu.c
> > @@ -13,6 +13,11 @@ __rust_helper int rust_helper_init_srcu_struct_with_key(struct srcu_struct *ssp,
> >  #endif /* CONFIG_DEBUG_LOCK_ALLOC */
> >  }
> >  
> > +__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);
> > -- 
> > 2.51.2
> > 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v5 4/4] MAINTAINERS: add Rust SRCU files to SRCU entry
  2026-05-27 17:40 ` [PATCH v5 4/4] MAINTAINERS: add Rust SRCU files to SRCU entry Onur Özkan
@ 2026-05-27 23:05   ` Paul E. McKenney
  0 siblings, 0 replies; 12+ messages in thread
From: Paul E. McKenney @ 2026-05-27 23:05 UTC (permalink / raw)
  To: Onur Özkan
  Cc: rcu, rust-for-linux, linux-kernel, ojeda, boqun, gary, bjorn3_gh,
	lossin, a.hindborg, aliceryhl, tmgross, dakr, peterz,
	fujita.tomonori, tamird, jiangshanlai, josh, rostedt,
	mathieu.desnoyers

On Wed, May 27, 2026 at 08:40:45PM +0300, Onur Özkan wrote:
> Include Rust side implementation files to the SRCU maintainer
> entry.
> 
> Signed-off-by: Onur Özkan <work@onurozkan.dev>

Reviewed-by: Paul E. McKenney <paulmck@kernel.org>

> ---
>  MAINTAINERS | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index e0b307b2108c..7739a435f258 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -24624,6 +24624,7 @@ SLEEPABLE READ-COPY UPDATE (SRCU)
>  M:	Lai Jiangshan <jiangshanlai@gmail.com>
>  M:	"Paul E. McKenney" <paulmck@kernel.org>
>  M:	Josh Triplett <josh@joshtriplett.org>
> +M:	Onur Özkan <work@onurozkan.dev> (RUST)
>  R:	Steven Rostedt <rostedt@goodmis.org>
>  R:	Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
>  L:	rcu@vger.kernel.org
> @@ -24632,6 +24633,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
>  
>  SMACK SECURITY MODULE
>  M:	Casey Schaufler <casey@schaufler-ca.com>
> -- 
> 2.51.2
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v5 1/4] rust: helpers: add SRCU helpers
  2026-05-27 23:03   ` Paul E. McKenney
@ 2026-05-28  6:13     ` Onur Özkan
  2026-05-28  6:23     ` Alice Ryhl
  1 sibling, 0 replies; 12+ messages in thread
From: Onur Özkan @ 2026-05-28  6:13 UTC (permalink / raw)
  To: Paul E. McKenney
  Cc: rcu, rust-for-linux, linux-kernel, ojeda, boqun, gary, bjorn3_gh,
	lossin, a.hindborg, aliceryhl, tmgross, dakr, peterz,
	fujita.tomonori, tamird, jiangshanlai, josh, rostedt,
	mathieu.desnoyers

On Wed, 27 May 2026 16:03:30 -0700
"Paul E. McKenney" <paulmck@kernel.org> wrote:

> On Wed, May 27, 2026 at 08:40:42PM +0300, Onur Özkan wrote:
> > Add helper wrappers for SRCU functions that are exposed to Rust
> > through generated bindings.
> > 
> > Signed-off-by: Onur Özkan <work@onurozkan.dev>
> > ---
> >  rust/helpers/helpers.c |  1 +
> >  rust/helpers/srcu.c    | 34 ++++++++++++++++++++++++++++++++++
> >  2 files changed, 35 insertions(+)
> >  create mode 100644 rust/helpers/srcu.c
> > 
> > diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c
> > index 625921e27dfb..f3562d3b3888 100644
> > --- a/rust/helpers/helpers.c
> > +++ b/rust/helpers/helpers.c
> > @@ -88,6 +88,7 @@
> >  #include "signal.c"
> >  #include "slab.c"
> >  #include "spinlock.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 000000000000..79dd24a104ef
> > --- /dev/null
> > +++ b/rust/helpers/srcu.c
> > @@ -0,0 +1,34 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +#include <linux/srcu.h>
> > +
> > +__rust_helper int rust_helper_init_srcu_struct_with_key(struct srcu_struct *ssp,
> > +							const char *name,
> > +							struct lock_class_key *key)
> > +{
> > +#ifdef CONFIG_DEBUG_LOCK_ALLOC
> > +	return __init_srcu_struct(ssp, name, key);
> > +#else /* !CONFIG_DEBUG_LOCK_ALLOC */
> > +	return init_srcu_struct(ssp);
> > +#endif /* CONFIG_DEBUG_LOCK_ALLOC */
> > +}
> 
> Similar to Boqun's feedback on a later patch, could you please make
> these be two functions under the corresponding legs of the existing
> CONFIG_DEBUG_LOCK_ALLOC #ifdef in include/linux/srcu.h?  You are including
> that file above, so it should work well.
> 
> Actually, you could just name thefunction __init_srcu_struct(), use the
> existing definition under #ifdef CONFIG_DEBUG_LOCK_ALLOC, and just create
> the simple wrapper in the other leg of this #ifdef.  That would be more
> aligned with the Linux-kernel coding guidelines and also be less code.
> 
> Or is the "rust_helper_" prefix mandatory?  If so, you could make

That prefix is indeed mandatory.

> rust_helper_init_srcu_struct() be a wrapper for __init_srcu_struct()
> in this file, then just define __init_srcu_struct() as a wrapper around
> init_srcu_struct() in the !CONFIG_DEBUG_LOCK_ALLOC leg of the #ifdef
> in include/linux/srcu.h.

Sure, sounds good to me.

Thanks,
Onur

> 
> As a historical note, I didn't much like this rule 25 years ago, but
> tried a new project both ways, and quickly abandoned the one that used
> #ifdef with abandon.  So I quickly came around to the Linux-kernel way
> of thinking on this particular point, anyway.  ;-)
> 
> 							Thanx, Paul
> 
> > +__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, int 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_struct *ssp)
> > +{
> > +	synchronize_srcu_expedited(ssp);
> > +}
> > -- 
> > 2.51.2
> > 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v5 1/4] rust: helpers: add SRCU helpers
  2026-05-27 23:03   ` Paul E. McKenney
  2026-05-28  6:13     ` Onur Özkan
@ 2026-05-28  6:23     ` Alice Ryhl
  2026-05-28 14:18       ` Paul E. McKenney
  1 sibling, 1 reply; 12+ messages in thread
From: Alice Ryhl @ 2026-05-28  6:23 UTC (permalink / raw)
  To: Paul E. McKenney
  Cc: Onur Özkan, rcu, rust-for-linux, linux-kernel, ojeda, boqun,
	gary, bjorn3_gh, lossin, a.hindborg, tmgross, dakr, peterz,
	fujita.tomonori, tamird, jiangshanlai, josh, rostedt,
	mathieu.desnoyers

On Wed, May 27, 2026 at 04:03:30PM -0700, Paul E. McKenney wrote:
> On Wed, May 27, 2026 at 08:40:42PM +0300, Onur Özkan wrote:
> > Add helper wrappers for SRCU functions that are exposed to Rust
> > through generated bindings.
> > 
> > Signed-off-by: Onur Özkan <work@onurozkan.dev>
> > ---
> >  rust/helpers/helpers.c |  1 +
> >  rust/helpers/srcu.c    | 34 ++++++++++++++++++++++++++++++++++
> >  2 files changed, 35 insertions(+)
> >  create mode 100644 rust/helpers/srcu.c
> > 
> > diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c
> > index 625921e27dfb..f3562d3b3888 100644
> > --- a/rust/helpers/helpers.c
> > +++ b/rust/helpers/helpers.c
> > @@ -88,6 +88,7 @@
> >  #include "signal.c"
> >  #include "slab.c"
> >  #include "spinlock.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 000000000000..79dd24a104ef
> > --- /dev/null
> > +++ b/rust/helpers/srcu.c
> > @@ -0,0 +1,34 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +#include <linux/srcu.h>
> > +
> > +__rust_helper int rust_helper_init_srcu_struct_with_key(struct srcu_struct *ssp,
> > +							const char *name,
> > +							struct lock_class_key *key)
> > +{
> > +#ifdef CONFIG_DEBUG_LOCK_ALLOC
> > +	return __init_srcu_struct(ssp, name, key);
> > +#else /* !CONFIG_DEBUG_LOCK_ALLOC */
> > +	return init_srcu_struct(ssp);
> > +#endif /* CONFIG_DEBUG_LOCK_ALLOC */
> > +}
> 
> Similar to Boqun's feedback on a later patch, could you please make
> these be two functions under the corresponding legs of the existing
> CONFIG_DEBUG_LOCK_ALLOC #ifdef in include/linux/srcu.h?  You are including
> that file above, so it should work well.
> 
> Actually, you could just name thefunction __init_srcu_struct(), use the
> existing definition under #ifdef CONFIG_DEBUG_LOCK_ALLOC, and just create
> the simple wrapper in the other leg of this #ifdef.  That would be more
> aligned with the Linux-kernel coding guidelines and also be less code.
> 
> Or is the "rust_helper_" prefix mandatory?  If so, you could make
> rust_helper_init_srcu_struct() be a wrapper for __init_srcu_struct()
> in this file, then just define __init_srcu_struct() as a wrapper around
> init_srcu_struct() in the !CONFIG_DEBUG_LOCK_ALLOC leg of the #ifdef
> in include/linux/srcu.h.

The rust_helper_ prefix helps avoid duplicate symbol errors.

When you invoke `bindings::foo` then it will prefer to call the symbol
actually called `foo()`, but if there is no `foo` symbol, then it will
fall back to `rust_helper_foo()`.

This is useful because many symbols are only marked inline under some
configurations, and this makes it automatically pick the right one
depending on whether the real symbol exists or not.

Alice

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v5 1/4] rust: helpers: add SRCU helpers
  2026-05-28  6:23     ` Alice Ryhl
@ 2026-05-28 14:18       ` Paul E. McKenney
  0 siblings, 0 replies; 12+ messages in thread
From: Paul E. McKenney @ 2026-05-28 14:18 UTC (permalink / raw)
  To: Alice Ryhl
  Cc: Onur Özkan, rcu, rust-for-linux, linux-kernel, ojeda, boqun,
	gary, bjorn3_gh, lossin, a.hindborg, tmgross, dakr, peterz,
	fujita.tomonori, tamird, jiangshanlai, josh, rostedt,
	mathieu.desnoyers

On Thu, May 28, 2026 at 06:23:50AM +0000, Alice Ryhl wrote:
> On Wed, May 27, 2026 at 04:03:30PM -0700, Paul E. McKenney wrote:
> > On Wed, May 27, 2026 at 08:40:42PM +0300, Onur Özkan wrote:
> > > Add helper wrappers for SRCU functions that are exposed to Rust
> > > through generated bindings.
> > > 
> > > Signed-off-by: Onur Özkan <work@onurozkan.dev>
> > > ---
> > >  rust/helpers/helpers.c |  1 +
> > >  rust/helpers/srcu.c    | 34 ++++++++++++++++++++++++++++++++++
> > >  2 files changed, 35 insertions(+)
> > >  create mode 100644 rust/helpers/srcu.c
> > > 
> > > diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c
> > > index 625921e27dfb..f3562d3b3888 100644
> > > --- a/rust/helpers/helpers.c
> > > +++ b/rust/helpers/helpers.c
> > > @@ -88,6 +88,7 @@
> > >  #include "signal.c"
> > >  #include "slab.c"
> > >  #include "spinlock.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 000000000000..79dd24a104ef
> > > --- /dev/null
> > > +++ b/rust/helpers/srcu.c
> > > @@ -0,0 +1,34 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +
> > > +#include <linux/srcu.h>
> > > +
> > > +__rust_helper int rust_helper_init_srcu_struct_with_key(struct srcu_struct *ssp,
> > > +							const char *name,
> > > +							struct lock_class_key *key)
> > > +{
> > > +#ifdef CONFIG_DEBUG_LOCK_ALLOC
> > > +	return __init_srcu_struct(ssp, name, key);
> > > +#else /* !CONFIG_DEBUG_LOCK_ALLOC */
> > > +	return init_srcu_struct(ssp);
> > > +#endif /* CONFIG_DEBUG_LOCK_ALLOC */
> > > +}
> > 
> > Similar to Boqun's feedback on a later patch, could you please make
> > these be two functions under the corresponding legs of the existing
> > CONFIG_DEBUG_LOCK_ALLOC #ifdef in include/linux/srcu.h?  You are including
> > that file above, so it should work well.
> > 
> > Actually, you could just name thefunction __init_srcu_struct(), use the
> > existing definition under #ifdef CONFIG_DEBUG_LOCK_ALLOC, and just create
> > the simple wrapper in the other leg of this #ifdef.  That would be more
> > aligned with the Linux-kernel coding guidelines and also be less code.
> > 
> > Or is the "rust_helper_" prefix mandatory?  If so, you could make
> > rust_helper_init_srcu_struct() be a wrapper for __init_srcu_struct()
> > in this file, then just define __init_srcu_struct() as a wrapper around
> > init_srcu_struct() in the !CONFIG_DEBUG_LOCK_ALLOC leg of the #ifdef
> > in include/linux/srcu.h.
> 
> The rust_helper_ prefix helps avoid duplicate symbol errors.
> 
> When you invoke `bindings::foo` then it will prefer to call the symbol
> actually called `foo()`, but if there is no `foo` symbol, then it will
> fall back to `rust_helper_foo()`.
> 
> This is useful because many symbols are only marked inline under some
> configurations, and this makes it automatically pick the right one
> depending on whether the real symbol exists or not.

Thank you both for the Rust-bindings tutorial!  ;-)

							Thanx, Paul

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2026-05-28 14:18 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-27 17:40 [PATCH v5 0/4] rust: add SRCU abstraction Onur Özkan
2026-05-27 17:40 ` [PATCH v5 1/4] rust: helpers: add SRCU helpers Onur Özkan
2026-05-27 23:03   ` Paul E. McKenney
2026-05-28  6:13     ` Onur Özkan
2026-05-28  6:23     ` Alice Ryhl
2026-05-28 14:18       ` Paul E. McKenney
2026-05-27 17:40 ` [PATCH v5 2/4] srcu: expose srcu_readers_active() Onur Özkan
2026-05-27 19:37   ` Boqun Feng
2026-05-27 23:04     ` Paul E. McKenney
2026-05-27 17:40 ` [PATCH v5 3/4] rust: sync: add SRCU abstraction Onur Özkan
2026-05-27 17:40 ` [PATCH v5 4/4] MAINTAINERS: add Rust SRCU files to SRCU entry Onur Özkan
2026-05-27 23:05   ` Paul E. McKenney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox