[PATCH 15/78] ASoC: codecs: cs42l43: Use guard() for mutex locks
Charles Keepax
ckeepax at opensource.cirrus.com
Fri Jun 19 03:39:09 PDT 2026
On Fri, Jun 19, 2026 at 10:13:46AM +0100, David Laight wrote:
> On Fri, 19 Jun 2026 15:20:37 +0700
> Bui Duc Phuc <phucduc.bui at gmail.com> wrote:
> > > > I believe you have to use scoped_guard here, as there is a return
> > > > from the function above, if memory serves it attempts to release
> > > > the mutex on that path despite it being above the guard.
> > >
> > > Indeed.
> > > I believe clang will complain.
> > > That makes these mechanical conversions of existing code dangerous churn.
> > >
> > > While using guard() (etc) can make it easier to ensure the lock is released
> > > when functions have multiple error exits, I'm not convinced it makes the
> > > code any easier to read (other people may disagree).
> >
> > I built the code with both GCC and Clang and didn't see any warnings.
> >
> > My understanding was that the early return exits the function before
> > the guard is instantiated, so it should not affect the guard's cleanup
> > handling.
>
> When a variable is defined (and initialised) part way down a block the
> compiler moves the definition to the top of the block but doesn't initialise
> it at all, the first assignment happens where the code contains the
> definition.
>
> However the destructor is always called at the end of the block.
> So if you return from a function before the definition the destructor
> is called with an uninitialised argument.
My understanding was exactly as your David, but it seems that isn't
the whole story and indeed I had to fix a bug in our SDCA code
that hit this. However testing this out, results in some things I
find very hard to explain.
It seems as far as I have managed to test, the code below works
fine as Phuc suggests. It does not appear to run the mutex_unlock
on the error path.
int function()
{
if (error)
return;
guard(mutex)(&mutex);
stuff();
return;
}
The situation I hit this in before that doesn't work was actually
this:
int function()
{
if (error)
goto error_label;
guard(mutex)(&mutex);
stuff();
error_label;
return;
}
Which in this case it does run the mutex_unlock and NULL pointer.
Will try to find sometime to look at the generated assembly, but
this basically totally blows my mind. Very unclear as to if this
is supposed to work this way or just does by pure luck.
Thanks,
Charles
More information about the Linux-mediatek
mailing list