On Wed, Jun 03, 2026 at 11:17:55PM +0800, Guanghui Feng wrote: > Use iommu_iova_to_phys_length() to get PTE page size, allowing > traversal by actual mapping granularity instead of PAGE_SIZE steps. > > Signed-off-by: Guanghui Feng <[email protected]> > Acked-by: Shiqiang Zhang <[email protected]> > Acked-by: Simon Guo <[email protected]> > --- > drivers/vfio/vfio_iommu_type1.c | 27 ++++++++++++++++++++++----- > 1 file changed, 22 insertions(+), 5 deletions(-) > > diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c > index c8151ba54de3..115d88d7003e 100644 > --- a/drivers/vfio/vfio_iommu_type1.c > +++ b/drivers/vfio/vfio_iommu_type1.c > @@ -1177,25 +1177,42 @@ static long vfio_unmap_unpin(struct vfio_iommu > *iommu, struct vfio_dma *dma, > > iommu_iotlb_gather_init(&iotlb_gather); > while (pos < dma->size) { > - size_t unmapped, len; > + size_t unmapped, len, pgsize; > phys_addr_t phys, next; > dma_addr_t iova = dma->iova + pos; > > - phys = iommu_iova_to_phys(domain->domain, iova); > - if (WARN_ON(!phys)) { > + /* Single page table walk returns both phys and PTE size */ > + phys = iommu_iova_to_phys_length(domain->domain, iova, > + &pgsize); > + if (WARN_ON(phys == PHYS_ADDR_MAX)) { > pos += PAGE_SIZE; > continue; > } > + if (WARN_ON(!pgsize || pgsize < PAGE_SIZE)) > + pgsize = PAGE_SIZE; > > /* > * To optimize for fewer iommu_unmap() calls, each of which > * may require hardware cache flushing, try to find the > * largest contiguous physical memory chunk to unmap. > + * > + * mapped_length already accounts for contiguous entries > + * from iova, then try to join following physically > + * contiguous PTEs. > */ > - for (len = PAGE_SIZE; pos + len < dma->size; len += PAGE_SIZE) { > - next = iommu_iova_to_phys(domain->domain, iova + len); > + len = min_t(size_t, pgsize, dma->size - pos); > + for (; pos + len < dma->size; ) { > + size_t next_pgsize; > + > + next = iommu_iova_to_phys_length(domain->domain, > + iova + len, > + &next_pgsize);
vfio should not be calling it twice, the core code needs to give the best length as efficiently as it can. not open coding this in callers. I think I've said this three times now Jason
