vhost_vdpa_pa_unmap() unpins each mapping a page at a time, dirtying
each page first if the mapping is writable. Each mapping is physically
contiguous, so use unpin_user_page_range_dirty_lock() instead, which
marks every folio dirty once and drops its pins in one go. Do the same
for the pages left pinned in the vhost_vdpa_pa_map() error path.

This removes the last use of set_page_dirty_lock() in vhost.

Signed-off-by: Tal Zussman <[email protected]>
---
 drivers/vhost/vdpa.c | 20 ++++++--------------
 1 file changed, 6 insertions(+), 14 deletions(-)

diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
index d9af728942b3..cd5da522fdc0 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -972,18 +972,11 @@ static void vhost_vdpa_pa_unmap(struct vhost_vdpa *v, 
struct vhost_iotlb *iotlb,
 {
        struct vhost_dev *dev = &v->vdev;
        struct vhost_iotlb_map *map;
-       struct page *page;
-       unsigned long pfn, pinned;
 
        while ((map = vhost_iotlb_itree_first(iotlb, start, last)) != NULL) {
-               pinned = PFN_DOWN(map->size);
-               for (pfn = PFN_DOWN(map->addr);
-                    pinned > 0; pfn++, pinned--) {
-                       page = pfn_to_page(pfn);
-                       if (map->perm & VHOST_ACCESS_WO)
-                               set_page_dirty_lock(page);
-                       unpin_user_page(page);
-               }
+               
unpin_user_page_range_dirty_lock(pfn_to_page(PFN_DOWN(map->addr)),
+                                                PFN_DOWN(map->size),
+                                                map->perm & VHOST_ACCESS_WO);
                atomic64_sub(PFN_DOWN(map->size), &dev->mm->pinned_vm);
                vhost_vdpa_general_unmap(v, map, asid);
                vhost_iotlb_map_free(iotlb, map);
@@ -1246,8 +1239,6 @@ static int vhost_vdpa_pa_map(struct vhost_vdpa *v,
 out:
        if (ret) {
                if (last_pfn) {
-                       unsigned long pfn;
-
                        /*
                         * Unpin the outstanding pages which are yet to be
                         * mapped but haven't due to vdpa_map() or
@@ -1257,8 +1248,9 @@ static int vhost_vdpa_pa_map(struct vhost_vdpa *v,
                         * the corresponding unpinning will be handled by
                         * vdpa_unmap().
                         */
-                       for (pfn = map_pfn; pfn <= last_pfn; pfn++)
-                               unpin_user_page(pfn_to_page(pfn));
+                       unpin_user_page_range_dirty_lock(pfn_to_page(map_pfn),
+                                                        last_pfn - map_pfn + 1,
+                                                        false);
                }
                vhost_vdpa_unmap(v, iotlb, start, size);
        }

-- 
2.39.5


Reply via email to