1.进程切换的大致过程
当进程在运行过程中遇到中断或触发系统调用,首先会进行中断上下文的切换,之后进行ISR中断服务,之后调用_schedule()函数进行进程的切换,schedule()将当前进程的标识符记为prev进程。然后再通过调度算法确定下一个要被换上的进程,记为next进程。之后,检查next如果和prev进程不一样,调用context_switch()函数进行上下文切换,next进程进入CPU运行。
在context_switch()中调用switch_to()进行寄存器和堆栈的切换,switch_to()会调用switch_to_asm()函数,在switch_to_asm()的中进行了从prev内核堆栈到next内核堆栈的切换,在最后不使用ret指令,而是通过jmp指令跳转到switch_to()函数,在switch_to()函数的结尾调用return返回,因为在switch_to_asm()中进行了堆栈的切换,因此_switch_to()返回后,回到的是next进程的内核堆栈,而不是prev进程的内核堆栈。
2.进程切换各函数分析
schedule()函数调用context_switch()函数进行上下文切换,在kernel/sched/core.c中查看函数的定义:
static __always_inline struct rq *
context_switch(struct rq *rq, struct task_struct *prev,
struct task_struct *next, struct rq_flags *rf)
{
prepare_task_switch(rq, prev, next);
/*
* For paravirt, this is coupled with an exit in swi