Balbi,

On Fri, Sep 18, 2015 at 5:02 PM, Felipe Balbi <ba...@ti.com> wrote:
> Hi,
>
> On Fri, Sep 18, 2015 at 04:53:09PM +0100, Felipe Tonello wrote:
>> Hi Balbi,
>>
>> On Fri, Sep 18, 2015 at 3:25 PM, Felipe Balbi <ba...@ti.com> wrote:
>> > On Fri, Sep 18, 2015 at 11:03:26AM +0100, Felipe Tonello wrote:
>> >> After some debugging, here is where I am:
>> >>
>> >> The crash trace is like this:
>> >>
>> >> (f_midi.c)
>> >> -> ALSA calls f_midi_in_trigger()
>> >>   ->tasklet_hi_schedule(&midi->tasklet)
>> >>     -> f_midi_transmit(midi, NULL) the NULL here causes the f_midi to
>> >> request a usb_request allocation, also it sets req->complete (which is
>> >> not been called? I am investigating this)
>> >
>> > ->complete() is called by the UDC when the request actually completes.
>>
>> The problem is that the udc driver is never calling it. I just realised that.
>>
>> (chipidea/udc.c) irqreturn_t udc_irq(struct ci_hdrc *ci) is not been
>> called after a f_midi_transmit(). Think here is the main problem. Any
>> ideas?
>
> have you looked at ci_irq() ? Look at how many return points it has. It's
> not inconceivable that it might be returning before calling ->udc_irq().

Looking into that. Thanks for the hint.

>
> Now, if that's valid or not, it's for you decide. I don't even have this
> HW and can't help much more than this.
>
>> >>       -> usb_ep_queue(ep, req, GFP_ATOMIC)
>> >> (chipidea/udc.c)
>> >>         -> ep_queue(ep, req, gfp_flags)
>> >>           -> _ep_queue(ep, req, gfp_flags)
>> >>             -> _hardware_enqueue(hwep, hwreq) here is where it is crashing
>> >>               -> add_td_to_list(hwep, hwreq, count) this guy returns
>> >> an error from dma_pool_alloc(), out of mem, which is not been checked
>> >> (I have a patch for this)
>> >
>> > oh, this probably part of the error. Care to send it ?
>>
>> Yes. It doesn't fix anything, but it prevents the kernel to panic.
>
> fair enough, and where's the patch ?

Sent.

>
>> >>                 -> lastnode = list_entry(hwreq->tds.prev, struct
>> >> td_node, td) get last node (which is NULL)
>> >>                   -> lastnode->ptr->next = cpu_to_le32(TD_TERMINATE)
>> >> CRASH!!! lastnode->ptr is NULL
>> >
>> > if lastnode was initialized with list_entry(), it can't be
>> > NULL. You're missing something
>>
>> lastnode is not NULL, lastnode->ptr is NULL. (because of the
>> dma_pool_alloc, check add_td_to_list function).
>
> right, so you're running out of memory. Why are you running out of memory ?
> probably because ->udc_irq() is never called and, thus, you never free from
> coherent. Find reason for that and your problems will be gone, probably.

Bingo! That is what it looks like.

The weird thing, like I said, is that I use different gadgets and they
don't have this leak problem, apparently. I didn't test but it never
panic'ed.

>
>> >> Any comments?
>> >
>> > yeah, continue debugging, what other information can you gather ? Does the
>> > problem go away if you add a ton of printks() around the code ?
>>
>> It doesn't change anything.
>
> ok, then it should be easy to reproduce. Wonder if this UDC has ever been
> tested with isochronous transfers at all.

Perhaps Peter could say better?

Thanks Balbi.

Felipe Tonello
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to