本文主要分析 Linux 5.4.34 版本內(nèi)核中進程切換的基本操作與基本代碼框架。
一、進程切換的工作機制
在實際的代碼中,每個進程切換基本都由兩個步驟組成,即切換頁全局目錄以安裝一個新的地址空間以及切換內(nèi)核態(tài)堆棧和進程cpu上下文。
具體的代碼走向如下:schedule()函數(shù)選擇一個新的進程來運行,并調(diào)用context_switch進行上下文的切換。context_switch首先調(diào)用switch_mm切換CR3,然后調(diào)用宏switch_to來進行CPU上下文切換。
content_switch 函數(shù)位于 Linux 內(nèi)核源碼目錄的 kernel/sched/core.c 中,代碼如下:
content_switch 函數(shù)有三個參數(shù):rq、prev、next,其中 rq 指向本次進程切換發(fā)生的 進程就緒隊列;prev 和 next 分別指向切換前后進程的進程描述符。下面我們來分析一下具體的執(zhí)行過程。
看代碼可知,首先執(zhí)行的是prepare_task_switch函數(shù),該函數(shù)需要在進程切換之前調(diào)用,內(nèi)核會執(zhí)行與體系結(jié)構(gòu)相關(guān)的一些調(diào)測指令。上下文切換完成后,必須調(diào)用 finish_task_switch,即這兩個函數(shù)一定是要成對出現(xiàn)的。
然后是arch_start_context_switch()函數(shù),該函數(shù)給各個體系結(jié)構(gòu)專有的開始上下文切換的工作提供了入口,在不同的體系結(jié)構(gòu)中其實現(xiàn)是不同的。
在本函數(shù)的主體部分(上述if-else部分)實現(xiàn)了進程地址空間切換過程,這里prev是進程切換之前的進程,next是進程切換后要執(zhí)行的進程,mm是進程的地址空間描述符。
-
這里首先判斷next進程mm是否為空,如果為空的話,說明是內(nèi)核級線程(否則就是用戶進程),如果是內(nèi)核級線程的話需要調(diào)用enter_lazy_tlb,標(biāo)記cpu內(nèi)核進入了lazy tlb mode(這里查閱了資料應(yīng)該是為了減少切換上下文時不必要的TLB更新,CPU進入該模式后不對TLB進行更新)。然后地址空間不用更改,如果之前的是用戶進程,則引用計數(shù)增加1個,如果之前的進程是內(nèi)核級線程,則需要把原來的進程的active_mm清空,結(jié)束對mm_struct的借用。
-
如果next->mm不為空,即要切換到的進程為用戶進程。首先調(diào)用membarrier_switch_mm函數(shù)來建立了一個內(nèi)存屏障,來保證上一個進程訪問其內(nèi)存空間與下一個進程訪問內(nèi)存空間之前的一個先后順序(其實就是一個進程同步),避免在訪存時出現(xiàn)訪存錯誤;然后是執(zhí)行switch_mm_irqs_off函數(shù),即真正切換 mm_struct;最后如果切換前的進程是內(nèi)核進程,則需要設(shè)置一些東西來用于后續(xù)清除引用計數(shù)。
最后面就是switch_to函數(shù),即切換寄存器狀態(tài)和棧,switch_to會進一步調(diào)用__switch_to_asm,而 __switch_to_asm 的實現(xiàn)是和體系結(jié)構(gòu)強相關(guān)的。
二、sp和ip在不同體系及結(jié)構(gòu)下匯編代碼的切換方法
__switch_to_asm是在C代碼中調(diào)用的,也就是使用call指令,而這段匯編的結(jié)尾是jmp __switch_to,__switch_to函數(shù)是C代碼最后有個return,也就是ret指令。 將__switch_to_asm和__switch_to結(jié)合起來,正好是call指令和ret指令的配對出現(xiàn)。 call指令壓棧RIP寄存器到進程切換前的prev進程內(nèi)核堆棧;而ret指令出棧存入RIP寄存器的是進程切換之后的next進程的內(nèi)核堆棧棧頂數(shù)據(jù).
然后下面是arm64下的代碼
文章來源:http://www.zghlxwxcb.cn/news/detail-454045.html
arm64 也沒有顯式保存和恢復(fù)程序計數(shù)器 PC 的值,這和 x86_64 的處理方法是大同小異的,也是通過函數(shù)調(diào)用堆棧的特性來巧妙解決這一問題。文章來源地址http://www.zghlxwxcb.cn/news/detail-454045.html
到了這里,關(guān)于lab5:深入理解進程切換的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!