From: Boqun Feng <boqun.feng@gmail.com>
To: Alice Ryhl <aliceryhl@google.com>
Cc: lina@asahilina.net, alex.gaynor@gmail.com, alyssa@rosenzweig.io,
asahi@lists.linux.dev, benno.lossin@proton.me,
bjorn3_gh@protonmail.com, daniel@ffwll.ch, gary@garyguo.net,
linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org,
llvm@lists.linux.dev, marcan@marcan.st, masahiroy@kernel.org,
nathan@kernel.org, ndesaulniers@google.com, nicolas@fjasle.eu,
ojeda@kernel.org, rust-for-linux@vger.kernel.org,
sven@svenpeter.dev, trix@redhat.com, wedsonaf@gmail.com
Subject: Re: [PATCH RFC 00/11] rust: Implicit lock class creation & Arc Lockdep integration
Date: Fri, 14 Jul 2023 08:21:05 -0700 [thread overview]
Message-ID: <ZLFn4RPiK3ig9I5M@Boquns-Mac-mini.home> (raw)
In-Reply-To: <20230714135926.382695-1-aliceryhl@google.com>
On Fri, Jul 14, 2023 at 01:59:26PM +0000, Alice Ryhl wrote:
> Asahi Lina <lina@asahilina.net> writes:
> > On 14/07/2023 19.13, Alice Ryhl wrote:
> > > Asahi Lina <lina@asahilina.net> writes:
> > >> 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
Thanks for looking into this! Could you also copy locking maintainers in
the next version?
> > >> 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).
> > >
> > > I'm not convinced that this is the right compromise. Moving lockdep
> > > class creation to runtime sounds unfortunate, especially since this
> > > makes them fallible due to memory allocations (I think?).
> > >
> > > I would be inclined to keep using macros for this.
> >
> > Most people were very enthusiastic about this change in the meetings...
> > it wasn't even my own idea ^^
>
> I don't think I was in that meeting. Anyway,
>
> > I don't think the fallibility is an issue. Lockdep is a debugging tool,
> > and it doesn't have to handle all possible circumstances perfectly. If
> > you are debugging normal lock issues you probably shouldn't be running
> > out of RAM, and if you are debugging OOM situations the lock keys would
> > normally have been created long before you reach an OOM situation, since
> > they would be created the first time a relevant lock class is used. More
> > objects of the same class don't cause any more allocations. And the code
> > has a fallback for the OOM case, where it just uses the Location object
> > as a static lock class. That's not ideal and degrades the quality of the
> > lockdep results, but it shouldn't completely break anything.
>
> If you have a fallback when the allocation fails, that helps ...
>
> You say that Location objects are not necessarily unique per file
> location. In practice, how often are they not unique? Always just using
> the Location object as a static lock class seems like it would
> significantly simplify this proposal.
>
Agreed. For example, `caller_lock_class_inner` has a Mutex critical
section in it (for the hash table synchronization), that makes it
impossible to be called in preemption disabled contexts, which limits
the usage.
Regards,
Boqun
> > The advantages of being able to throw lockdep checking into arbitrary
> > types, like the Arc<T> thing, are pretty significant. It closes a major
> > correctness checking issue we have with Rust and its automagic Drop
> > implementations that are almost impossible to properly audit for
> > potential locking issues. I think that alone makes this worth it, even
> > if you don't use it for normal mutex creation...
>
> I do agree that there is value in being able to more easily detect
> potential deadlocks involving destructors of ref-counted values. I once
> had a case of that myself, though lockdep was able to catch it without
> this change because it saw the refcount hit zero in the right place.
>
> Alice
>
next prev parent reply other threads:[~2023-07-14 15:21 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-14 9:13 [PATCH RFC 00/11] rust: Implicit lock class creation & Arc Lockdep integration Asahi Lina
2023-07-14 9:13 ` [PATCH RFC 01/11] rust: types: Add Opaque::zeroed() Asahi Lina
2023-07-14 10:15 ` Alice Ryhl
2023-07-15 14:27 ` Gary Guo
2023-07-14 9:13 ` [PATCH RFC 02/11] rust: lock: Add Lock::pin_init() Asahi Lina
2023-07-15 14:29 ` Gary Guo
2023-07-14 9:13 ` [PATCH RFC 03/11] rust: Use absolute paths to build Rust objects Asahi Lina
2023-07-15 14:35 ` Gary Guo
2023-07-16 7:53 ` Asahi Lina
2023-07-14 9:13 ` [PATCH RFC 04/11] rust: siphash: Add a simple siphash abstraction Asahi Lina
2023-07-14 14:28 ` Martin Rodriguez Reboredo
2023-07-15 14:52 ` Gary Guo
2023-07-14 9:13 ` [PATCH RFC 05/11] rust: sync: Add dummy LockClassKey implementation for !CONFIG_LOCKDEP Asahi Lina
2023-07-14 14:57 ` Martin Rodriguez Reboredo
2023-07-14 9:13 ` [PATCH RFC 06/11] rust: sync: Replace static LockClassKey refs with a pointer wrapper Asahi Lina
2023-07-14 15:10 ` Martin Rodriguez Reboredo
2023-07-14 9:13 ` [PATCH RFC 07/11] rust: sync: Implement dynamic lockdep class creation Asahi Lina
2023-07-14 19:56 ` Martin Rodriguez Reboredo
2023-07-15 15:47 ` Gary Guo
2023-07-14 9:14 ` [PATCH RFC 08/11] rust: sync: Classless Lock::new() and pin_init() Asahi Lina
2023-07-14 9:14 ` [PATCH RFC 09/11] rust: init: Update documentation for new mutex init style Asahi Lina
2023-07-14 9:14 ` [PATCH RFC 10/11] rust: sync: Add LockdepMap abstraction Asahi Lina
2023-07-14 9:14 ` [PATCH RFC 11/11] rust: sync: arc: Add lockdep integration Asahi Lina
2023-07-15 16:00 ` Gary Guo
2023-07-14 10:13 ` [PATCH RFC 00/11] rust: Implicit lock class creation & Arc Lockdep integration Alice Ryhl
2023-07-14 12:20 ` Asahi Lina
2023-07-14 13:59 ` Alice Ryhl
2023-07-14 15:21 ` Boqun Feng [this message]
2023-07-16 6:56 ` Asahi Lina
2023-07-15 14:25 ` Gary Guo
2023-07-18 16:48 ` Boqun Feng
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=ZLFn4RPiK3ig9I5M@Boquns-Mac-mini.home \
--to=boqun.feng@gmail.com \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=alyssa@rosenzweig.io \
--cc=asahi@lists.linux.dev \
--cc=benno.lossin@proton.me \
--cc=bjorn3_gh@protonmail.com \
--cc=daniel@ffwll.ch \
--cc=gary@garyguo.net \
--cc=lina@asahilina.net \
--cc=linux-kbuild@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=llvm@lists.linux.dev \
--cc=marcan@marcan.st \
--cc=masahiroy@kernel.org \
--cc=nathan@kernel.org \
--cc=ndesaulniers@google.com \
--cc=nicolas@fjasle.eu \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=sven@svenpeter.dev \
--cc=trix@redhat.com \
--cc=wedsonaf@gmail.com \
/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).