summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCalvin Owens <calvin@wbinvd.org>2026-04-29 00:10:25 -0700
committerDavid Sterba <dsterba@suse.com>2026-05-08 00:30:53 +0200
commit4822703b150fc25f7bdb8cf266a482619881a97e (patch)
tree87db32acef201e46d98fdcdbfebe4280739ba234
parentfc51cba3ebae67f967120e27162e94cfb8594479 (diff)
btrfs: always pass __GFP_NOWARN from add_ra_bio_pages()
A build workload newly prints order-0 allocation failures on 7.1-rc1: sh: page allocation failure: order:0 mode:0x14084a(__GFP_HIGHMEM|__GFP_MOVABLE|__GFP_IO|__GFP_KSWAPD_RECLAIM| __GFP_COMP|__GFP_HARDWALL) CPU: 27 UID: 1000 PID: 855540 Comm: sh Not tainted 7.1.0-rc1-llvm-00058-gdca922e019dd #1 PREEMPTLAZY Call Trace: <TASK> dump_stack_lvl+0x50/0x70 warn_alloc+0xeb/0x100 __alloc_pages_slowpath+0x567/0x5a0 ? filemap_get_entry+0x11a/0x140 __alloc_frozen_pages_noprof+0x249/0x2d0 alloc_pages_mpol+0xe4/0x180 folio_alloc_noprof+0x80/0xa0 add_ra_bio_pages+0x13c/0x4b0 btrfs_submit_compressed_read+0x229/0x300 submit_one_bio+0x9e/0xe0 btrfs_readahead+0x185/0x1a0 [...] (lldb) source list -a add_ra_bio_pages+0x13c .../vmlinux.unstripped add_ra_bio_pages + 316 at .../fs/btrfs/compression.c:454:8 451 452 folio = filemap_alloc_folio(mapping_gfp_constraint(mapping, constraint_gfp), 453 0, NULL); -> 454 if (!folio) 455 break; I can reproduce this consistently by running a memory hog concurrently with a buffered writer on a machine with a very large amount of swap. Commit 7ae37b2c94ed ("btrfs: prevent direct reclaim during compressed readahead") clearly intended to suppress these warnings. But because the mask set in the address_space with mapping_set_gfp_mask() doesn't include __GFP_NOWARN, mapping_gfp_constraint() removes it from constraint_gfp before it is passed to filemap_alloc_folio(). Fix by refactoring the code to add __GFP_NOWARN after the call to mapping_gfp_constraint(). Fixes: 7ae37b2c94ed ("btrfs: prevent direct reclaim during compressed readahead") Signed-off-by: Calvin Owens <calvin@wbinvd.org> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--fs/btrfs/compression.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index c5783ac1b646..e2ef01a59d04 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -407,22 +407,18 @@ static noinline int add_ra_bio_pages(struct inode *inode,
end_index = (i_size_read(inode) - 1) >> PAGE_SHIFT;
- /*
- * Avoid direct reclaim when the caller does not allow it. Since
- * add_ra_bio_pages() is always speculative, suppress allocation warnings
- * in either case.
- */
+ /* Avoid direct reclaim when the caller does not allow it. */
+ constraint_gfp = ~__GFP_FS;
+ cache_gfp = GFP_NOFS | __GFP_NOWARN;
if (!direct_reclaim) {
- constraint_gfp = ~(__GFP_FS | __GFP_DIRECT_RECLAIM) | __GFP_NOWARN;
- cache_gfp = (GFP_NOFS & ~__GFP_DIRECT_RECLAIM) | __GFP_NOWARN;
- } else {
- constraint_gfp = (~__GFP_FS) | __GFP_NOWARN;
- cache_gfp = GFP_NOFS | __GFP_NOWARN;
+ constraint_gfp &= ~__GFP_DIRECT_RECLAIM;
+ cache_gfp &= ~__GFP_DIRECT_RECLAIM;
}
while (cur < compressed_end) {
pgoff_t page_end;
pgoff_t pg_index = cur >> PAGE_SHIFT;
+ gfp_t masked_constraint_gfp;
u32 add_size;
if (pg_index > end_index)
@@ -449,8 +445,14 @@ static noinline int add_ra_bio_pages(struct inode *inode,
continue;
}
- folio = filemap_alloc_folio(mapping_gfp_constraint(mapping, constraint_gfp),
- 0, NULL);
+ /*
+ * Since add_ra_bio_pages() is always speculative, suppress
+ * allocation warnings.
+ */
+ masked_constraint_gfp = mapping_gfp_constraint(mapping, constraint_gfp);
+ masked_constraint_gfp |= __GFP_NOWARN;
+
+ folio = filemap_alloc_folio(masked_constraint_gfp, 0, NULL);
if (!folio)
break;