mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v12 0/6] rust: add ww_mutex support
@ 2026-10-12 10:26 Onur Özkan
  2026-10-12 10:26 ` [PATCH v12 1/6] rust: add C wrappers for ww_mutex inline functions Onur Özkan
                   ` (5 more replies)
  0 siblings, 6 replies; 13+ messages in thread
From: Onur Özkan @ 2026-10-12 10:26 UTC (permalink / raw)
  To: rust-for-linux
  Cc: Onur Özkan, lossin, lyude, ojeda, alex.gaynor, boqun.feng,
	gary, a.hindborg, aliceryhl, tmgross, dakr, peterz, mingo, will,
	longman, felipe_life, daniel, daniel.almeida, thomas.hellstrom,
	linux-kernel

This series adds Rust abstractions for ww_mutex, including Class, Mutex,
AcquireCtx and MutexGuard. LockSet handles deadlock recovery for callers
that need to acquire multiple locks.

Changes in v12 (sashiko fixes):
  - Give Rust-defined classes separate _acquire and _mutex lockdep names
    to match the C initializer.
  - Correct the Class Sync safety comment and add an invariant comment
    when constructing MutexGuard.
  - Add #[inline] to Class::from_raw(), Mutex::is_locked(),
    AcquireCtx::done(), MutexGuard::drop() and RawGuard::drop().

Built x86_64 kernels with and without PREEMPT_RT. rustfmtcheck, Clippy and
rustdoc passed. All 14 ww_mutex/LockSet KUnit tests passed on both builds
with CONFIG_PROVE_LOCKING and CONFIG_DEBUG_WW_MUTEX_SLOWPATH enabled.

Previous version:
https://lore.kernel.org/all/cover.1791743500.git.work@onurozkan.dev/

Onur Özkan (6):
  rust: add C wrappers for ww_mutex inline functions
  ww_mutex: add ww_class field unconditionally
  rust: implement Class for ww_class support
  rust: ww_mutex: add Mutex, AcquireCtx and MutexGuard
  rust: ww_mutex: implement LockSet
  MAINTAINERS: add Onur Özkan as WW MUTEX maintainer

 MAINTAINERS                                   |   2 +
 include/linux/ww_mutex.h                      |   8 +-
 rust/helpers/helpers.c                        |   1 +
 rust/helpers/ww_mutex.c                       |  33 ++
 rust/kernel/sync/lock.rs                      |   1 +
 rust/kernel/sync/lock/ww_mutex.rs             | 447 +++++++++++++++++
 rust/kernel/sync/lock/ww_mutex/acquire_ctx.rs | 149 ++++++
 rust/kernel/sync/lock/ww_mutex/class.rs       | 151 ++++++
 rust/kernel/sync/lock/ww_mutex/lock_set.rs    | 449 ++++++++++++++++++
 9 files changed, 1235 insertions(+), 6 deletions(-)
 create mode 100644 rust/helpers/ww_mutex.c
 create mode 100644 rust/kernel/sync/lock/ww_mutex.rs
 create mode 100644 rust/kernel/sync/lock/ww_mutex/acquire_ctx.rs
 create mode 100644 rust/kernel/sync/lock/ww_mutex/class.rs
 create mode 100644 rust/kernel/sync/lock/ww_mutex/lock_set.rs

