On Fri, Oct 23, 2020 at 09:39:58AM -0700, Jianxin Xiong wrote: > +/* > + * Generate a new dma sg list from a sub range of an existing dma sg list. > + * Both the input and output have their entries page aligned. > + */ > +static int ib_umem_dmabuf_sgt_slice(struct sg_table *sgt, u64 offset, > + u64 length, struct sg_table *new_sgt) > +{ > + struct scatterlist *sg, *new_sg; > + u64 start, end, off, addr, len; > + unsigned int new_nents; > + int err; > + int i; > + > + start = ALIGN_DOWN(offset, PAGE_SIZE); > + end = ALIGN(offset + length, PAGE_SIZE); > + > + offset = start; > + length = end - start; > + new_nents = 0; > + for_each_sgtable_dma_sg(sgt, sg, i) { > + len = sg_dma_len(sg); > + off = min(len, offset); > + len -= off; > + len = min(len, length); > + if (len) > + new_nents++; > + length -= len; > + offset -= off; > + } > + > + err = sg_alloc_table(new_sgt, new_nents, GFP_KERNEL); > + if (err) > + return err; I would really rather not allocate an entirely new table just to take a slice of an existing SGT. Ideally the expoter API from DMA buf would prepare the SGL slice properly instead of always giving a whole buffer. Alternatively making some small edit to rdma_umem_for_each_dma_block() and ib_umem_find_best_pgsz() would let it slice the SGL at runtime You need to rebase on top of this series: https://patchwork.kernel.org/project/linux-rdma/list/?series=370437 Which makes mlx5 use those new APIs Jason