Re: [PATCH v5 update 29/32] mm: memcontrol: prepare for reparenting non-hierarchical stats

From: Yosry Ahmed

Date: Mon Mar 02 2026 - 10:59:55 EST


[..]
> @@ -763,6 +851,64 @@ unsigned long memcg_page_state_local(struct mem_cgroup *memcg, int idx)
> #endif
> return x;
> }
> +
> +static void __mod_memcg_state(struct mem_cgroup *memcg,
> + enum memcg_stat_item idx, int val)
> +{
> + int i = memcg_stats_index(idx);
> + int cpu;
> +
> + if (mem_cgroup_disabled())
> + return;
> +
> + cpu = get_cpu();
> +
> + this_cpu_add(memcg->vmstats_percpu->state[i], val);
> + val = memcg_state_val_in_pages(idx, val);
> + memcg_rstat_updated(memcg, val, cpu);
> + trace_mod_memcg_state(memcg, idx, val);
> +
> + put_cpu();
> +}
> +
> +static void __mod_memcg_lruvec_state(struct lruvec *lruvec,
> + enum node_stat_item idx, int val)
> +{
> + struct mem_cgroup_per_node *pn;
> + struct mem_cgroup *memcg;
> + int i = memcg_stats_index(idx);
> + int cpu;
> +
> + pn = container_of(lruvec, struct mem_cgroup_per_node, lruvec);
> + memcg = pn->memcg;
> +
> + cpu = get_cpu();
> +
> + /* Update memcg */
> + this_cpu_add(memcg->vmstats_percpu->state[i], val);
> +
> + /* Update lruvec */
> + this_cpu_add(pn->lruvec_stats_percpu->state[i], val);
> +
> + val = memcg_state_val_in_pages(idx, val);
> + memcg_rstat_updated(memcg, val, cpu);
> + trace_mod_memcg_lruvec_state(memcg, idx, val);
> +
> + put_cpu();
> +}

I don't think we should end up with two copies of
__mod_memcg_state/mod_memcg_state() and
__mod_memcg_lruvec_state/mod_memcg_lruvec_state(). I meant to refactor
mod_memcg_state() to call __mod_memcg_state(), where the latter does
not call get_non_dying_memcg_{start/end}(). Same for
mod_memcg_lruvec_state().

> +
> +void reparent_memcg_state_local(struct mem_cgroup *memcg,
> + struct mem_cgroup *parent, int idx)
> +{
> + int i = memcg_stats_index(idx);
> + unsigned long value = memcg_page_state_local(memcg, idx);
> +
> + if (WARN_ONCE(BAD_STAT_IDX(i), "%s: missing stat item %d\n", __func__, idx))
> + return;
> +
> + __mod_memcg_state(memcg, idx, -value);
> + __mod_memcg_state(parent, idx, value);
> +}
> #endif
>
> static void mod_memcg_lruvec_state(struct lruvec *lruvec,
> --
> 2.20.1
>
>