probe_memory_block_size()是 x86-64 架构中用于在启动时动态决定内存热插拔块大小的探测函数位于arch/x86/mm/init_64.c。它的核心目标是平衡热插拔粒度与管理开销。核心目标该函数通过分析系统物理内存总量和末尾地址选择一个能整除内存末尾且尽可能大的 2 的幂次块大小以减少/sys/devices/system/memory/下memory_block设备的数量。决策逻辑现代内核现代内核的逻辑包含几个关键判断1. 命令行覆盖如果用户通过set_memory_block_size参数指定了块大小则直接使用该值。2. 小内存系统如果物理内存总量小于MEM_SIZE_FOR_LARGE_BLOCK64GB则直接返回MIN_MEMORY_BLOCK_SIZE通常 128MB无需复杂探测。3. 裸机优化如果系统是裸机非虚拟化环境由于内存末尾对齐通常不是热插拔的硬性要求直接使用MAX_BLOCK_SIZE2GB以最小化管理开销。4. 虚拟化/对齐场景对于虚拟化环境或有热插拔建议值的系统代码会从MAX_BLOCK_SIZE开始循环右移寻找第一个能整除boot_mem_end的大小。这确保了块大小与内存末尾对齐同时尽可能大。历史演进该函数最初由 Yinghai Lu 于 2012 年引入目的是解决大内存系统如 2TB 内存上/sys/devices/system/memory/目录下出现 16400 个条目的性能问题。通过匹配 MMIO 重映射大小来增大块尺寸可将 6TB 系统的启动时间缩短 35 秒。后续补丁增加了裸机场景直接使用最大块的优化以及更近期的热插拔建议值支持。调用关系该函数是memory_block_size_bytes()的内部实现后者是通用内存热插拔子系统调用的接口仅在首次调用时执行探测并缓存结果。memory_block_size_bytes()是 Linux 内存热插拔子系统中的核心查询接口用于获取当前系统内存块的字节大小。它由通用内存管理代码调用而具体的块大小决策则由各架构通过probe_memory_block_size()等函数实现。函数定义与返回值该函数在include/linux/memory.h中声明其默认弱符号实现位于drivers/base/memory.c仅返回MIN_MEMORY_BLOCK_SIZE。在 x86 等架构上它被覆盖以实现更复杂的逻辑。核心调用关系该函数在内存热插拔的多个关键路径中被调用确保所有操作都按块大小对齐添加内存在add_memory()中按memory_block_size_bytes()分块处理。注册热插拔内存在hotplug_memory_register()中用于对齐验证。范围校验在check_hotplug_memory_range()中验证起始地址和大小是否对齐。移除内存在offline_and_remove_memory()中用于处理跨块范围。x86 架构的实现逻辑在 x86 上该函数的实际工作由probe_memory_block_size()完成其决策依据包括用户配置是否已通过set_memory_block_size_order()设定。内存大小根据物理 RAM 大小判断。运行环境裸机环境下通常直接使用最大块尺寸虚拟化环境则需寻找能对齐内存末端且尽可能大的块。架构限制块大小必须是 2 的幂且不小于MIN_MEMORY_BLOCK_SIZE。设计要点memory_block_size_bytes()是架构相关实现与通用内存热插拔框架之间的桥梁。x86 通过probe_memory_block_size()在首次调用时完成探测并缓存结果后续调用直接返回缓存值避免重复计算。这种设计使得通用代码无需关心底层架构如何决策块大小只需通过该接口获取结果即可。