☰
page_alloc local_memory_node
2026/10/15 10:37:36 网站建设 项目流程

local_memory_node(int node)是内核中用于解决memoryless node(无内存节点)问题的关键函数。它的核心作用是:给定一个节点 ID,返回该节点或其最近的“有内存”节点的 ID,确保内核分配内存时不会落到一个物理上没有内存的节点上。

函数实现

根据源码中的注释,它的实现逻辑如下:

/* * Return node id of node used for "local" allocations. * I.e., first node id of first zone in arg node's generic zonelist. * Used for initializing percpu 'numa_mem', which is used primarily * for kernel allocations, so use GFP_KERNEL flags to locate zonelist. */ int local_memory_node(int node) { struct zoneref *z; struct zone *zone; z = first_zones_zonelist(node_zonelist(node, GFP_KERNEL), gfp_zone(GFP_KERNEL), NULL); zone = zonelist_zone(z); if (!zone) return node; return zone_to_nid(zone); }

核心逻辑

  1. 利用 zonelist 回退机制:函数通过node_zonelist(node, GFP_KERNEL)获取该节点的 zonelist。zonelist 在构建时已经考虑了“如果本节点没有内存,应该回退到哪个最近的节点”的问题。

  2. 找到第一个有内存的节点:first_zones_zonelist()会沿着 zonelist 找到第一个满足GFP_KERNEL分配条件的 zone。如果传入的node本身没有内存,zonelist 的第一个有效条目会指向最近的有内存节点。

  3. 返回节点 ID:找到 zone 后,通过zone_to_nid(zone)返回它所属的节点 ID。如果没有任何可用 zone(极端情况),则回退返回原始node。

为什么需要它?

在 PowerPC 等架构上,CPU 可以连接到物理上没有挂载内存的 NUMA 节点(memoryless node)。如果代码直接使用cpu_to_node(cpu)获取节点 ID,然后从这个节点分配内存,而该节点实际上没有内存,分配就会失败或产生性能问题。

local_memory_node()保证了:无论 CPU 连接的是不是无内存节点,都能拿到一个确定有内存的、距离最近的节点 ID。

典型使用场景

1. 初始化 per-CPU 的numa_mem变量

在build_all_zonelists()中,内核会为每个在线 CPU 初始化其“本地内存节点”:

for_each_online_cpu(cpu) set_cpu_numa_mem(cpu, local_memory_node(cpu_to_node(cpu)));

这样,后续的numa_mem_id()或cpu_to_mem()就能返回一个有内存的节点 ID。

2. 子系统避免在无内存节点上分配

多个子系统曾修复过相关问题,改用local_memory_node()替代直接的cpu_to_node():

  • blk-mq:避免将无内存节点的 ID 编码到硬件队列的numa_node中

  • IB/hfi1:避免在无内存节点上分配内存

  • BPF:避免在无内存节点上分配

关于cpu_to_node()的争论

值得注意的是,社区曾讨论过是否应该直接在cpu_to_node()内部处理无内存节点的问题。有开发者建议:与其逐个子系统修改cpu_to_node()的调用点,不如在CONFIG_HAVE_MEMORYLESS_NODES下让cpu_to_node()本身返回有内存的节点。不过这个建议最终没有被采纳,local_memory_node()作为显式的转换函数保留了下来。

总结

local_memory_node()是memoryless node 架构的适配层:它利用 zonelist 的回退机制,将“CPU 所在的拓扑节点”映射为“最近的有内存节点”,确保内核在初始化numa_mem和子系统分配内存时不会落到物理上空无一物的节点上。它的存在让内核在 PowerPC 等支持无内存节点的平台上能够正确地进行本地内存分配。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询