Re: [PATCH v4 03/17] mm/memcg: add folio-based lruvec live helper

From: Harry Yoo

Date: Thu Oct 15 2026 - 15:12:05 EST


On Fri, Oct 16, 2026 at 02:15:52AM +0800, Kairui Song via B4 Relay wrote:
> From: Kairui Song <kasong@xxxxxxxxxxx>
>
> Add a helper that resolves a stable lruvec for a folio under RCU
> without taking the lruvec lock. It takes a folio directly so the
> lruvec lookup happens inside the RCU read-side critical section,
> which a lruvec-based interface cannot guarantee.
>
> No functional change.
>
> Tested-by: zhaozhengzhuo <zhaozhengzhuo@xxxxxxxxxxxxx>
> Signed-off-by: Kairui Song <kasong@xxxxxxxxxxx>
> ---

This new helper is doing the the same thing as what
get_non_dying_memcg_start/end() do.

> include/linux/memcontrol.h | 39 +++++++++++++++++++++++++++++++++++++++
> 1 file changed, 39 insertions(+)
>
> diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
> index 74110a324f9e..829ab776ab44 100644
> --- a/include/linux/memcontrol.h
> +++ b/include/linux/memcontrol.h
> @@ -1535,6 +1535,45 @@ static inline void lruvec_lock_irq(struct lruvec *lruvec)
> spin_lock_irq(&lruvec->lru_lock);
> }
>
> +/**
> + * folio_lruvec_live_get - get a live lruvec for a folio under RCU
> + * @folio: the folio
> + *
> + * Computes @folio's lruvec and walks up to the nearest live ancestor
> + * if the folio's memcg is dying. Paired with folio_lruvec_live_put().
> + * The result may be stale: RCU keeps it alive but does not pin @folio
> + * to it. That is fine as the counters are fixed up on reparenting.
> + *
> + * Return: the live lruvec, with rcu_read_lock held.
> + */
> +static inline struct lruvec *folio_lruvec_live_get(struct folio *folio)
> +{
> +#ifdef CONFIG_MEMCG
> + struct lruvec *lruvec;
> + struct pglist_data *pgdat;
> + struct mem_cgroup *memcg;
> +
> + rcu_read_lock();
> + lruvec = folio_lruvec(folio);
> + pgdat = lruvec_pgdat(lruvec);
> + memcg = lruvec_memcg(lruvec);
> + while (unlikely(memcg && css_is_dying(&memcg->css))) {
> + memcg = parent_mem_cgroup(memcg);
> + lruvec = mem_cgroup_lruvec(memcg, pgdat);
> + }
> + return lruvec;
> +#else
> + return folio_lruvec(folio);
> +#endif
> +}
> +
> +static inline void folio_lruvec_live_put(struct lruvec *lruvec)
> +{
> +#ifdef CONFIG_MEMCG
> + rcu_read_unlock();
> +#endif
> +}
> +
> static inline struct lruvec *lruvec_live_lock_irq(struct lruvec *lruvec)
> {
> #ifdef CONFIG_MEMCG
>
> --
> 2.56.0

--
Cheers,
Harry / Hyeonggon