The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: lyude@redhat.com
To: "Gary Guo" <gary@garyguo.net>, "Boqun Feng" <boqun@kernel.org>,
	"Alice Ryhl" <aliceryhl@google.com>,
	"Daniel Almeida" <daniel.almeida@collabora.com>,
	"Onur Özkan" <work@onurozkan.dev>,
	"Miguel Ojeda" <ojeda@kernel.org>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Benno Lossin" <lossin@kernel.org>,
	"Andreas Hindborg" <a.hindborg@kernel.org>,
	"Trevor Gross" <tmgross@umich.edu>,
	"Danilo Krummrich" <dakr@kernel.org>,
	"Tamir Duberstein" <tamird@kernel.org>,
	"Alexandre Courbot" <acourbot@nvidia.com>,
	"Peter Zijlstra" <peterz@infradead.org>,
	"Ingo Molnar" <mingo@redhat.com>, "Will Deacon" <will@kernel.org>,
	"Waiman Long" <longman@redhat.com>
Cc: linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org
Subject: Re: [PATCH RFC 2/2] lockdep: delegate Rust lock class printing to Rust code
Date: Tue, 07 Jul 2026 17:24:59 -0400	[thread overview]
Message-ID: <be7651a76f2932b8781b05fc72dfb60c4e779732.camel@redhat.com> (raw)
In-Reply-To: <20260703-rust_lockdep-v1-2-1c21c62d0341@garyguo.net>

This looks great, one comment below:

