大型复杂系统内存热插拔技术的实现
2017-11-09高云岭贺信庄克良
高云岭++贺信++庄克良
摘 要针对目前Linux的内核的热插拔特性以及ACPI里关于内存电源状态表MPST的状态定义,通过重新编译Linux内核,开发专有的内存管理程序驱动和外部设置应用程序,来完成在大型复杂服务器系统上在关机的情况下,实现内存的动态热插拔操作。同时,提供了在Linux平台的测试程序,来验证整个流程的可行性。
【关键词】Linux内核 热插拔特性 内存 内存电源状态表
动态热插拔技术的提出,基本上是为了在相关部件出现故障时,保证用户能够在系统正常运行的同时,进行在线维护。所谓热插拔(hot-plugging或Hot Swap)功能就是允许用户在不关闭系统,不切断电源的情况下取出和更换损坏的内存、硬盘、电源或板卡等部件,从而极大地提高了系统对灾难的及时恢复能力、扩展性和灵活性等,使复杂大型服务器系统的容错能力大大上升,为用户提供了最大限度的可用性。
本文针对内存热插拔这一难题,实现了一种可操作性强、可行性的技术方案,并针对Linux操作系统之上进行原型的开发和验证。
1 总体架构设计
总体架构设计有八部分组成,涉及从操作系统上层应用程序,中间层驱动设置程序,操作系统内核,底层硬件驱动,硬件和BIOS等,具体如图1所示。
1.1 Linux内核修改
要实现内存的热插拔,首先需要操作系统的深度支持。其主要完成的功能是,错误检测和页表迁移。当得到用户设置指令或者根据自身RAS(Reliability Availability Serviceability)机制检测到硬件错误的时候,操作系统要主动把支持热插拔内存上正在运行的页表和数据项迁移交换到其他物理内存条。页表迁移主要任务包括在目的内存分配新的页表,修改内核数据结构树,移除老的页表入口以及移动页表内容。
1.2 驱动设置程序
驱动设置程序主要负责外部应用程序和Linux内核进行双向通信,从而对硬件的设备驱动程序进行监控和设置。驱动设置程序架设起了内核态和用户态进行双向通信的安全桥梁。它的作用主要是,在内核态通过调用ACPICA(ACPI Component Architecture)接口读取MPST(Memory Power State Table)表项中的内存节点,地址以及电源状态列表,转发给用户态的应用程序;同时,接收用户对内存迁移和插拔的输入要求,命令操作系统内核完成页表迁移工作,然后进行内存电源状态控制,使其安全掉电,为手动的内存条热插拔操作做好软件和固件层面的准备工作。
1.3 应用程序
应用程序是用户和计算机操作的用户界面窗口。主要响应用户指令,显示内存电源状态信息,执行内存电源状态控制,以及提供内存分配迁移的压力测试程序。
2 模块功能详细设计
2.1 Linux内核修改
Linux内核主要是确保在操作系统中将内存热插拔特性打开,并确保ACPI表项定义include\linux\acpi中新加入的对MPST表的支持,为了明显的看到整个内存的迁移过程的变化,可以修改mm\vmscan.c中的线程页面守护神kswapd的源代码。相关代码路径如下。
include\linux\acpi.h;mm\vmscan.c;include\acpi
Kswapd进程会被操作系统内核间歇性的唤醒,进行两部分工作。第一部分是在发现物理页面已经短缺的情况下,预先找出如果页面,且将这些页面的映射断开,使这些物理页面从活跃状态转入不活跃状态,为页面的换出作好准备。第二部分是每次都要执行的,把已经处于不活跃状态的“”页面写入交换设备,使它们成为不活跃“干净”页面继续缓冲,或进一步回收这样的页面成为空闲页面。所以,可以在Kswapd中插入代码,实现在内存热插拔过程中,完成对内存迁移状态的检测。当内存不足的时候,Kswapd会自动唤醒沉睡过程中的内存,而在内存过剩,或者需要内存热插拔的时候,完成页表迁移整理工作。
在修改完Linux源代码之后,就可以进行内核配置修改、操作系统新内核的编译和加载工作了。
2.2 驱动设置程序设计
该驱动设置模块被设计成一个字符型驱动,用于内核态和用户态的数据通信。其主要功能如下:
(1)通过调用ACPICA架构提供的用户接口,读取内存MPST内容。
(2)提供可供用户态应用程序调用的,物理内存条内电源控制模式。
(3)读取物理内存条的状态和属性
(4)传输逻辑内存的使用状态到Kswapd线程,为其进行内存迁移提供依据。
2.3 Hot-Plug模块
当重新加载支持内存热插拔的Linux内核后,可以在/sys/devices/system/memory下面看到按照内存块ID区分的内存状态信息。该系统有两个内存memory0和memory1。在每个内存下面又包含着五个信息:phys_index、phys_device、state、removable、valid_zones。
phys_device是真正的物理内存序号,想要执行物理内存的热插拔,就是操作这个属性字段。State是内存电源状态信息,操作系统层面只有两种,在线和离线。而MPST中提供了物理内存的多种状态的控制。想要做物理内存热插拔,必须首先要设置该字段为offline。Removeable显示该内存是否可被移除的,只有是removable的物理內存里面存放的页表才可以被操作系统进行页表迁移。
在操作系统层面对内存离线和在线的操作命令比较简单,只需要对state进行设置即可。
% echo offline > /sys/devices/system/memory/memoryXXX/state
该Linux的hot-plug模块只有和MPST相配合才能区分清楚物理内存和逻辑内存块以及页表的关系,进而做到真正的物理内存的热插拔操作。
2.4 应用程序测试程序设计
应用程序运行在Linux shell环境中,主要负责和用户进行交互。它一方面通过调用驱动配置程序拿到MPST表返回给用户。用户根据MPST的信息,区分清楚每个物理内存的状态,地址和状态。并找到该物理内存和Linux 系统中/sys/devices/system/memory/memoryXXX/的对应关系。然后,通过 % echo offline/online > /sys/devices/system/memory/memoryXXX/state系统内存的状态控制,并通过配置驱动程序完成对真实物理内存的状态控制,最后來实现内存的完全移除的目的。
测试程序可以通过在用户空间不停的malloc()大量的内存来模拟急剧内存占用和释放的压力测试。随着内存的占用到达一定阀值,越来越多的内存会由经过MPST的命令设置,变为上电状态。当达到一定压力,通过杀掉应用程序看操作系统清理整理内存的能力。而当一个物理内存中的所有逻辑内存块全部被移除后,测试程序会调用MPST将该物理内存下电,在操作系统的资源管理器中,可以清楚地看到操作系统检测到的物理内存大小的急剧变化。
3 结束语与展望
本文主要实现了Linux平台上对物理内存热插拔操作的程序设计和系统配置,综合使用了ACPI MPST对物理内存状态的检测设置和操作系统内核自身的逻辑内存块的在线离线操作,来达到物理内存和逻辑内存状态控制的统一,最后在具有可移除属性的物理内存上实现了内存热插拔操作。该技术目前还处于研究的初级阶段,还有的工作,比如解决逻辑内存块在物理内存中的空洞问题,以及部分映射内核空间的物理内存的不可移除的问题。内存的热插拔问题是一个涉及面非常广泛的复杂性的综合性的问题,该问题的初步解决对于复杂系统设备的开发、维护和调试,尤其是关键服务器的不间断运行,具有非常现实的积极意义。
参考文献
[1]Robert Love.Linux kernel development.Novell Press,2005.
[2]Daniel P.Bovet,Marco Cesati. Understanding the Linux Kernel,3rd. Novell Press.OReilly,2007.
[3]Advanced Configuration and Power Interface Specification Version 6.0, Unified EFI,2008.
作者单位
海军704厂 山东省青岛市 266109