linux/mm/vmscan.c
Imported from
_research/manual-study-linux/file-notes/linux__mm__vmscan.c.md.
File Notes: mm/vmscan.c
Status: reviewed.
Purpose
Implements page reclaim under memory pressure: scan-control policy, LRU
isolation, inactive-list shrinking, folio writeback/unmap/free decisions,
memcg-aware reclaim, direct reclaim, and background kswapd balancing.
Key Types And Functions
struct scan_control: per-reclaim invocation policy and accounting object.shrink_folio_list(): core folio reclaim decision loop.isolate_lru_folios(): moves folios from LRU lists to private scan lists.shrink_inactive_list(): isolates inactive folios, calls reclaim, and moves unreclaimed folios back.try_to_free_mem_cgroup_pages(): memcg reclaim entry.kswapd_shrink_node(),balance_pgdat(),kswapd(),wakeup_kswapd(): background reclaim control path.
Data Flow
Reclaim begins with a scan_control describing how much to reclaim, which node
or memcg to target, whether unmap/writepage/swap are allowed, what GFP context
triggered pressure, and how much work has already been scanned or reclaimed.
Inactive-list reclaim isolates folios from an LRU vector, accounts the scan,
passes the private list to shrink_folio_list(), and then returns unreclaimed
folios to LRU state. shrink_folio_list() decides whether each folio can be
locked, unmapped, written back, demoted, swapped, or freed. It handles
writeback congestion, reference activation, anonymous swap allocation, dirty
file writeback, pinned folios, and demotion fallback.
Background reclaim runs in kswapd(). Wakeups record the target node, order,
and reclaim index. balance_pgdat() builds a scan-control instance, chooses
priority and reclaim index, ages active lists, reclaims memcg soft-limit pages,
shrinks nodes, wakes blocked direct reclaimers when watermarks improve, and
decides whether to sleep or continue.
Invariants And Safety Contracts
- Reclaim policy must respect
may_writepage,may_unmap, andmay_swap. - Folios are isolated before expensive reclaim work and either freed, demoted, or moved back to an LRU list.
- Writeback and dirty-page handling avoid blocking in contexts that cannot write or wait.
- Memcg reclaim tracks low-limit pressure and skipped groups separately from global reclaim.
kswapdoperates withPF_MEMALLOC/PF_KSWAPDsemantics because it exists to free memory for the system.
Rust Translation Guidance
A Rust reclaim loop should expose ScanControl as an immutable policy plus
mutable counters, and model folios as state machines: isolated, locked,
referenced, dirty, writeback, unmapped, demoted, freed, or returned. The code
should make “cannot write”, “cannot unmap”, and “cannot swap” compile-visible
policy constraints rather than hidden booleans passed through many helpers.
AI-Native Systems Guidance
Agent systems need equivalent pressure loops for context, cache, and embedding stores. Reclaim should isolate candidates, score references, checkpoint dirty state when allowed, demote cold data to cheaper storage, and wake blocked work only after watermarks improve.
Evidence
struct scan_controldefines reclaim target, memcg, cost, permissions, priority, order, reclaim index, GFP mask, and counters atmm/vmscan.c:74-180.shrink_folio_list()begins atmm/vmscan.c:1058-1060.- Its main loop locks folios, accounts scans, checks unevictable and unmap
constraints, and classifies dirty/writeback state at
mm/vmscan.c:1078-1132. - Writeback cases and throttling behavior are documented at
mm/vmscan.c:1143-1188and implemented atmm/vmscan.c:1189-1230. - Reference checks, demotion handling, swap allocation, unmap, pinned-folio,
dirty-file, and writepage decisions run through
mm/vmscan.c:1233-1441. - Demotion/free/move-back completion is handled near
mm/vmscan.c:1553-1594. isolate_lru_folios()is documented and implemented atmm/vmscan.c:1667-1780.shrink_inactive_list()isolates LRU folios, callsshrink_folio_list(), and moves survivors back atmm/vmscan.c:1988-2055.try_to_free_mem_cgroup_pages()builds memcg reclaim scan-control state and callsdo_try_to_free_pages()atmm/vmscan.c:6767-6805.kswapd_shrink_node()is atmm/vmscan.c:6996-7027.balance_pgdat()sets up background reclaim policy and node balancing atmm/vmscan.c:7056-7290.kswapd()runs the background reclaim thread atmm/vmscan.c:7391-7476.wakeup_kswapd()records reclaim demand and wakes the daemon atmm/vmscan.c:7478-7528.