On Wed, Jun 18, 2025 at 02:28:20PM +0800, lizhe.67@xxxxxxxxxxxxx wrote:
On Tue, 17 Jun 2025 12:22:10 -0300, jgg@xxxxxxxx wrote:
+ while (npage) {
+ long nr_pages = 1;
+
+ if (!is_invalid_reserved_pfn(pfn)) {
+ struct page *page = pfn_to_page(pfn);
+ struct folio *folio = page_folio(page);
+ long folio_pages_num = folio_nr_pages(folio);
+
+ /*
+ * For a folio, it represents a physically
+ * contiguous set of bytes, and all of its pages
+ * share the same invalid/reserved state.
+ *
+ * Here, our PFNs are contiguous. Therefore, if we
+ * detect that the current PFN belongs to a large
+ * folio, we can batch the operations for the next
+ * nr_pages PFNs.
+ */
+ if (folio_pages_num > 1)
+ nr_pages = min_t(long, npage,
+ folio_pages_num -
+ folio_page_idx(folio, page));
+
+ unpin_user_folio_dirty_locked(folio, nr_pages,
+ dma->prot & IOMMU_WRITE);
Are you suggesting that we should directly call
unpin_user_page_range_dirty_lock() here (patch 3/3) instead?
I'm saying you should not have the word 'folio' inside the VFIO. You
accumulate a contiguous range of pfns, by only checking the pfn, and
then call
unpin_user_page_range_dirty_lock(pfn_to_page(first_pfn)...);
No need for any of this. vfio should never look at the struct page
except as the last moment to pass the range.