Hi Mathias,
On 1/10/2023 11:47 AM, Mathias Nyman wrote:
On 9.1.2023 22.24, Wesley Cheng wrote:
Hi Mathias,
On 1/2/2023 8:38 AM, Mathias Nyman wrote:
On 29.12.2022 23.14, Wesley Cheng wrote:
Hi Mathias,
On 12/28/2022 7:47 AM, Mathias Nyman wrote:
On 24.12.2022 1.31, Wesley Cheng wrote:
Implement the XHCI operations for allocating and requesting for a
secondary
interrupter. The secondary interrupter can allow for events for a
particular endpoint to be routed to a separate event ring. The event
routing is defined when submitting a transfer descriptor to the
USB HW.
There is a specific field which denotes which interrupter ring to
route the
event to when the transfer is completed.
An example use case, such as audio packet offloading can utilize a
separate
event ring, so that these events can be routed to a different
processor
within the system. The processor would be able to independently
submit
transfers and handle its completions without intervention from the
main
processor.
Adding support for more xHCI interrupters than just the primary one
make sense for
both the offloading and virtualization cases.
xHCI support for several interrupters was probably added to support
virtualization,
to hand over usb devices to virtual machines and give them their
own event ring and
MSI/MSI-X vector.
In this offloading case you probably want to avoid xHC interrupts
from this device
completely, making sure it doesn't wake up the main CPU unnecessarily.
So is the idea here to let xhci driver set up the new interrupter,
its event ring,
and the endpoint transfer rings. Then pass the address of the
endpoint transfer rings
and the new event ring to the separate processor.
This separate processor then both polls the event ring for new
events, sets its dequeue
pointer, clears EHB bit, and queues new TRBs on the transfer ring.
so xhci driver does not handle any events for the audio part, and
no audio data URBs
are sent to usb core?
Your entire description is correct. To clarify, the interfaces
which are non-audio will still be handled by the main processor.
For example, a USB headset can have a HID interface as well for
volume control. The HID interface will still be handled by the main
processor, and events routed to the main event ring.
How about the control part?
Is the control endpoint for this device still handled normally by
usb core/xhci?
Control transfers are always handled on the main processor. Only
audio interface's endpoints.
Good to know, that means interrupter should be chosen per endpoint,
not per device.
For the xhci parts I think we should start start by adding generic
support for several
interrupters, then add parts needed for offloading.
I can split up the patchsets to add interrupters first, then adding
the offloading APIs in a separate patch.
I started looking at supporting secondary interrupters myself.
Let me work on that part a bit first. We have a bit different end goals.
I want to handle interrupts from a secondary interrupter, while this
audio offload
really just wants to mask some interrupts.
I was looking at how we could possibly split up the XHCI secondary
interrupter, and offloading parts. Since the XHCI secondary
interrupter is a feature that is defined in the XHCI spec (and we
aren't doing anything outside of what is defined), I was thinking of
having a separate XHCI driver (ie xhci-sec.c/h) that can be used to
define all APIs related to setting up the event ring and ring
management. (interrupt support can be added here) This aligns a bit
with what Alan suggested, and removing the APIs in the USB HCD, since
this is XHCI specific stuff. (
https://lore.kernel.org/linux-usb/Y6zwZOquZOTZfnvP@xxxxxxxxxxxxxxxxxxx/ )
Already started working on the interrupter, that part fits well into
current driver.
Code (untested, will be randomly rebased etc) can be found in my
feature_interrupters branch:
git://git.kernel.org/pub/scm/linux/kernel/git/mnyman/xhci.git
feature_interrupters
https://git.kernel.org/pub/scm/linux/kernel/git/mnyman/xhci.git/log/?h=feature_interrupters
Oh perfect, let me take a look. Thanks for this!
First step turns current event ring into a primary interrupter.
last patch is a test implementation for creating and freeing new
secondary interrupters.
For the offloading part, I think this is a bit more dependent on how
different platforms implement it. To use more of a generic approach
like how Albert suggested here:
https://patchwork.kernel.org/project/linux-usb/list/?series=704174
Basically to give vendors the ability to define their own
sequences/callbacks, and from which the XHCI driver will call into.
(if needed) These would need to be a separate set of XHCI drivers as
well.
Do you think this is a proper model for us to go with, so that we can
allow for vendors to easily add functionality? Appreciate the inputs.
I'm not convinced that overriding different xhci memory allocation
functions is the best solution.
I think xhci driver will need to know which endpoints are offloaded.
maybe usb class driver could register an "offloader" with xhci for a usb
device.
Trying to figure out what this xhci offload API would look like.
The dsp needs at least dma address of an event ring, and offloaded
endpoint rings.
Is there anything else that the dsp would directly need to take care of,
or can
we just export some xhci functions for starting/stopping endpoints, and
update event deq?
I'm still working it out with Albert as well to see what they actually
require, and if "hooking" into these XHCI apis is really necessary. I
wouldn't follow the path of hooking into existing XHCI APIs either,
since I'm sure most of it will be duplicate code that is already done by
the XHCI drivers. I'll follow up a bit more to get a better
understanding, or if Albert wants to chime in here that would be helpful
also, so everyone is on the same page.
In the QC implementation, we only need the transfer and event ring
address, skipping pending events in the secondary event ring (similar to
update event deq), and starting/stopping eps. Exporting APIs would work
for us.
Thanks
Wesley Cheng