Re: [PATCH v4 4/5] mm/memcontrol: convert memcg to use page_counter_stock

From: Joshua Hahn

Date: Wed Jun 24 2026 - 11:30:56 EST


On Wed, 24 Jun 2026 07:43:47 -0700 Usama Arif <usama.arif@xxxxxxxxx> wrote:

> On Tue, 23 Jun 2026 11:01:22 -0700 Joshua Hahn <joshua.hahnjy@xxxxxxxxx> wrote:

Hello Usama!!

Thank you for reviewing the patch : -)

[...snip...]

> > @@ -2595,7 +2596,6 @@ void __mem_cgroup_handle_over_high(gfp_t gfp_mask)
> > static int try_charge_memcg(struct mem_cgroup *memcg, gfp_t gfp_mask,
> > unsigned int nr_pages)
> > {
> > - unsigned int batch = max(MEMCG_CHARGE_BATCH, nr_pages);
> > int nr_retries = MAX_RECLAIM_RETRIES;
> > struct mem_cgroup *mem_over_limit;
> > struct page_counter *counter;
> > @@ -2606,36 +2606,30 @@ 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);
> > + unsigned long nr_charged = 0;
> >
> > retry:
> > - if (consume_stock(memcg, nr_pages))
> > - return 0;
> > -
> > - if (!allow_spinning)
> > - /* Avoid the refill and flush of the older stock */
> > - batch = nr_pages;
> > -
> > reclaim_options = MEMCG_RECLAIM_MAY_SWAP;
> > if (do_memsw_account() &&
> > - !page_counter_try_charge(&memcg->memsw, batch, &counter)) {
> > + !page_counter_try_charge_stock(&memcg->memsw, nr_pages,
> > + &counter, NULL)) {
> > mem_over_limit = mem_cgroup_from_counter(counter, memsw);
> > reclaim_options &= ~MEMCG_RECLAIM_MAY_SWAP;
> > goto reclaim;
> > }
> >
> > - if (page_counter_try_charge(&memcg->memory, batch, &counter))
> > - goto done_restock;
> > + if (page_counter_try_charge_stock(&memcg->memory, nr_pages,
> > + &counter, &nr_charged)) {
> > + if (!nr_charged)
> > + return 0;
> > + goto handle_high;
> > + }
> >
> > if (do_memsw_account())
> > - page_counter_uncharge(&memcg->memsw, batch);
> > + page_counter_uncharge(&memcg->memsw, nr_pages);
>
> This needs a transactional rollback. page_counter_try_charge_stock() can
> succeed by consuming memsw stock and charging 0 new pages, but the
> memory-failure path unconditionally uncharges nr_pages from memsw.
> That turns a failed allocation into a real memsw usage decrement.

Hmmmmmmmmmm....... I'm not sure.

At this point in the code, we are either (1) using cgroup v1 with memsw
and charged successfully, or (2) not using cgroup v1 with memsw. So I'm
not sure if this really is unconditional, we're just distinguishing
between cases (1) and (2) by checking if we're using cgroupv1.

Or is your concern with taking a charge via stock, but uncharging with
a hierarchical page_counter walk? If so, I think there's a case to be
made here with just simply returning the stock. I just wanted to keep
it consistent with the original memcontrol code, which only used
stock to fulfill charges, not uncharges, since this could make the
stock grow without bound.

What do you think? Thanks again for reviewing Usama, I hope you have a
great day!!!
Joshua