mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
vhost-vdpa: unpin mappings by range
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 <tz2294@columbia.edu> Message-ID: <20261031-vhost-vdpa-unpin-v1-2-94ffc9683256@columbia.edu> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
fd1462c96b
commit
73d135601d
|
|
@ -972,20 +972,13 @@ 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) {
|
||||
/* Stop device access before releasing the pinned pages. */
|
||||
vhost_vdpa_general_unmap(v, map, asid);
|
||||
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_iotlb_map_free(iotlb, map);
|
||||
}
|
||||
|
|
@ -1265,8 +1258,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
|
||||
|
|
@ -1276,8 +1267,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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user