内存热插拔机制中启用“大块”(large blocks)模式所需的最小内存容量阈值。
核心含义
#define MEM_SIZE_FOR_LARGE_BLOCK (64UL << 30) // 64GB
MEM_SIZE_FOR_LARGE_BLOCK被定义为64GB。当系统的物理内存总量达到或超过 64GB时,内核在启动时会倾向于使用更大的内存块粒度(如 2GB),以减少memory_block设备数量和管理开销。
与MAX_BLOCK_SIZE的配合
这个宏与MAX_BLOCK_SIZE紧密配合使用。在probe_memory_block_size()中,典型的逻辑是:
/* * If the system has more than 64GB of RAM, use large blocks * to reduce the number of memory block devices. */ if (boot_mem_end >= MEM_SIZE_FOR_LARGE_BLOCK) return MAX_BLOCK_SIZE; // 2GB
当内存达到 64GB 阈值时,内核会选择MAX_BLOCK_SIZE(2GB)作为块大小。这样,64GB 内存只需要 32 个memory_block设备,而如果使用 128MB 的小块,则需要 512 个设备——sysfs 节点的数量相差 16 倍,启动速度和内存开销差异显著。
设计意图
这个阈值的设定是为了在大内存系统上避免管理开销的爆炸。内存热插拔的块大小是一个权衡:
小块(如 128MB):热插拔粒度精细,但设备数量多,管理开销大。
大块(如 2GB):管理开销小,但热插拔粒度粗。
64GB 这个阈值是一个经验值。低于 64GB 的系统,即使使用较小的块(如 128MB 或 256MB),设备数量也在可接受范围内;而超过 64GB 的系统,如果继续使用小块,设备数量会迅速增长到数千个,导致 sysfs 遍历和内存管理效率严重下降。
与MAX_BLOCK_SIZE的协同
这两个宏共同构成了 x86 内存热插拔块大小的决策框架:
| 宏 | 值 | 作用 |
|---|---|---|
MIN_MEMORY_BLOCK_SIZE | 通常 128MB | 块大小的下限 |
MEM_SIZE_FOR_LARGE_BLOCK | 64GB | 启用大块的阈值 |
MAX_BLOCK_SIZE | 2GB | 块大小的上限 |
probe_memory_block_size()会根据系统内存总量是否达到MEM_SIZE_FOR_LARGE_BLOCK,来决定是否将块大小提升到MAX_BLOCK_SIZE,从而在精细度和开销之间取得平衡。
唯一的直接调用点
这个宏在probe_memory_block_size()中用于判断是否应该启用大内存块。
典型的判断逻辑如下:
static unsigned long probe_memory_block_size(void) { unsigned long boot_mem_end = max_pfn << PAGE_SHIFT; unsigned long bz; /* ... */ /* * If RAM is smaller than MEM_SIZE_FOR_LARGE_BLOCK (64GB), * use the regular (smaller) block size. */ if (boot_mem_end < MEM_SIZE_FOR_LARGE_BLOCK) { bz = MIN_MEMORY_BLOCK_SIZE; goto done; } /* RAM >= 64GB, use the larger block size (MAX_BLOCK_SIZE, 2GB) */ bz = MAX_BLOCK_SIZE; done: return bz; }调用关系链
这个宏的调用路径非常清晰:
memory_block_size_bytes() ← 通用内存热插拔代码调用 ↓ probe_memory_block_size() ← x86 架构实现,启动时执行一次 ↓ MEM_SIZE_FOR_LARGE_BLOCK ← 用于阈值判断
memory_block_size_bytes()是通用内存热插拔子系统(drivers/base/memory.c)调用的接口,用来获取当前系统的内存块大小。x86 架构通过probe_memory_block_size()来实现它,而MEM_SIZE_FOR_LARGE_BLOCK就是这个实现中用来判断“内存是否足够大,值得使用大块”的阈值。
上下文中的用途
在邮件列表讨论中,开发者明确指出:“只在系统物理地址末端至少达到MEM_SIZE_FOR_LARGE_BLOCK(64G)时才会进行这个检查”。这意味着,对于内存小于 64GB 的系统,内核根本不会考虑使用MAX_BLOCK_SIZE,直接使用较小的默认块大小(如MIN_MEMORY_BLOCK_SIZE,通常为 128MB)。
这个设计背后的逻辑很直接:内存块越大,热插拔的粒度就越粗,但管理开销(sysfs 设备数量)越小。64GB 是一个平衡点——低于此值时,小块的精细度更有利;超过此值时,使用 2GB 大块来避免设备数量爆炸。