Thread (34 messages) 34 messages, 7 authors, 2022-11-09

Re: [PATCH v11 3/9] iov_iter: introduce iov_iter_get_pages_[alloc_]flags()

From: Logan Gunthorpe <logang@deltatee.com>
Date: 2022-10-25 15:35:39
Also in: linux-mm, linux-nvme, linux-pci, lkml


On 2022-10-24 19:14, Chaitanya Kulkarni wrote:
On 10/21/22 10:41, Logan Gunthorpe wrote:
quoted
Add iov_iter_get_pages_flags() and iov_iter_get_pages_alloc_flags()
which take a flags argument that is passed to get_user_pages_fast().

This is so that FOLL_PCI_P2PDMA can be passed when appropriate.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
  include/linux/uio.h |  6 ++++++
  lib/iov_iter.c      | 32 ++++++++++++++++++++++++--------
  2 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/include/linux/uio.h b/include/linux/uio.h
index 2e3134b14ffd..9ede533ce64c 100644
--- a/include/linux/uio.h
+++ b/include/linux/uio.h
@@ -247,8 +247,14 @@ void iov_iter_pipe(struct iov_iter *i, unsigned int direction, struct pipe_inode
  void iov_iter_discard(struct iov_iter *i, unsigned int direction, size_t count);
  void iov_iter_xarray(struct iov_iter *i, unsigned int direction, struct xarray *xarray,
  		     loff_t start, size_t count);
+ssize_t iov_iter_get_pages(struct iov_iter *i, struct page **pages,
+		size_t maxsize, unsigned maxpages, size_t *start,
+		unsigned gup_flags);
  ssize_t iov_iter_get_pages2(struct iov_iter *i, struct page **pages,
  			size_t maxsize, unsigned maxpages, size_t *start);
+ssize_t iov_iter_get_pages_alloc(struct iov_iter *i,
+		struct page ***pages, size_t maxsize, size_t *start,
+		unsigned gup_flags);
  ssize_t iov_iter_get_pages_alloc2(struct iov_iter *i, struct page ***pages,
  			size_t maxsize, size_t *start);
  int iov_iter_npages(const struct iov_iter *i, int maxpages);
diff --git a/lib/iov_iter.c b/lib/iov_iter.c
index c3ca28ca68a6..53efad017f3c 100644
--- a/lib/iov_iter.c
+++ b/lib/iov_iter.c
@@ -1430,7 +1430,8 @@ static struct page *first_bvec_segment(const struct iov_iter *i,
  
  static ssize_t __iov_iter_get_pages_alloc(struct iov_iter *i,
  		   struct page ***pages, size_t maxsize,
-		   unsigned int maxpages, size_t *start)
+		   unsigned int maxpages, size_t *start,
+		   unsigned int gup_flags)
  {
  	unsigned int n;
  
@@ -1442,7 +1443,6 @@ static ssize_t __iov_iter_get_pages_alloc(struct iov_iter *i,
  		maxsize = MAX_RW_COUNT;
  
  	if (likely(user_backed_iter(i))) {
-		unsigned int gup_flags = 0;
  		unsigned long addr;
  		int res;
  
@@ -1492,33 +1492,49 @@ static ssize_t __iov_iter_get_pages_alloc(struct iov_iter *i,
  	return -EFAULT;
  }
  
-ssize_t iov_iter_get_pages2(struct iov_iter *i,
+ssize_t iov_iter_get_pages(struct iov_iter *i,
  		   struct page **pages, size_t maxsize, unsigned maxpages,
-		   size_t *start)
+		   size_t *start, unsigned gup_flags)
  {
  	if (!maxpages)
  		return 0;
  	BUG_ON(!pages);
  
-	return __iov_iter_get_pages_alloc(i, &pages, maxsize, maxpages, start);
+	return __iov_iter_get_pages_alloc(i, &pages, maxsize, maxpages,
+					  start, gup_flags);
+}
+EXPORT_SYMBOL_GPL(iov_iter_get_pages);
+
+ssize_t iov_iter_get_pages2(struct iov_iter *i, struct page **pages,
+		size_t maxsize, unsigned maxpages, size_t *start)
+{
+	return iov_iter_get_pages(i, pages, maxsize, maxpages, start, 0);
  }
  EXPORT_SYMBOL(iov_iter_get_pages2);
  
-ssize_t iov_iter_get_pages_alloc2(struct iov_iter *i,
+ssize_t iov_iter_get_pages_alloc(struct iov_iter *i,
  		   struct page ***pages, size_t maxsize,
-		   size_t *start)
+		   size_t *start, unsigned gup_flags)
  {
  	ssize_t len;
  
  	*pages = NULL;
  
-	len = __iov_iter_get_pages_alloc(i, pages, maxsize, ~0U, start);
+	len = __iov_iter_get_pages_alloc(i, pages, maxsize, ~0U, start,
+					 gup_flags);
  	if (len <= 0) {
  		kvfree(*pages);
  		*pages = NULL;
  	}
  	return len;
  }
+EXPORT_SYMBOL_GPL(iov_iter_get_pages_alloc);
+
+ssize_t iov_iter_get_pages_alloc2(struct iov_iter *i,
+		struct page ***pages, size_t maxsize, size_t *start)
+{
+	return iov_iter_get_pages_alloc(i, pages, maxsize, start, 0);
+}
  EXPORT_SYMBOL(iov_iter_get_pages_alloc2);
Just one minor question why not make following functions
EXPORT_SYMBOL_GPL() ?

1. iov_iter_get_pages2()
2. iov_iter_get_pages_alloc2()
They previously were not GPL, so I didn't think that should be changed
in this patch.

Thanks for the review!

Logan
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help