Re: [PATCH] xhci: fix lost bounce buffers on TDs spanning several ring segments

Michal Pecio <[email protected]>
Newsgroups org.kernel.vger.linux-usb,org.kernel.vger.stable
Message-ID <[email protected]>
On Tue, 11 Aug 2026 10:42:37 +0200, Michal Pecio wrote:
> The code looks correct, though I would do it differently: store the
> last bounce_seg and run the loop from td->start_seg to td->bounce_seg.
> This avoids adding the 'if' during enqueue, and still works correctly
> if the TD wraps around the whole ring so that end_seg == start_seg.
> 
> The driver is never supposed to create such TDs (they break the ring
> expansion procedure) but I prefer more robust code if it costs nothing.
> Bugs happen, or expansion could theoretically become more flexible.
> 
> Regards,
> Michal
> 
> > +	seg = td->bounce_seg;
> > +	for (i = 0; i < ring->num_segs; i++) {
> > +		if (seg->bounce_len)
> > +			xhci_unmap_one_bounce_buffer(xhci, ring, td, seg);
> > +		if (seg == td->end_seg)
> > +			break;
> > +		seg = seg->next;
> > +	}

Oops, sorry, Mathias is right, this loop may incorrectly unmap a buffer
belonging to a later TD which starts somewhere in td->end_seg.

I think the alternative procedure I suggested is free of this problem.

- if td has bounce_seg, then it surely spans beyond start_seg, so we
  can safely unmap start_seg's bounce buffer
- if start_seg == bounce_seg then this was the last bounce to unmap,
  because it's impossible for end_trb to also be a bonuce.
- otherwise, we can continue to blindly unmap until reachng bounce_seg
- after unmapping bounce_seg, there is nothing more left to unmap

Regards,
Michal
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.