* [PATCH] rust: sync: Accept errors for Lock payload data
@ 2026-09-24 8:55 Philipp Stanner
2026-09-24 10:41 ` Gary Guo
0 siblings, 1 reply; 2+ messages in thread
From: Philipp Stanner @ 2026-09-24 8:55 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng,
Waiman Long, Gary Guo, Alice Ryhl, Lyude Paul, Daniel Almeida,
Onur Özkan, Miguel Ojeda, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich,
Tamir Duberstein, Alexandre Courbot
Cc: linux-kernel, rust-for-linux, Philipp Stanner
The `Lock` baseclass currently does not allow for fallible user-data.
This can cause conflicts when used with other primitives, for example
when a lock shall be pin-initialized with payload data that is fallible.
Add support for the lock base class so that it works with
try_pin_init!(). Adjust spinlock and mutex accordingly.
Signed-off-by: Philipp Stanner <phasta@kernel.org>
---
Regarding removal of the CStrExt, I got "unused import" errors because
of it. Don't fully understand why?
P.
---
rust/kernel/sync/lock.rs | 21 ++++++++++++++-------
rust/kernel/sync/lock/mutex.rs | 7 ++++---
rust/kernel/sync/lock/spinlock.rs | 20 ++++++++++----------
3 files changed, 28 insertions(+), 20 deletions(-)
diff --git a/rust/kernel/sync/lock.rs b/rust/kernel/sync/lock.rs
index 10b6b5e9b024..1b2df5d0dcf9 100644
--- a/rust/kernel/sync/lock.rs
+++ b/rust/kernel/sync/lock.rs
@@ -7,11 +7,13 @@
use super::LockClassKey;
use crate::{
- str::{CStr, CStrExt as _},
+ str::CStr,
types::{NotThreadSafe, Opaque, ScopeGuard},
};
use core::{cell::UnsafeCell, marker::PhantomPinned, pin::Pin};
-use pin_init::{pin_data, pin_init, PinInit, Wrapper};
+use pin_init::{pin_data, PinInit, Wrapper};
+
+use kernel::prelude::*;
pub mod mutex;
pub mod spinlock;
@@ -126,14 +128,19 @@ unsafe impl<T: ?Sized + Send, B: Backend> Send for Lock<T, B> {}
// data it protects is `Send`.
unsafe impl<T: ?Sized + Send, B: Backend> Sync for Lock<T, B> {}
+use core::convert::Infallible;
+
impl<T, B: Backend> Lock<T, B> {
/// Constructs a new lock initialiser.
- pub fn new(
- t: impl PinInit<T>,
+ pub fn new<E>(
+ t: impl PinInit<T, E>,
name: &'static CStr,
key: Pin<&'static LockClassKey>,
- ) -> impl PinInit<Self> {
- pin_init!(Self {
+ ) -> impl PinInit<Self, E>
+ where
+ E: From<Infallible>,
+ {
+ try_pin_init!(Self {
data <- UnsafeCell::pin_init(t),
_pin: PhantomPinned,
// SAFETY: `slot` is valid while the closure is called and both `name` and `key` have
@@ -141,7 +148,7 @@ pub fn new(
state <- Opaque::ffi_init(|slot| unsafe {
B::init(slot, name.as_char_ptr(), key.as_ptr())
}),
- })
+ }? E)
}
}
diff --git a/rust/kernel/sync/lock/mutex.rs b/rust/kernel/sync/lock/mutex.rs
index cda0203efefb..35e6b02ff426 100644
--- a/rust/kernel/sync/lock/mutex.rs
+++ b/rust/kernel/sync/lock/mutex.rs
@@ -35,6 +35,7 @@ macro_rules! new_mutex {
///
/// ```
/// use kernel::sync::{new_mutex, Mutex};
+/// use kernel::prelude::*;
///
/// struct Inner {
/// a: u32,
@@ -49,8 +50,8 @@ macro_rules! new_mutex {
/// }
///
/// impl Example {
-/// fn new() -> impl PinInit<Self> {
-/// pin_init!(Self {
+/// fn new() -> impl PinInit<Self, Error> {
+/// try_pin_init!(Self {
/// c: 10,
/// d <- new_mutex!(Inner { a: 20, b: 30 }),
/// })
@@ -58,7 +59,7 @@ macro_rules! new_mutex {
/// }
///
/// // Allocate a boxed `Example`.
-/// let e = KBox::pin_init(Example::new(), GFP_KERNEL)?;
+/// let e = KBox::try_pin_init(Example::new(), GFP_KERNEL)?;
/// assert_eq!(e.c, 10);
/// assert_eq!(e.d.lock().a, 20);
/// assert_eq!(e.d.lock().b, 30);
diff --git a/rust/kernel/sync/lock/spinlock.rs b/rust/kernel/sync/lock/spinlock.rs
index aafc80125f59..8ea2c5b202e6 100644
--- a/rust/kernel/sync/lock/spinlock.rs
+++ b/rust/kernel/sync/lock/spinlock.rs
@@ -4,10 +4,7 @@
//!
//! This module allows Rust code to use the kernel's `spinlock_t`.
use super::*;
-use crate::{
- interrupt::LocalInterruptDisabled,
- prelude::*, //
-};
+use crate::interrupt::LocalInterruptDisabled;
/// Creates a [`SpinLock`] initialiser with the given name and a newly-created lock class.
///
@@ -38,6 +35,7 @@ macro_rules! new_spinlock {
///
/// ```
/// use kernel::sync::{new_spinlock, SpinLock};
+/// use kernel::prelude::*;
///
/// struct Inner {
/// a: u32,
@@ -52,8 +50,8 @@ macro_rules! new_spinlock {
/// }
///
/// impl Example {
-/// fn new() -> impl PinInit<Self> {
-/// pin_init!(Self {
+/// fn new() -> impl PinInit<Self, Error> {
+/// try_pin_init!(Self {
/// c: 10,
/// d <- new_spinlock!(Inner { a: 20, b: 30 }),
/// })
@@ -184,6 +182,7 @@ macro_rules! new_spinlock_irq {
///
/// ```
/// use kernel::sync::{new_spinlock_irq, SpinLockIrq};
+/// use kernel::prelude::*;
///
/// struct Inner {
/// a: u32,
@@ -199,8 +198,8 @@ macro_rules! new_spinlock_irq {
/// }
///
/// impl Example {
-/// fn new() -> impl PinInit<Self> {
-/// pin_init!(Self {
+/// fn new() -> impl PinInit<Self, Error> {
+/// try_pin_init!(Self {
/// c <- new_spinlock_irq!(Inner { a: 0, b: 10 }),
/// d <- new_spinlock_irq!(Inner { a: 20, b: 30 }),
/// })
@@ -232,6 +231,7 @@ macro_rules! new_spinlock_irq {
/// ```
/// use kernel::sync::{new_spinlock_irq, SpinLockIrq};
/// use kernel::interrupt::*;
+/// use kernel::prelude::*;
///
/// struct Inner {
/// a: u32,
@@ -244,8 +244,8 @@ macro_rules! new_spinlock_irq {
/// }
///
/// impl Example {
-/// fn new() -> impl PinInit<Self> {
-/// pin_init!(Self {
+/// fn new() -> impl PinInit<Self, Error> {
+/// try_pin_init!(Self {
/// inner <- new_spinlock_irq!(Inner { a: 20 }),
/// })
/// }
--
2.55.0
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: [PATCH] rust: sync: Accept errors for Lock payload data
2026-09-24 8:55 [PATCH] rust: sync: Accept errors for Lock payload data Philipp Stanner
@ 2026-09-24 10:41 ` Gary Guo
0 siblings, 0 replies; 2+ messages in thread
From: Gary Guo @ 2026-09-24 10:41 UTC (permalink / raw)
To: Philipp Stanner, Peter Zijlstra, Ingo Molnar, Will Deacon,
Boqun Feng, Waiman Long, Gary Guo, Alice Ryhl, Lyude Paul,
Daniel Almeida, Onur Özkan, Miguel Ojeda,
Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, Tamir Duberstein,
Alexandre Courbot
Cc: linux-kernel, rust-for-linux
On Thu Sep 24, 2026 at 9:55 AM BST, Philipp Stanner wrote:
> The `Lock` baseclass currently does not allow for fallible user-data.
> This can cause conflicts when used with other primitives, for example
> when a lock shall be pin-initialized with payload data that is fallible.
>
> Add support for the lock base class so that it works with
> try_pin_init!(). Adjust spinlock and mutex accordingly.
>
> Signed-off-by: Philipp Stanner <phasta@kernel.org>
> ---
> Regarding removal of the CStrExt, I got "unused import" errors because
> of it. Don't fully understand why?
Because it's part of the prelude.
>
> P.
> ---
> rust/kernel/sync/lock.rs | 21 ++++++++++++++-------
> rust/kernel/sync/lock/mutex.rs | 7 ++++---
> rust/kernel/sync/lock/spinlock.rs | 20 ++++++++++----------
> 3 files changed, 28 insertions(+), 20 deletions(-)
>
> diff --git a/rust/kernel/sync/lock.rs b/rust/kernel/sync/lock.rs
> index 10b6b5e9b024..1b2df5d0dcf9 100644
> --- a/rust/kernel/sync/lock.rs
> +++ b/rust/kernel/sync/lock.rs
> @@ -7,11 +7,13 @@
>
> use super::LockClassKey;
> use crate::{
> - str::{CStr, CStrExt as _},
> + str::CStr,
> types::{NotThreadSafe, Opaque, ScopeGuard},
> };
> use core::{cell::UnsafeCell, marker::PhantomPinned, pin::Pin};
> -use pin_init::{pin_data, pin_init, PinInit, Wrapper};
> +use pin_init::{pin_data, PinInit, Wrapper};
> +
> +use kernel::prelude::*;
>
> pub mod mutex;
> pub mod spinlock;
> @@ -126,14 +128,19 @@ unsafe impl<T: ?Sized + Send, B: Backend> Send for Lock<T, B> {}
> // data it protects is `Send`.
> unsafe impl<T: ?Sized + Send, B: Backend> Sync for Lock<T, B> {}
>
> +use core::convert::Infallible;
> +
> impl<T, B: Backend> Lock<T, B> {
> /// Constructs a new lock initialiser.
> - pub fn new(
> - t: impl PinInit<T>,
> + pub fn new<E>(
> + t: impl PinInit<T, E>,
> name: &'static CStr,
> key: Pin<&'static LockClassKey>,
> - ) -> impl PinInit<Self> {
> - pin_init!(Self {
> + ) -> impl PinInit<Self, E>
> + where
> + E: From<Infallible>,
> + {
> + try_pin_init!(Self {
FWIW if `? E` is specified, both `pin_init!` and `try_pin_init!` behave the
same, so there no need to change it here.
The difference between these two macros are the default error type; the former is
`Infallible` and the latter is `kernel::error::Error`.
> data <- UnsafeCell::pin_init(t),
> _pin: PhantomPinned,
> // SAFETY: `slot` is valid while the closure is called and both `name` and `key` have
> @@ -141,7 +148,7 @@ pub fn new(
> state <- Opaque::ffi_init(|slot| unsafe {
> B::init(slot, name.as_char_ptr(), key.as_ptr())
> }),
> - })
> + }? E)
> }
> }
>
> diff --git a/rust/kernel/sync/lock/mutex.rs b/rust/kernel/sync/lock/mutex.rs
> index cda0203efefb..35e6b02ff426 100644
> --- a/rust/kernel/sync/lock/mutex.rs
> +++ b/rust/kernel/sync/lock/mutex.rs
> @@ -35,6 +35,7 @@ macro_rules! new_mutex {
> ///
> /// ```
> /// use kernel::sync::{new_mutex, Mutex};
> +/// use kernel::prelude::*;
> ///
> /// struct Inner {
> /// a: u32,
> @@ -49,8 +50,8 @@ macro_rules! new_mutex {
> /// }
> ///
> /// impl Example {
> -/// fn new() -> impl PinInit<Self> {
> -/// pin_init!(Self {
> +/// fn new() -> impl PinInit<Self, Error> {
> +/// try_pin_init!(Self {
> /// c: 10,
> /// d <- new_mutex!(Inner { a: 20, b: 30 }),
> /// })
> @@ -58,7 +59,7 @@ macro_rules! new_mutex {
> /// }
> ///
> /// // Allocate a boxed `Example`.
> -/// let e = KBox::pin_init(Example::new(), GFP_KERNEL)?;
> +/// let e = KBox::try_pin_init(Example::new(), GFP_KERNEL)?;
> /// assert_eq!(e.c, 10);
> /// assert_eq!(e.d.lock().a, 20);
> /// assert_eq!(e.d.lock().b, 30);
> diff --git a/rust/kernel/sync/lock/spinlock.rs b/rust/kernel/sync/lock/spinlock.rs
> index aafc80125f59..8ea2c5b202e6 100644
> --- a/rust/kernel/sync/lock/spinlock.rs
> +++ b/rust/kernel/sync/lock/spinlock.rs
> @@ -4,10 +4,7 @@
> //!
> //! This module allows Rust code to use the kernel's `spinlock_t`.
> use super::*;
> -use crate::{
> - interrupt::LocalInterruptDisabled,
> - prelude::*, //
> -};
> +use crate::interrupt::LocalInterruptDisabled;
>
> /// Creates a [`SpinLock`] initialiser with the given name and a newly-created lock class.
> ///
> @@ -38,6 +35,7 @@ macro_rules! new_spinlock {
> ///
> /// ```
> /// use kernel::sync::{new_spinlock, SpinLock};
> +/// use kernel::prelude::*;
Doctests have prelude imported by default.
Best,
Gary
> ///
> /// struct Inner {
> /// a: u32,
> @@ -52,8 +50,8 @@ macro_rules! new_spinlock {
> /// }
> ///
> /// impl Example {
> -/// fn new() -> impl PinInit<Self> {
> -/// pin_init!(Self {
> +/// fn new() -> impl PinInit<Self, Error> {
> +/// try_pin_init!(Self {
> /// c: 10,
> /// d <- new_spinlock!(Inner { a: 20, b: 30 }),
> /// })
> @@ -184,6 +182,7 @@ macro_rules! new_spinlock_irq {
> ///
> /// ```
> /// use kernel::sync::{new_spinlock_irq, SpinLockIrq};
> +/// use kernel::prelude::*;
> ///
> /// struct Inner {
> /// a: u32,
> @@ -199,8 +198,8 @@ macro_rules! new_spinlock_irq {
> /// }
> ///
> /// impl Example {
> -/// fn new() -> impl PinInit<Self> {
> -/// pin_init!(Self {
> +/// fn new() -> impl PinInit<Self, Error> {
> +/// try_pin_init!(Self {
> /// c <- new_spinlock_irq!(Inner { a: 0, b: 10 }),
> /// d <- new_spinlock_irq!(Inner { a: 20, b: 30 }),
> /// })
> @@ -232,6 +231,7 @@ macro_rules! new_spinlock_irq {
> /// ```
> /// use kernel::sync::{new_spinlock_irq, SpinLockIrq};
> /// use kernel::interrupt::*;
> +/// use kernel::prelude::*;
> ///
> /// struct Inner {
> /// a: u32,
> @@ -244,8 +244,8 @@ macro_rules! new_spinlock_irq {
> /// }
> ///
> /// impl Example {
> -/// fn new() -> impl PinInit<Self> {
> -/// pin_init!(Self {
> +/// fn new() -> impl PinInit<Self, Error> {
> +/// try_pin_init!(Self {
> /// inner <- new_spinlock_irq!(Inner { a: 20 }),
> /// })
> /// }
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-09-24 10:41 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-24 8:55 [PATCH] rust: sync: Accept errors for Lock payload data Philipp Stanner
2026-09-24 10:41 ` Gary Guo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®