On Fri, 2010-08-20 at 17:12 -0700, Paul Zimmerman wrote: > > From: Xu, Andiry [mailto:Andiry.Xu@xxxxxxx] > > Hi Sarah, > > > > When a missed service interval event is encountered, we just set the > > ep->skip flag, increase the event ring dequeue pointer, and then return. > > We will enter the do-while loop and process missed tds the next time we > > encounter a transfer event from this endpoint. > > > > If the next event after a missed service interval isn't for that > > endpoint, I think is OK. This endpoint does not have its skip flag set, > > and the do-while loop will run only once and then returns. If this > > endpoint's skip flag is also set, then we'll process its missed tds, > > since it must have a missed service interval event some time ago. > > > > If we get two missed service intervals for the same endpoint in a row, > > it will be two cases: the two missed service interval events are > > consecutive, or not. If they are consecutive, we just return and process > > the missed tds next time when it's not a missed service interval event; > > if they are not consecutive and there's a transfer event between them, > > we should process the missed tds for twice. > > > > If a missed service interval is followed by a Ring Underrun/overrun > > event for that isoc ring, there may be problems. In this case the > > handle_tx_event() should return. I think ep->skip flag should get > > cleared when encounter a Ring Underrun/overrun event. Maybe this causes > > Paul's issue? > > > > If Paul can print his event ring when the infinite loop case happens, > > that may help to find the actual case. > > > > Thanks & Best regards, > > Andiry > > Hi Andiry, > > Attached is a dmesg log from when this happens. I have added calls to > xhci_debug_ring, xhci_dbg_ring_ptrs, and xhci_dbg_ep_rings (for each of > the active slots) when I see that event_seg is NULL. You can search for > the message "event_seg is NULL" to find where this happens. > > Note, I have removed some of the other debug messages, because the log > was way too verbose otherwise, and also added one or two of my own. > > Let me know if you need any more info. Thanks. > Hi Paul, Thanks for the log. I've seen a missed service interval event in event ring, the skip flag is set and some tds are missed. The NULL event_seg is normal in this case. Tds from bd4144f0 to bd415140 are missed, actually they're cancelled. So there is a missed service interval event for bd415150, and following tds have events in the event ring. Suppose when process event @bd438460, the do-while loop will look for td bd415160 on the td list, and clear the skip flag when found the td. Then do-while loop will end. But I haven't seen td bd415150 and following tds on the endpoint ring. I'm afraid the full endpoint ring is not printed, because I allocate 8 segments for isoc endpoint, but there is only one segment showed in the log. Perhaps you only print one segment of isoc endpoint ring? With your patch, every time when event_seg is NULL, you break out and returns. But event_seg will be NULL when a missed service interval event is encountered and it's quite normal for isoc transfer. Your patch may workaround the issue but it does not help to find the root cause. And suppose the do-while will not run infinity. ep->skip is cleared when irq_handler found the td on the ring, or when the td_list is empty. Since urb_enqueue needs to acquire the lock which is hold by irq_handler, it cannot insert tds to the ring. Eventually the td_list is empty, and ep->skip is clear. Thanks, Andiry -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html