diff mbox series

[v2,6/7] NFS: direct-io: convert to FOLL_PIN pages

Message ID 20220831041843.973026-7-jhubbard@nvidia.com (mailing list archive)
State Deferred, archived
Headers show
Series convert most filesystems to pin_user_pages_fast() | expand

Commit Message

John Hubbard Aug. 31, 2022, 4:18 a.m. UTC
Convert the NFS Direct IO layer to use pin_user_pages_fast() and
unpin_user_page(), instead of get_user_pages_fast() and put_page().

The user of pin_user_pages_fast() depends upon:

1) CONFIG_BLK_USE_PIN_USER_PAGES_FOR_DIO, and

2) User-space-backed pages: user_backed_iter(i) == true

Signed-off-by: John Hubbard <jhubbard@nvidia.com>
---
 fs/nfs/direct.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

Comments

Christoph Hellwig Sept. 6, 2022, 6:49 a.m. UTC | #1
On Tue, Aug 30, 2022 at 09:18:42PM -0700, John Hubbard wrote:
static void nfs_direct_release_pages(struct iov_iter *iter, struct page **pages,
				     unsigned int npages)
>  {
> -	unsigned int i;
> -	for (i = 0; i < npages; i++)
> -		put_page(pages[i]);
> +	if (user_backed_iter(iter) || iov_iter_is_bvec(iter))
> +		dio_w_unpin_user_pages(pages, npages);
> +	else
> +		release_pages(pages, npages);

Instead of having this magic in all kinds of places, we need a helper
that takes the page array, npages and iter->type and does the right
thing.
John Hubbard Sept. 6, 2022, 7:16 a.m. UTC | #2
On 9/5/22 23:49, Christoph Hellwig wrote:
> On Tue, Aug 30, 2022 at 09:18:42PM -0700, John Hubbard wrote:
> static void nfs_direct_release_pages(struct iov_iter *iter, struct page **pages,
> 				     unsigned int npages)
>>  {
>> -	unsigned int i;
>> -	for (i = 0; i < npages; i++)
>> -		put_page(pages[i]);
>> +	if (user_backed_iter(iter) || iov_iter_is_bvec(iter))
>> +		dio_w_unpin_user_pages(pages, npages);
>> +	else
>> +		release_pages(pages, npages);
> 
> Instead of having this magic in all kinds of places, we need a helper
> that takes the page array, npages and iter->type and does the right
> thing.

Yes, Miklos asked for much the same thing, too. :)

thanks,
diff mbox series

Patch

diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 1707f46b1335..71b794f39ee2 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -142,11 +142,13 @@  int nfs_swap_rw(struct kiocb *iocb, struct iov_iter *iter)
 	return 0;
 }
 
-static void nfs_direct_release_pages(struct page **pages, unsigned int npages)
+static void nfs_direct_release_pages(struct iov_iter *iter, struct page **pages,
+				     unsigned int npages)
 {
-	unsigned int i;
-	for (i = 0; i < npages; i++)
-		put_page(pages[i]);
+	if (user_backed_iter(iter) || iov_iter_is_bvec(iter))
+		dio_w_unpin_user_pages(pages, npages);
+	else
+		release_pages(pages, npages);
 }
 
 void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo,
@@ -332,11 +334,11 @@  static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
 		size_t pgbase;
 		unsigned npages, i;
 
-		result = iov_iter_get_pages_alloc2(iter, &pagevec,
+		result = dio_w_iov_iter_pin_pages_alloc(iter, &pagevec,
 						  rsize, &pgbase);
 		if (result < 0)
 			break;
-	
+
 		bytes = result;
 		npages = (result + pgbase + PAGE_SIZE - 1) / PAGE_SIZE;
 		for (i = 0; i < npages; i++) {
@@ -362,7 +364,7 @@  static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
 			pos += req_len;
 			dreq->bytes_left -= req_len;
 		}
-		nfs_direct_release_pages(pagevec, npages);
+		nfs_direct_release_pages(iter, pagevec, npages);
 		kvfree(pagevec);
 		if (result < 0)
 			break;
@@ -791,8 +793,8 @@  static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
 		size_t pgbase;
 		unsigned npages, i;
 
-		result = iov_iter_get_pages_alloc2(iter, &pagevec,
-						  wsize, &pgbase);
+		result = dio_w_iov_iter_pin_pages_alloc(iter, &pagevec,
+							wsize, &pgbase);
 		if (result < 0)
 			break;
 
@@ -829,7 +831,7 @@  static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
 			pos += req_len;
 			dreq->bytes_left -= req_len;
 		}
-		nfs_direct_release_pages(pagevec, npages);
+		nfs_direct_release_pages(iter, pagevec, npages);
 		kvfree(pagevec);
 		if (result < 0)
 			break;