On Thu, Aug 21, 2025 at 12:06:42AM +0200, Klara Modin wrote: [...] > > The following diff resolves the issue for me: > > diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h > index fae105a9cb46..c70e789201fc 100644 > --- a/include/linux/memcontrol.h > +++ b/include/linux/memcontrol.h > @@ -809,7 +809,7 @@ void mem_cgroup_scan_tasks(struct mem_cgroup *memcg, > > static inline unsigned short mem_cgroup_id(struct mem_cgroup *memcg) > { > - if (mem_cgroup_disabled()) > + if (mem_cgroup_disabled() || !memcg) > return 0; > > return memcg->id.id; > > However, it's mentioned in folio_memcg() that it can return NULL so this > might be an existing bug which this patch just makes more obvious. > > There's also workingset_eviction() which instead gets the memcg from > lruvec. Doing that in lru_gen_eviction() also resolves the issue for me: > > diff --git a/mm/workingset.c b/mm/workingset.c > index 68a76a91111f..e805eadf0ec7 100644 > --- a/mm/workingset.c > +++ b/mm/workingset.c > @@ -243,6 +243,7 @@ static void *lru_gen_eviction(struct folio *folio) > int tier = lru_tier_from_refs(refs, workingset); > struct mem_cgroup *memcg = folio_memcg(folio); > struct pglist_data *pgdat = folio_pgdat(folio); > + int memcgid; > > BUILD_BUG_ON(LRU_GEN_WIDTH + LRU_REFS_WIDTH > BITS_PER_LONG - EVICTION_SHIFT); > > @@ -254,7 +255,9 @@ static void *lru_gen_eviction(struct folio *folio) > hist = lru_hist_from_seq(min_seq); > atomic_long_add(delta, &lrugen->evicted[hist][type][tier]); > > - return pack_shadow(mem_cgroup_id(memcg), pgdat, token, workingset); > + memcgid = mem_cgroup_id(lruvec_memcg(lruvec)); > + > + return pack_shadow(memcgid, pgdat, token, workingset); > } > > /* > > I don't really know what I'm doing here, though. Thanks a lot for the report and I think we will prefer your second approach which makes lru_gen_eviction() similar to workingset_eviction(). Can you please send a formal patch and Boris can add that patch in his series?