Re: [PATCH 0/2] Add larger page size support for USB audio offload path
From: Takashi Iwai
Date: Tue Aug 25 2026 - 07:12:23 EST
On Tue, 25 Aug 2026 04:06:54 +0200,
Wesley Cheng wrote:
>
> On some environments, 16kB pages can be enabled from the Linux subsystem,
> which manages the IOMMU mappings for the audio DSP within the system. In
> the current design, the following assumptions break when 16k pages are
> utilized:
> 1. xHCI ring size is equal to PAGE_SIZE
> 2. Ring addresses start at the beginning of a page
>
> When the USB offload driver maps the rings (w/ the audio DSP SID), it is
> set with a 16k granular, which is a problem, as several xHCI rings could
> exist on the same page. This is because the rings are currently allocated
> from the segment_pool. Hence, potentially mapping non USB audio related
> rings into the region accessible by the audio DSP.
>
> To mitigate this, this series introduces the alignment_req parameter.
> Before the USB audio offload path is enabled, the USB audio data
> streams/endpoint are not active. Only when the class driver issues a
> usb_set_interface() call (done from snd_usb_endpoint_prepare()), will the
> xHCI allocate the transfer ring resources. By setting the alignment_req
> beforehand, when allocating the ring segment, it can fulfill the audio DSP
> alignment requirements by allocating DMA-able memory on the fly (based on
> what is being requested) versus fetching it from the segment pool.
> Likewise, keep track of if memory was dynamically allocated to handle the
> free path properly. The function call flow will now look like the
> following:
>
> handle_uaudio_stream_req()
> │
> ▼
> enable_audio_stream(subs, ..., pcm_card_num)
> │
> ├─ xhci_sideband_add_endpoint(sb, data_ep, PAGE_SIZE)
> │ │ alignment_req == PAGE_SIZE
> │ ▼
> │ sb->alignment_req = alignment_req
> │
> ├─ snd_usb_endpoint_prepare(chip, data_endpoint)
> │ → xhci_check_bandwidth() → xhci_endpoint_init())
> │ ▼
> xhci_endpoint_init(..., ep_index, ...)
> │ if (sideband && sideband->alignment_req)
> │ new_ring = xhci_ring_alloc(xhci, 2, ring_type, max_packet,
> │ sideband->alignment_req, mem_flags)
> │ ▼
> xhci_ring_alloc(..., alignment_req, ...)
> │ ring->alignment_req = alignment_req
> │ ▼
> xhci_alloc_segments_for_ring(xhci, ring, flags)
> │ xhci_segment_alloc(xhci, ..., ring->alignment_req, flags)
> │ ▼
> xhci_segment_alloc(..., alignment_req, flags)
> if (alignment_req > TRB_SEGMENT_SIZE)
> seg->trbs = dma_alloc_coherent(dev, alignment_req, &dma, flags)
> else
> seg->trbs = dma_pool_zalloc(xhci->segment_pool, ...)
>
> Similar logic is added for the secondary interrupter path as well. The USB
> offload class driver calls xhci_sideband_create_interrupter(), which will
> be responsible for allocating the secondary event ring. The same
> alignment_req parameter is passed, and during xHCI event ring creation, the
> same set of APIs are utilized, so the runtime memory allocation is already
> handled.
>
> This was confirmed to work on the SM8350 MTP platform, with the
> CONFIG_ARM64_16K_PAGES config enabled, alongside tinyaudio binaries:
>
> tinymix -D 0 set 513 1 (Enables USB_RX multimedia#1 path)
> tinyplay -D 0 -d 0.... (Routes PCM data to ASoC platform sound card)
>
> Signed-off-by: Wesley Cheng <wesley.cheng@xxxxxxxxxxxxxxxx>
> ---
> Wesley Cheng (2):
> xhci: sideband: support page-aligned ring segment allocation
> ALSA: usb-audio: qcom: request page-aligned xHCI ring buffers
I guess your first patch alone breaks the build, and this is bad for
bisection. When you change the API, the callers should be addressed
in the same commit altogether in order to keep the stuff working
during the transition.
thanks,
Takashi