Range-diff against v11:
1:  4942155a8873e = 1:  4942155a8873e rust: add C wrappers for ww_mutex inline functions
2:  168394bb52a6c = 2:  168394bb52a6c ww_mutex: add ww_class field unconditionally
3:  003bc88697dc8 ! 3:  ba8ea8e2e2b50 rust: implement Class for ww_class support
    @@ rust/kernel/sync/lock/ww_mutex/class.rs (new)
     +            // SAFETY: This is `static`, so address is fixed and won't move.
     +            unsafe {
     +                $crate::sync::lock::ww_mutex::Class::new_unpinned(
    -+                    $crate::c_str!(::core::stringify!($name)),
    ++                    $crate::c_str!(::core::concat!(::core::stringify!($name), "_acquire")),
    ++                    $crate::c_str!(::core::concat!(::core::stringify!($name), "_mutex")),
     +                    false,
     +                )
     +            };
    @@ rust/kernel/sync/lock/ww_mutex/class.rs (new)
     +            // SAFETY: This is `static`, so address is fixed and won't move.
     +            unsafe {
     +                $crate::sync::lock::ww_mutex::Class::new_unpinned(
    -+                    $crate::c_str!(::core::stringify!($name)),
    ++                    $crate::c_str!(::core::concat!(::core::stringify!($name), "_acquire")),
    ++                    $crate::c_str!(::core::concat!(::core::stringify!($name), "_mutex")),
     +                    true,
     +                )
     +            };
    @@ rust/kernel/sync/lock/ww_mutex/class.rs (new)
     +    ///
     +    /// Caller must guarantee that the returned value must be pinned before
     +    /// its first use.
    -+    pub const unsafe fn new_unpinned(name: &'static CStr, is_wait_die: bool) -> Self {
    ++    pub const unsafe fn new_unpinned(
    ++        acquire_name: &'static CStr,
    ++        mutex_name: &'static CStr,
    ++        is_wait_die: bool,
    ++    ) -> Self {
     +        Class {
     +            inner: Opaque::new(bindings::ww_class {
     +                stamp: bindings::atomic_long_t { counter: 0 },
    -+                acquire_name: crate::str::as_char_ptr_in_const_context(name),
    -+                mutex_name: crate::str::as_char_ptr_in_const_context(name),
    ++                acquire_name: crate::str::as_char_ptr_in_const_context(acquire_name),
    ++                mutex_name: crate::str::as_char_ptr_in_const_context(mutex_name),
     +                is_wait_die: is_wait_die as u32,
     +                // TODO: Replace with `bindings::lock_class_key::default()` once
     +                // stabilized for `const`.
    @@ rust/kernel/sync/lock/ww_mutex/class.rs (new)
     +    ///
     +    /// The caller must ensure that `ptr` points to the `inner` field of
     +    /// [`Class`] and that it remains valid for the lifetime `'a`.
    ++    #[inline]
     +    pub const unsafe fn from_raw<'a>(ptr: *mut bindings::ww_class) -> &'a Self {
     +        // SAFETY: By the safety contract, `ptr` is valid to construct `Class`.
     +        unsafe { &*ptr.cast() }
     +    }
     +}
     +
    -+// SAFETY: [`Class`] is set up once and never modified. It's fine to share it across threads.
    ++// SAFETY: [`Class`] is immutable except for its atomic stamp. It's fine to share it across threads.
     +unsafe impl Sync for Class {}
     +// SAFETY: Doesn't hold anything thread-specific. It's safe to send to other threads.
     +unsafe impl Send for Class {}
4:  293fbbc0bcc0f ! 4:  36bddd73ca296 rust: ww_mutex: add Mutex, AcquireCtx and MutexGuard
    @@ rust/kernel/sync/lock/ww_mutex.rs
     +    ///
     +    /// The returned value is racy as another thread can acquire
     +    /// or release the lock immediately after this call returns.
    ++    #[inline]
     +    pub fn is_locked(&self) -> bool {
     +        // SAFETY: It's safe to call `ww_mutex_is_locked` on
     +        // a valid mutex.
    @@ rust/kernel/sync/lock/ww_mutex.rs
     +    fn new(mutex: &'a Mutex<'a, T>) -> Self {
     +        assert!(mutex.is_locked());
     +
    ++        // INVARIANT: `lock_common` and `from_raw` ensure that the current task holds the mutex
    ++        // and transfer sole responsibility for unlocking it to this guard.
     +        Self {
     +            mutex,
     +            _not_send: NotThreadSafe,
    @@ rust/kernel/sync/lock/ww_mutex.rs
     +}
     +
     +impl<T: ?Sized> Drop for MutexGuard<'_, T> {
    ++    #[inline]
     +    fn drop(&mut self) {
     +        // SAFETY: self.mutex is locked and are about to release it.
     +        unsafe { bindings::ww_mutex_unlock(self.mutex.inner.get()) };
    @@ rust/kernel/sync/lock/ww_mutex/acquire_ctx.rs (new)
     +    ///
     +    /// After calling this function, no more mutexes can be acquired with
     +    /// this context.
    ++    #[inline]
     +    pub fn done(&self) {
     +        // SAFETY: `self.inner` contains a valid, initialized acquire context.
     +        unsafe { bindings::ww_acquire_done(self.inner.get()) };
5:  d085c15ba9da4 ! 5:  8a3e94391fcee rust: ww_mutex: implement LockSet
    @@ rust/kernel/sync/lock/ww_mutex/lock_set.rs (new)
     +}
     +
     +impl Drop for RawGuard {
    ++    #[inline]
     +    fn drop(&mut self) {
     +        // SAFETY: `mutex_ptr` originates from a locked `Mutex` and remains
     +        // valid for the lifetime of this guard, so unlocking here is sound.
6:  8f0e93bd1781e = 6:  2b7b779f72f77 MAINTAINERS: add Onur Özkan as WW MUTEX maintainer

base-commit: 47324d3a5b3abd781295044d01d92d09f184e872
-- 
2.51.2


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

end of thread, other threads:[~2026-10-12 12:02 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-12 10:26 [PATCH v12 0/6] rust: add ww_mutex support Onur Özkan
2026-10-12 10:26 ` [PATCH v12 1/6] rust: add C wrappers for ww_mutex inline functions Onur Özkan
2026-10-12 11:41   ` Gary Guo
2026-10-12 10:26 ` [PATCH v12 2/6] ww_mutex: add ww_class field unconditionally Onur Özkan
2026-10-12 11:42   ` Gary Guo
2026-10-12 10:26 ` [PATCH v12 3/6] rust: implement Class for ww_class support Onur Özkan
2026-10-12 11:03   ` Gary Guo
2026-10-12 11:26     ` Onur Özkan
2026-10-12 10:26 ` [PATCH v12 4/6] rust: ww_mutex: add Mutex, AcquireCtx and MutexGuard Onur Özkan
2026-10-12 11:40   ` Gary Guo
2026-10-12 10:26 ` [PATCH v12 5/6] rust: ww_mutex: implement LockSet Onur Özkan
2026-10-12 12:02   ` Gary Guo
2026-10-12 10:26 ` [PATCH v12 6/6] MAINTAINERS: add Onur Özkan as WW MUTEX maintainer Onur Özkan

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®