彻底理解Linux 进程调度所有知识点( 六 )

  1. 从红黑树中找到 se 所应该在的位置
  2. 以 se->vruntime 值为键值进行红黑树结点的比较
  3. 将新进程的节点加入到红黑树中
  4. 为新插入的结点进行着色
set_next_entityset_next_entity 会调用 __dequeue_entity 将下一个选择的进程从 CFS 队列的红黑树中删除 , 然后将 CFS 队列的 curr 指向进程的调度实体 。
进程上下文切换理解了下一个进程的选择后 , 就需要做当前进程和所选进程的上下文切换 。
Linux 内核用函数 context_switch 进行进程的上下文切换 , 进程上下文切换主要涉及到两部分:进程地址空间切换和处理器状态切换:
彻底理解Linux 进程调度所有知识点

文章插图
 
  • 进程的地址空间切换

彻底理解Linux 进程调度所有知识点

文章插图
 
将下一个进程的 pgd 虚拟地址转化为物理地址存放在 ttbr0_el1 中(这是用户空间的页表基址寄存器) , 当访问用户空间地址的时候 mmu 会通过这个寄存器来做遍历页表获得物理地址 。完成了这一步 , 也就完成了进程的地址空间切换 , 确切的说是进程的虚拟地址空间切换 。
  • 寄存器状态切换

彻底理解Linux 进程调度所有知识点

文章插图
 
其中 x19-x28 是 arm64 架构规定需要调用保存的寄存器 , 可以看到处理器状态切换的时候将前一个进程(prev)的 x19-x28 , fp,sp,pc 保存到了进程描述符的 cpu_contex 中 , 然后将即将执行的进程 (next) 描述符的 cpu_contex 的 x19-x28 , fp,sp,pc 恢复到相应寄存器中 , 而且将 next 进程的进程描述符 task_struct 地址存放在 sp_el0 中 , 用于通过 current 找到当前进程 , 这样就完成了处理器的状态切换 。

【彻底理解Linux 进程调度所有知识点】


推荐阅读