On Mon, Dec 24, 2018 at 04:32:22PM -0600, Shiraz Saleem wrote: > - for_each_sg(umem->sg_head.sgl, sg, umem->nmap, entry) { > - pages = sg_dma_len(sg) >> PAGE_SHIFT; > - for (i = 0; i < pages; i++) { > - paddr = sg_dma_address(sg) + (i << PAGE_SHIFT); > - if (pbl_tbl == pbl_tbl_orig) > - *pbl_tbl++ = paddr & ~page_mask; > - else if ((paddr & page_mask) == 0) > - *pbl_tbl++ = paddr; > - } > + struct sg_page_iter sg_iter; > + > + for_each_sg_page(umem->sg_head.sgl, &sg_iter, umem->nmap, 0) { > + paddr = sg_page_iter_dma_address(&sg_iter); Actually, I'm looking at this again, and thinking this looks problematic.. for_each_sg_page iterates over the original SGL, it does not iterate over the DMA mapped SGL (ie it does not use sg_dma_len()) - so this is not an entirely equivalent transformation. I think you need to add a for_each_sg_dma_page() to make this work correctly? The only difference would be to use sg_dma_len instead of length? And I wonder how many of these places in drivers work properly if PAGE_SIZE != 4k :( CH: Does sg_page_iter_dma_address() even make any sense?? Jason