Commit 91d6ac1d authored by Sweet Tea Dorminy's avatar Sweet Tea Dorminy Committed by David Sterba

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: default avatarNikolay Borisov <nborisov@suse.com>
Signed-off-by: default avatarSweet Tea Dorminy <sweettea-kernel@dorminy.me>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent dd137dd1
...@@ -3146,17 +3146,20 @@ static void end_bio_extent_readpage(struct bio *bio) ...@@ -3146,17 +3146,20 @@ static void end_bio_extent_readpage(struct bio *bio)
*/ */
int btrfs_alloc_page_array(unsigned int nr_pages, struct page **page_array) 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++) { for (allocated = 0; allocated < nr_pages;) {
struct page *page; unsigned int last = allocated;
if (page_array[i]) allocated = alloc_pages_bulk_array(GFP_NOFS, nr_pages, page_array);
continue;
page = alloc_page(GFP_NOFS); /*
if (!page) * 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; return -ENOMEM;
page_array[i] = page;
} }
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment