linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Michal Hocko <mhocko@suse.com>
To: Vlastimil Babka <vbabka@suse.cz>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	Suren Baghdasaryan <surenb@google.com>,
	Brendan Jackman <jackmanb@google.com>,
	Johannes Weiner <hannes@cmpxchg.org>, Zi Yan <ziy@nvidia.com>,
	David Rientjes <rientjes@google.com>,
	David Hildenbrand <david@kernel.org>,
	Lorenzo Stoakes <lorenzo.stoakes@oracle.com>,
	"Liam R. Howlett" <Liam.Howlett@oracle.com>,
	Mike Rapoport <rppt@kernel.org>,
	Joshua Hahn <joshua.hahnjy@gmail.com>,
	Pedro Falcato <pfalcato@suse.de>,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH mm-unstable v3 2/3] mm/page_alloc: refactor the initial compaction handling
Date: Tue, 6 Jan 2026 14:56:24 +0100	[thread overview]
Message-ID: <aV0UiNM1BXo17meQ@tiehlicka> (raw)
In-Reply-To: <20260106-thp-thisnode-tweak-v3-2-f5d67c21a193@suse.cz>

On Tue 06-01-26 12:52:37, Vlastimil Babka wrote:
> The initial direct compaction done in some cases in
> __alloc_pages_slowpath() stands out from the main retry loop of
> reclaim + compaction.
> 
> We can simplify this by instead skipping the initial reclaim attempt via
> a new local variable compact_first, and handle the compact_prority as
> necessary to match the original behavior. No functional change intended.
> 
> Suggested-by: Johannes Weiner <hannes@cmpxchg.org>
> Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
> Reviewed-by: Joshua Hahn <joshua.hahnjy@gmail.com>

