www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 嵌入式 > Linux閱碼場
[導(dǎo)讀]4.進(jìn)程上下文切換接前文:深入理解Linux內(nèi)核之主調(diào)度器(上)前面選擇了一個(gè)合適進(jìn)程作為下一個(gè)進(jìn)程,接下來做重要的上下文切換動(dòng)作,來保存上一個(gè)進(jìn)程的“上下文”恢復(fù)下一個(gè)進(jìn)程的“上下文”,主要包括進(jìn)程地址空間切換和處理器狀態(tài)切換。注:這里的上下文實(shí)際上是指進(jìn)程運(yùn)行時(shí)最小寄存器的集...

4.進(jìn)程上下文切換

接前文:深入理解Linux內(nèi)核之主調(diào)度器(上)


前面選擇了一個(gè)合適進(jìn)程作為下一個(gè)進(jìn)程,接下來做重要的上下文切換動(dòng)作,來保存上一個(gè)進(jìn)程的“上下文”恢復(fù)下一個(gè)進(jìn)程的“上下文”,主要包括進(jìn)程地址空間切換和處理器狀態(tài)切換。

注:這里的上下文實(shí)際上是指進(jìn)程運(yùn)行時(shí)最小寄存器的集合。

如果切換的next進(jìn)程不是同一個(gè)進(jìn)程,才進(jìn)行切換:

__schedule
?i??f?(likely(prev?!=?next))?{??????
????????...
????????context_switch??//進(jìn)程上下文切換
????}

4.1 進(jìn)程地址空間切換

進(jìn)程地址空間切換就是切換虛擬地址空間,使得切換之后,當(dāng)前進(jìn)程訪問的是屬于自己的虛擬地址空間(包括用戶地址空間和內(nèi)核地址空間),本質(zhì)上是切換頁表基地址寄存器

進(jìn)程地址空間切換讓進(jìn)程產(chǎn)生獨(dú)占系統(tǒng)內(nèi)存的錯(cuò)覺,因?yàn)榍袚Q完地址空間后,當(dāng)前進(jìn)程可以訪問屬于它的海量的虛擬地址空間(內(nèi)核地址空間各個(gè)進(jìn)程共享,用戶地址空間各個(gè)進(jìn)程私有),而實(shí)際上物理地址空間只有一份。

下面給出源代碼分析:

context_switch
->
?/*
?|*?kernel?->?kernel???lazy? ?transfer?active
?|*???user?->?kernel???lazy? ?mmgrab()?active
?|*
?|*?kernel?->???user???switch? ?mmdrop()?active
?|*???user?->???user???switch
?|*/
?if?(!next->mm)?{????????????????????????????????//?to?kernel
?????????enter_lazy_tlb(prev->active_mm,?next);

?????????next->active_mm?=?prev->active_mm;
?????????if?(prev->mm)???????????????????????????//?from?user
?????????????????mmgrab(prev->active_mm);
?????????else
?????????????????prev->active_mm?=?NULL;
?}?else?{????????????????????????????????????????//?to?user
????????...
?????????switch_mm_irqs_off(prev->active_mm,?next->mm,?next);

?????????if?(!prev->mm)?{????????????????????????//?from?kernel
?????????????????/*?will?mmdrop()?in?finish_task_switch().?*/
?????????????????rq->prev_mm?=?prev->active_mm;
?????????????????prev->active_mm?=?NULL;
?????????}????????????
?}????????????????????
?????????????????????

以上代碼是判斷是否next進(jìn)程是內(nèi)核線程,如果是則不需要進(jìn)行地址空間切換(實(shí)際上指的是用戶地址空間),因?yàn)閮?nèi)核線程總是運(yùn)行在內(nèi)核態(tài)訪問的是內(nèi)核地址空間,而內(nèi)核地址空間是所有的進(jìn)程共享的。在arm64架構(gòu)中,內(nèi)核地址空間是通過ttbr1_el1來訪問,而它的主內(nèi)核頁表在內(nèi)核初始化的時(shí)候已經(jīng)填充好了,也就是我們常說的swapper_pg_dir頁表,后面所有對(duì)內(nèi)核地址空間的訪問,無論是內(nèi)核線程也好還是用戶任務(wù),統(tǒng)統(tǒng)通過swapper_pg_dir頁表來訪問,而在內(nèi)核初始化期間swapper_pg_dir頁表地址已經(jīng)加載到ttbr1_el1中。

