• 理解进程调度时机跟踪分析进程调度与进程切换的过程


    理解进程调度时机跟踪分析进程调度与进程切换的过程

    20135224陈实 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ”

    第一部分---调度时机

    发生方式:

    1 中断处理过程(时钟中断、I/O中断、系统调用和异常)中或返回用户态根据need_resched标记调用

    2 内核线程直接调用进行进程切换,也可以在中断处理过程中进行调度,内核线程可以主动调度,也可以被动调度

    3 用户态进程无法实现主动调度,仅能通过陷入内核态后的某个时机点进行调度,在中断处理过程中调度

    调度中介:schedule()函数

    1 schedule()函数开始,禁用内核抢占并初始化一些局部变量,此时,schedule()检查运行队列中剩余的可运行进程数,如果有可调用进程,开始调用。

    schedule()函数中在switch_to宏之后紧接着的指令并不由next进程立即执行,而是稍后当调度程序选择prev又执行时由prev执行。 prev局部变量并不指向开始描述schedule()时所替换出去的原来的那个进程,而是指向prev被调度时由prev替换出的原来那个进程。

    3 紧接着context_switch()函数调用之后,宏barrier()产生一个代码优化屏障。执行finish_task_switch()函数。

    4 schedule()函数最后执行的是:重新获得大内核锁,重新启动内核抢占,并检查是否其他进程设置了当前进程的TIF_RESCHED标志,如果是,整个schedule()函数重新开始执行

    swtich_to关键代码

    "movl $1f,%[prev_ip] "保存当前进程的eip,恢复的时候从prev_ip来恢复eip

    "pushl %[next_ip] "把下个进程的起点ip位置压到next进程堆栈栈顶(起点)

    "jmp __switch_to " jmp通过prevnext寄存器的方式传递参数

    "popl %%ebp "恢复上下文,next曾经pushebp

    context_switch(struct rq *rq,struct task_struct *prev context_switch()上下文切换;建立next的地址空间。

    struct task_struct *next)

    {

    struct mm_struct *mm, *oldmm;

    prepare_task_switch(rq, prev, next);

    mm= next -> mm; mm字段指向进程所拥有的内存描述符。

    oldmm = prev -> active_mm; active_mm字段指向进程所使用的内存描述符。

    arch_start_context_switch(prev);

    if (!mm) {

    next->active_mm = oldmm; 如果next是内核线程,则线程使用prev所使用的地址空间;

    atomic_inc(&oldmm->mm_count); schedule()函数把该线程设置为懒惰TLB模式。

    enter_lazy_tlb(oldmm,next);

    }else

    switch_mm(oldmm,mm,next); 如果next是普通进程,schedule()函数用next替换prev的地址空间

    if (!prev->mm) {

    prev->active_mm = NULL; 如果prev是内核线程或正退出的进程,context_switch()函数就把

    rq->prev_mm = oldmm; 指向prev内存描述的支撑保存到运行队列的prev_mm字段中;

    } 并且重新设置prev->active_mm。

    spin_release(&rq->lock,dep_map,1,_THIS_IP_);

    context_tracking_task_switch(prev,next); context_switch()可以调用switch_to执行prev和next之间的进程切换

    finish_task_switch(this_rq(),prev);

    }

    第二部分:GDB跟踪

    设置断点——分别schedule,context_switch,switch_to对应断点进行查看

    对每个断点的里的switch函数进行单步分析,查看代码

    总结:

    对于理解进程调度时机跟踪分析进程调度与进程切换的过程,一般可以归纳为以下几点:

    1 用户需求的进程执行态

    2 故意或者系统中断

    3 SAVE_ALL 

    4 调用schedule()

    5 执行到switch_to进程上下文切换

    6 另一个进程进入并进行

    7 restore_all 

    8  iret - pop cs:eip/ss:esp/eflag from kernel stack

    9 继续运行用户态进程

     
  • 相关阅读:
    html中frameset的详细使用方法
    日期控件API
    限制input输入类型(多种方法实现)
    springmvc导出excel并弹出下载框
    Spring mvc 验证码的做法
    Spring Boot 集成MyBatis
    Spring Boot 实践折腾记(三):三板斧,Spring Boot下使用Mybatis
    支付系统架构
    javaScript事件(六)事件类型之滚轮事件
    你不是真正的快乐
  • 原文地址:https://www.cnblogs.com/chuishi/p/5400943.html
Copyright © 2020-2023  润新知