summaryrefslogtreecommitdiff
path: root/fs/btrfs/extent_io.c
diff options
context:
space:
mode:
authorSweet Tea Dorminy <sweettea-kernel@dorminy.me>2022-03-30 23:11:23 +0300
committerDavid Sterba <dsterba@suse.com>2022-05-16 18:03:11 +0300
commit91d6ac1d62c3dc0f102986318f4027ccfa22c638 (patch)
treedec40c8a71ce428f4ff34057043f31924df4082a /fs/btrfs/extent_io.c
parentdd137dd1f2d719682b522d4eabe6dec461b7d6fa (diff)
downloadlinux-91d6ac1d62c3dc0f102986318f4027ccfa22c638.tar.xz
btrfs: allocate page arrays using bulk page allocator
While calling alloc_page() in a loop is an effective way to populate an array of pages, the MM subsystem provides a method to allocate pages in bulk. alloc_pages_bulk_array() populates the NULL slots in a page array, trying to grab more than one page at a time. Unfortunately, it doesn't guarantee allocating all slots in the array, but it's easy to call it in a loop and return an error if no progress occurs. Reviewed-by: Nikolay Borisov <nborisov@suse.com> Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r--fs/btrfs/extent_io.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index e472886c3b22..cfcbfd5a5467 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -3146,17 +3146,20 @@ readpage_ok:
*/
int btrfs_alloc_page_array(unsigned int nr_pages, struct page **page_array)
{
- int i;
+ unsigned int allocated;
- for (i = 0; i < nr_pages; i++) {
- struct page *page;
+ for (allocated = 0; allocated < nr_pages;) {
+ unsigned int last = allocated;
- if (page_array[i])
- continue;
- page = alloc_page(GFP_NOFS);
- if (!page)
+ allocated = alloc_pages_bulk_array(GFP_NOFS, nr_pages, page_array);
+
+ /*
+ * During this iteration, no page could be allocated, even
+ * though alloc_pages_bulk_array() falls back to alloc_page()
+ * if it could not bulk-allocate. So we must be out of memory.
+ */
+ if (allocated == last)
return -ENOMEM;
- page_array[i] = page;
}
return 0;
}