Re: [PATCH v3] dma-buf: Split sgl by largest page-aligned chunk
Leon Romanovsky <[email protected]>
| Newsgroups | dev.linux.lists.iommu,org.freedesktop.lists.dri-devel,org.kernel.vger.linux-kernel,org.kernel.vger.linux-media,org.kernel.vger.stable |
|---|---|
| Message-ID | <20260723094625.GE110966@unreal> |
On Wed, Jul 22, 2026 at 11:39:32PM +0000, [email protected] wrote: > From: David Hu <[email protected]> > > Currently, `fill_sg_entry()` splits the scatterlist using `UINT_MAX`. > This creates a non-page-aligned DMA length (`0xFFFFFFFF`) for the > first entry, resulting in non-page-aligned DMA addresses for all > subsequent entries. > > While the underlying IOMMU mapping may be contiguous, hardware > DMA engines often require explicit address alignment (e.g., page, > cacheline, or storage sector boundaries). Passing unaligned > addresses and lengths can cause explicit failures in DMA descriptor > creation or silent data corruption if lower unaligned bits are > truncated. > > In addition, a non-page-aligned sgl length will trigger an edge case > in `ib_umem_find_best_pgsz()`. In case of a discontinuity in later > buffers, we will have a `va` with lowest bit set to 1. That will lead > to `ib_umem_find_best_pgsz()` always return 0, and break the promise > to find best page size for the mapping on the NIC side. > > Fix this by splitting the scatterlist by the largest possible page > aligned chunk within `UINT_MAX` (`ALIGN_DOWN(UINT_MAX, PAGE_SIZE)`). > This ensures all scatterlist DMA addresses and lengths remain page > aligned, while minimizing the total number of sgl entries. > > Page-aligned entries allow the system to cleanly chunk payloads into > PCIe MaxPayloadSize (MPS) (e.g., 128 bytes, 256 bytes, 512 bytes). > As a result, this may help reduce TLP fragmentation in P2P transfers > and alleviate potential congestion within a logical PCIe switch > partition, especially when Relaxed Ordering is not possible due to > hardware constraints. > > Reported-by: sashiko-bot <[email protected]> > Closes: https://lore.kernel.org/all/[email protected]/ > Fixes: 3aa31a8bb11e ("dma-buf: provide phys_vec to scatter-gather mapping routine") > Cc: [email protected] > Signed-off-by: David Hu <[email protected]> > --- > Changes in v3: > - Removed the type cast for `min` (David Laight) > - Reverted max ent size to be `ALIGN_DOWN(UINT_MAX, PAGE_SIZE)` and > updated commit message to reflect that (Jason Gunthorpe) > - Updated commit message to reflect that this also fixes an edge case > in `ib_umem_find_best_pgsz()` > > Changes in v2: > - Updated commit title and message to reflect the switch to 2G chunks > - Switch to using 2G as the max sg entry size as it naturally aligns > with most hardware boundaries, while allowing compiler optimizations > with bit shifts (David Laight) > - Optimized away division calculation for `nent`, and multiplication > calculation for sgl address, by dropping the `for` loop in favor of a > `while (length)` loop (David Laight) > - Dropped `min_t` in favor of `min()` to maintain a strict type > checking safety net (David Laight) > > drivers/dma-buf/dma-buf-mapping.c | 19 +++++++++++-------- > 1 file changed, 11 insertions(+), 8 deletions(-) Could you please avoid sending patches as replies? It severely disrupts the reading flow when using mutt's threaded view. Regarding the patch, Reviewed-by: Leon Romanovsky <[email protected]> Thanks