> Very interesting.  The UHCI Design Guide document is _not_ very specific
> about what happens with short packets.  It does say that if the SPD bit is
> set then the TD is marked inactive, the QH element ptr is not updated, and
> an interrupt is requested.  It doesn't say what happens if the SPD bit
> isn't set; I'm guessing that it does the same thing but doesn't request
> an interrupt.  One could easily argue that this behavior is a design flaw
> and that the QH element ptr's Terminate bit should get set.
>
> The Design Guide also doesn't say how the schedule execution works when
> the HC retrieves a TD marked inactive.  I'll assume that it doesn't
> process the TD any farther but just follows the QH horizontal link ptr.
>
> It _does_ say this (table 3.2.2 bit 29 = SPD): "The behavior is undefined
> when this bit is set with output packets or packets outside of queues."
> I think it's pretty clear that this means uhci_submit_common() isn't
> setting SPD correctly.  It should _always_ be set for queued (not iso.) IN
> packets regardless of URB_SHORT_NOT_OK, which is handled in
> uhci_result_common().  It should _never_ be set for OUT packets.  Of
> course, that's not the cause of the problem here.
>
>
> So look at what happens in uhci_irq().  It calls uhci_transfer_result(),
> which in turn calls uhci_unlink_generic() for completed URBs.  That calls
> uhci_delete_queued_urb(), which unlinks the URB's QH from the schedule.
>
> Then later on uhci_irq() calls uhci_finish_completion(), which in turn
> calls uhci_finish_urb() for each completed URB.  That calls
> uhci_destroy_urb_priv(), which among other things deallocates the URB's
> TDs.
>
> Apparently there's an assumption here that once an URB is completed, the
> HC scheduler won't look at its TDs any more.  But that's not necessarily
> true.  Consider first that the SPD interrupt doesn't arrive until the end
> of the frame.  The CPU won't start processing the interrupt until the HC
> has already begun the next frame, and if the schedule isn't very full then
> the HC may easily reach the URB's QH before uhci_delete_queued_urb() has
> managed to unlink it.  With FSBR turned on, the HC may even read that QH
> several times before it gets unlinked.
>
> Consider second that if the URB completes because of a short read, the
> QH's element ptr _won't_ point to the next queued QH; it will still point
> to the TD that got the short packet and is now marked inactive.  (That's
> true even if there isn't another URB queued for the same endpoint.  And
> it's also true for URBs that complete because of an error, not just a
> short read.)  As far as the scheduler is concerned that won't make any
> difference; when it sees the inactive TD it will ignore it and follow the
> QH link ptr anyway.  But the HC still has to decode that TD!
>
> The upshot of all this is that when uhci_destroy_urb_priv() removes and
> frees the TD, the HC might be about to read it.  Now I don't know how
> likely that is since there's clearly a race; the CPU would have to unlink
> the QH and free the TD all during the time the HC is processing the QH.
> But it would explain what Duncan is seeing.
>
> It's exactly as Johannes said; the driver doesn't wait for the next
> interrupt after unlinking the QH before freeing the TDs.
>
> Would it make more sense to store the td_list header in the uhci_qh
> rather than in the urb_priv?  That way the TDs could be freed along with
> the QH in uhci_free_pending_qhs(), which does execute at the right time.
> Maybe there's a less invasive way to accomplish the same thing, but I
> can't think of one.

Hi Alan, if this scenario is correct then the same problem could occur
even if urbs are not being queued, right?  So the fact I only see this
with queued urbs would be a coincidence: getting the timing just right
so as to hit the race...

Ciao,

Duncan.


-------------------------------------------------------
This SF.Net email is sponsored by: INetU
Attention Web Developers & Consultants: Become An INetU Hosting Partner.
Refer Dedicated Servers. We Manage Them. You Get 10% Monthly Commission!
INetU Dedicated Managed Hosting http://www.inetu.net/partner/index.php
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to