需要說明一點(diǎn)的是:這里會(huì)做“借用” prev->active_mm的處理,借用的目的是為了避免切換屬于同一個(gè)進(jìn)程的地址空間。舉例說明:Ua ?-> ?Ka ?-> ?Ua ??,Ua表示用戶進(jìn)程, ?Ka表示內(nèi)核線程,當(dāng)進(jìn)行這樣的切換的時(shí)候,Ka 借用Ua地址空間,Ua ?-> ?Ka不需要做地址空間切換,而Ka ?-> ?Ua按理來說需要做地址空間切換,但是由于切換的還是Ua 地址空間,所以也不需要真正的切換(判斷了Ka->active_mm == Ua->active_mm ),當(dāng)然還包括切換的是同一個(gè)進(jìn)程的多個(gè)線程的情況,這留給大家思考。

下面來看下真正的地址空間切換:

?switch_mm_irqs_off(prev->active_mm,?next->mm,?next);
?->switch_mm??//arch/arm64/include/asm/mmu_context.h
????->?if?(prev?!=?next)?
?????????__switch_mm(next);
???????????->check_and_switch_context(next)
????????????????->?...??//asid處理
???????????????->?cpu_switch_mm(mm->pgd,?mm)
???????????????????->cpu_do_switch_mm(virt_to_phys(pgd),mm)
?????????????????????????->?unsigned?long?ttbr1?=?read_sysreg(ttbr1_el1);??
?????????????????????????????unsigned?long?asid?=?ASID(mm);?????????????????
?????????????????????????????unsigned?long?ttbr0?=?phys_to_ttbr(pgd_phys);??
?????????????????????????????...
?????????????????????????????write_sysreg(ttbr1,?ttbr1_el1);???//設(shè)置asid到ttbr1_el1
?????????????????????????????isb();????????????????????????????
?????????????????????????????write_sysreg(ttbr0,?ttbr0_el1);???//設(shè)置mm->pgd?到ttbr0_el1

上面代碼是做真正的地址空間切換,實(shí)際的切換很簡單,并沒有那么復(fù)雜和玄乎,僅僅設(shè)置頁表基地址寄存器即可,當(dāng)然這里還涉及到了為了防止頻繁無效tlb的ASID的設(shè)置。

主要做的工作就是設(shè)置next進(jìn)程的ASID到ttbr1_el1, 設(shè)置mm->pgd 到ttbr0_el1,僅此而已!

需要注意的是:1.寫到ttbr0_el1的值是進(jìn)程pgd頁表的物理地址。2.雖然做了這樣的切換,但是這個(gè)時(shí)候并不能訪問到next的用戶地址空間,因?yàn)檫€處在主調(diào)度器上下文中,屬于內(nèi)核態(tài),訪問的是內(nèi)核空間。

而一旦返回了用戶態(tài),next進(jìn)程就能正常訪問自己地址空間內(nèi)容:

  • 訪問一個(gè)用戶空間的虛擬地址va,首先通過va和記錄在ttbr1_el1的asid查詢tlb,如果找到相應(yīng)表項(xiàng)則獲得pa進(jìn)行訪問。

  • 如果tlb中沒有找到,通過ttbr0_el1來遍歷自己的多級(jí)頁表,找到相應(yīng)表項(xiàng)則獲得pa進(jìn)行訪問。

  • 如果發(fā)生中斷異常等訪問內(nèi)核地址空間,直接通過ttbr1_el1即可完成訪問。

  • 訪問沒有建立頁表映射的合法va,發(fā)生缺頁異常來建立映射關(guān)系,填寫屬于進(jìn)程自己的各級(jí)頁表,然后訪問。

  • 訪問無法地址,發(fā)生缺頁殺死進(jìn)程等等。

4.2 處理器狀態(tài)切換

