Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Shakeel Butt <shakeel.butt@linux.dev>
To: Joe Damato <joe@dama.to>
Cc: linux-kernel@vger.kernel.org,
	Johannes Weiner <hannes@cmpxchg.org>,
	 Michal Hocko <mhocko@kernel.org>,
	Roman Gushchin <roman.gushchin@linux.dev>,
	 Muchun Song <muchun.song@linux.dev>,
	Andrew Morton <akpm@linux-foundation.org>,
	 cgroups@vger.kernel.org, linux-mm@kvack.org,
	bpf@vger.kernel.org
Subject: Re: [PATCH] mm: memcontrol: raise MEMCG_MAX for charges that fail without reclaiming
Date: Fri, 28 Aug 2026 18:04:37 -0700	[thread overview]
Message-ID: <apIvUej_7wvcDUjg@linux.dev> (raw)
In-Reply-To: <apDPJzlJ4gS9YUDX@linux.dev>

On Thu, Aug 27, 2026 at 05:13:44PM -0700, Shakeel Butt wrote:
> On Thu, Aug 27, 2026 at 04:31:18PM -0700, Joe Damato wrote:
> > Charges that exceed memory.max and return through the nomem label can
> > raise no event and simply return -ENOMEM.
> > 
> > A non-blocking charge can hit the limit, get rejected, but is not
> > visible in memory.events.
> > 
> > This was noticed in a production setting where bpf_mem_alloc() attempted
> > to refill its per-cpu freelists, which triggered a non-blocking charge
> > while at the limit.
> > 
> > Move the event so that it is raised as soon as the charge is known not
> > to fit.
> > 
> > Suggested-by: Shakeel Butt <shakeel.butt@linux.dev>
> > Signed-off-by: Joe Damato <joe@dama.to>
> > ---
> >  mm/memcontrol.c | 15 +++++----------
> >  1 file changed, 5 insertions(+), 10 deletions(-)
> > 
> > diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> > index 1271d390b617..3904fe9a7b2e 100644
> > --- a/mm/memcontrol.c
> > +++ b/mm/memcontrol.c
> > @@ -2683,6 +2683,11 @@ static int try_charge_memcg(struct mem_cgroup *memcg, gfp_t gfp_mask,
> >  		goto retry;
> >  	}
> >  
> > +	if (!raised_max_event) {
> > +		__memcg_memory_event(mem_over_limit, MEMCG_MAX, allow_spinning);
> > +		raised_max_event = true;
> > +	}
> > +
> >  	/*
> >  	 * Prevent unbounded recursion when reclaim operations need to
> >  	 * allocate memory. This might exceed the limits temporarily,
> > @@ -2711,9 +2716,6 @@ static int try_charge_memcg(struct mem_cgroup *memcg, gfp_t gfp_mask,
> >  	    mm_flags_test(MMF_OOM_SKIP, current->signal->oom_mm))
> >  		goto nomem;
> >  
> > -	__memcg_memory_event(mem_over_limit, MEMCG_MAX, allow_spinning);
> > -	raised_max_event = true;
> 
> I just noticed that this will change the current behavior where we keep
> increasing MAX counter while charge request loops through reclaim and retry.
> Though we have not documented that behavior, so not sure if it is worth
> preserving. It does help identify cases where a request keep looping in the
> charge/reclaim/retry path.
> 
> Let's see what others say. Keeping the behavior should not be that hard if we
> decide to keep it. Something like below (untested):
> 

Hi Joe, let's go with the following patch. No need to change the semantics. Also
I think we should Cc stable as getting ENOMEM/allocation-failures without the
corresponding counter i.e. MAX getting increased is clearly a bug and unexpected
to the users and will make debugging/monitoring harder.

> 
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index 1271d390b617..6bfa4ad30b24 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -2656,10 +2656,11 @@ static int try_charge_memcg(struct mem_cgroup *memcg, gfp_t gfp_mask,
>  	bool raised_max_event = false;
>  	unsigned long pflags;
>  	bool allow_spinning = gfpflags_allow_spinning(gfp_mask);
> +	int ret = 0;
>  
>  retry:
>  	if (consume_stock(memcg, nr_pages))
> -		return 0;
> +		return ret;
>  
>  	if (!allow_spinning)
>  		/* Avoid the refill and flush of the older stock */
> @@ -2770,16 +2771,11 @@ static int try_charge_memcg(struct mem_cgroup *memcg, gfp_t gfp_mask,
>  	 * put the burden of reclaim on regular allocation requests
>  	 * and let these go through as privileged allocations.
>  	 */
> -	if (!(gfp_mask & (__GFP_NOFAIL | __GFP_HIGH)))
> -		return -ENOMEM;
> +	if (!(gfp_mask & (__GFP_NOFAIL | __GFP_HIGH))) {
> +		ret = -ENOMEM;
> +		goto out;
> +	}
>  force:
> -	/*
> -	 * If the allocation has to be enforced, don't forget to raise
> -	 * a MEMCG_MAX event.
> -	 */
> -	if (!raised_max_event)
> -		__memcg_memory_event(mem_over_limit, MEMCG_MAX, allow_spinning);
> -
>  	/*
>  	 * The allocation either can't fail or will lead to more memory
>  	 * being freed very soon.  Allow memory usage go over the limit
> @@ -2789,7 +2785,15 @@ static int try_charge_memcg(struct mem_cgroup *memcg, gfp_t gfp_mask,
>  	if (do_memsw_account())
>  		page_counter_charge(&memcg->memsw, nr_pages);
>  
> -	return 0;
> +out:
> +	/*
> +	 * Don't forget to raise a MEMCG_MAX event for forced or rejected requests.
> +	 */
> +	if (!raised_max_event)
> +		__memcg_memory_event(mem_over_limit, MEMCG_MAX, allow_spinning);
> +
> +	return ret;
>  
>  done_restock:
>  	if (batch > nr_pages)
> @@ -2848,7 +2852,7 @@ static int try_charge_memcg(struct mem_cgroup *memcg, gfp_t gfp_mask,
>  	    !(current->flags & PF_MEMALLOC) &&
>  	    gfpflags_allow_blocking(gfp_mask))
>  		__mem_cgroup_handle_over_high(gfp_mask);
> -	return 0;
> +	return ret;
>  }
>  
>  static inline int try_charge(struct mem_cgroup *memcg, gfp_t gfp_mask,
>  
> 


      reply	other threads:[~2026-08-29  1:04 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-27 23:31 [PATCH] mm: memcontrol: raise MEMCG_MAX for charges that fail without reclaiming Joe Damato
2026-08-28  0:13 ` Shakeel Butt
2026-08-29  1:04   ` Shakeel Butt [this message]

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=apIvUej_7wvcDUjg@linux.dev \
    --to=shakeel.butt@linux.dev \
    --cc=akpm@linux-foundation.org \
    --cc=bpf@vger.kernel.org \
    --cc=cgroups@vger.kernel.org \
    --cc=hannes@cmpxchg.org \
    --cc=joe@dama.to \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mhocko@kernel.org \
    --cc=muchun.song@linux.dev \
    --cc=roman.gushchin@linux.dev \
    /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