Re: [PATCH 6/9] memcg: remove lru_gen_soft_reclaim()
From: T.J. Mercier
Date: Wed Aug 19 2026 - 11:23:15 EST
On Thu, Aug 13, 2026 at 1:27 AM Michal Hocko <mhocko@xxxxxxxx> wrote:
>
> On Tue 11-08-26 13:32:00, Shakeel Butt wrote:
> > The soft limit rbtree was the only caller. Dropping it leaves
> > MEMCG_LRU_HEAD unreachable, since nothing else ever rotates a memcg with
> > that op, so remove the op too and update the memcg LRU comment.
> >
> > Signed-off-by: Shakeel Butt <shakeel.butt@xxxxxxxxx>
>
> I am not deeply familiar with MGLRU to give my ack but from a quick look
> this looks right.
This looks good to me.
Reviewed-by: T.J. Mercier <tjmercier@xxxxxxxxxx>
>
> > ---
> > include/linux/mmzone.h | 30 +++++++++++-------------------
> > mm/vmscan.c | 16 ++--------------
> > 2 files changed, 13 insertions(+), 33 deletions(-)
> >
> > diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
> > index 94f9c3ff5416..01fabd0ece0d 100644
> > --- a/include/linux/mmzone.h
> > +++ b/include/linux/mmzone.h
> > @@ -635,35 +635,32 @@ struct lru_gen_mm_walk {
> > * For each node, memcgs are divided into two generations: the old and the
> > * young. For each generation, memcgs are randomly sharded into multiple bins
> > * to improve scalability. For each bin, the hlist_nulls is virtually divided
> > - * into three segments: the head, the tail and the default.
> > + * into two segments: the tail and the default.
> > *
> > * An onlining memcg is added to the tail of a random bin in the old generation.
> > * The eviction starts at the head of a random bin in the old generation. The
> > * per-node memcg generation counter, whose reminder (mod MEMCG_NR_GENS) indexes
> > * the old generation, is incremented when all its bins become empty.
> > *
> > - * There are four operations:
> > - * 1. MEMCG_LRU_HEAD, which moves a memcg to the head of a random bin in its
> > - * current generation (old or young) and updates its "seg" to "head";
> > - * 2. MEMCG_LRU_TAIL, which moves a memcg to the tail of a random bin in its
> > + * There are three operations:
> > + * 1. MEMCG_LRU_TAIL, which moves a memcg to the tail of a random bin in its
> > * current generation (old or young) and updates its "seg" to "tail";
> > - * 3. MEMCG_LRU_OLD, which moves a memcg to the head of a random bin in the old
> > + * 2. MEMCG_LRU_OLD, which moves a memcg to the head of a random bin in the old
> > * generation, updates its "gen" to "old" and resets its "seg" to "default";
> > - * 4. MEMCG_LRU_YOUNG, which moves a memcg to the tail of a random bin in the
> > + * 3. MEMCG_LRU_YOUNG, which moves a memcg to the tail of a random bin in the
> > * young generation, updates its "gen" to "young" and resets its "seg" to
> > * "default".
> > *
> > * The events that trigger the above operations are:
> > - * 1. Exceeding the soft limit, which triggers MEMCG_LRU_HEAD;
> > - * 2. The first attempt to reclaim a memcg below low, which triggers
> > + * 1. The first attempt to reclaim a memcg below low, which triggers
> > * MEMCG_LRU_TAIL;
> > - * 3. The first attempt to reclaim a memcg offlined or below reclaimable size
> > + * 2. The first attempt to reclaim a memcg offlined or below reclaimable size
> > * threshold, which triggers MEMCG_LRU_TAIL;
> > - * 4. The second attempt to reclaim a memcg offlined or below reclaimable size
> > + * 3. The second attempt to reclaim a memcg offlined or below reclaimable size
> > * threshold, which triggers MEMCG_LRU_YOUNG;
> > - * 5. Attempting to reclaim a memcg below min, which triggers MEMCG_LRU_YOUNG;
> > - * 6. Finishing the aging on the eviction path, which triggers MEMCG_LRU_YOUNG;
> > - * 7. Offlining a memcg, which triggers MEMCG_LRU_OLD.
> > + * 4. Attempting to reclaim a memcg below min, which triggers MEMCG_LRU_YOUNG;
> > + * 5. Finishing the aging on the eviction path, which triggers MEMCG_LRU_YOUNG;
> > + * 6. Offlining a memcg, which triggers MEMCG_LRU_OLD.
> > *
> > * Notes:
> > * 1. Memcg LRU only applies to global reclaim, and the round-robin incrementing
> > @@ -696,7 +693,6 @@ void lru_gen_exit_memcg(struct mem_cgroup *memcg);
> > void lru_gen_online_memcg(struct mem_cgroup *memcg);
> > void lru_gen_offline_memcg(struct mem_cgroup *memcg);
> > void lru_gen_release_memcg(struct mem_cgroup *memcg);
> > -void lru_gen_soft_reclaim(struct mem_cgroup *memcg, int nid);
> > void max_lru_gen_memcg(struct mem_cgroup *memcg, int nid);
> > bool recheck_lru_gen_max_memcg(struct mem_cgroup *memcg, int nid);
> > void lru_gen_reparent_memcg(struct mem_cgroup *memcg, struct mem_cgroup *parent, int nid);
> > @@ -737,10 +733,6 @@ static inline void lru_gen_release_memcg(struct mem_cgroup *memcg)
> > {
> > }
> >
> > -static inline void lru_gen_soft_reclaim(struct mem_cgroup *memcg, int nid)
> > -{
> > -}
> > -
> > static inline void max_lru_gen_memcg(struct mem_cgroup *memcg, int nid)
> > {
> > }
> > diff --git a/mm/vmscan.c b/mm/vmscan.c
> > index 790b50c78a2e..71244cf33d59 100644
> > --- a/mm/vmscan.c
> > +++ b/mm/vmscan.c
> > @@ -4373,7 +4373,6 @@ bool lru_gen_look_around(struct page_vma_mapped_walk *pvmw, unsigned int nr)
> > /* see the comment on MEMCG_NR_GENS */
> > enum {
> > MEMCG_LRU_NOP,
> > - MEMCG_LRU_HEAD,
> > MEMCG_LRU_TAIL,
> > MEMCG_LRU_OLD,
> > MEMCG_LRU_YOUNG,
> > @@ -4395,9 +4394,7 @@ static void lru_gen_rotate_memcg(struct lruvec *lruvec, int op)
> > new = old = lruvec->lrugen.gen;
> >
> > /* see the comment on MEMCG_NR_GENS */
> > - if (op == MEMCG_LRU_HEAD)
> > - seg = MEMCG_LRU_HEAD;
> > - else if (op == MEMCG_LRU_TAIL)
> > + if (op == MEMCG_LRU_TAIL)
> > seg = MEMCG_LRU_TAIL;
> > else if (op == MEMCG_LRU_OLD)
> > new = get_memcg_gen(pgdat->memcg_lru.seq);
> > @@ -4411,7 +4408,7 @@ static void lru_gen_rotate_memcg(struct lruvec *lruvec, int op)
> >
> > hlist_nulls_del_rcu(&lruvec->lrugen.list);
> >
> > - if (op == MEMCG_LRU_HEAD || op == MEMCG_LRU_OLD)
> > + if (op == MEMCG_LRU_OLD)
> > hlist_nulls_add_head_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]);
> > else
> > hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]);
> > @@ -4489,15 +4486,6 @@ void lru_gen_release_memcg(struct mem_cgroup *memcg)
> > }
> > }
> >
> > -void lru_gen_soft_reclaim(struct mem_cgroup *memcg, int nid)
> > -{
> > - struct lruvec *lruvec = get_lruvec(memcg, nid);
> > -
> > - /* see the comment on MEMCG_NR_GENS */
> > - if (READ_ONCE(lruvec->lrugen.seg) != MEMCG_LRU_HEAD)
> > - lru_gen_rotate_memcg(lruvec, MEMCG_LRU_HEAD);
> > -}
> > -
> > bool recheck_lru_gen_max_memcg(struct mem_cgroup *memcg, int nid)
> > {
> > struct lruvec *lruvec = get_lruvec(memcg, nid);
> > --
> > 2.53.0-Meta
>
> --
> Michal Hocko
> SUSE Labs
>