





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