From: Dave Chinner <dchinner@xxxxxxxxxx> Because it's more efficient than allocating pages one at a time in a loop. Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx> [hch: rebased ontop of a bunch of cleanups] Signed-off-by: Christoph Hellwig <hch@xxxxxx> --- fs/xfs/xfs_buf.c | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) 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; -- 2.30.2