linux操作系统分析实验五-深入理解进程切换

发布时间 2023-04-25 19:20:44作者: skadfj

Lab5:深入理解进程切换

首先找到对应进程调度的代码文件

Kernal/sched/core.c

 

 

找到 context_switch() 函数

 

 

 

其中包括rq,为进程的running queue;以及进程切换前后的进程描述符prev和next

 

 

首先调用一些函数做上下文切换的准备,与最后出现的finish_task_switch()成对使用

 

接着进行进程地址空间的切换

(1)     对于next->mm为空的情况,这是一个内核级线程(to kernal),此时linux使用active_mm指向其实际地址空间。此时首先调用entry_lazy_tlb进入lazy_tlb模式

 

 

接着将prev进程的active_mm赋给next进程,并在prev进程是用户进程的情况下调用mmgrab,增加prev的active_mm空间的引用计数,因为它现在同时被next进程所持有。

在prev是内核进程的情况下,将其active_mm指针置空即可

(2)     对于其他情况 ,即next为一个用户线程,调用membarrier_switch_mm创建内存屏障,保证进程访问mm的先后顺序

 

         接着调用switch_mm_irqs_off进行地址空间切换,这是一个很长的函数?

 

 

之后对从内核进程切换过来的情况设置rq的prev_mm为切换前线程的active_mm,并将该指针置空

 

最后会调用switch_to()

 

 

该函数主要进行寄存器和堆栈的切换,其中调用了prepare_switch_to进行准备工作,并调用_switch_to_asm()函数进行了从prev到next内核堆栈的真正切换,

 

在最后不使用ret指令,通过jmp指令跳转到_switch_to()函数,在_switch_to()函数中return。_switch_to_asm()中进行了堆栈的切换,

_switch_to()返回后,回到的是next进程而不是prev进程的内核堆栈。