On Thu, Dec 11, 2025 at 02:19:28PM +0100, Marco Elver wrote:
> On Thu, 11 Dec 2025 at 13:17, Peter Zijlstra <[email protected]> wrote:
> >
> > On Thu, Nov 20, 2025 at 04:09:31PM +0100, Marco Elver wrote:
> > > Introduce basic compatibility with cleanup.h infrastructure: introduce
> > > DECLARE_LOCK_GUARD_*_ATTRS() helpers to add attributes to constructors
> > > and destructors respectively.
> > >
> > > Note: Due to the scoped cleanup helpers used for lock guards wrapping
> > > acquire and release around their own constructors/destructors that store
> > > pointers to the passed locks in a separate struct, we currently cannot
> > > accurately annotate *destructors* which lock was released. While it's
> > > possible to annotate the constructor to say which lock was acquired,
> > > that alone would result in false positives claiming the lock was not
> > > released on function return.
> > >
> > > Instead, to avoid false positives, we can claim that the constructor
> > > "assumes" that the taken lock is held via __assumes_ctx_guard().
> 
> 
> > Moo, so the alias analysis didn't help here?
> 
> Unfortunately no, because intra-procedural alias analysis for these
> kinds of diagnostics is infeasible. The compiler can only safely
> perform alias analysis for local variables that do not escape the
> function. The layers of wrapping here make this a bit tricky.
> 
> The compiler (unlike before) is now able to deal with things like:
> {
>     spinlock_t *lock_scope __attribute__((cleanup(spin_unlock))) = &lock;
>     spin_lock(&lock);  // lock through &lock
>     ... critical section ...
> }  // unlock through lock_scope (alias -> &lock)
> 
> > What is the scope of this __assumes_ctx stuff? The way it is used in the
> > lock initializes seems to suggest it escapes scope. But then something
> > like:
> 
> It escapes scope.
> 
> >         scoped_guard (mutex, &foo) {
> >                 ...
> >         }
> >         // context analysis would still assume foo held
> >
> > is somewhat sub-optimal, no?
> 
> Correct. We're trading false negatives over false positives at this
> point, just to get things to compile cleanly.

Right, and this all 'works' right up to the point someone sticks a
must_not_hold somewhere.

> > > Better support for Linux's scoped guard design could be added in
> > > future if deemed critical.
> >
> > I would think so, per the above I don't think this is 'right'.
> 
> It's not sound, but we'll avoid false positives for the time being.
> Maybe we can wrangle the jigsaw of macros to let it correctly acquire
> and then release (via a 2nd cleanup function), it might be as simple
> as marking the 'constructor' with the right __acquires(..), and then
> have a 2nd __attribute__((cleanup)) variable that just does a no-op
> release via __release(..) so we get the already supported pattern
> above.

Right, like I mentioned in my previous email; it would be lovely if at
the very least __always_inline would get a *very* early pass such that
the above could be resolved without inter-procedural bits. I really
don't consider an __always_inline as another procedure.

Because as I already noted yesterday, cleanup is now all
__always_inline, and as such *should* all end up in the one function.

But yes, if we can get a magical mash-up of __cleanup and __release (let
it be knows as __release_on_cleanup ?) that might also work I suppose.
But I vastly prefer __always_inline actually 'working' ;-)

Reply via email to