Re: [PATCH 15/78] ASoC: codecs: cs42l43: Use guard() for mutex locks
Bui Duc Phuc <[email protected]>
| Newsgroups | dev.linux.lists.chrome-platform,dev.linux.lists.asahi,org.infradead.lists.linux-arm-kernel,org.infradead.lists.linux-mediatek,org.kernel.vger.linux-arm-msm,org.kernel.vger.linux-kernel,org.kernel.vger.linux-sound |
|---|---|
| Message-ID | <CAABR9nEdHwXpg8+6J5L9Af1PvybGt3KSfRy=LnMHXSQSHnd25w@mail.gmail.com> |
On Fri, Jun 19, 2026 at 6:14 PM Takashi Iwai <[email protected]> wrote: > > On Fri, 19 Jun 2026 12:57:57 +0200, > Bui Duc Phuc wrote: > > > > Hi Charles, David, > > > > > > > > > > > > > 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; > > > } > > > > > > > Thanks both for the clarification. > > > > > 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. > > > > > > > As stated in cleanup.h, mixing goto-based cleanup and scope-based > > cleanup helpers in the same function is not expected, so I think > > we should keep a consistent approach here. > > Right, and IIRC, clang would complain the mixed goto case at least > with W=1. > > > Takashi Thank you all. In fact, I have only been using GCC for building and testing. It was only after David mentioned Clang that I decided to give it a try, and this is actually the first time I have used it. Also, thanks to Takashi-san for adding the W=1 build option. It helped me catch and address warnings more easily. I will send a v2 to address a few remaining goto cases that slipped through. In addition, I will switch to using guards for PM runtime to reduce indentation and improve code readability. Best regards, Phuc