Re: [PATCH v2] staging: r8188eu: Remove _enter/_exit_critical_mutex()

From: Fabio M. De Francesco
Date: Thu Aug 19 2021 - 15:54:53 EST


On Thursday, August 19, 2021 4:54:00 PM CEST Greg Kroah-Hartman wrote:
> On Thu, Aug 19, 2021 at 02:49:55PM +0200, Fabio M. De Francesco wrote:
> > Remove _enter_critical_mutex() and _exit_critical_mutex(). They are
> > unnecessary wrappers, respectively to mutex_lock_interruptible() and
> > to mutex_unlock(). They also have an odd interface that takes an
> > unused argument named pirqL of type unsigned long.
> > Replace them with the in-kernel API. Ignore return values as it was
> > in the old code.
> >
> > Signed-off-by: Fabio M. De Francesco <fmdefrancesco@xxxxxxxxx>
> > ---
> >
> > v2: Ignore return values from Mutexes API.
> >
> > drivers/staging/r8188eu/core/rtw_mlme_ext.c | 5 +++--
> > drivers/staging/r8188eu/hal/usb_ops_linux.c | 5 +++--
> > drivers/staging/r8188eu/include/osdep_service.h | 13 -------------
> > drivers/staging/r8188eu/os_dep/os_intfs.c | 5 +++--
> > 4 files changed, 9 insertions(+), 19 deletions(-)
> >
> > diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c
> > index 5325fe41fbee..9f53cab33333 100644
> > --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c
> > +++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c
> > @@ -4359,7 +4359,8 @@ s32 dump_mgntframe_and_wait_ack(struct adapter *padapter, struct xmit_frame *pmg
> > if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
> > return -1;
> >
> > - _enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
> > + if (mutex_lock_interruptible(&pxmitpriv->ack_tx_mutex))
> > + ; /*ignore return value */
>
> Ick, no. (not to mention the wrong comment style...)
>
> If this really is "criticial", why can it be interrupted?
>
> The existing code is such that the code can be interrupted, but if it
> fails, the lock is not gotten, and the CODE CONTINUES AS IF IT IS OK!

This was perfectly clear. The old code ignored -EINTR and, in case when
blocking to wait for the lock to become available is interrupted (although
I really don't know how - a signal to a driver? I guess it cannot happen) it
continues to execute in the critical region so leading to potential race
conditions.

This is what I get and I guess I'm not too far from the truth... Did I get it
right?

> So either this is never interruptable (my guess, one almost never needs
> interruptable locks in a driver)

This is what I think, why interruptible locks in a driver? I suppose that they
should only be used when the kernel executes on behalf of a process.

> and should just do a normal mutex lock,
> or the code is totally broken and the locking should be revisited
> entirely.

My guess is that the code that is waiting to acquire a lock could *really*
be interrupted should manage that interruption without falling blindly
in the critical region and we have two ways to do that:

1) return -EINTR to the caller which should manage that error by retrying
the acquisition, or

2) retry in a loop inside the callee, avoiding to proceed to the critical section
without an acquired mutex.

A third option is using mutex_lock() (uninterruptible), which I would prefer
if I were absolutely sure that nothing could interrupt waiting for acquiring
the lock.

I have to look at how other drivers manage similar cases, although I'm
pretty convinced that a simple mutex_lock() should be fine here.

Thanks,

Fabio

> But a "blind" change like this is not good, let's get it right...

I agree, let me take some time to investigate what are the best practices
that the kernel implements in cases like this. What I'm sure at the moment is
that the old code, as-is, is broken.

Thanks,

Fabio

> thanks,
>
> greg k-h
>