Hi Michal,
On 04/04/16 13:11, Michal Nazarewicz wrote:
> On Sat, Apr 02 2016, Dan Carpenter wrote:
>> We added some new locking here, but missed an error path where we need
>> to unlock.
>>
>> Fixes: 9acdf4df2fc4 ('usb: gadget: f_midi: added spinlock on transmit
>> function')
>> Signed-off-by: Dan Carpenter <[email protected]>
>>
>
> Acked-by: Michal Nazarewicz <[email protected]>
>
> But perhaps this would be cleaner:
>
> diff --git a/drivers/usb/gadget/function/f_midi.c
> b/drivers/usb/gadget/function/f_midi.c
> index 56e2dde..c04436f 100644
> --- a/drivers/usb/gadget/function/f_midi.c
> +++ b/drivers/usb/gadget/function/f_midi.c
> @@ -606,19 +606,14 @@ static void f_midi_transmit(struct f_midi *midi)
> goto drop_out;
>
> spin_lock_irqsave(&midi->transmit_lock, flags);
> -
> - do {
> - ret = f_midi_do_transmit(midi, ep);
> - if (ret < 0)
> - goto drop_out;
> - } while (ret);
> -
> + while ((ret = f_midi_do_transmit(midi, ep)) > 0) {
> + /* nop */
> + }
> spin_unlock_irqrestore(&midi->transmit_lock, flags);
>
> - return;
> -
> + if (ret < 0)
> drop_out:
> - f_midi_drop_out_substreams(midi);
> + f_midi_drop_out_substreams(midi);
> }
>
> static void f_midi_in_tasklet(unsigned long data)
>
> Or maybe even this which gets away with gotos all together:
>
> diff --git a/drivers/usb/gadget/function/f_midi.c
> b/drivers/usb/gadget/function/f_midi.c
> index 56e2dde..91cae60 100644
> --- a/drivers/usb/gadget/function/f_midi.c
> +++ b/drivers/usb/gadget/function/f_midi.c
> @@ -598,27 +598,20 @@ done:
> static void f_midi_transmit(struct f_midi *midi)
> {
> struct usb_ep *ep = midi->in_ep;
> - int ret;
> unsigned long flags;
> + int ret = -1;
>
> /* We only care about USB requests if IN endpoint is enabled */
> - if (!ep || !ep->enabled)
> - goto drop_out;
> -
> - spin_lock_irqsave(&midi->transmit_lock, flags);
> -
> - do {
> - ret = f_midi_do_transmit(midi, ep);
> - if (ret < 0)
> - goto drop_out;
> - } while (ret);
> -
> - spin_unlock_irqrestore(&midi->transmit_lock, flags);
> -
> - return;
> + if (ep && ep->enabled) {
> + spin_lock_irqsave(&midi->transmit_lock, flags);
> + while ((ret = f_midi_do_transmit(midi, ep)) > 0) {
> + /* nop */
> + }
> + spin_unlock_irqrestore(&midi->transmit_lock, flags);
> + }
>
> -drop_out:
> - f_midi_drop_out_substreams(midi);
> + if (ret < 0)
> + f_midi_drop_out_substreams(midi);
> }
>
> static void f_midi_in_tasklet(unsigned long data)
I am fine with these options, probably the second, but I don't think
they are any clearer than before, so I don't see any real benefits with
the changes.
In fact, I think f_midi_do_transmit should be documented, since there
are 3 possible return condition:
<0 breaks the loop and drop out substreams
0 breaks the loop
>0 continues the loop
>
>
>
>> diff --git a/drivers/usb/gadget/function/f_midi.c
>> b/drivers/usb/gadget/function/f_midi.c
>> index 56e2dde..2c0616c 100644
>> --- a/drivers/usb/gadget/function/f_midi.c
>> +++ b/drivers/usb/gadget/function/f_midi.c
>> @@ -609,8 +609,10 @@ static void f_midi_transmit(struct f_midi *midi)
>>
>> do {
>> ret = f_midi_do_transmit(midi, ep);
>> - if (ret < 0)
>> + if (ret < 0) {
>> + spin_unlock_irqrestore(&midi->transmit_lock, flags);
>> goto drop_out;
>> + }
>> } while (ret);
>>
>> spin_unlock_irqrestore(&midi->transmit_lock, flags);
>
--
Felipe
0x92698E6A.asc
Description: application/pgp-keys
