v4
2026-08-12
修复MGLRU swappiness行为 · v4
MGLRU 改进 v4:改善隔离/扫描可读性与耗尽检测,处理隔离竞态,批量更新计数等。
原始补丁链接
子 Patch(16)
1/16
mm/mglru: improve readability of isolate_folios()
重构 isolate_folios() 的 for_each_evictable_type() 循环,明确实际由 get_type_to_scan() 决定扫描类型,i 仅限制尝试次数,避免误导。
2/16
mm/mglru: improve scan_folios() exhaustion detection
为 scan_folios() 增加 exhausted 输出参数,用 early_stop 判断是否提前停止;仅 scanned==0 无法识别最老代耗尽但第二老代仍可回收的情况。
3/16
mm/mglru: retry the same type once if isolation fails due to races
在未耗尽但因 promotion/protection/race 隔离不到 folio 时,对同一类型重试一次,避免直接进入外层循环换类型。
4/16
mm/mglru: boost swappiness responsiveness in get_type_to_scan()
get_type_to_scan() 中改用距中性点 MAX_SWAPPINESS/2 的二次方提升 swappiness 权重,避免被历史 refault 成本淹没,用移位代替除法。
5/16
mm/mglru: batch update lrugen->nr_pages in inc_min_seq()
inc_min_seq() 中累计 folio 大小变化,在扫描完最老代后批量更新 lrugen->nr_pages,避免逐个 folio_inc_gen() 更新;因只跨代不改变 active/inactive,可跳过 __lru_update_size()。
6/16
mm/mglru: batch update lrugen->protected in inc_min_seq()
inc_min_seq() 将 lrugen->protected 的更新由 per-folio WRITE_ONCE 改为本地累加后批量写入,减少频繁 WRITE_ONCE 带来的开销。
7/16
mm/mglru: enhance cold/hot inversion handling in inc_min_seq()
inc_min_seq() 处理 aging 中已被 folio_update_gen() 提升的 folio:未提升的移到新最老代尾部,已提升的应像 sort_folio() 那样移到更新代头部,避免冷热反转。
8/16
mm/mglru: exclude folios promoted by aging from protected in inc_min_seq()
inc_min_seq() 统计 protected 时排除 aging 期间已被提升的 folio,与 sort_folio() 行为一致,避免错误计入保护计数。
9/16
mm/mglru: move folios from oldest gen to second-oldest gen from head to tail
inc_min_seq() 将 folio 从最老代移到次老代时应从 head 到 tail;若沿用回收的 tail-to-head 顺序,会导致冷热反转。
10/16
mm/mglru: batch move folios to the second-oldest gen's LRU
在 inc_min_seq() 中批量移动需要从最老代升级到次老代的 folios,减少逐个操作和锁开销,降低 sys time,尤其当另一类型落后时。
11/16
mm/mglru: skip gentle reclaim at DEF_PRIORITY for extreme swappiness
在 DEF_PRIORITY 下对极端 swappiness(<=MIN+1 或 >=MAX)跳过 gentle reclaim,避免过早 fallback,与 get_type_to_scan() 的类型选择保持一致。
12/16
mm/mglru: run aging if the preferred type has no reclaimable gens
当 get_type_to_scan() 选中的类型没有可回收代时,直接运行 aging,而不是 fallback 到另一类型,以尊重 swappiness 配置。
13/16
mm/mglru: remove redundant gens <= MIN_NR_GENS check in should_run_aging()
should_run_aging() 中移除 evictable_min_seq()+MIN_NR_GENS>max_seq 检查:它由 min_seq[type]+MIN_NR_GENS>max_seq 蕴含,属冗余条件。
14/16
mm/mglru: run aging when pages are severely imbalanced across gens
lru_gen_imbalanced() 检测年轻代 folio 数至少是年老代 MAX_NR_GENS 倍时运行 aging;若另一类型最老代落后太多,避免高成本 inc_min_seq(),除非极端 swappiness。
15/16
mm/mglru: dynamically scale aging threshold in lru_gen_imbalanced()
lru_gen_imbalanced() 的固定阈值 MAX_NR_GENS 改为按内存 GB 数平方根自适应缩放,借鉴 inactive_is_low(),避免大内存下失衡判断不灵敏。
16/16
mm/mglru: reduce folios pulled from the oldest gen in inc_min_seq()
减小 inc_min_seq() 每次从最老代拉取的批量(原 MAX_LRU_BATCH),缩短持锁时间,让并发 reclaim/lru_cache_drain 等有机会推进。