diff mbox series

[11/11] xfs: use alloc_pages_bulk_array() for buffers

Message ID 20210519190900.320044-12-hch@lst.de (mailing list archive)
State Superseded
Headers show
Series [01/11] xfs: cleanup error handling in xfs_buf_get_map | expand

Commit Message

Christoph Hellwig May 19, 2021, 7:09 p.m. UTC
From: Dave Chinner <dchinner@redhat.com>

Because it's more efficient than allocating pages one at a time in a
loop.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
[hch: rebased ontop of a bunch of cleanups]
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/xfs_buf.c | 39 +++++++++++++++------------------------
 1 file changed, 15 insertions(+), 24 deletions(-)
diff mbox series

Patch

diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index a1295b5b6f0ca6..e2439503fc13bb 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -354,7 +354,7 @@  xfs_buf_alloc_pages(
 	xfs_buf_flags_t		flags)
 {
 	gfp_t			gfp_mask = __GFP_NOWARN;
-	int			i;
+	unsigned long		filled = 0;
 
 	if (flags & XBF_READ_AHEAD)
 		gfp_mask |= __GFP_NORETRY;
@@ -377,36 +377,27 @@  xfs_buf_alloc_pages(
 		bp->b_pages = bp->b_page_array;
 	}
 
-	for (i = 0; i < bp->b_page_count; i++) {
-		struct page	*page;
-		uint		retries = 0;
-retry:
-		page = alloc_page(gfp_mask);
-		if (unlikely(!page)) {
+	/*
+	 * Bulk filling of pages can take multiple calls. Not filling the entire
+	 * array is not an allocation failure, so don't back off if we get at
+	 * least one extra page.
+	 */
+	for (;;) {
+		unsigned long	last = filled;
+
+		filled = alloc_pages_bulk_array(gfp_mask, bp->b_page_count,
+						bp->b_pages);
+		if (filled == bp->b_page_count)
+			break;
+		if (filled == last) {
 			if (flags & XBF_READ_AHEAD) {
-				bp->b_page_count = i;
+				bp->b_page_count = filled;
 				xfs_buf_free_pages(bp);
 				return -ENOMEM;
 			}
-
-			/*
-			 * This could deadlock.
-			 *
-			 * But until all the XFS lowlevel code is revamped to
-			 * handle buffer allocation failures we can't do much.
-			 */
-			if (!(++retries % 100))
-				xfs_err(NULL,
-		"%s(%u) possible memory allocation deadlock in %s (mode:0x%x)",
-					current->comm, current->pid,
-					__func__, gfp_mask);
-
 			XFS_STATS_INC(bp->b_mount, xb_page_retries);
 			congestion_wait(BLK_RW_ASYNC, HZ/50);
-			goto retry;
 		}
-
-		bp->b_pages[i] = page;
 	}
 
 	bp->b_flags |= _XBF_PAGES;