高云嶺++賀信++莊克良
摘 要針對(duì)目前Linux的內(nèi)核的熱插拔特性以及ACPI里關(guān)于內(nèi)存電源狀態(tài)表MPST的狀態(tài)定義,通過重新編譯Linux內(nèi)核,開發(fā)專有的內(nèi)存管理程序驅(qū)動(dòng)和外部設(shè)置應(yīng)用程序,來完成在大型復(fù)雜服務(wù)器系統(tǒng)上在關(guān)機(jī)的情況下,實(shí)現(xiàn)內(nèi)存的動(dòng)態(tài)熱插拔操作。同時(shí),提供了在Linux平臺(tái)的測試程序,來驗(yàn)證整個(gè)流程的可行性。
【關(guān)鍵詞】Linux內(nèi)核 熱插拔特性 內(nèi)存 內(nèi)存電源狀態(tài)表
動(dòng)態(tài)熱插拔技術(shù)的提出,基本上是為了在相關(guān)部件出現(xiàn)故障時(shí),保證用戶能夠在系統(tǒng)正常運(yùn)行的同時(shí),進(jìn)行在線維護(hù)。所謂熱插拔(hot-plugging或Hot Swap)功能就是允許用戶在不關(guān)閉系統(tǒng),不切斷電源的情況下取出和更換損壞的內(nèi)存、硬盤、電源或板卡等部件,從而極大地提高了系統(tǒng)對(duì)災(zāi)難的及時(shí)恢復(fù)能力、擴(kuò)展性和靈活性等,使復(fù)雜大型服務(wù)器系統(tǒng)的容錯(cuò)能力大大上升,為用戶提供了最大限度的可用性。
本文針對(duì)內(nèi)存熱插拔這一難題,實(shí)現(xiàn)了一種可操作性強(qiáng)、可行性的技術(shù)方案,并針對(duì)Linux操作系統(tǒng)之上進(jìn)行原型的開發(fā)和驗(yàn)證。
1 總體架構(gòu)設(shè)計(jì)
總體架構(gòu)設(shè)計(jì)有八部分組成,涉及從操作系統(tǒng)上層應(yīng)用程序,中間層驅(qū)動(dòng)設(shè)置程序,操作系統(tǒng)內(nèi)核,底層硬件驅(qū)動(dòng),硬件和BIOS等,具體如圖1所示。
1.1 Linux內(nèi)核修改
要實(shí)現(xiàn)內(nèi)存的熱插拔,首先需要操作系統(tǒng)的深度支持。其主要完成的功能是,錯(cuò)誤檢測和頁表遷移。當(dāng)?shù)玫接脩粼O(shè)置指令或者根據(jù)自身RAS(Reliability Availability Serviceability)機(jī)制檢測到硬件錯(cuò)誤的時(shí)候,操作系統(tǒng)要主動(dòng)把支持熱插拔內(nèi)存上正在運(yùn)行的頁表和數(shù)據(jù)項(xiàng)遷移交換到其他物理內(nèi)存條。頁表遷移主要任務(wù)包括在目的內(nèi)存分配新的頁表,修改內(nèi)核數(shù)據(jù)結(jié)構(gòu)樹,移除老的頁表入口以及移動(dòng)頁表內(nèi)容。
1.2 驅(qū)動(dòng)設(shè)置程序
驅(qū)動(dòng)設(shè)置程序主要負(fù)責(zé)外部應(yīng)用程序和Linux內(nèi)核進(jìn)行雙向通信,從而對(duì)硬件的設(shè)備驅(qū)動(dòng)程序進(jìn)行監(jiān)控和設(shè)置。驅(qū)動(dòng)設(shè)置程序架設(shè)起了內(nèi)核態(tài)和用戶態(tài)進(jìn)行雙向通信的安全橋梁。它的作用主要是,在內(nèi)核態(tài)通過調(diào)用ACPICA(ACPI Component Architecture)接口讀取MPST(Memory Power State Table)表項(xiàng)中的內(nèi)存節(jié)點(diǎn),地址以及電源狀態(tài)列表,轉(zhuǎn)發(fā)給用戶態(tài)的應(yīng)用程序;同時(shí),接收用戶對(duì)內(nèi)存遷移和插拔的輸入要求,命令操作系統(tǒng)內(nèi)核完成頁表遷移工作,然后進(jìn)行內(nèi)存電源狀態(tài)控制,使其安全掉電,為手動(dòng)的內(nèi)存條熱插拔操作做好軟件和固件層面的準(zhǔn)備工作。
1.3 應(yīng)用程序
應(yīng)用程序是用戶和計(jì)算機(jī)操作的用戶界面窗口。主要響應(yīng)用戶指令,顯示內(nèi)存電源狀態(tài)信息,執(zhí)行內(nèi)存電源狀態(tài)控制,以及提供內(nèi)存分配遷移的壓力測試程序。
2 模塊功能詳細(xì)設(shè)計(jì)
2.1 Linux內(nèi)核修改
Linux內(nèi)核主要是確保在操作系統(tǒng)中將內(nèi)存熱插拔特性打開,并確保ACPI表項(xiàng)定義include\linux\acpi中新加入的對(duì)MPST表的支持,為了明顯的看到整個(gè)內(nèi)存的遷移過程的變化,可以修改mm\vmscan.c中的線程頁面守護(hù)神kswapd的源代碼。相關(guān)代碼路徑如下。
include\linux\acpi.h;mm\vmscan.c;include\acpi
Kswapd進(jìn)程會(huì)被操作系統(tǒng)內(nèi)核間歇性的喚醒,進(jìn)行兩部分工作。第一部分是在發(fā)現(xiàn)物理頁面已經(jīng)短缺的情況下,預(yù)先找出如果頁面,且將這些頁面的映射斷開,使這些物理頁面從活躍狀態(tài)轉(zhuǎn)入不活躍狀態(tài),為頁面的換出作好準(zhǔn)備。第二部分是每次都要執(zhí)行的,把已經(jīng)處于不活躍狀態(tài)的“”頁面寫入交換設(shè)備,使它們成為不活躍“干凈”頁面繼續(xù)緩沖,或進(jìn)一步回收這樣的頁面成為空閑頁面。所以,可以在Kswapd中插入代碼,實(shí)現(xiàn)在內(nèi)存熱插拔過程中,完成對(duì)內(nèi)存遷移狀態(tài)的檢測。當(dāng)內(nèi)存不足的時(shí)候,Kswapd會(huì)自動(dòng)喚醒沉睡過程中的內(nèi)存,而在內(nèi)存過剩,或者需要內(nèi)存熱插拔的時(shí)候,完成頁表遷移整理工作。
在修改完Linux源代碼之后,就可以進(jìn)行內(nèi)核配置修改、操作系統(tǒng)新內(nèi)核的編譯和加載工作了。
2.2 驅(qū)動(dòng)設(shè)置程序設(shè)計(jì)
該驅(qū)動(dòng)設(shè)置模塊被設(shè)計(jì)成一個(gè)字符型驅(qū)動(dòng),用于內(nèi)核態(tài)和用戶態(tài)的數(shù)據(jù)通信。其主要功能如下:
(1)通過調(diào)用ACPICA架構(gòu)提供的用戶接口,讀取內(nèi)存MPST內(nèi)容。
(2)提供可供用戶態(tài)應(yīng)用程序調(diào)用的,物理內(nèi)存條內(nèi)電源控制模式。
(3)讀取物理內(nèi)存條的狀態(tài)和屬性
(4)傳輸邏輯內(nèi)存的使用狀態(tài)到Kswapd線程,為其進(jìn)行內(nèi)存遷移提供依據(jù)。
2.3 Hot-Plug模塊
當(dāng)重新加載支持內(nèi)存熱插拔的Linux內(nèi)核后,可以在/sys/devices/system/memory下面看到按照內(nèi)存塊ID區(qū)分的內(nèi)存狀態(tài)信息。該系統(tǒng)有兩個(gè)內(nèi)存memory0和memory1。在每個(gè)內(nèi)存下面又包含著五個(gè)信息:phys_index、phys_device、state、removable、valid_zones。
phys_device是真正的物理內(nèi)存序號(hào),想要執(zhí)行物理內(nèi)存的熱插拔,就是操作這個(gè)屬性字段。State是內(nèi)存電源狀態(tài)信息,操作系統(tǒng)層面只有兩種,在線和離線。而MPST中提供了物理內(nèi)存的多種狀態(tài)的控制。想要做物理內(nèi)存熱插拔,必須首先要設(shè)置該字段為offline。Removeable顯示該內(nèi)存是否可被移除的,只有是removable的物理內(nèi)存里面存放的頁表才可以被操作系統(tǒng)進(jìn)行頁表遷移。
在操作系統(tǒng)層面對(duì)內(nèi)存離線和在線的操作命令比較簡單,只需要對(duì)state進(jìn)行設(shè)置即可。
% echo offline > /sys/devices/system/memory/memoryXXX/state
該Linux的hot-plug模塊只有和MPST相配合才能區(qū)分清楚物理內(nèi)存和邏輯內(nèi)存塊以及頁表的關(guān)系,進(jìn)而做到真正的物理內(nèi)存的熱插拔操作。
2.4 應(yīng)用程序測試程序設(shè)計(jì)
應(yīng)用程序運(yùn)行在Linux shell環(huán)境中,主要負(fù)責(zé)和用戶進(jìn)行交互。它一方面通過調(diào)用驅(qū)動(dòng)配置程序拿到MPST表返回給用戶。用戶根據(jù)MPST的信息,區(qū)分清楚每個(gè)物理內(nèi)存的狀態(tài),地址和狀態(tài)。并找到該物理內(nèi)存和Linux 系統(tǒng)中/sys/devices/system/memory/memoryXXX/的對(duì)應(yīng)關(guān)系。然后,通過 % echo offline/online > /sys/devices/system/memory/memoryXXX/state系統(tǒng)內(nèi)存的狀態(tài)控制,并通過配置驅(qū)動(dòng)程序完成對(duì)真實(shí)物理內(nèi)存的狀態(tài)控制,最后來實(shí)現(xiàn)內(nèi)存的完全移除的目的。
測試程序可以通過在用戶空間不停的malloc()大量的內(nèi)存來模擬急劇內(nèi)存占用和釋放的壓力測試。隨著內(nèi)存的占用到達(dá)一定閥值,越來越多的內(nèi)存會(huì)由經(jīng)過MPST的命令設(shè)置,變?yōu)樯想姞顟B(tài)。當(dāng)達(dá)到一定壓力,通過殺掉應(yīng)用程序看操作系統(tǒng)清理整理內(nèi)存的能力。而當(dāng)一個(gè)物理內(nèi)存中的所有邏輯內(nèi)存塊全部被移除后,測試程序會(huì)調(diào)用MPST將該物理內(nèi)存下電,在操作系統(tǒng)的資源管理器中,可以清楚地看到操作系統(tǒng)檢測到的物理內(nèi)存大小的急劇變化。
3 結(jié)束語與展望
本文主要實(shí)現(xiàn)了Linux平臺(tái)上對(duì)物理內(nèi)存熱插拔操作的程序設(shè)計(jì)和系統(tǒng)配置,綜合使用了ACPI MPST對(duì)物理內(nèi)存狀態(tài)的檢測設(shè)置和操作系統(tǒng)內(nèi)核自身的邏輯內(nèi)存塊的在線離線操作,來達(dá)到物理內(nèi)存和邏輯內(nèi)存狀態(tài)控制的統(tǒng)一,最后在具有可移除屬性的物理內(nèi)存上實(shí)現(xiàn)了內(nèi)存熱插拔操作。該技術(shù)目前還處于研究的初級(jí)階段,還有的工作,比如解決邏輯內(nèi)存塊在物理內(nèi)存中的空洞問題,以及部分映射內(nèi)核空間的物理內(nèi)存的不可移除的問題。內(nèi)存的熱插拔問題是一個(gè)涉及面非常廣泛的復(fù)雜性的綜合性的問題,該問題的初步解決對(duì)于復(fù)雜系統(tǒng)設(shè)備的開發(fā)、維護(hù)和調(diào)試,尤其是關(guān)鍵服務(wù)器的不間斷運(yùn)行,具有非常現(xiàn)實(shí)的積極意義。
參考文獻(xiàn)
[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