Skip to content

Commit cafcea4

Browse files
Muchun Songjfvogel
authored andcommitted
mm: workingset: prevent lruvec release in workingset_refault()
In the near future, a folio will no longer pin its corresponding memory cgroup. So an lruvec returned by folio_lruvec() could be released without the rcu read lock or a reference to its memory cgroup. In the current patch, the rcu read lock is employed to safeguard against the release of the lruvec in workingset_refault(). 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 9cbfd1c mm/mglru: clean up workingset') This suppresses the warning: WARNING: CPU: 0 PID: 9726 at include/linux/memcontrol.h:407 workingset_refault+0x21f/0x270 [...] Call Trace: <TASK> filemap_add_folio+0xcd/0x100 page_cache_ra_unbounded+0x149/0x240 do_sync_mmap_readahead+0x1b6/0x4e0 filemap_fault+0x546/0x910 ? srso_alias_return_thunk+0x5/0xfbef5 ? mark_held_locks+0x49/0x80 ? srso_alias_return_thunk+0x5/0xfbef5 ? __xfs_filemap_fault+0xdd/0x1e0 [xfs] __do_fault+0x39/0x210 do_fault+0x146/0x2f0 __handle_mm_fault+0x592/0x770 handle_mm_fault+0x104/0x3a0 do_user_addr_fault+0x16d/0x7b0 exc_page_fault+0x77/0x270 asm_exc_page_fault+0x26/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 adfd07a commit cafcea4

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

mm/workingset.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -565,14 +565,15 @@ void workingset_refault(struct folio *folio, void *shadow)
565565
*/
566566
VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio);
567567
nr = folio_nr_pages(folio);
568+
rcu_read_lock();
568569
memcg = folio_memcg(folio);
569570
pgdat = folio_pgdat(folio);
570571
lruvec = mem_cgroup_lruvec(memcg, pgdat);
571572

572573
mod_lruvec_state(lruvec, WORKINGSET_REFAULT_BASE + file, nr);
573574

574575
if (!workingset_test_recent(shadow, file, &workingset, true))
575-
return;
576+
goto out;
576577

577578
folio_set_active(folio);
578579
workingset_age_nonresident(lruvec, nr);
@@ -588,6 +589,8 @@ void workingset_refault(struct folio *folio, void *shadow)
588589
lru_note_cost_refault(folio);
589590
mod_lruvec_state(lruvec, WORKINGSET_RESTORE_BASE + file, nr);
590591
}
592+
out:
593+
rcu_read_unlock();
591594
}
592595

593596
/**

0 commit comments

Comments
 (0)