Re: [PATCH RFC 0/2] rust: sync: create lock class using `#[track_caller]`
From: Gary Guo
Date: Sat Jul 04 2026 - 12:53:00 EST
On Fri Jul 3, 2026 at 11:32 PM BST, Peter Zijlstra wrote:
> On Fri, Jul 03, 2026 at 03:24:29PM +0100, Gary Guo wrote:
>> [snip] On the lockdep side,
>> essentially the name will be "(rust)", while the actual name can be retrieved
>> from the lock class key.
>>
>> So for
>>
>> let foo = KBox::pin_init(Mutex::new(42));
>>
>> in, say, foo.c:123
>>
>> it will eventually call
>>
>> struct rust_location *loc = /* static generated by the Rust compiler */;
>> mutex_init_lockdep(foo, "(rust)", (struct lock_class_key *)loc)
>>
>> And when "(rust)" is encountered as lock class name, instead of printing the
>> string as is, lockdep will call
>>
>> lockdep_print_rust_name(loc)
>>
>> which will be doing essentially
>>
>> pr_cont("foo.c:123");
>
> That seems quite terrible. The C names are based on the expression used
> to initialize the class and are thus somewhat descriptive. But file:line
> combos are horrid identifiers for locks.
>
> Why would you want to do this?
I do think this is not ideal, however the current code is already doing this.
This RFC series isn't changing the name at all, just represent this in a
different way.
The reason that file:line is used for names is due to the fundamental difference
between initialization in C and Rust. In C you create something uninitialized
first, and then initialize it, and it'll be UB if the value is used before
initialization or (for some types) initialize a value twice. In Rust we use
pin_init to ensure that a value cannot be used uninitialized.
The way the syntax is write out currently is something like
pin_init!(MyStruct {
my_mutex <- new_mutex!(initial_data),
})
[
which this series is turning it to
pin_init!(MyStruct {
my_mutex <- Mutex::new(initial_data),
})
]
as you can see the `new_mutex!` or `Mutx::new` does not know where it is going
to be initialized to, because we prevent people from being able to name a
yet-to-be-initialized place.
It is possible to use the C approach (which early days of Rust-for-Linux does
use), but doing so require a lot of unsafe keywords because you are relying on
the programmer to not mess things up, instead of having the compiler check.
So the best alternative that we can use for the name under this constraint is
the file:line combo. It is less descriptive, but at least it does tell you where
the lock class is used, so you can still trace it back. Given lockdep is a
debugging feature, I think the less descriptive name, albeit inconvenient, is
not a dealbreaker.
The trade off here is the convenience of creating a lock (safely) vs the
descriptiveness of the name, and I think the former is more important. It is
still possible to explicit give a name if it helps (Binder is actually doing
this already), but this currently cannot be implicitly created.
Best,
Gary