LGTM and it makes the code flow easier to follow
Acked-by: Michal Hocko <mhocko@suse.com>
> ---
>  include/linux/gfp.h |   8 ++++-
>  mm/page_alloc.c     | 100 +++++++++++++++++++++++++---------------------------
>  2 files changed, 55 insertions(+), 53 deletions(-)
> 
> diff --git a/include/linux/gfp.h b/include/linux/gfp.h
> index aa45989f410d..6ecf6dda93e0 100644
> --- a/include/linux/gfp.h
> +++ b/include/linux/gfp.h
> @@ -407,9 +407,15 @@ extern gfp_t gfp_allowed_mask;
>  /* Returns true if the gfp_mask allows use of ALLOC_NO_WATERMARK */
>  bool gfp_pfmemalloc_allowed(gfp_t gfp_mask);
>  
> +/* A helper for checking if gfp includes all the specified flags */
> +static inline bool gfp_has_flags(gfp_t gfp, gfp_t flags)
> +{
> +	return (gfp & flags) == flags;
> +}
> +
>  static inline bool gfp_has_io_fs(gfp_t gfp)
>  {
> -	return (gfp & (__GFP_IO | __GFP_FS)) == (__GFP_IO | __GFP_FS);
> +	return gfp_has_flags(gfp, __GFP_IO | __GFP_FS);
>  }
>  
>  /*
> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index b06b1cb01e0e..3b2579c5716f 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -4702,7 +4702,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
>  						struct alloc_context *ac)
>  {
>  	bool can_direct_reclaim = gfp_mask & __GFP_DIRECT_RECLAIM;
> -	bool can_compact = gfp_compaction_allowed(gfp_mask);
> +	bool can_compact = can_direct_reclaim && gfp_compaction_allowed(gfp_mask);
>  	bool nofail = gfp_mask & __GFP_NOFAIL;
>  	const bool costly_order = order > PAGE_ALLOC_COSTLY_ORDER;
>  	struct page *page = NULL;
> @@ -4715,6 +4715,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
>  	unsigned int cpuset_mems_cookie;
>  	unsigned int zonelist_iter_cookie;
>  	int reserve_flags;
> +	bool compact_first = false;
>  
>  	if (unlikely(nofail)) {
>  		/*
> @@ -4738,6 +4739,19 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
>  	cpuset_mems_cookie = read_mems_allowed_begin();
>  	zonelist_iter_cookie = zonelist_iter_begin();
>  
> +	/*
> +	 * For costly allocations, try direct compaction first, as it's likely
> +	 * that we have enough base pages and don't need to reclaim. For non-
> +	 * movable high-order allocations, do that as well, as compaction will
> +	 * try prevent permanent fragmentation by migrating from blocks of the
> +	 * same migratetype.
> +	 */
> +	if (can_compact && (costly_order || (order > 0 &&
> +					ac->migratetype != MIGRATE_MOVABLE))) {
> +		compact_first = true;
> +		compact_priority = INIT_COMPACT_PRIORITY;
> +	}
> +
>  	/*
>  	 * The fast path uses conservative alloc_flags to succeed only until
>  	 * kswapd needs to be woken up, and to avoid the cost of setting up
> @@ -4780,53 +4794,6 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
>  	if (page)
>  		goto got_pg;
>  
> -	/*
> -	 * For costly allocations, try direct compaction first, as it's likely
> -	 * that we have enough base pages and don't need to reclaim. For non-
> -	 * movable high-order allocations, do that as well, as compaction will
> -	 * try prevent permanent fragmentation by migrating from blocks of the
> -	 * same migratetype.
> -	 * Don't try this for allocations that are allowed to ignore
> -	 * watermarks, as the ALLOC_NO_WATERMARKS attempt didn't yet happen.
> -	 */
> -	if (can_direct_reclaim && can_compact &&
> -			(costly_order ||
> -			   (order > 0 && ac->migratetype != MIGRATE_MOVABLE))
> -			&& !gfp_pfmemalloc_allowed(gfp_mask)) {
> -		page = __alloc_pages_direct_compact(gfp_mask, order,
> -						alloc_flags, ac,
> -						INIT_COMPACT_PRIORITY,
> -						&compact_result);
> -		if (page)
> -			goto got_pg;
> -
> -		/*
> -		 * Checks for costly allocations with __GFP_NORETRY, which
> -		 * includes some THP page fault allocations
> -		 */
> -		if (costly_order && (gfp_mask & __GFP_NORETRY)) {
> -			/*
> -			 * THP page faults may attempt local node only first,
> -			 * but are then allowed to only compact, not reclaim,
> -			 * see alloc_pages_mpol().
> -			 *
> -			 * Compaction has failed above and we don't want such
> -			 * THP allocations to put reclaim pressure on a single
> -			 * node in a situation where other nodes might have
> -			 * plenty of available memory.
> -			 */
> -			if (gfp_mask & __GFP_THISNODE)
> -				goto nopage;
> -
> -			/*
> -			 * Proceed with single round of reclaim/compaction, but
> -			 * since sync compaction could be very expensive, keep
> -			 * using async compaction.
> -			 */
> -			compact_priority = INIT_COMPACT_PRIORITY;
> -		}
> -	}
> -
>  retry:
>  	/*
>  	 * Deal with possible cpuset update races or zonelist updates to avoid
> @@ -4870,10 +4837,12 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
>  		goto nopage;
>  
>  	/* Try direct reclaim and then allocating */
> -	page = __alloc_pages_direct_reclaim(gfp_mask, order, alloc_flags, ac,
> -							&did_some_progress);
> -	if (page)
> -		goto got_pg;
> +	if (!compact_first) {
> +		page = __alloc_pages_direct_reclaim(gfp_mask, order, alloc_flags,
> +							ac, &did_some_progress);
> +		if (page)
> +			goto got_pg;
> +	}
>  
>  	/* Try direct compaction and then allocating */
>  	page = __alloc_pages_direct_compact(gfp_mask, order, alloc_flags, ac,
> @@ -4881,6 +4850,33 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
>  	if (page)
>  		goto got_pg;
>  
> +	if (compact_first) {
> +		/*
> +		 * THP page faults may attempt local node only first, but are
> +		 * then allowed to only compact, not reclaim, see
> +		 * alloc_pages_mpol().
> +		 *
> +		 * Compaction has failed above and we don't want such THP
> +		 * allocations to put reclaim pressure on a single node in a
> +		 * situation where other nodes might have plenty of available
> +		 * memory.
> +		 */
> +		if (gfp_has_flags(gfp_mask, __GFP_NORETRY | __GFP_THISNODE))
> +			goto nopage;
> +
> +		/*
> +		 * For the initial compaction attempt we have lowered its
> +		 * priority. Restore it for further retries, if those are
> +		 * allowed. With __GFP_NORETRY there will be a single round of
> +		 * reclaim and compaction with the lowered priority.
> +		 */
> +		if (!(gfp_mask & __GFP_NORETRY))
> +			compact_priority = DEF_COMPACT_PRIORITY;
> +
> +		compact_first = false;
> +		goto retry;
> +	}
> +
>  	/* Do not loop if specifically requested */
>  	if (gfp_mask & __GFP_NORETRY)
>  		goto nopage;
> 
> -- 
> 2.52.0

-- 
Michal Hocko
SUSE Labs


  reply	other threads:[~2026-01-06 13:56 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-06 11:52 [PATCH mm-unstable v3 0/3] tweaks for __alloc_pages_slowpath() Vlastimil Babka
2026-01-06 11:52 ` [PATCH mm-unstable v3 1/3] mm/page_alloc: ignore the exact initial compaction result Vlastimil Babka
2026-01-06 13:51   ` Michal Hocko
2026-01-06 11:52 ` [PATCH mm-unstable v3 2/3] mm/page_alloc: refactor the initial compaction handling Vlastimil Babka
2026-01-06 13:56   ` Michal Hocko [this message]
2026-01-06 11:52 ` [PATCH mm-unstable v3 3/3] mm/page_alloc: simplify __alloc_pages_slowpath() flow Vlastimil Babka
2026-01-06 14:00   ` Michal Hocko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aV0UiNM1BXo17meQ@tiehlicka \
    --to=mhocko@suse.com \
    --cc=Liam.Howlett@oracle.com \
    --cc=akpm@linux-foundation.org \
    --cc=david@kernel.org \
    --cc=hannes@cmpxchg.org \
    --cc=jackmanb@google.com \
    --cc=joshua.hahnjy@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=lorenzo.stoakes@oracle.com \
    --cc=pfalcato@suse.de \
    --cc=rientjes@google.com \
    --cc=rppt@kernel.org \
    --cc=surenb@google.com \
    --cc=vbabka@suse.cz \
    --cc=ziy@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox