
calculate_totalreserve_pages()是内存管理初始化阶段用于计算系统总保留页数totalreserve_pages的函数。它遍历所有 zone把每个 zone 的保留内存汇总到全局变量totalreserve_pages中供内存热插拔、水位判断和内存可用性评估使用。核心作用与背景totalreserve_pages是一个全局变量记录系统中不能被常规分配使用的保留页总数。它由三部分构成lowmem_reserve[]前面讲过的低端内存保留——低端 zone 为保护自己而保留的页数WMARK_MIN水位线每个 zone 的最低保留水位nr_reserved_highatomic为高阶原子分配保留的页数。这个汇总值用于内存热插拔判断下线内存后是否仍有足够的保留内存si_meminfo()//proc/meminfo计算MemAvailable等字段OOM 决策评估系统实际可用的内存量。典型实现static void calculate_totalreserve_pages(void) { struct pglist_data *pgdat; unsigned long reserve_pages 0; enum zone_type i, j; for_each_online_pgdat(pgdat) { pgdat-totalreserve_pages 0; for (i 0; i MAX_NR_ZONES; i) { struct zone *zone pgdat-node_zones i; long max 0; if (!populated_zone(zone)) continue; /* 累加 lowmem_reserve */ for (j i; j MAX_NR_ZONES; j) { if (populated_zone(pgdat-node_zones j)) max zone-lowmem_reserve[j]; } /* 加上 WMARK_MIN 水位 */ max wmark_pages(zone, WMARK_MIN); /* 加上高阶原子保留 */ max zone-nr_reserved_highatomic; pgdat-totalreserve_pages max; reserve_pages max; } } totalreserve_pages reserve_pages; }逐步解析1. 遍历所有在线节点和 zonefor_each_online_pgdat(pgdat) { pgdat-totalreserve_pages 0; for (i 0; i MAX_NR_ZONES; i) {外层遍历 NUMA 节点内层遍历每个节点上的 zone 类型。2. 累加lowmem_reservefor (j i; j MAX_NR_ZONES; j) { if (populated_zone(pgdat-node_zones j)) max zone-lowmem_reserve[j]; }zone-lowmem_reserve[j]当来自jzone 的分配回退到izone 时izone 要保留的页数。从j i开始遍历到最高 zone把所有相关的高端 zone 对应的保留量累加。这确保totalreserve_pages反映最坏情况下低端 zone 需要保留的总量。3. 加上WMARK_MINmax wmark_pages(zone, WMARK_MIN);WMARK_MIN是 zone 的最低水位线——低于这个值直接回收/OOM 就会触发。这部分内存不能被常规分配使用必须计入保留。4. 加上nr_reserved_highatomicmax zone-nr_reserved_highatomic;为高阶原子分配保留的 pageblock 页数。这些页普通分配不能用也必须计入保留。5. 汇总到全局变量pgdat-totalreserve_pages max; reserve_pages max;同时更新节点级的pgdat-totalreserve_pages和全局的reserve_pages。循环结束后把全局汇总值写入totalreserve_pages。调用场景它主要在以下时机被调用setup_per_zone_wmarks()水位初始化/调整后重新计算总保留setup_per_zone_lowmem_reserve()lowmem reserve 更新后内存热插拔节点上线/下线后CPU 热插拔影响水位计算时sysctl 修改调整min_free_kbytes、lowmem_reserve_ratio、watermark_scale_factor等参数后calculate_min_free_kbytes()计算最小空闲内存时。总结calculate_totalreserve_pages()是系统保留内存的汇总器它遍历所有在线节点和 populated zone把每个 zone 的lowmem_reserve、WMARK_MIN水位和nr_reserved_highatomic累加得到节点级和全局的totalreserve_pages。这个值反映了系统中不能被常规分配使用的保留内存总量是内存热插拔判断、/proc/meminfo统计和 OOM 决策的重要基准。