__build_all_zonelists()是build_all_zonelists()的底层执行函数负责遍历系统中所有在线节点为每个节点构建 zonelist。核心实现static int __build_all_zonelists(void *data) { int nid; int cpu; pg_data_t *self data; for_each_online_node(nid) { pg_data_t *pgdat NODE_DATA(nid); build_zonelists(pgdat); } for_each_possible_cpu(cpu) per_cpu_pages_init(per_cpu(boot_pageset, cpu), per_cpu(boot_zonestats, cpu)); mminit_verify_zonelist(); cpuset_init_current_mems_allowed(); return 0; }关键步骤解析1. 遍历所有在线节点for_each_online_node(nid) { pg_data_t *pgdat NODE_DATA(nid); build_zonelists(pgdat); }对每个在线 NUMA 节点调用build_zonelists()前面讲过的为其构建ZONELIST_FALLBACK和ZONELIST_NOFALLBACK。在 UMA 系统中只有一个节点此循环只执行一次。2. 初始化 boot pagesetfor_each_possible_cpu(cpu) per_cpu_pages_init(per_cpu(boot_pageset, cpu), ...);初始化每个可能 CPU 的boot_pageset。这些是引导阶段的 per-CPU 页缓存在真正的 per-CPU 分配器就绪之前使用。它们的high0、batch1使得放入的页会立即转交给伙伴系统避免在早期缓存页。3. 验证与 cpuset 初始化mminit_verify_zonelist()在调试配置下验证构建的 zonelist 是否正确。cpuset_init_current_mems_allowed()将当前任务的mems_allowed掩码置为全部节点。调用上下文__build_all_zonelists()由build_all_zonelists()调用系统启动阶段SYSTEM_BOOTING通过build_all_zonelists_init()间接调用传入NULL遍历所有在线节点。内存热插拔传入具体的pgdat指针只构建该节点的 zonelist。build_all_zonelists()被标记为__ref因为它会调用__meminit注解的辅助函数但在内存热插拔时也需要被调用。总结__build_all_zonelists()是 zonelist 构建的遍历执行层它遍历所有在线节点对每个节点调用build_zonelists()构建分配回退列表同时初始化引导阶段的 per-CPU 页缓存boot_pageset并完成 zonelist 验证和 cpuset 初始化。它是build_all_zonelists()在启动和热插拔场景下的实际工作函数。