From: "Onur Özkan" <work@onurozkan.dev>
To: dakr@kernel.org, aliceryhl@google.com,
daniel.almeida@collabora.com, airlied@gmail.com, simona@ffwll.ch,
dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
rust-for-linux@vger.kernel.org, jiangshanlai@gmail.com,
paulmck@kernel.org, josh@joshtriplett.org, rostedt@goodmis.org
Cc: "Onur Özkan" <work@onurozkan.dev>
Subject: [PATCH v2 RESEND 1/4] rust: add SRCU abstraction
Date: Thu, 16 Apr 2026 20:43:07 +0300 [thread overview]
Message-ID: <20260416174308.221235-1-work@onurozkan.dev> (raw)
In-Reply-To: <20260416171728.205141-1-work@onurozkan.dev>
Add a Rust abstraction for sleepable RCU (SRCU), backed by
srcu_struct. Provide FFI helpers and a safe wrapper with a
guard-based API for read-side critical sections.
Signed-off-by: Onur Özkan <work@onurozkan.dev>
---
rust/helpers/helpers.c | 1 +
rust/helpers/srcu.c | 18 +++++++
rust/kernel/sync.rs | 2 +
rust/kernel/sync/srcu.rs | 109 +++++++++++++++++++++++++++++++++++++++
4 files changed, 130 insertions(+)
create mode 100644 rust/helpers/srcu.c
create mode 100644 rust/kernel/sync/srcu.rs
diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c
index 875a9788ad40..052fef89d5f0 100644
--- a/rust/helpers/helpers.c
+++ b/rust/helpers/helpers.c
@@ -60,6 +60,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..b372b733eb89
--- /dev/null
+++ b/rust/helpers/srcu.c
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/srcu.h>
+
+__rust_helper int rust_helper_init_srcu_struct(struct srcu_struct *ssp)
+{
+ return init_srcu_struct(ssp);
+}
+
+__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);
+}
\ No newline at end of file
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..cf0c16248ea3
--- /dev/null
+++ b/rust/kernel/sync/srcu.rs
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Sleepable read-copy update (SRCU) abstraction.
+//!
+//! C header: [`include/linux/srcu.h`](srctree/include/linux/srcu.h)
+
+use crate::{
+ bindings,
+ error::to_result,
+ prelude::*,
+ types::{
+ NotThreadSafe,
+ Opaque, //
+ },
+};
+
+use pin_init::pin_data;
+
+/// Creates an [`Srcu`] initialiser.
+#[macro_export]
+macro_rules! new_srcu {
+ () => {
+ $crate::sync::Srcu::new()
+ };
+}
+
+/// Sleepable read-copy update primitive.
+///
+/// SRCU readers may sleep while holding the read-side guard.
+#[repr(transparent)]
+#[pin_data(PinnedDrop)]
+pub struct Srcu {
+ #[pin]
+ inner: Opaque<bindings::srcu_struct>,
+}
+
+impl Srcu {
+ /// Creates a new SRCU instance.
+ pub fn new() -> impl PinInit<Self, Error> {
+ try_pin_init!(Self {
+ 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(ptr) })
+ }),
+ })
+ }
+
+ /// Enters an SRCU read-side critical section.
+ pub fn read_lock(&self) -> Guard<'_> {
+ // SAFETY: By the type invariants, `self.inner.get()` is a valid initialized `srcu_struct`.
+ let idx = unsafe { bindings::srcu_read_lock(self.inner.get()) };
+
+ Guard {
+ srcu: self,
+ idx,
+ _nts: NotThreadSafe,
+ }
+ }
+
+ /// Waits until all pre-existing SRCU readers have completed.
+ pub fn synchronize(&self) {
+ // SAFETY: By the type invariants, `self.inner.get()` is a valid initialized `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.
+ pub fn synchronize_expedited(&self) {
+ // SAFETY: By the type invariants, `self.inner.get()` is a valid initialized `srcu_struct`.
+ unsafe { bindings::synchronize_srcu_expedited(self.inner.get()) };
+ }
+}
+
+#[pinned_drop]
+impl PinnedDrop for Srcu {
+ fn drop(self: Pin<&mut Self>) {
+ // SAFETY: `self` is pinned and `inner` contains a valid initialized `srcu_struct`.
+ unsafe { bindings::cleanup_srcu_struct(self.as_ref().get_ref().inner.get()) };
+ }
+}
+
+// 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`].
+pub struct Guard<'a> {
+ srcu: &'a Srcu,
+ idx: core::ffi::c_int,
+ _nts: NotThreadSafe,
+}
+
+impl Guard<'_> {
+ /// Explicitly exits the SRCU read-side critical section.
+ pub fn unlock(self) {}
+}
+
+impl Drop for Guard<'_> {
+ 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
next prev parent reply other threads:[~2026-04-16 17:43 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-16 17:17 [PATCH v2 0/4] drm/tyr: implement GPU reset API Onur Özkan
2026-04-16 17:17 ` [PATCH v2 3/4] rust: add Work::disable_sync Onur Özkan
2026-04-16 17:17 ` [PATCH v2 4/4] drm/tyr: add reset management API Onur Özkan
2026-04-16 17:23 ` [PATCH v2 0/4] drm/tyr: implement GPU reset API Onur Özkan
2026-04-16 18:45 ` Boqun Feng
2026-04-17 8:02 ` Onur Özkan
2026-04-28 10:49 ` Onur Özkan
2026-04-16 17:43 ` Onur Özkan [this message]
2026-04-16 17:43 ` [PATCH v2 RESEND 2/4] MAINTAINERS: add Rust SRCU files to SRCU entry Onur Özkan
2026-04-21 16:14 ` [PATCH v2 RESEND 1/4] rust: add SRCU abstraction Gary Guo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260416174308.221235-1-work@onurozkan.dev \
--to=work@onurozkan.dev \
--cc=airlied@gmail.com \
--cc=aliceryhl@google.com \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=jiangshanlai@gmail.com \
--cc=josh@joshtriplett.org \
--cc=linux-kernel@vger.kernel.org \
--cc=paulmck@kernel.org \
--cc=rostedt@goodmis.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=simona@ffwll.ch \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.