On Fri, 2026-07-03 at 14:47 +0100, Gary Guo wrote:
> Add a special "(rust)" name which means that the lock class comes
> from Rust
> `#[track_caller]` and thus should be delegated to Rust code to print
> the
> name.
> 
> This allows locks to be created with usual constructor syntax and
> does not
> need macros anymore.
> 
> Signed-off-by: Gary Guo <gary@garyguo.net>
> ---
>  kernel/locking/lockdep.c           |  7 ++++++-
>  kernel/locking/lockdep_internals.h |  3 +++
>  rust/kernel/sync.rs                | 24 ++++++++++++++++++++++++
>  rust/kernel/sync/lock.rs           |  8 ++++++++
>  rust/kernel/sync/lock/mutex.rs     |  8 ++++----
>  rust/kernel/sync/lock/spinlock.rs  |  8 ++++----
>  6 files changed, 49 insertions(+), 9 deletions(-)
> 
> diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
> index 2d4c5bab5af8..1e05d51e710f 100644
> --- a/kernel/locking/lockdep.c
> +++ b/kernel/locking/lockdep.c
> @@ -724,7 +724,12 @@ static void __print_lock_name(struct held_lock
> *hlock, struct lock_class *class)
>  		name = __get_key_name(class->key, str);
>  		printk(KERN_CONT "%s", name);
>  	} else {
> -		printk(KERN_CONT "%s", name);
> +		if (CONFIG_RUST && class->name == lockdep_rust_name)
> +			lockdep_print_rust_name((struct
> lock_class_key *)(
> +				class->key - class->subclass
> +			));
> +		else
> +			printk(KERN_CONT "%s", name);
>  		if (class->name_version > 1)
>  			printk(KERN_CONT "#%d", class-
> >name_version);
>  		if (class->subclass)
> diff --git a/kernel/locking/lockdep_internals.h
> b/kernel/locking/lockdep_internals.h
> index 0e5e6ffe91a3..d18d50f7fd99 100644
> --- a/kernel/locking/lockdep_internals.h
> +++ b/kernel/locking/lockdep_internals.h
> @@ -134,6 +134,9 @@ extern void get_usage_chars(struct lock_class
> *class,
>  extern const char *__get_key_name(const struct lockdep_subclass_key
> *key,
>  				  char *str);
>  
> +extern const char lockdep_rust_name[];
> +extern void lockdep_print_rust_name(struct lock_class_key *key);
> +
>  struct lock_class *lock_chain_get_class(struct lock_chain *chain,
> int i);
>  
>  extern unsigned long nr_lock_classes;
> diff --git a/rust/kernel/sync.rs b/rust/kernel/sync.rs
> index cf76fb37c460..cf35858469d1 100644
> --- a/rust/kernel/sync.rs
> +++ b/rust/kernel/sync.rs
> @@ -8,6 +8,7 @@
>  use core::panic::Location;
>  
>  use crate::{
> +    pr_cont,
>      prelude::*,
>      types::Opaque, //
>  };
> @@ -150,6 +151,29 @@ fn drop(self: Pin<&mut Self>) {
>      }
>  }
>  
> +// We want this to be completely unique so lockdep can identify when
> lock classes are generated with
> +// `new_static` mechanism, hence making this `static` and attach a
> `link_section` so it cannot be
> +// merged with other constants.
> +#[export_name = "lockdep_rust_name"]
> +#[link_section = ".rodata"]
> +static LOCKDEP_RUST_NAME_BYTES: [u8; 7] = *b"(rust)\0";
> +
> +// This should only be used in conjunction of
> `LockClassKey::from_caller`.
> +const LOCKDEP_RUST_NAME: &CStr = match
> CStr::from_bytes_with_nul(&LOCKDEP_RUST_NAME_BYTES) {
> +    Ok(v) => v,
> +    Err(_) => unreachable!(),
> +};
> +
> +#[cfg(CONFIG_LOCKDEP)]
> +#[expect(clippy::missing_safety_doc)]
> +#[no_mangle]
> +unsafe extern "C" fn lockdep_print_rust_name(key: *mut
> bindings::lock_class_key) {
> +    // SAFETY: `rust_print_lockdep_name` is called when the lock
> name is a reserved value indicating
> +    // that the lock_class_key is static and backed by a `Location`.
> +    let location = unsafe { &*key.cast::<Location<'_>>() };
> +    pr_cont!("{}:{}", location.file(), location.line());
> +}
> +
>  /// Defines a new static lock class and returns a pointer to it.
>  ///
>  /// # Examples
> diff --git a/rust/kernel/sync/lock.rs b/rust/kernel/sync/lock.rs
> index 447fec291cdf..66d51c860483 100644
> --- a/rust/kernel/sync/lock.rs
> +++ b/rust/kernel/sync/lock.rs
> @@ -127,6 +127,14 @@ unsafe impl<T: ?Sized + Send, B: Backend> Send
> for Lock<T, B> {}
>  unsafe impl<T: ?Sized + Send, B: Backend> Sync for Lock<T, B> {}
>  
>  impl<T, B: Backend> Lock<T, B> {
> +    /// Constructs a new lock initialiser with a custom name.

I think this rustdoc is a bit confusing: we say "with a custom name"
but this function doesn't provide any way of actually specifying a
name. Maybe this would make more sense?

"Constructs a new lock initialiser using an auto-generated name."

With that fixed:

Reviewed-by: Lyude Paul <lyude@redhat.com>

> +    #[inline]
> +    #[track_caller]
> +    pub fn new(t: impl PinInit<T>) -> impl PinInit<Self> {
> +        let key = LockClassKey::from_caller();
> +        Self::new_with_lock_class(t, super::LOCKDEP_RUST_NAME, key)
> +    }
> +
>      /// Constructs a new lock initialiser with a custom name.
>      #[inline]
>      #[track_caller]
> diff --git a/rust/kernel/sync/lock/mutex.rs
> b/rust/kernel/sync/lock/mutex.rs
> index 3675ce244e08..c730196b9d2d 100644
> --- a/rust/kernel/sync/lock/mutex.rs
> +++ b/rust/kernel/sync/lock/mutex.rs
> @@ -24,8 +24,8 @@ macro_rules! new_mutex {
>  ///
>  /// Since it may block, [`Mutex`] needs to be used with care in
> atomic contexts.
>  ///
> -/// Instances of [`Mutex`] need a lock class and to be pinned. The
> recommended way to create such
> -/// instances is with the [`pin_init`](pin_init::pin_init) and
> [`new_mutex`] macros.
> +/// Instances of [`Mutex`] need to be pinned. You can create such
> instances with the
> +/// [`pin_init`](pin_init::pin_init).
>  ///
>  /// # Examples
>  ///
> @@ -33,7 +33,7 @@ macro_rules! new_mutex {
>  /// contains an inner struct (`Inner`) that is protected by a mutex.
>  ///
>  /// ```
> -/// use kernel::sync::{new_mutex, Mutex};
> +/// use kernel::sync::Mutex;
>  ///
>  /// struct Inner {
>  ///     a: u32,
> @@ -51,7 +51,7 @@ macro_rules! new_mutex {
>  ///     fn new() -> impl PinInit<Self> {
>  ///         pin_init!(Self {
>  ///             c: 10,
> -///             d <- new_mutex!(Inner { a: 20, b: 30 }),
> +///             d <- Mutex::new(Inner { a: 20, b: 30 }),
>  ///         })
>  ///     }
>  /// }
> diff --git a/rust/kernel/sync/lock/spinlock.rs
> b/rust/kernel/sync/lock/spinlock.rs
> index 091167ceda66..f8bec26f1cee 100644
> --- a/rust/kernel/sync/lock/spinlock.rs
> +++ b/rust/kernel/sync/lock/spinlock.rs
> @@ -22,8 +22,8 @@ macro_rules! new_spinlock {
>  /// one at a time is allowed to progress, the others will block
> (spinning) until the spinlock is
>  /// unlocked, at which point another CPU will be allowed to make
> progress.
>  ///
> -/// Instances of [`SpinLock`] need a lock class and to be pinned.
> The recommended way to create such
> -/// instances is with the [`pin_init`](pin_init::pin_init) and
> [`new_spinlock`] macros.
> +/// Instances of [`SpinLock`] need to be pinned. You can create such
> instances with the
> +/// [`pin_init`](pin_init::pin_init).
>  ///
>  /// # Examples
>  ///
> @@ -31,7 +31,7 @@ macro_rules! new_spinlock {
>  /// contains an inner struct (`Inner`) that is protected by a
> spinlock.
>  ///
>  /// ```
> -/// use kernel::sync::{new_spinlock, SpinLock};
> +/// use kernel::sync::SpinLock;
>  ///
>  /// struct Inner {
>  ///     a: u32,
> @@ -49,7 +49,7 @@ macro_rules! new_spinlock {
>  ///     fn new() -> impl PinInit<Self> {
>  ///         pin_init!(Self {
>  ///             c: 10,
> -///             d <- new_spinlock!(Inner { a: 20, b: 30 }),
> +///             d <- SpinLock::new(Inner { a: 20, b: 30 }),
>  ///         })
>  ///     }
>  /// }


  reply	other threads:[~2026-07-07 21:25 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-03 13:47 [PATCH RFC 0/2] rust: sync: create lock class using `#[track_caller]` Gary Guo
2026-07-03 13:47 ` [PATCH RFC 1/2] rust: sync: introduce a way to create lock class from caller Gary Guo
2026-07-07 21:25   ` lyude
2026-07-03 13:47 ` [PATCH RFC 2/2] lockdep: delegate Rust lock class printing to Rust code Gary Guo
2026-07-07 21:24   ` lyude [this message]
2026-07-03 14:01 ` [PATCH RFC 0/2] rust: sync: create lock class using `#[track_caller]` Peter Zijlstra
2026-07-03 14:24   ` Gary Guo
2026-07-03 22:32     ` Peter Zijlstra
2026-07-04 16:52       ` Gary Guo
2026-07-04 17:10         ` Peter Zijlstra
2026-07-04 17:46           ` Gary Guo
2026-07-07 21:05             ` lyude

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=be7651a76f2932b8781b05fc72dfb60c4e779732.camel@redhat.com \
    --to=lyude@redhat.com \
    --cc=a.hindborg@kernel.org \
    --cc=acourbot@nvidia.com \
    --cc=aliceryhl@google.com \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun@kernel.org \
    --cc=dakr@kernel.org \
    --cc=daniel.almeida@collabora.com \
    --cc=gary@garyguo.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=longman@redhat.com \
    --cc=lossin@kernel.org \
    --cc=mingo@redhat.com \
    --cc=ojeda@kernel.org \
    --cc=peterz@infradead.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=tamird@kernel.org \
    --cc=tmgross@umich.edu \
    --cc=will@kernel.org \
    --cc=work@onurozkan.dev \
    /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