From: Peter Zijlstra <peterz@infradead.org>
To: Dan Williams <dan.j.williams@intel.com>
Cc: linux-cxl@vger.kernel.org, linux-kernel@vger.kernel.org,
David Lechner <dlechner@baylibre.com>,
Linus Torvalds <torvalds@linux-foundation.org>,
Ingo Molnar <mingo@kernel.org>,
"Fabio M. De Francesco"
<fabio.maria.de.francesco@linux.intel.com>,
Davidlohr Bueso <dave@stgolabs.net>,
Jonathan Cameron <jonathan.cameron@huawei.com>,
Dave Jiang <dave.jiang@intel.com>,
Alison Schofield <alison.schofield@intel.com>,
Vishal Verma <vishal.l.verma@intel.com>,
Ira Weiny <ira.weiny@intel.com>
Subject: Re: [PATCH 1/7] cleanup: Introduce DEFINE_ACQUIRE() a CLASS() for conditional locking
Date: Thu, 8 May 2025 13:00:43 +0200 [thread overview]
Message-ID: <20250508110043.GG4439@noisy.programming.kicks-ass.net> (raw)
In-Reply-To: <681bce2193f38_1229d6294c7@dwillia2-xfh.jf.intel.com.notmuch>
On Wed, May 07, 2025 at 02:18:25PM -0700, Dan Williams wrote:
> Peter Zijlstra wrote:
> [..]
> > > @@ -202,6 +204,28 @@ DEFINE_GUARD(mutex, struct mutex *, mutex_lock(_T), mutex_unlock(_T))
> > > DEFINE_GUARD_COND(mutex, _try, mutex_trylock(_T))
> > > DEFINE_GUARD_COND(mutex, _intr, mutex_lock_interruptible(_T) == 0)
> > >
> > > +/* mutex type that only implements scope-based unlock */
> > > +struct mutex_acquire {
> > > + /* private: */
> > > + struct mutex mutex;
> > > +};
> > > +DEFINE_GUARD(mutex_acquire, struct mutex_acquire *, mutex_lock(&_T->mutex),
> > > + mutex_unlock(&_T->mutex))
> > > +DEFINE_GUARD_COND(mutex_acquire, _try, mutex_trylock(&_T->mutex))
> > > +DEFINE_GUARD_COND(mutex_acquire, _intr, mutex_lock_interruptible(&_T->mutex) == 0)
> > > +DEFINE_ACQUIRE(mutex_intr_acquire, mutex, mutex_unlock,
> > > + mutex_lock_interruptible)
> > > +
> > > +static inline int mutex_try_or_busy(struct mutex *lock)
> > > +{
> > > + int ret[] = { -EBUSY, 0 };
> > > +
> > > + return ret[mutex_trylock(lock)];
> > > +}
> > > +
> > > +DEFINE_ACQUIRE(mutex_try_acquire, mutex, mutex_unlock,
> > > + mutex_try_or_busy)
> > > +
> > > extern unsigned long mutex_get_owner(struct mutex *lock);
> > >
> > > #endif /* __LINUX_MUTEX_H */
> >
> > I'm terribly confused...
>
> I suspect the disconnect is that this proposal adds safety where guard()
> does not today. That was driven by the mistake that Linus caught in the
> RFC [1]
>
> at the same time I note that your patch is horribly broken. Look
> at your change to drivers/cxl/core/mbox.c: you made it use
>
> + struct mutex *lock __drop(mutex_unlock) =
> + mutex_intr_acquire(&mds->poison.lock);
>
> but then you didn't remove the existing unlocking, so that
> function still has
>
> [1]: http://lore.kernel.org/CAHk-=wgRPDGvofj1PU=NemF6iFu308pFZ=w5P+sQyOMGd978fA@mail.gmail.com
>
> I.e. in my haste I forgot to cleanup a straggling open-coded
> mutex_unlock(), but that is something the compiler warns about iff we
> switch to parallel primitive universe.
AFAICT all you've done is an effective rename. You can still write:
mutex_unlock(&foo->lock.lock);
and the compiler will again happily do so.
> > What's wrong with:
> >
> > CLASS(mutex_intr, lock)(&foo);
> > if (IS_ERR(__guard_ptr(mutex_intr)(lock)))
> > return __guard_ptr(mutex_intr)(lock);
>
> __guard_ptr() returns NULL on error, not an ERR_PTR, but I get the gist.
(Yeah, I realized after sending, but didn't want to self-reply for
something minor like that :-)
> > I mean, yeah __guard_ptr(mutex_intr) doesn't really roll of the tongue,
> > but if that is the whole objection, surely we can try and fix that bit
> > instead of building an entire parallel set of primitives.
>
> Yes, the "entire set of parallel primitives" was the least confident
> part of this proposal, but the more I look, that is a feature (albeit
> inelegant) not a bug.
>
> Today one can write:
>
> guard(mutex_intr)(&lock);
> ...
> mutex_unlock(lock);
>
> ...and the compiler does not tell you that the lock may not even be held
> upon return, nor that this is unlocking a lock that will also be
> unlocked when @lock goes out of scope.
>
> The only type safety today is the BUILD_BUG_ON() in scoped_cond_guard()
> when passing in the wrong lock class.
>
> So the proposal is, if you know what you are doing, or have a need to
> switch back and forth between scope-based and explicit unlock for a give
> lock, use the base primitives. If instead you want to fully convert to
> scope-based lock management (excise all explicit unlock() calls) *and*
> you want the compiler to validate the conversion, switch to the _acquire
> parallel universe.
As with all refactoring ever, the rename trick always works. But I don't
think that warrants building a parallel infrastructure just for that.
Specifically, it very much does not disallow calling mutex_unlock() on
your new member. So all you get is some compiler help during refactor,
and again, just rename the lock member already.
Also, if we ever actually get LLVM's Thread Safety Analysis working,
that will help us with all these problems:
https://lore.kernel.org/all/20250304092417.2873893-1-elver@google.com/
But the compiler needs a little more work go grok C :-)
next prev parent reply other threads:[~2025-05-08 11:00 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-05-07 7:21 [PATCH 0/7] Introduce DEFINE_ACQUIRE(), a scoped_cond_guard() replacement Dan Williams
2025-05-07 7:21 ` [PATCH 1/7] cleanup: Introduce DEFINE_ACQUIRE() a CLASS() for conditional locking Dan Williams
2025-05-07 9:32 ` Peter Zijlstra
2025-05-07 21:18 ` Dan Williams
2025-05-08 11:00 ` Peter Zijlstra [this message]
2025-05-09 5:04 ` Dan Williams
2025-05-09 10:40 ` Peter Zijlstra
2025-05-10 1:11 ` dan.j.williams
2025-05-12 10:50 ` Peter Zijlstra
2025-05-12 18:25 ` Peter Zijlstra
2025-05-12 18:58 ` Peter Zijlstra
2025-05-12 20:39 ` Linus Torvalds
2025-05-13 7:09 ` Peter Zijlstra
2025-05-13 8:50 ` Peter Zijlstra
2025-05-13 19:46 ` Linus Torvalds
2025-05-13 20:06 ` Al Viro
2025-05-13 20:31 ` Al Viro
2025-05-13 21:28 ` Linus Torvalds
2025-05-17 9:17 ` David Laight
2025-05-14 6:46 ` Peter Zijlstra
2025-05-13 3:32 ` dan.j.williams
2025-05-09 19:10 ` kernel test robot
2025-05-07 7:21 ` [PATCH 2/7] cxl/decoder: Move decoder register programming to a helper Dan Williams
2025-05-07 7:21 ` [PATCH 3/7] cxl/decoder: Drop pointless locking Dan Williams
2025-05-07 7:21 ` [PATCH 4/7] cxl/region: Split commit_store() into __commit() and queue_reset() helpers Dan Williams
2025-05-07 7:21 ` [PATCH 5/7] cxl/region: Move ready-to-probe state check to a helper Dan Williams
2025-05-07 7:21 ` [PATCH 6/7] cxl/region: Introduce CLASS(cxl_decoder_detach...) consolidate multiple paths Dan Williams
2025-05-08 7:44 ` kernel test robot
2025-05-07 7:21 ` [PATCH 7/7] cleanup: Create an rwsem conditional acquisition class Dan Williams
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=20250508110043.GG4439@noisy.programming.kicks-ass.net \
--to=peterz@infradead.org \
--cc=alison.schofield@intel.com \
--cc=dan.j.williams@intel.com \
--cc=dave.jiang@intel.com \
--cc=dave@stgolabs.net \
--cc=dlechner@baylibre.com \
--cc=fabio.maria.de.francesco@linux.intel.com \
--cc=ira.weiny@intel.com \
--cc=jonathan.cameron@huawei.com \
--cc=linux-cxl@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=torvalds@linux-foundation.org \
--cc=vishal.l.verma@intel.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