From: Felipe Ferreri Tonello <eu@felipetonello.com>
To: Felipe Balbi <balbi@kernel.org>, linux-usb@vger.kernel.org
Cc: linux-kernel@vger.kernel.org,
Michal Nazarewicz <mina86@mina86.com>,
Clemens Ladisch <clemens@ladisch.de>
Subject: Re: [PATCH 2/5] usb: gadget: f_midi: added spinlock on transmit function
Date: Tue, 8 Mar 2016 15:40:23 +0000 [thread overview]
Message-ID: <56DEF267.5090803@felipetonello.com> (raw)
In-Reply-To: <87r3flgjb1.fsf@intel.com>
[-- Attachment #1: Type: text/plain, Size: 8523 bytes --]
Hi Balbi,
On 08/03/16 14:01, Felipe Balbi wrote:
>
> Hi,
>
> Felipe Ferreri Tonello <eu@felipetonello.com> writes:
>>>>>>>> Since f_midi_transmit is called by both ALSA and USB frameworks, it
>>>>>>> can
>>>>>>>> potentially cause a race condition between both calls. This is bad
>>>>>>> because the
>>>>>>>> way f_midi_transmit is implemented can't handle concurrent calls.
>>>>>>> This is due
>>>>>>>> to the fact that the usb request fifo looks for the next element and
>>>>>>> only if
>>>>>>>> it has data to process it enqueues the request, otherwise re-uses it.
>>>>>>> If both
>>>>>>>> (ALSA and USB) frameworks calls this function at the same time, the
>>>>>>>> kfifo_seek() will return the same usb_request, which will cause a
>>>>>>> race
>>>>>>>> condition.
>>>>>>>>
>>>>>>>> To solve this problem a syncronization mechanism is necessary. In
>>>>>>> this case it
>>>>>>>> is used a spinlock since f_midi_transmit is also called by
>>>>>>> usb_request->complete
>>>>>>>> callback in interrupt context.
>>>>>>>>
>>>>>>>> On benchmarks realized by me, spinlocks were more efficient then
>>>>>>> scheduling
>>>>>>>> the f_midi_transmit tasklet in process context and using a mutex
>>>>>>>> to synchronize. Also it performs better then previous
>>>>>>>> implementation
>>>>>>> that
>>>>>>>> allocated a usb_request for every new transmit made.
>>>>>>>
>>>>>>> behaves better in what way ? Also, previous implementation would not
>>>>>>> suffer from this concurrency problem, right ?
>>>>>>
>>>>>> The spin lock is faster than allocating usb requests all the time,
>>>>>> even if the udc uses da for it.
>>>>>
>>>>> did you measure ? Is the extra speed really necessary ? How did you
>>>>> benchmark this ?
>>>>
>>>> Yes I did measure and it was not that significant. This is not about
>>>> speed. There was a bug in that approach that I already explained on
>>>
>>> you have very confusing statements. When I mentioned that previous code
>>> wouldn't have the need for the spinlock you replied that spinlock was
>>> faster.
>>>
>>> When I asked you about benchmarks you reply saying it's not about the
>>> speed.
>>>
>>> Make up your mind dude. What are you trying to achieve ?
>>>
>>>> that patch, which was approved and applied BTW.
>>>
>>> patches can be reverted if we realise we're better off without
>>> them. Don't get cocky, please.
>>
>> Yes am I aware of that, but I honestly think that is the wrong way of
>> dealing with this.
>>
>> ?? I don't get why am I giving this impression.
>
> re-read your emails. The gist goes like this:
>
> . Send patch
> . Got comments
> . Well, whatever, you can just ignore if you don't agree
This is one of the problems with email. It can give the wrong impression
and feelings. :)
That was not what I meant at all. I mean that for real, not in a
childish manner. I'm sorry if I gave you that impression.
>
>>>> Any way, this spinlock should've been there since that patch but I
>>>> couldn't really trigger this problem without a stress test.
>>>
>>> which tells me you sent me patches without properly testing. How much
>>> time did it take to trigger this ? How did you trigger this situation ?
>>
>> No, that is no true. The implementation I sent is working properly for
>> any real world usage.
>>
>> The stress test I made to break the current implementation is *not* a
>> real use-case. I made it in order to push as far as possible how fast
>> the driver can *reliably* handle while sending and reading data. Then I
>> noticed the bug.
>>
>> So, to answer your question. To trigger this bug is not a matter of
>> time. The following needs to happen:
>> 1. Device send MIDI message that is *bigger* than the usb request
>> length. (just this by itself is really unlikely to happen in real world
>> usage)
>
> I wouldn't say it's unlikely. You just cannot trust the other side of
> the wire. We've seen e.g. Xbox 360's SCSI layer sending messages of the
> wrong size and we worked around them in g_mass_storage.
>
> Broken implementations are a real thing ;-)
Fair enough. And that's why I am pushing this fix. :)
>
>> 2. Host send a MIDI message back *exactly* at the same time as the
>> device is processing the second part of the usb request from the same
>> message.
>
> also not that unlikely to happen ;-) You can't assume the host will only
> shift tokens on the wire at the time you're expecting it to.
>
>> I couldn't trigger this in all the tests we've made. I just triggered
>> when I was sending huge messages back and forth (device <-> host) as
>> mentioned.
>
> fair enough.
>
>> In fact, we have thousands of devices out there without this patch (but
>> with my previous patch that introduced this bug).
>
> that's thousands of devices waiting to have a problem, right ? :-)
:X
>
>> I am not trying to say it wasn't a mistake. That patch unfortunately
>> introduces this bug, but it has real improvements over the previous
>> implementation. AFAIR the improvements are:
>> * Fixes a bug that was causing the DMA buffer to fill it up causing a
>> kernel panic.
>
> this is a good point. Had forgotten about that detail. Thanks
>
>> * Pre allocate IN usb requests so there is no allocation overhead while
>> sending data (same behavior already existed for the OUT endpoint). This
>> ensure that the DMA memory is not misused affecting the rest of the
>> system.
>
> also, arguably, a good idea. Recycling requests is a lot nicer and it's
> what most gadget drivers do.
>
>> * It doesn't crash if the host doesn't send an ACK after IN data
>> packets and we have reached the limit of available memory. Also, this is
>> useful because it causes the ALSA layer to timeout, which is the correct
>> userspace behavior.
>
> right
>
>> * Continuous to send data to the correct Jack (associated to each ALSA
>> substream) if that was interrupted somehow, for instance by the size
>> limit of a usb request.
>
> ok.
>
>>>> So, this patch fixes a bug in the current implementation.
>>>
>>> fixes a regression introduced by you, true. I'm trying to figure out if
>>> we're better off without the original patch; to make a good decision I
>>> need to know if the extra "speed" we get from not allocating requests on
>>> demand are really that important.
>>>
>>> So, how much faster did you get and is that extra "speed" really
>>> important ?
>>
>> The speed is not relevant at all in this case. It was not the goal of
>> the patch, but I mentioned because it is obvious that with no memory
>> allocation there will be an increase of speed that the code is executed.
>>
>> I did measure the speed improvements at that time, it was real but not
>> relevant. I don't think we should be discussing this anyway.
>
> fair enough. This was probably the first email from you which gave me
> some peace of mind that you know what you're doing with this fix. Keep
> in mind that we all receive hundreds of emails a day and it's difficult
> to track things over time.
True. I will try to keep this always in mind.
>
> It's also a big PITA when someone sends fixes and cleanups on the same
> series and/or with dependencies between them. The correct way is to send
> *only* fixes first. They should be minimal patches that *only* fix the
> problem. If the code looks messy or doesn't follow the coding style,
> that's something you do on a completely separate fix and, usually, from
> a clean topic branch starting at a tag from Linus (exceptions may arise,
> of course).
Got it.
>
> So anyway, to finally finish this up. Can you send JUST the bare minimum
> fix necessary to avoid the regression ? Also, add a proper Fixes: foobar
> line on commit log (see commit e18b7975c885bc3a938b9a76daf32957ea0235fa
> for an example).
>
> Then we can get that merged. Keep in mind that you might have to Cc
> stable (see same commit listed above).
Ok.
I will send the state-machine refactor as another patch in another topic
then.
>
> After this is sorted out, then let's see how we can help you move your
> product to libusbgx and check if there's anything missing in configfs
> to cope with your use-case.
That will be great, thanks! I will keep the list posted.
>
> ps: can you point me to your devices shipping with f_midi ? Which
> architecture are they using ? Which USB Peripheral Controller ? This
> might be a good addition to my test farm depending on your answers above
> :-p
Seaboard GRAND[1]. Freescale's i.MX 6 running an ARM A9. The controller
is Chip Idea.
[1] https://www.roli.com/products/seaboard-grand
--
Felipe
[-- Attachment #2: 0x92698E6A.asc --]
[-- Type: application/pgp-keys, Size: 7310 bytes --]
next prev parent reply other threads:[~2016-03-08 15:38 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-03-02 19:40 [PATCH 0/5] MIDI USB Gadget improvements Felipe F. Tonello
2016-03-02 19:40 ` [PATCH 1/5] usb: gadget: f_midi: refactor state machine Felipe F. Tonello
2016-03-02 21:09 ` Clemens Ladisch
2016-03-03 8:57 ` Felipe Ferreri Tonello
2016-03-03 11:38 ` Clemens Ladisch
2016-03-03 16:30 ` Felipe Ferreri Tonello
2016-03-04 8:07 ` Clemens Ladisch
2016-03-04 18:39 ` Felipe Ferreri Tonello
2016-03-04 18:43 ` Clemens Ladisch
2016-03-02 19:40 ` [PATCH 2/5] usb: gadget: f_midi: added spinlock on transmit function Felipe F. Tonello
2016-03-04 7:20 ` Felipe Balbi
2016-03-04 18:49 ` Felipe Ferreri Tonello
2016-03-07 7:32 ` Felipe Balbi
2016-03-07 9:28 ` Felipe Ferreri Tonello
2016-03-08 7:37 ` Felipe Balbi
2016-03-08 13:46 ` Felipe Ferreri Tonello
2016-03-08 14:01 ` Felipe Balbi
2016-03-08 15:40 ` Felipe Ferreri Tonello [this message]
2016-03-09 7:22 ` Felipe Balbi
2016-03-02 19:40 ` [PATCH 3/5] usb: gadget: gmidi: remove bus powered requirement on bmAttributes Felipe F. Tonello
2016-03-04 7:16 ` Felipe Balbi
2016-03-04 18:46 ` Felipe Ferreri Tonello
2016-03-07 7:34 ` Felipe Balbi
2016-03-07 9:40 ` Felipe Ferreri Tonello
2016-03-07 10:59 ` Felipe Balbi
2016-03-07 11:13 ` Felipe Ferreri Tonello
2016-03-08 7:43 ` Felipe Balbi
2016-03-08 10:14 ` Krzysztof Opasiak
2016-03-08 10:34 ` Felipe Balbi
2016-03-08 13:54 ` Felipe Ferreri Tonello
2016-03-08 14:04 ` Felipe Balbi
2016-03-08 14:15 ` Krzysztof Opasiak
2016-03-08 14:20 ` Felipe Balbi
2016-03-08 15:24 ` Felipe Ferreri Tonello
2016-03-02 19:40 ` [PATCH 4/5] usb: gadget: f_midi: cleanups and typos fixes Felipe F. Tonello
2016-03-04 7:13 ` Felipe Balbi
2016-03-04 19:17 ` Michal Nazarewicz
2016-03-04 20:17 ` Felipe Ferreri Tonello
2016-03-05 16:28 ` Michal Nazarewicz
2016-03-05 19:39 ` Greg KH
2016-03-05 23:53 ` Felipe Ferreri Tonello
2016-03-06 3:02 ` Greg KH
2016-03-05 23:57 ` Felipe Ferreri Tonello
2016-03-07 7:35 ` Felipe Balbi
2016-03-07 9:32 ` Felipe Ferreri Tonello
2016-03-08 7:44 ` Felipe Balbi
2016-03-02 19:40 ` [PATCH 5/5] usb: gadget: f_midi: updated copyright Felipe F. Tonello
2016-03-04 7:13 ` Felipe Balbi
2016-03-04 18:41 ` Felipe Ferreri Tonello
2016-03-07 7:36 ` Felipe Balbi
2016-03-07 9:23 ` Felipe Ferreri Tonello
2016-03-04 7:11 ` [PATCH 0/5] MIDI USB Gadget improvements Felipe Balbi
2016-03-04 18:43 ` Felipe Ferreri Tonello
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=56DEF267.5090803@felipetonello.com \
--to=eu@felipetonello.com \
--cc=balbi@kernel.org \
--cc=clemens@ladisch.de \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=mina86@mina86.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox