《linux 内核分析》 第八周 关于进城的调度

王一+《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-100002900

  1、进城调度的时机

中断处理过程(包括时钟中断、I/O中断、系统调用和异常)中,直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule();
内核线程可以直接调用schedule()进行进程切换,也可以在中断处理过程中进行调度,也就是说内核线程作为一类的特殊的进程可以主动调度,也可以被动调度;
用户态进程无法实现主动调度,仅能通过陷入内核态后的某个时机点进行调度,即在中断处理过程中进行调度。
2、进程的切换
进程上下文包含了进程执行需要的所有信息:
        
        用户地址空间:包括程序代码,数据,用户堆栈等
        控制信息:进程描述符,内核堆栈等
        硬件上下文(注意中断也要保存硬件上下文知识保存的方法不同)
       schedule()函数选择一个新的进程来运行,并调用context_switch进行上下文的切换,这个宏调用switch_to来进行关键上下文切换。
        next = pick_next_task(rq, prev);//按照调度算法寻找下一个进程
        context_switch(rq, prev, next);//进程上下文切换,和前几节课分析的进程切换几乎一样
        switch_to利用了prev和next两个参数:prev指向当前进程,next指向被调度的进程
3、schedule()
中断处理过程(包括时钟中断、I/O中断、系统调用和异常)中,直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule();内核线程可以直接调用schedule()。
进行进程切换,也可以在中断处理过程中进行调度,也就是说内核线程作为一类的特殊的进程可以主动调度,也可以被动调度;用户态进程无法实现主动调度,仅能通过陷入内核态后的某个时机点进行调度,即在中断处理过程中进行调度。
内核线程若通过通过中断处理过程中的调度时机,用户态进程与内核线程之间互相切换和内核线程之间互相切换,与最一般的情况非常类似,只是内核线程运行过程中发生中断没有进程用户态和内核态的转换;内核线程主动调用schedule(),
只有进程上下文的切换,没有发生中断上下文的切换,与最一般的情况略简略。
4、实验

设置断点调试:


5、总结
正在运行的用户态进程X切换到运行用户态进程Y的过程
    1. 正在运行的用户态进程X
    2. 发生中断——save cs:eip/esp/eflags(current) to kernel stack,then load cs:eip(entry of a specific ISR//中断服务例程的起点) and ss:esp(point to kernel stack).
    3. SAVE_ALL //保存现场
    4. 中断处理过程中或中断返回前调用了schedule(),其中的switch_to做了关键的进程上下文切换
    5. 标号1之后开始运行用户态进程Y(这里Y曾经通过以上步骤被切换出去过因此可以从标号1继续执行)
      restore_all //恢复现场
    6. iret - pop cs:eip/ss:esp/eflags from kernel stack
    7. 继续运行用户态进程Y

 




 

posted @ 2017-04-16 22:30  AAX  阅读(293)  评论(0)    收藏  举报