Begone, lock classes! As discussed in meetings/etc, we would really like to support implicit lock class creation for Rust code. Right now, lock classes are created using macros and passed around (similar to C). Unfortunately, Rust macros don't look like Rust functions, which means adding lockdep to a type is a breaking API change. This makes Rust mutex creation rather ugly, with the new_mutex!() macro and friends. Implicit lock classes have to be unique per instantiation code site. Notably, with Rust generics and monomorphization, this is not the same as unique per generated code instance. If this weren't the case, we could use inline functions and asm!() magic to try to create lock classes that have the right uniqueness semantics. But that doesn't work, since it would create too many lock classes for the same actual lock creation in the source code. But Rust does have one trick we can use: it can track the caller location (as file:line:column), across multiple functions. This works using an implicit argument that gets passed around, which is exactly the thing we do for lock classes. The tricky bit is that, while the value of these Location objects has the semantics we want (unique value per source code location), there is no guarantee that they are deduplicated in memory. So we use a hash table, and map Location values to lock classes. Et voila, implicit lock class support! This lets us clean up the Mutex & co APIs and make them look a lot more Rust-like, but it also means we can now throw Lockdep into more APIs without breaking the API. And so we can pull a neat trick: adding Lockdep support into Arc<T>. This catches cases where the Arc Drop implementation could create a locking correctness violation only when the reference count drops to 0 at that particular drop site, which is otherwise not detectable unless that condition actually happens at runtime. Since Drop is "magic" in Rust and Drop codepaths very difficult to audit, this helps a lot. For the initial RFC, this implements the new API only for Mutex. If this looks good, I can extend it to CondVar & friends in the next version. This series also folds in a few related minor dependencies / changes (like the pin_init mutex stuff). Signed-off-by: Asahi Lina <lina@xxxxxxxxxxxxx> --- Asahi Lina (11): rust: types: Add Opaque::zeroed() rust: lock: Add Lock::pin_init() rust: Use absolute paths to build Rust objects rust: siphash: Add a simple siphash abstraction rust: sync: Add dummy LockClassKey implementation for !CONFIG_LOCKDEP rust: sync: Replace static LockClassKey refs with a pointer wrapper rust: sync: Implement dynamic lockdep class creation rust: sync: Classless Lock::new() and pin_init() rust: init: Update documentation for new mutex init style rust: sync: Add LockdepMap abstraction rust: sync: arc: Add lockdep integration lib/Kconfig.debug | 8 ++ rust/Makefile | 2 +- rust/bindings/bindings_helper.h | 2 + rust/helpers.c | 24 ++++ rust/kernel/init.rs | 22 ++-- rust/kernel/lib.rs | 1 + rust/kernel/siphash.rs | 39 +++++++ rust/kernel/sync.rs | 33 ++---- rust/kernel/sync/arc.rs | 71 +++++++++++- rust/kernel/sync/condvar.rs | 2 +- rust/kernel/sync/lock.rs | 68 ++++++++++- rust/kernel/sync/lock/mutex.rs | 15 ++- rust/kernel/sync/lock/spinlock.rs | 2 +- rust/kernel/sync/lockdep.rs | 229 ++++++++++++++++++++++++++++++++++++++ rust/kernel/sync/no_lockdep.rs | 38 +++++++ rust/kernel/types.rs | 7 +- scripts/Makefile.build | 8 +- 17 files changed, 525 insertions(+), 46 deletions(-) --- base-commit: 7eb28ae62e16abc207c90064ad2b824c19566fe2 change-id: 20230714-classless_lockdep-f1d5972fb4ba Thank you, ~~ Lina