Re: Misbehaving Alder Lake-N PCH USB 3.2 xHCI Host Controller

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




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





[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux