Linux内核进行进程切换的理解 内核版本4.15

文章详细阐述了进程切换的原因,包括时钟中断和系统调用。在多核CPU环境中,内核内存空间是共享的,CR3寄存器用于指向当前进程的页表。进程切换涉及三个进程,主要是由于__switch_to_asm函数的参数在不同内核栈中的存储。在切换过程中,内核栈、寄存器以及用户层的执行断点都会发生相应的变化。
摘要由CSDN通过智能技术生成

以前写博客都是为了自己能记住,这次写希望别人也能看的懂  写的自己都觉得晦涩了,请多指教

进程切换的原因

1 时钟节拍或者其他进程中断到达并且调度器选择了其他进程运行

2进程发出某些系统调用而操作系统暂时无法完成,如read阅读的页不在页缓存

在多核CPU中,内核内存空间是共享的,每个核心上的CR3寄存器是指向正在这个核上运行的进程的整个虚拟地址空间。 画个图吧

 首先说CR3寄存器,页表寄存器指向正在运行进程空间的页表,如果是内核进程就会借用上一个正在运行进程的内核空间(指的是task_struct中的mm和active_mm字段,不懂的要自己看这个内容)也不用进行CR3寄存器的转换(CR3寄存器转换源码目录 \linux-4.15.1\arch\x86\mm\tlb.c)。

为什么进程切换回涉及到三个进程?

看源码

 主要是这个宏定义,进入__switch_to_asm函数

在__switch_to_asm函数有三个参数分别是进程结构体prev next prev。上面我们放了重要的__switch_to_asm函数代码行,在__switch_to_asm函数中对prev进程(此时正在运行的进程)进行了内核栈切换。内核进程调用函数是内核的代码段,是被所有进程所共享且相同的。当prev进程在__switch_to_asm寒素中进行了内核栈切换后,又执行了函数返回return prev_p。仔细想想这个返回的prev_p是什么,首先prev_p是局部变量,执行内核代码局部变量存储在内核栈上,return prev_p就是把此时内核栈上的prev_p变量储存在rax中返回。但是重点来了,此时的内核栈已经从进程prev的内核栈经过内核函数update_sp0切换成了next进程的内核栈了,此时return返回取到的prev_p是进程next内核栈上的prev_p,和进程prev内核栈上的prev_p不是一个值。

再仔细想想,内核代码是共享的,__switch_to_asm函数的参数分别是prev_p和next_p这两个参数都是放在当前进程内核栈中的

这么理解进程A切换到B进程,运行到__switch_to_asm函数的return prev_p   此时A的内核栈中存放的是A和B进程      B进程内核栈中存放的是 B进程和 (曾经)把B进程切换出CPU的进程。这是目前A进程  和  B进程内核栈情况。

A是当前进程prev_p   B是下一个要运行的进程next_p    在调度函数中执行update_sp0后此时内核栈由A转换成B进程内核栈了,因此return  prev_p返回的是B进程内核栈中的prev_p 也就是(曾经)把B进程切换出CPU的进程(这个进程可能是 A C D等等)。

也就是说从switch_to宏(里面会调用__switch_to_asm函数)执行到下一条指令时就已经是进程B在运行了,此时内存已经转换完成,一些寄存器也已经转换完成,sp0也已经转换,此时用的内核栈也是B的内核栈(用户程序的执行断点也保存在内核栈用)。 当下一次切换到A进程运行时,内核层也是,切换到A进程内核栈时switch_to宏的下一条指令开始执行,用户层则是在回到用户层时pop内核栈恢复原来PC的值。

当从A进程切换到B进程时,当回到用户层时,B的内核栈出栈,恢复寄存器的值,也会恢复用户层的指令执行断点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值