内存热插拔¶
将 CXL 内存呈现给内核页面分配器的最后阶段是让 DAX 驱动程序通过内存热插拔组件呈现 驱动程序管理 内存区域。
需要考虑四个主要配置
默认在线行为(开/关和区域)
热插拔内存块大小
内存映射资源位置
驱动程序管理的内存指定
默认在线行为¶
热插拔内存的默认在线行为由以下因素决定,按优先级排序
CONFIG_MHP_DEFAULT_ONLINE_TYPE
构建配置memhp_default_state
启动参数/sys/devices/system/memory/auto_online_blocks
值
这些决定了热插拔内存块到达以下三种状态之一
离线
在线,位于
ZONE_NORMAL
在线,位于
ZONE_MOVABLE
ZONE_NORMAL
表示此容量可用于几乎任何分配,而 ZONE_MOVABLE
表示此容量仅应用于可迁移的分配。
ZONE_MOVABLE
尝试保留内存块的热插拔能力,以便稍后可以热拔出整个区域。 任何上线到 ZONE_NORMAL
的容量都应被视为永久附加到页面分配器。
热插拔内存块大小¶
默认情况下,在大多数架构上,热插拔内存块大小为 128MB 或 256MB。 在 x86 上,随着总内存容量超过 64GB,块大小会增加到 2GB。 从 v6.15 开始,Linux 在确定热插拔内存块大小时,不会考虑 ACPI CEDT CFMWS 区域的大小和对齐方式(请参阅早期启动文档)。
内存映射¶
用于表示热插拔内存容量的 struct folio
分配的位置由以下系统设置决定
/sys_module/memory_hotplug/parameters/memmap_on_memory
/sys/bus/dax/devices/daxN.Y/memmap_on_memory
如果这两个参数都设置为 true,则此容量的 struct folio
将从正在上线的内存块中划分出来。 如果内存的延迟特别高且其 struct folio
变得竞争激烈,则这会产生性能影响。
如果任一参数设置为 false,则此容量的 struct folio
将从运行热插拔过程的处理器的本地节点分配。 此容量将从该节点上的 ZONE_NORMAL
分配,因为它是一个 GFP_KERNEL
分配。
具有极大量 ZONE_MOVABLE
内存(例如 CXL 内存池)的系统必须确保有足够的本地 ZONE_NORMAL
容量来托管热插拔容量的内存映射。
驱动程序管理的内存¶
DAX 驱动程序将此内存作为“驱动程序管理”呈现给内存热插拔。 这不是一个可配置的设置,但需要注意的是,驱动程序管理的内存被明确排除在 kexec 期间使用。 这是必需的,以确保 CXL 设备在功能系统重启期间可能受到的任何重置或带外操作(例如 probe 时重置)不会导致 kexec 内核的部分被覆盖。