Skip to content

Commit 0f240e5

Browse files
Muchun Songjfvogel
authored andcommitted
mm: workingset: prevent memory cgroup release in lru_gen_eviction()
In the near future, a folio will no longer pin its corresponding memory cgroup. To ensure safety, it will only be appropriate to hold the rcu read lock or acquire a reference to the memory cgroup returned by folio_memcg(), thereby preventing it from being released. In the current patch, the rcu read lock is employed to safeguard against the release of the memory cgroup in lru_gen_eviction(). This serves as a preparatory measure for the reparenting of the LRU pages. Signed-off-by: Muchun Song <[email protected]> Orabug: 37997580 Conflicts: mm/workingset.c (Due to prescence of 'commit 4d5d14a mm/mglru: rework workingset protection') This suppresses the warning: WARNING: CPU: 3 PID: 224 at include/linux/memcontrol.h:407 lru_gen_eviction+0x204/0x240 [...] Call Trace: <TASK> __remove_mapping+0x228/0x330 shrink_folio_list+0x79d/0x1120 ? evict_folios+0x256/0x8d0 evict_folios+0x280/0x8d0 try_to_shrink_lruvec+0x195/0x2c0 shrink_one+0x107/0x1c0 shrink_many+0x1e6/0x900 ? shrink_many+0x73/0x900 shrink_node+0x3e3/0x440 ? balance_pgdat+0xdb/0x7d0 balance_pgdat+0x2d7/0x7d0 kswapd+0x114/0x1e0 ? __pfx_kswapd+0x10/0x10 kthread+0xd6/0x110 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x34/0x50 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 </TASK> Link: https://lore.kernel.org/linux-mm/[email protected]/ Fixes: 4717687 ("mm: memcontrol: make all the callers of {folio,page}_memcg() safe") Reviewed-by: Imran Khan <[email protected]> Signed-off-by: Harry Yoo <[email protected]>
1 parent 681519b commit 0f240e5

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

mm/workingset.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,20 +240,25 @@ static void *lru_gen_eviction(struct folio *folio)
240240
int delta = folio_nr_pages(folio);
241241
int refs = folio_lru_refs(folio);
242242
int tier = lru_tier_from_refs(refs);
243-
struct mem_cgroup *memcg = folio_memcg(folio);
243+
struct mem_cgroup *memcg;
244244
struct pglist_data *pgdat = folio_pgdat(folio);
245+
unsigned short memcg_id;
245246

246247
BUILD_BUG_ON(LRU_GEN_WIDTH + LRU_REFS_WIDTH > BITS_PER_LONG - EVICTION_SHIFT);
247248

249+
rcu_read_lock();
250+
memcg = folio_memcg(folio);
248251
lruvec = mem_cgroup_lruvec(memcg, pgdat);
249252
lrugen = &lruvec->lrugen;
250253
min_seq = READ_ONCE(lrugen->min_seq[type]);
251254
token = (min_seq << LRU_REFS_WIDTH) | max(refs - 1, 0);
252255

253256
hist = lru_hist_from_seq(min_seq);
254257
atomic_long_add(delta, &lrugen->evicted[hist][type][tier]);
258+
memcg_id = mem_cgroup_id(memcg);
259+
rcu_read_unlock();
255260

256-
return pack_shadow(mem_cgroup_id(memcg), pgdat, token, refs);
261+
return pack_shadow(memcg_id, pgdat, token, refs);
257262
}
258263

259264
/*

0 commit comments

Comments
 (0)