Re: [PATCH v3] mm/page_alloc: avoid direct compaction for costly __GFP_NORETRY allocations

"Vlastimil Babka (SUSE)" <[email protected]>
Newsgroups org.kernel.vger.linux-xfs,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel,org.kernel.vger.stable,org.kvack.linux-mm
Message-ID <[email protected]>
On 7/10/26 20:03, Matthew Wilcox wrote:
> On Fri, Jul 10, 2026 at 02:34:37PM +0000, Salvatore Dipietro wrote:
>> Commit 5d8edfb900d5 ("iomap: Copy larger chunks from userspace")
>> introduced high-order folio allocations in the iomap buffered write
>> path.
> 
> https://lore.kernel.org/linux-mm/[email protected]/
> 
> I just had a go at implementing what I thought might be the right design
> (having a folio_alloc_orders(min, max, gfp)), but that's not really what
> __filemap_get_folio_mpol() wants because it needs to integrate the actual
> adding of folios to the page cache into the retry loop.
> 
> So instead, let's try this.  The idea is that we want to try direct reclaim
> _twice_.  Once gently (ie with NORETRY specified) when we're trying to
> allocate the maximum order folio.  But now that we've tried that once,
> there's no point trying direct reclaim for other sizes, we just want to
> ask the page allocator if it can give us memory of any subsequent size.
> 
> Until we come to the minimum order.  Then we want to try exactly as hard
> as we were originally asked to try.  So revert to the original gfp flags
> and don't set the NOWARN or NORETRY flags.
> 
> diff --git a/mm/filemap.c b/mm/filemap.c
> index 58eb9d240643..23eecaf9b328 100644
> --- a/mm/filemap.c
> +++ b/mm/filemap.c
> @@ -1983,6 +1983,7 @@ struct folio *__filemap_get_folio_mpol(struct address_space *mapping,
>  	if (!folio && (fgp_flags & FGP_CREAT)) {
>  		unsigned int min_order = mapping_min_folio_order(mapping);
>  		unsigned int order = max(min_order, FGF_GET_ORDER(fgp_flags));
> +		gfp_t alloc_gfp = gfp | __GFP_NORETRY | __GFP_NOWARN;
>  		int err;
>  		index = mapping_align_index(mapping, index);

Note here fgp_flags are checked and may alter gfp towards NOFS or NOWAIT or
add __GFP_WRITE. But alloc_gfp set above will ignore all that for >min_order
attempts, which isn't right. Probably doesn't affect Salvatore's evaluation
though.

> @@ -2004,12 +2005,11 @@ struct folio *__filemap_get_folio_mpol(struct address_space *mapping,
>  			order = __ffs(index);
>  
>  		do {
> -			gfp_t alloc_gfp = gfp;
> -
>  			err = -ENOMEM;
> -			if (order > min_order)
> -				alloc_gfp |= __GFP_NORETRY | __GFP_NOWARN;
> +			if (order == min_order)
> +				alloc_gfp = gfp;
>  			folio = filemap_alloc_folio(alloc_gfp, order, policy);
> +			alloc_gfp &= ~__GFP_DIRECT_RECLAIM;
>  			if (!folio)
>  				continue;
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.