[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250730-lock-t-when-t-is-pinned-v1-3-1b97d5f28aa2@collabora.com>
Date: Wed, 30 Jul 2025 14:14:46 -0300
From: Daniel Almeida <daniel.almeida@...labora.com>
To: Peter Zijlstra <peterz@...radead.org>, Ingo Molnar <mingo@...hat.com>,
Will Deacon <will@...nel.org>, Boqun Feng <boqun.feng@...il.com>,
Waiman Long <longman@...hat.com>, Miguel Ojeda <ojeda@...nel.org>,
Alex Gaynor <alex.gaynor@...il.com>, Gary Guo <gary@...yguo.net>,
Björn Roy Baron <bjorn3_gh@...tonmail.com>,
Benno Lossin <lossin@...nel.org>, Andreas Hindborg <a.hindborg@...nel.org>,
Alice Ryhl <aliceryhl@...gle.com>, Trevor Gross <tmgross@...ch.edu>,
Danilo Krummrich <dakr@...nel.org>
Cc: linux-kernel@...r.kernel.org, rust-for-linux@...r.kernel.org,
Daniel Almeida <daniel.almeida@...labora.com>
Subject: [PATCH 3/3] rust: lock: add a Pin<&mut T> accessor
In order for callers to be able to access the inner T safely if T: !Unpin,
there needs to be a way to get a Pin<&mut T>. Add this accessor and a
corresponding example to tell users how it works.
This is not useful on its own for now, because we do not support pin
projections yet. This means that the following is not going to compile:
let mut data: MutexGuard<'_, Data> = mutex.lock();
let mut data: Pin<&mut Data> = data.as_mut();
let foo = &mut data.foo;
A future patch can enable the behavior above by implementing support for
pin projections.
Link: https://github.com/Rust-for-Linux/linux/issues/1181
Suggested-by: Benno Lossin <lossin@...nel.org>
Suggested-by: Boqun Feng <boqun.feng@...il.com>
Signed-off-by: Daniel Almeida <daniel.almeida@...labora.com>
---
rust/kernel/sync/lock.rs | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/rust/kernel/sync/lock.rs b/rust/kernel/sync/lock.rs
index 087bc0391f92a73b9af18ca31461b513bb5a9bcd..27857659a7f1ba4a8b844bb18d009d037e0c5b03 100644
--- a/rust/kernel/sync/lock.rs
+++ b/rust/kernel/sync/lock.rs
@@ -243,6 +243,25 @@ pub(crate) fn do_unlocked<U>(&mut self, cb: impl FnOnce() -> U) -> U {
cb()
}
+
+ /// Returns a pinned mutable reference to the protected data.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use kernel::sync::{Mutex, MutexGuard};
+ /// # use core::pin::Pin;
+ /// struct Data;
+ ///
+ /// fn example(mutex: &Mutex<Data>) {
+ /// let mut data: MutexGuard<'_, Data> = mutex.lock();
+ /// let mut data: Pin<&mut Data> = data.as_mut();
+ /// }
+ /// ```
+ pub fn as_mut(&mut self) -> Pin<&mut T> {
+ // SAFETY: `self.lock.data` is structurally pinned.
+ unsafe { Pin::new_unchecked(&mut *self.lock.data.get()) }
+ }
}
impl<T: ?Sized, B: Backend> core::ops::Deref for Guard<'_, T, B> {
--
2.50.1
Powered by blists - more mailing lists