setup_min_unmapped_ratio()是 NUMA 系统中用于计算每个 zone 的min_unmapped_pages阈值的辅助函数。这个阈值决定了zone_reclaim节点回收是否值得触发。核心作用与背景在 NUMA 系统中当本地节点内存不足时内核可以选择回收本地节点的不映射文件页unmapped file pages而不是直接去远程节点分配内存。这个决策由zone_reclaim_mode控制。但回收并非总是划算——如果本地节点的文件页太少回收收益不大。min_unmapped_pages就是一道“值不值得回收”的门槛如果 zone 中可回收的文件页数量 ≤min_unmapped_pages说明回收潜力太小zone_reclaim会放弃只有超过这个阈值才值得扫描 LRU 链表进行回收。函数实现该函数的实现非常直接static void setup_min_unmapped_ratio(struct zone *zone) { zone-min_unmapped_pages (zone-managed_pages * sysctl_min_unmapped_ratio) / 100; }参数解析参数含义zone目标 zonesysctl_min_unmapped_ratio用户配置的比例默认1%通过/proc/sys/vm/min_unmapped_ratio调整演进与重构从 zone 级到 pgdat 级在较新的内核版本中如 v5.2-rc2计算粒度发生了变化旧版本zone 级static void setup_min_unmapped_ratio(struct zone *zone) { zone-min_unmapped_pages (zone-managed_pages * sysctl_min_unmapped_ratio) / 100; }每个 zone 有自己的min_unmapped_pages基于该 zone 的managed_pages计算。新版本pgdat 级static void setup_min_unmapped_ratio(void) { pg_data_t *pgdat; struct zone *zone; for_each_online_pgdat(pgdat) pgdat-min_unmapped_pages 0; for_each_zone(zone) zone-zone_pgdat-min_unmapped_pages (zone_managed_pages(zone) * sysctl_min_unmapped_ratio) / 100; }现在计算的是整个 NUMA 节点的min_unmapped_pages汇总该节点上所有 zone 的贡献。这个改动是为了让zone_reclaim的判断更符合节点级别的语义——回收是针对整个节点的。调用场景setup_min_unmapped_ratio()的调用场景在 2016 年的补丁中得到了规范化free_area_init_core()zone 初始化时首次计算init_per_zone_wmark_min()启动初始化时在for_each_zone循环中调用sysctl_min_unmapped_ratio_sysctl_handler()用户修改/proc/sys/vm/min_unmapped_ratio后重新计算。补丁注释指出zone 的阈值依赖于managed_pages而内存热插拔会改变它因此需要在适当的地方重新计算。与sysctl_min_unmapped_ratio的关系sysctl_min_unmapped_ratio的默认值为1即 1%。它的语义在 2009 年由 Mel Gorman 修正过——早期文档说它是“文件页中未映射部分的比例”但实际实现是“zone 总页数中可用于 zone_reclaim 的页的比例”。如果zone_reclaim_mode设置了RECLAIM_SWAP值 4则阈值比较的是所有文件页包括 swapcache 和 tmpfs否则只考虑普通文件的未映射页。总结setup_min_unmapped_ratio()是NUMA 节点回收的门槛计算器它根据sysctl_min_unmapped_ratio默认 1%和 zone 的managed_pages计算出min_unmapped_pages阈值。只有可回收文件页超过这个阈值时zone_reclaim才会真正执行避免在回收潜力不足时浪费 CPU 扫描 LRU。它从早期的 zone 级计算演进为 pgdat 级计算更准确地反映了节点回收的语义。
阅读完成 · 觉得有帮助?