aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSweet Tea Dorminy <[email protected]>2022-04-06 14:24:18 -0400
committerDavid Sterba <[email protected]>2022-05-16 17:03:11 +0200
commit395cb57e85604715110bc28bd51bdf532394b68d (patch)
tree7c1487af39bc4fd0aad7bd56d802e20974141f9a
parent91d6ac1d62c3dc0f102986318f4027ccfa22c638 (diff)
btrfs: wait between incomplete batch memory allocations
When allocating memory in a loop, each iteration should call memalloc_retry_wait() in order to prevent starving memory-freeing processes (and to mark where allocation loops are). Other filesystems do that as well. The bulk page allocation is the only place in btrfs with an allocation retry loop, so add an appropriate call to it. Signed-off-by: Sweet Tea Dorminy <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]>
-rw-r--r--fs/btrfs/extent_io.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index cfcbfd5a5467..50626f487599 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -6,6 +6,7 @@
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/page-flags.h>
+#include <linux/sched/mm.h>
#include <linux/spinlock.h>
#include <linux/blkdev.h>
#include <linux/swap.h>
@@ -3153,6 +3154,9 @@ int btrfs_alloc_page_array(unsigned int nr_pages, struct page **page_array)
allocated = alloc_pages_bulk_array(GFP_NOFS, nr_pages, page_array);
+ if (allocated == nr_pages)
+ return 0;
+
/*
* During this iteration, no page could be allocated, even
* though alloc_pages_bulk_array() falls back to alloc_page()
@@ -3160,6 +3164,8 @@ int btrfs_alloc_page_array(unsigned int nr_pages, struct page **page_array)
*/
if (allocated == last)
return -ENOMEM;
+
+ memalloc_retry_wait(GFP_NOFS);
}
return 0;
}