On 8/27/24 2:37 PM, Mathias Nyman wrote: > It's a bit complex, but it shows the missed service events started from > out transfers. > > Quick background, audio class driver queues URBs. One URB containis one or several > TDs (transfer descriptors). One TD is consumed each interval, in this case each 125us. > In this case audio driver uses two URBs, usually containing 7 or 8 TDs, each transferring > 48 bytes. TD (Transfer descriptor) equals one TRB (Transfer Block) in this particular case. Thanks for the explanation! > USB audio driver queues two URBs: > 185.943950: xhci_urb_enqueue: ep1out-isoc: urb 000000007faac5c4 pipe 33792 slot 3 length 0/384 8 x 48 bytes 0x10a3f5000 - 0x10a3f5070 > 185.943966: xhci_urb_enqueue: ep1out-isoc: urb 0000000094a36c26 pipe 33792 slot 3 length 0/336 7 x 48 bytes 0x10a3f5080 - 0x10a3f50e0 > > xHCI gives back URBs once completed. About 1ms apart which is ok. > Odd that audio driver doesn't queue back the fist URB immediately after receiving it, this could cause missed service event. > 185.946834: xhci_urb_giveback: ep1out-isoc: urb 000000007faac5c4 pipe 33792 slot 3 length 384/384 > 185.947705: xhci_urb_giveback: ep1out-isoc: urb 0000000094a36c26 pipe 33792 slot 3 length 336/336 > > Audio driver queues both URBs after it has processed their content. > very odd that the other URB only contains 1 TD (covering only 125us) > 185.947732: xhci_urb_enqueue: ep1out-isoc: urb 000000007faac5c4 pipe 33792 slot 3 length 0/48 1 x 48 bytes (0x10a3f50f0) > 185.947745: xhci_urb_enqueue: ep1out-isoc: urb 0000000094a36c26 pipe 33792 slot 3 length 0/336 7 x 48 bytes (0x10a3f5100 - 10a3f5160) > > Audio driver cancels both URBs, Odd, why does it do that? > 185.949843: xhci_urb_dequeue: ep1out-isoc: urb 000000007faac5c4 pipe 33792 slot 3 length 0/48 CANCEL why?? (0x10a3f50f0) > 185.949848: xhci_urb_dequeue: ep1out-isoc: urb 0000000094a36c26 pipe 33792 slot 3 length 0/336 CANCEL why?? (0x10a3f5100 - 10a3f5160) turned to no-ops, deq at af5100 I looked a bit at the snd_usb_audio driver for places where urb unlinking or killing might happen: [fps@arch97 usb]$ grep -n usb_kill_urb *.c -R midi2.c:242: usb_kill_urb(ep->urbs[i].urb); midi.c:1496: usb_kill_urb(ep->out->urbs[j].urb); midi.c:1507: usb_kill_urb(ep->in->urbs[j]); midi.c:2364: usb_kill_urb(ep->in->urbs[j]); mixer.c:3647: usb_kill_urb(mixer->urb); mixer.c:3649: usb_kill_urb(mixer->rc_urb); mixer.c:3658: usb_kill_urb(mixer->urb); mixer.c:3659: usb_kill_urb(mixer->rc_urb); [fps@arch97 usb]$ grep -n usb_unlink_urb *.c -R endpoint.c:1053: usb_unlink_urb(u); The only really possibly relevant file here is endpoint.c since we're only dealing with pcm streams. endpoint.c:1053 is part of * * Stop active urbs * * This function moves the EP to STOPPING state if it's being RUNNING. */ static int stop_urbs(struct snd_usb_endpoint *ep, bool force, bool keep_pending) But none of the call sites for this function look as if they would be called in the middle of an active use of the endpoint. Weird. [...] > URBs contain 8TDs with 125us interval, and should complete 1ms apart on average. > This won't be true for every URB as sometimes urb giveback might be blocked for > a short while, but it should average out. Next URB would then return a bit earlier. > > In this case it doesn't. URB are permanently delayed. > > We use "SIA" (Start Isoc ASAP) flag for Isoc transfers, this allows controller > to queue TD to be transferred "as soon as possible" without forcing it to a > specific microframe. Could be that this flag in combination with queueing TDs > very close to the IST limit causes the delay but not triggering missed service > events, or under/overruns. > > Adding more URBs could help, but causes a bit more latency. > > Or maybe see if we can get audio driver to use 3 URBs with 6TDs each? I will play around with the code a little bit. I'll probably only break things though :) Thanks! FPS