diff options
| author | Calvin Owens <calvin@wbinvd.org> | 2026-04-29 00:10:25 -0700 |
|---|---|---|
| committer | David Sterba <dsterba@suse.com> | 2026-05-08 00:30:53 +0200 |
| commit | 4822703b150fc25f7bdb8cf266a482619881a97e (patch) | |
| tree | 87db32acef201e46d98fdcdbfebe4280739ba234 | |
| parent | fc51cba3ebae67f967120e27162e94cfb8594479 (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.c | 26 |
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; |
