摘 要:目前申威架構(gòu)所使用的Linux內(nèi)核是基于通用目的操作系統(tǒng)設(shè)計的,其實時性難以滿足實時場景應(yīng)用的需求。為提高申威平臺的實時性,構(gòu)建了基于申威架構(gòu)的實時搶占補丁,實現(xiàn)了申威架構(gòu)內(nèi)核態(tài)可搶占和Lazy Preemption機制,并根據(jù)申威架構(gòu)的特征對補丁進(jìn)行了優(yōu)化。運用多種方法對申威架構(gòu)的實時搶占補丁展開測試,測試結(jié)果表明,加入補丁后的申威Linux內(nèi)核實時性得到了大幅提升,且在較強壓力下仍能保持較好的性能,這證明了所提出的申威架構(gòu)實時搶占補丁的有效性,為申威內(nèi)核在實時場景中的應(yīng)用奠定了堅實的基礎(chǔ)。
關(guān)鍵詞:申威架構(gòu);Linux內(nèi)核;實時搶占補??;實時性;內(nèi)核態(tài)可搶占;Lazy Preemption機制
中圖分類號:TP39 文獻(xiàn)標(biāo)識碼:A 文章編號:2095-1302(2025)07-0-04
0 引 言
隨著嵌入式技術(shù)在通信、交通、航空航天等領(lǐng)域的廣泛應(yīng)用,嵌入式系統(tǒng)對實時性的要求也越來越高。目前,國內(nèi)外已經(jīng)有相關(guān)成熟的實時操作系統(tǒng),包括VxWorks系統(tǒng)[1]、SylixOS系統(tǒng)、DeltaOS系統(tǒng)等,但是這些商用實時操作系統(tǒng)價格昂貴、源碼不開放,無法滿足我國關(guān)鍵行業(yè)對實時操作系統(tǒng)的自主可控要求。對于使用最為廣泛的Linux系統(tǒng),雖然性能穩(wěn)定、兼容性強且可裁剪,但由于Linux本身是通用操作系統(tǒng),追求高吞吐率和公平性,對實時性設(shè)計考慮較少,所以其實時性能并不是很強[2]。隨著Linux系統(tǒng)在嵌入式領(lǐng)域的應(yīng)用,對其實時性要求越來越高,工業(yè)界、學(xué)術(shù)界和Linux內(nèi)核社區(qū)等對Linux內(nèi)核進(jìn)行了各種改進(jìn)。
目前主流的改進(jìn)Linux內(nèi)核實時性的方法主要有兩種:雙內(nèi)核法和修改內(nèi)核代碼的方法。雙內(nèi)核法在Linux內(nèi)核與硬件中斷之間增加了一個可搶先的實時內(nèi)核,實時任務(wù)在實時內(nèi)核中運行,原來的標(biāo)準(zhǔn)Linux內(nèi)核就作為運行在該實時內(nèi)核上的最低優(yōu)先級任務(wù),非實時任務(wù)運行在標(biāo)準(zhǔn)內(nèi)核中[3]。雙內(nèi)核法既保留了標(biāo)準(zhǔn)Linux分時操作系統(tǒng)的各項服務(wù),又為實時進(jìn)程提供了低延時運行環(huán)境,典型應(yīng)用有RT-Linux、Xenomai[4]。雙內(nèi)核增加了系統(tǒng)設(shè)計的復(fù)雜性,且沒有充分利用CPU核心,屬于折中的方式。修改內(nèi)核代碼方法通過打補丁的方式,針對制約Linux內(nèi)核實時性的因素,直接修改Linux內(nèi)核源代碼,使其具有實時能力,如RT-Preempt補丁[5],目前該補丁已包含ARM、ARM64、X86等架構(gòu)。修改內(nèi)核代碼的方法可保證應(yīng)用程序能夠直接使用Linux原有的API編程方式,未改變系統(tǒng)設(shè)計,所以可維護(hù)性高、移植性好。
目前申威已具備發(fā)展嵌入式產(chǎn)業(yè)的芯片基礎(chǔ),正在開展嵌入式操作系統(tǒng)的研究工作。本文通過構(gòu)建基于申威架構(gòu)的RT-Preempt補丁,對申威Linux內(nèi)核代碼進(jìn)行修改,并針對申威架構(gòu)改造優(yōu)化補丁,有效提升了申威Linux內(nèi)核的實時性。
1 相關(guān)工作
1.1 實時操作系統(tǒng)
為了滿足嵌入式系統(tǒng)的實時性要求,很多嵌入式系統(tǒng)中應(yīng)用了實時操作系統(tǒng)(Real Time Operating System, RTOS)[6]。目前,RTOS在航空航天、國防裝備、物聯(lián)網(wǎng)等高可靠場景中得到了廣泛的應(yīng)用。RTOS要求在一定時間限制內(nèi)完成特定功能,除了保證計算結(jié)果的邏輯正確,還要考慮計算結(jié)果的時效性。RTOS旨在讓有實時性要求的任務(wù)能夠優(yōu)先獲得資源,在限制時間內(nèi)保證任務(wù)得到處理。與分時操作系統(tǒng)相比,RTOS具有實時性強、可靠性和可預(yù)測性高的特點。
1.2 Linux實時搶占補丁
實時搶占補?。≧T-Preempt patch)是Linux內(nèi)核的一個實時補丁,由IngoMolnar和Thomas Gleixner負(fù)責(zé)更新維護(hù),它會隨著Linux內(nèi)核主線發(fā)布[7]。該補丁的核心在于:一是最小化內(nèi)核中不可搶占部分的代碼;二是將為支持搶占性而必須修改的代碼量降至最低。它通過添加額外的搶占性,對臨界區(qū)、中斷處理等代碼進(jìn)行搶占改進(jìn),且不需要完整的內(nèi)核重寫[8]。Linux內(nèi)核原本是一個分時操作系統(tǒng),借助RT-Preempt補丁有望轉(zhuǎn)變?yōu)橛矊崟r操作系統(tǒng)。
實時搶占補丁主要通過中斷線程化、優(yōu)先級繼承、鎖的優(yōu)化、內(nèi)核態(tài)可搶占、高精度時鐘等方法來提高Linux內(nèi)核的實時性。這些補丁可以分為架構(gòu)無關(guān)補丁和架構(gòu)相關(guān)補丁,在架構(gòu)相關(guān)補丁中,目前尚未包含申威架構(gòu)。
2 申威架構(gòu)實時搶占補丁實現(xiàn)
2.1 申威架構(gòu)內(nèi)核態(tài)搶占補丁實現(xiàn)
從是否搶占的角度來看,進(jìn)程管理中的調(diào)度算法可以分為可搶占式調(diào)度和非搶占式調(diào)度。在非搶占式調(diào)度中各進(jìn)程公平地使用CPU資源,一般采用完全公平調(diào)度算法(Completely Fair Scheduler, CFS)[9]。而搶占式調(diào)度通常基于進(jìn)程優(yōu)先級,它允許重要或緊迫的進(jìn)程優(yōu)先使用處理器。每個進(jìn)程都對應(yīng)一種調(diào)度策略,且不同的調(diào)度策略對應(yīng)不同的調(diào)度器。例如,對于普通進(jìn)程,一般使用CFS調(diào)度器,而實時進(jìn)程則采用RT調(diào)度器[10]。
申威架構(gòu)Linux內(nèi)核在調(diào)度中沿用其他架構(gòu)的邏輯,進(jìn)程調(diào)度切換過程如圖1所示。當(dāng)用戶空間發(fā)生中斷或系統(tǒng)調(diào)用時,開始進(jìn)程切換,進(jìn)入內(nèi)核空間后,先保存中斷現(xiàn)場并關(guān)閉中斷。在返回用戶態(tài)前,需要判斷可調(diào)度標(biāo)志TIF_NEED_RESCHED,如果該標(biāo)志被置位,則允許搶占,此時調(diào)用_schedule函數(shù)進(jìn)行上下文切換,切換到被調(diào)度的進(jìn)程上下文;如果該標(biāo)志未被置位,則直接出棧,恢復(fù)中斷現(xiàn)場,最后返回到用戶態(tài),并執(zhí)行下一條指令。當(dāng)中斷或系統(tǒng)調(diào)用發(fā)生時進(jìn)程處于內(nèi)核態(tài)。對于不允許搶占的內(nèi)核而言,在處理完中斷后,只有在返回用戶空間前才會判斷是否會被更高優(yōu)先級的進(jìn)程或其他中斷搶占。
本文通過對申威內(nèi)核態(tài)源碼進(jìn)行修改,實現(xiàn)申威架構(gòu)內(nèi)核態(tài)搶占補丁,解決了內(nèi)核態(tài)不允許搶占的問題。申威可搶占內(nèi)核會檢查內(nèi)核態(tài)進(jìn)入中斷的情況,若需要被調(diào)度且滿足調(diào)度條件,則調(diào)用調(diào)度函數(shù)進(jìn)行調(diào)度,進(jìn)而降低內(nèi)核態(tài)調(diào)度延遲。基于申威架構(gòu)的內(nèi)核態(tài)可搶占具體流程如圖2所示,中斷返回到內(nèi)核態(tài)時會跳轉(zhuǎn)到ret_to_kernel函數(shù)執(zhí)行:首先判斷搶占計數(shù)preempt_count是否為0;接著判斷TIF_NEED_RESCHED標(biāo)志位是否置位,以確定是否需要被其他進(jìn)程搶占;只有當(dāng)preempt_count為0且需要被搶占時,才進(jìn)行內(nèi)核態(tài)搶占,調(diào)用preempt_schedule_irq函數(shù)執(zhí)行相應(yīng)進(jìn)程,否則跳轉(zhuǎn)到retint_restore_args函數(shù),恢復(fù)被中斷時的處理器狀態(tài)。
與內(nèi)核態(tài)不允許搶占的方式相比,內(nèi)核態(tài)可搶占能夠更快地響應(yīng)調(diào)度。在申威架構(gòu)中加入內(nèi)核態(tài)搶占補丁后,避免了用戶進(jìn)程只有在返回用戶態(tài)前才能進(jìn)行調(diào)度的情況,從而降低了內(nèi)核態(tài)延遲,提升了系統(tǒng)實時性。
2.2 申威架構(gòu)Lazy Preemption補丁實現(xiàn)
在對申威架構(gòu)實時性補丁進(jìn)行測試和完善的過程中發(fā)現(xiàn),當(dāng)申威Linux內(nèi)核的進(jìn)程調(diào)度搶占功能被使能后,系統(tǒng)實時性有明顯提升。然而,內(nèi)核態(tài)搶占會使進(jìn)程切換次數(shù)同步增加,進(jìn)而導(dǎo)致部分讀寫性能降低。經(jīng)實驗分析發(fā)現(xiàn),由于不同進(jìn)程的調(diào)度策略不同,非實時進(jìn)程被喚醒,且搶占鎖后無法被其他進(jìn)程獲取,這增加了實時進(jìn)程對所有鎖的無效競爭,最終導(dǎo)致無效進(jìn)程切換增多,系統(tǒng)性能降低。為了解決該問題,本文使用申威架構(gòu)Lazy Preemption補丁,通過設(shè)置標(biāo)志位來區(qū)分實時和普通進(jìn)程的調(diào)度策略,從而避免進(jìn)程間無效搶占,提高系統(tǒng)實時性。
首先,在通用代碼部分,針對SCHED_OTHER類進(jìn)程設(shè)置TIF_NEED_RESCHED_LAZY標(biāo)志與lazy_preempt_count變量,而RT類進(jìn)程保持原狀。其次,于申威架構(gòu)相關(guān)代碼中增添TIF_NEED_RESCHED_LAZY標(biāo)志,并在thread_info結(jié)構(gòu)體里加入lazy_preempt_count變量。最后,增加檢查和調(diào)度動作,如此一來,只有在TIF_NEED_RESCHED_LAZY標(biāo)記已設(shè)置且lazy_preempt_count為0時,才能夠搶占SCHED_OTHER類進(jìn)程,流程如圖3所示。Lazy Preemption補丁進(jìn)一步對SCHED_OTHER類進(jìn)程的被搶占條件加以限制,進(jìn)而可避免因進(jìn)程調(diào)度搶占使能而產(chǎn)生的無效搶占。
3 申威架構(gòu)實時搶占補丁優(yōu)化
3.1 Slab緩存優(yōu)化補丁
Ftrace是一款功能強大的內(nèi)核函數(shù)追蹤工具,可用于調(diào)試和分析意外代碼路徑、系統(tǒng)延遲等問題。在申威架構(gòu)下,利用ftrace對測試程序的路徑進(jìn)行追蹤時發(fā)現(xiàn),系統(tǒng)出現(xiàn)最大延遲時,有大量流程在deactivate_slab()函數(shù)處循環(huán),循環(huán)總時長達(dá)到200 μs。經(jīng)源碼分析,在申威內(nèi)核中,當(dāng)deactivate_slab()函數(shù)內(nèi)部檢測到對CPU的Slab緩存存在并發(fā)訪問時,就會不斷重新進(jìn)入該函數(shù),直至其他進(jìn)程的并發(fā)訪問結(jié)束,進(jìn)而導(dǎo)致deactivate_slab()函數(shù)處不斷循環(huán)。
為減少Slab緩存對系統(tǒng)延時的影響,本文采用工作隊列方法對其進(jìn)行優(yōu)化。在刷新CPU的Slab緩存時,通過工作隊列處理deactivate_slab()函數(shù)的工作。工作隊列是內(nèi)核提供的一種將工作暫時推后的機制,在需要暫緩執(zhí)行時,注冊相關(guān)任務(wù),之后由內(nèi)核線程在適當(dāng)時候代為執(zhí)行。如此一來,即便deactivate_slab()函數(shù)遭遇并發(fā)訪問Slab緩存的情況,也不會占用用戶進(jìn)程時間,進(jìn)而避免該函數(shù)循環(huán)執(zhí)行影響系統(tǒng)實時性。
通過ftrace抓取目標(biāo)進(jìn)程延遲,發(fā)現(xiàn)添加Slab緩存優(yōu)化補丁后的路徑?jīng)]有deactivate_slab()函數(shù)循環(huán)執(zhí)行的情況,測試進(jìn)程的延遲時間明顯縮短。
3.2 函數(shù)搶占優(yōu)化補丁
由于申威架構(gòu)部分代碼尚不支持可搶占內(nèi)核,所以在使能RT后,部分不可搶占函數(shù)可能會被強行搶占,進(jìn)而產(chǎn)生不可預(yù)測的影響。實驗表明,申威架構(gòu)獲取時間的代碼中用到了此類不可搶占函數(shù)。當(dāng)加入申威架構(gòu)內(nèi)核態(tài)可搶占補丁時,在申威內(nèi)核中獲取時間的過程可能被搶占,再次調(diào)度回來時可能已經(jīng)在其他CPU核心執(zhí)行,這會導(dǎo)致時間獲取不準(zhǔn)確,測得的系統(tǒng)延遲比實際值偏大。
通過在相關(guān)函數(shù)執(zhí)行前加入禁止搶占標(biāo)記,執(zhí)行后再開啟搶占的優(yōu)化補丁,從而保證了此類函數(shù)在執(zhí)行期間不會被搶占。經(jīng)實驗測試,添加函數(shù)搶占優(yōu)化補丁后的內(nèi)核延遲測試結(jié)果更加準(zhǔn)確穩(wěn)定。
4 申威內(nèi)核實時性測試與分析
4.1 測試環(huán)境
本文實驗的測試對象為申威831處理器的rootfs文件系統(tǒng)和申威831整機統(tǒng)信系統(tǒng)中的內(nèi)核,包括原生標(biāo)準(zhǔn)內(nèi)核和加入申威實時搶占補丁后的實時內(nèi)核。申威rootfs是定制的根文件系統(tǒng),包含了操作系統(tǒng)所需的基本文件和目錄結(jié)構(gòu)。申威831整機系統(tǒng)采用統(tǒng)信2.0(UOS 2.0),其內(nèi)核版本為4.19.180,RT_Preempt版本為4.19.292-rt282。測試工具RT_test 2.0和加壓工具stress-ng是通過源碼移植獲取的。
4.2 測試結(jié)果與分析
4.2.1 申威rootfs Cyclictest測試
Cyclictest[11]是RT_test中應(yīng)用最廣泛的Linux系統(tǒng)實時性測試工具,其本身是一個高精度的測試程序,可以測量系統(tǒng)的最小、平均以及最大延遲。Cyclictest可以在不同的CPU負(fù)載下進(jìn)行測試。為了驗證測試結(jié)果的可靠性和穩(wěn)定性,本文使用stress-ng產(chǎn)生系統(tǒng)負(fù)載。Cyclictest的測試命令為:./cyclictest -t 5-p 80;stress-ng的加壓命令為:./stress-ng --cpu 8 --vm 1 --vm-bytes 1G。申威架構(gòu)Linux標(biāo)準(zhǔn)內(nèi)核和實時內(nèi)核在rootfs文件系統(tǒng)中加壓/不加壓情況下的測試結(jié)果見表1。
表1中的測試結(jié)果是在使用stress-ng加壓的情況下得出的。其中,申威標(biāo)準(zhǔn)內(nèi)核通過Cyclictest測試兩千萬次,實時內(nèi)核測試兩億多次,延時單位為μs。由實驗結(jié)果可知,實時內(nèi)核的最大延時遠(yuǎn)小于標(biāo)準(zhǔn)內(nèi)核。這表明,本文所實現(xiàn)的申威架構(gòu)實時搶占補丁,能夠有效提升申威Linux內(nèi)核的實時性,也進(jìn)一步驗證了添加補丁后申威Linux內(nèi)核的穩(wěn)定性。
4.2.2 申威831整機Cyclictest測試
為了使實驗結(jié)果更加直觀,本文對申威831整機統(tǒng)信系統(tǒng)上的測試結(jié)果進(jìn)行統(tǒng)計分析,并繪制延時/次數(shù)波形圖如圖4所示,其中橫坐標(biāo)表示出現(xiàn)頻次,縱坐標(biāo)表示延遲時間。
圖4(a)所示為實時內(nèi)核加壓力波形圖,圖4(b)所示為實時內(nèi)核不加壓力波形圖,圖4(c)所示為標(biāo)準(zhǔn)內(nèi)核加壓力波形圖,圖4(d)所示為標(biāo)準(zhǔn)內(nèi)核不加壓力波形圖。對比圖4(a)與圖4(b)、圖4(c)與圖4(d)可以看出,在對系統(tǒng)施加壓力后,延時時間增加,密度區(qū)域上移,說明加壓有效;并且在實時內(nèi)核加壓前后,離散區(qū)相較標(biāo)準(zhǔn)內(nèi)核波動較小,說明實時內(nèi)核的穩(wěn)定性有明顯提升。對比圖4(a)與圖4(b)、圖4(c)與圖4(d)可以看出,添加申威架構(gòu)實時補丁后的Linux實時內(nèi)核,最大延時異常明顯減少,實時內(nèi)核加壓后延時穩(wěn)定在200 μs以內(nèi),而標(biāo)準(zhǔn)內(nèi)核最大延時達(dá)到1 600 μs,說明添加補丁后內(nèi)核的實時性明顯提升。測試結(jié)果進(jìn)一步驗證了本文所提出的申威架構(gòu)實時搶占補丁的有效性。
4.2.3 其他測試結(jié)果
為了讓測試結(jié)果更加可信,本文在申威831整機統(tǒng)信系統(tǒng)上使用RT-test的sigwaittest、signaltest、pmqtest和ptsematest工具對申威標(biāo)準(zhǔn)內(nèi)核和實時內(nèi)核進(jìn)行了測試,結(jié)果見表2。由測試結(jié)果可以看出,各種測試方法的最大延遲均有所減小,進(jìn)一步證明了本文所提出的申威架構(gòu)實時補丁的有效性。
5 結(jié) 語
本文實現(xiàn)了基于申威架構(gòu)的實時搶占補丁,通過內(nèi)核態(tài)可搶占、Lazy Preemption機制以及Slab緩存和不可搶占函數(shù)優(yōu)化補丁,有效提升了申威Linux內(nèi)核的實時性。結(jié)果表明,在較強壓力測試下,申威內(nèi)核仍能保持很好的實時性,從而證明了申威架構(gòu)可在Linux中實現(xiàn)硬實時特性,為申威平臺在實時場景中的應(yīng)用奠定堅實基礎(chǔ)。
參考文獻(xiàn)
[1] 黃江泉.面向航天應(yīng)用的高可靠系統(tǒng)軟件設(shè)計研究[D].北京:中國科學(xué)院研究生院,2012.
[2] 錢家樂.計算機操作系統(tǒng)的應(yīng)用與發(fā)展分析[J].無線互聯(lián)科技,2015(19):95-96.
[3] 劉濤.一種嵌入式實時Linux的設(shè)計與實現(xiàn)[D].成都:電子科技大學(xué),2007.
[4] 陳曾漢.基于Xenomai的實時測控系統(tǒng)的研究與實現(xiàn)[J]. 計算機應(yīng)用與軟件,2009,26(5):162-165.
[5] WU Z J, MC GUIRE N. Porting RT-preempt to Longson2F [C]//Eleventh Real-Time Linux Workshop. Dresden, Germany: [s.n.], 2009: 169.
[6] 梁紅兵,湯小丹.《計算機操作系統(tǒng)》學(xué)習(xí)指導(dǎo)與題解[M]. 西安:西安電子科技大學(xué)出版社,2008.
[7] 吳章金. Linux實時搶占補丁的研究與實踐[D].蘭州:蘭州大學(xué),2010.
[8] FAYYAD-KAZAN H, PERNEEL L, TIMMERMAN M. Linux preempt-rt v2.6.33 versus v3.6.6: better or worse for real-time applications? [J]. ACM sigbed review, 2014, 11(1): 26-31.
[9] 楊嘉,王移芝. Linux內(nèi)核調(diào)度器算法研究與性能分析[J].計算機技術(shù)與發(fā)展,2006,16(3):95-97.
[10] GARG A. Real-time Linux kernel scheduler[J]. Linux journal, 2009(184): 54-59.
[11] EBUGDEN. Cyclitest [EB/OL]. (2018-10-15). https://wiki.linuxfoundation.org/realtime/documentation/howto/tools/cyclictest/start.
收稿日期:2024-04-26 修回日期:2024-05-29