rust-for-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Onur Özkan" <work@onurozkan.dev>
To: rust-for-linux@vger.kernel.org
Cc: "Onur Özkan" <work@onurozkan.dev>,
	lossin@kernel.org, lyude@redhat.com, ojeda@kernel.org,
	alex.gaynor@gmail.com, boqun.feng@gmail.com, gary@garyguo.net,
	a.hindborg@kernel.org, aliceryhl@google.com, tmgross@umich.edu,
	dakr@kernel.org, peterz@infradead.org, mingo@redhat.com,
	will@kernel.org, longman@redhat.com, felipe_life@live.com,
	daniel@sedlak.dev, daniel.almeida@collabora.com,
	thomas.hellstrom@linux.intel.com, linux-kernel@vger.kernel.org
Subject: [PATCH v12 0/6] rust: add ww_mutex support
Date: Mon, 12 Oct 2026 13:26:27 +0300	[thread overview]
Message-ID: <cover.1791799751.git.work@onurozkan.dev> (raw)

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


             reply	other threads:[~2026-10-12 10:27 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-12 10:26 Onur Özkan [this message]
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

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=cover.1791799751.git.work@onurozkan.dev \
    --to=work@onurozkan.dev \
    --cc=a.hindborg@kernel.org \
    --cc=alex.gaynor@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=boqun.feng@gmail.com \
    --cc=dakr@kernel.org \
    --cc=daniel.almeida@collabora.com \
    --cc=daniel@sedlak.dev \
    --cc=felipe_life@live.com \
    --cc=gary@garyguo.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=longman@redhat.com \
    --cc=lossin@kernel.org \
    --cc=lyude@redhat.com \
    --cc=mingo@redhat.com \
    --cc=ojeda@kernel.org \
    --cc=peterz@infradead.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=thomas.hellstrom@linux.intel.com \
    --cc=tmgross@umich.edu \
    --cc=will@kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).