mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 00:51:51 -04:00
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 7ae37b2c94 ("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: 7ae37b2c94 ("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>
This commit is contained in:
committed by
David Sterba
parent
fc51cba3eb
commit
4822703b15
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user