來切換下一個(gè)進(jìn)程的執(zhí)行流,上一個(gè)進(jìn)程執(zhí)行狀態(tài)保存,讓下一個(gè)進(jìn)程恢復(fù)執(zhí)行狀態(tài)。

處理器狀態(tài)切換而后者讓進(jìn)程產(chǎn)生獨(dú)占系統(tǒng)cpu的錯(cuò)覺,使得系統(tǒng)中各個(gè)任務(wù)能夠并發(fā)(多個(gè)任務(wù)在多個(gè)cpu上運(yùn)行)或分時(shí)復(fù)用(多個(gè)任務(wù)在一個(gè)cpu上運(yùn)行)cpu資源。

下面給出代碼:

context_switch
->(last)?=?__switch_to((prev),?(next))
????->?fpsimd_thread_switch(next)?//浮點(diǎn)寄存器切換
????????...
????????last?=?cpu_switch_to(prev,?next);?

處理器狀態(tài)切換會(huì)做浮點(diǎn)寄存器等切換,最終調(diào)用cpu_switch_to做真正切換。

cpu_switch_to??//arch/arm64/kernel/entry.S
SYM_FUNC_START(cpu_switch_to)
????????mov?????x10,?#THREAD_CPU_CONTEXT
????????add?????x8,?x0,?x10
????????mov?????x9,?sp
????????stp?????x19,?x20,?[x8],?#16?????????????//?store?callee-saved?registers
????????stp?????x21,?x22,?[x8],?#16
????????stp?????x23,?x24,?[x8],?#16
????????stp?????x25,?x26,?[x8],?#16
????????stp?????x27,?x28,?[x8],?#16
????????stp?????x29,?x9,?[x8],?#16
????????str?????lr,?[x8]
????????add?????x8,?x1,?x10
????????ldp?????x19,?x20,?[x8],?#16?????????????//?restore?callee-saved?registers
????????ldp?????x21,?x22,?[x8],?#16
????????ldp?????x23,?x24,?[x8],?#16
????????ldp?????x25,?x26,?[x8],?#16
????????ldp?????x27,?x28,?[x8],?#16
????????ldp?????x29,?x9,?[x8],?#16
????????ldr?????lr,?[x8]
????????mov?????sp,?x9
????????msr?????sp_el0,?x1
????????ptrauth_keys_install_kernel?x1,?x8,?x9,?x10
????????scs_save?x0,?x8
????????scs_load?x1,?x8
????????ret
SYM_FUNC_END(cpu_switch_to)
這里傳遞過來的是x0為prev進(jìn)程的進(jìn)程描述符(struct task_struct)地址, x1為next的進(jìn)程描述符地址。會(huì)就將prev進(jìn)程的 x19-x28,fp,sp,lr保存到prev進(jìn)程的tsk.thread.cpu_context中,next進(jìn)程的這些寄存器值從next進(jìn)程的tsk.thread.cpu_context中恢復(fù)到相應(yīng)寄存器。這里還做了sp_el0設(shè)置為next進(jìn)程描述符的操作,為了通過current宏找到當(dāng)前的任務(wù)。

需要注意的是:

  1. mov ? ? sp, x9 ?做了切換進(jìn)程內(nèi)核棧的操作。
  2. ldr ? ? lr, [x8] 設(shè)置了鏈接寄存器,然后ret的時(shí)候會(huì)將lr恢復(fù)到pc從而真正完成了執(zhí)行流的切換。

4.3 精美圖示

這里給出了進(jìn)程切換的圖示(以arm64處理器為例),這里從prev進(jìn)程切換到next進(jìn)程。


5.進(jìn)程再次被調(diào)度

當(dāng)進(jìn)程重新被調(diào)度的時(shí)候,從原來的調(diào)度現(xiàn)場恢復(fù)執(zhí)行。

5.1 關(guān)于lr地址的設(shè)置

1)如果切換的next進(jìn)程是剛fork的進(jìn)程,它并沒有真正的這些調(diào)度上下文的存在,那么lr是什么呢?這是在fork的時(shí)候設(shè)置的:

do_fork
????...
????copy_thread?//arch/arm64/kernel/process.c
????->memset(
本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢抑制與過流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問題卻十分常見,不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車場照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對(duì)周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