您的位置 首页 golang

Linux进程上下文切换过程context_switch详解

1 前言

1.1 Linux的调度器组成

2个调度器

可以用两种方法来激活调度

  • 一种是直接的, 比如进程打算睡眠或出于其他原因放弃CPU
  • 另一种是通过周期性的机制, 以固定的频率运行, 不时的检测是否有必要

因此当前linux的调度程序由两个调度器组成:主调度器,周期性调度器(两者又统称为通用调度器(generic scheduler)或核心调度器(core scheduler))

并且每个调度器包括两个内容:调度框架(其实质就是两个函数框架)及调度器类

6种调度策略

linux内核目前实现了6中调度策略(即调度算法), 用于对不同类型的进程进行调度, 或者支持某些特殊的功能

  • SCHED_NORMAL和SCHED_BATCH调度普通的非实时进程
  • SCHED_FIFO和SCHED_RR和SCHED_DEADLINE则采用不同的调度策略调度实时进程
  • SCHED_IDLE则在系统空闲时调用idle进程.

5个调度器类

而依据其调度策略的不同实现了5个调度器类, 一个调度器类可以用一种种或者多种调度策略调度某一类进程, 也可以用于特殊情况或者调度特殊功能的进程.

其所属进程的优先级顺序为

 stop_sched_class -> dl_sched_class -> rt_sched_class -> fair_sched_class -> idle_sched_class  

3个调度实体

调度器不限于调度进程, 还可以调度更大的实体, 比如实现组调度.

这种一般性要求调度器不直接操作进程, 而是处理可调度实体, 因此需要一个通用的数据结构描述这个调度实体,即seched_entity结构, 其实际上就代表了一个调度对象,可以为一个进程,也可以为一个进程组.

linux中针对当前可调度的实时和非实时进程, 定义了类型为seched_entity的3个调度实体

  • sched_dl_entity 采用EDF算法调度的实时调度实体
  • sched_rt_entity 采用Roound-Robin或者FIFO算法调度的实时调度实体
  • sched_entity 采用CFS算法调度的普通非实时进程的调度实体

1.2 调度工作

周期性调度器通过调用各个调度器类的task_tick函数完成周期性调度工作

  • 如果当前进程是完全公平队列中的进程, 则首先根据当前就绪队列中的进程数算出一个延迟时间间隔,大概每个进程分配2ms时间,然后按照该进程在队列中的总权重中占得比例,算出它该执行的时间X,如果该进程执行物理时间超过了X,则激发延迟调度;如果没有超过X,但是红黑树就绪队列中下一个进程优先级更高,即curr->vruntime-leftmost->vruntime > X,也将延迟调度
  • 如果当前进程是实时调度类中的进程:则如果该进程是SCHED_RR,则递减时间片[为HZ/10],到期,插入到队列尾部,并激发延迟调度,如果是SCHED_FIFO,则什么也不做,直到该进程执行完成

延迟调度**的真正调度过程在:schedule中实现,会按照调度类顺序和优先级挑选出一个最高优先级的进程执行

而对于主调度器则直接关闭内核抢占后, 通过调用schedule来完成进程的调度

可见不管是周期性调度器还是主调度器, 内核中的许多地方, 如果要将CPU分配给与当前活动进程不同的另外一个进程(即抢占),都会直接或者调用调度函数, 包括schedule或者其子函数__schedule, 其中schedule在关闭内核抢占后调用__schedule完成了抢占.

而__schedule则执行了如下操作

__schedule如何完成内核抢占

1、完成一些必要的检查, 并设置进程状态, 处理进程所在的就绪队列

2、调度全局的pick_next_task选择抢占的进程

  • 如果当前cpu上所有的进程都是cfs调度的普通非实时进程, 则直接用cfs调度, 如果无程序可调度则调度idle进程
  • 否则从优先级最高的调度器类sched_class_highest(目前是stop_sched_class)开始依次遍历所有调度器类的pick_next_task函数, 选择最优的那个进程执行

3、context_switch完成进程上下文切换

即进程的抢占或者切换工作是由context_switch完成的

那么我们今天就详细讲解一下context_switch完成进程上下文切换的原理

2 进程上下文

2.1 进程上下文的概念

操作系统管理很多进程的执行. 有些进程是来自各种程序、系统和应用程序的单独进程,而某些进程来自被分解为很多进程的应用或程序。当一个进程从内核中移出,另一个进程成为活动的, 这些进程之间便发生了上下文切换. 操作系统必须记录重启进程和启动新进程使之活动所需要的所有信息. 这些信息被称作上下文, 它描述了进程的现有状态, 进程上下文是可执行程序代码是进程的重要组成部分, 实际上是进程执行活动全过程的静态描述, 可以看作是用户进程传递给内核的这些参数以及内核要保存的那一整套的变量和寄存器值和当时的环境等

进程的上下文信息包括, 指向可执行文件的指针, 栈, 内存(数据段和堆), 进程状态, 优先级, 程序I/O的状态, 授予权限, 调度信息, 审计信息, 有关资源的信息(文件描述符和读/写指针), 关事件和信号的信息, 寄存器组(栈指针, 指令计数器)等等, 诸如此类.

处理器总处于以下三种状态之一

1. 内核态,运行于进程上下文,内核代表进程运行于内核空间;

2. 内核态,运行于中断上下文,内核代表硬件运行于内核空间;

3. 用户态,运行于用户空间。

用户空间的应用程序,通过系统调用,进入内核空间。这个时候用户空间的进程要传递 很多变量、参数的值给内核,内核态运行的时候也要保存用户进程的一些寄存器值、变量等。所谓的”进程上下文”

硬件通过触发信号,导致内核调用中断处理程序,进入内核空间。这个过程中,硬件的 一些变量和参数也要传递给内核,内核通过这些参数进行中断处理。所谓的”中断上下文”,其实也可以看作就是硬件传递过来的这些参数和内核需要保存的一些其他环境(主要是当前被打断执行的进程环境)。

2.2 上下文切换

进程被抢占CPU时候, 操作系统保存其上下文信息, 同时将新的活动进程的上下文信息加载进来, 这个过程其实就是上下文切换, 而当一个被抢占的进程再次成为活动的, 它可以恢复自己的上下文继续从被抢占的位置开始执行.

上下文切换(有时也称做进程切换或任务切换)是指CPU从一个进程或线程切换到另一个进程或线程

稍微详细描述一下,上下文切换可以认为是内核(操作系统的核心)在 CPU 上对于进程(包括线程)进行以下的活动:

  1. 挂起一个进程,将这个进程在 CPU 中的状态(上下文)存储于内存中的某处,
  2. 在内存中检索下一个进程的上下文并将其在 CPU 的寄存器中恢复
  3. 跳转到程序计数器所指向的位置(即跳转到进程被中断时的代码行),以恢复该进程

因此上下文是指某一时间点CPU寄存器和程序计数器的内容, 广义上还包括内存中进程的虚拟地址映射信息.

上下文切换只能发生在内核态中, 上下文切换通常是计算密集型的。也就是说,它需要相当可观的处理器时间,在每秒几十上百次的切换中,每次切换都需要纳秒量级的时间。所以,上下文切换对系统来说意味着消耗大量的 CPU 时间,事实上,可能是操作系统中时间消耗最大的操作。

Linux相比与其他操作系统(包括其他类 Unix 系统)有很多的优点,其中有一项就是,其上下文切换和模式切换的时间消耗非常少.

相关视频推荐

学习地址:

需要更多C/C++ Linux服务器架构师学习资料加群812855908(资料包括C/C++,Linux,golang技术,内核,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg,大厂面试题 等)

3 context_switch进程上下文切换

linux中进程调度时, 内核在选择新进程之后进行抢占时, 通过context_switch完成进程上下文切换.

注意 进程调度与抢占的区别

进程调度不一定发生抢占, 但是抢占时却一定发生了调度

在进程发生调度时, 只有当前内核发生当前进程因为主动或者被动需要放弃CPU时, 内核才会选择一个与当前活动进程不同的进程来抢占CPU

context_switch其实是一个分配器, 他会调用所需的特定体系结构的方法

  • 调用switch_mm(), 把虚拟内存从一个进程映射切换到新进程中(switch_mm更换通过task_struct->mm描述的内存管理上下文, 该工作的细节取决于处理 器, 主要包括加载页表, 刷出地址转换后备缓冲器(部分或者全部), 向内存管理单元(MMU) 提供新的信息)
  • 调用switch_to(),从上一个进程的处理器状态切换到新进程的处理器状态。这包括保存、恢复栈信息和寄存器信息(switch_to切换处理器寄存器的呢内容和内核栈(虚拟地址空间的用户部分已经通过switch_mm变更, 其中也包括了用户状态下的栈, 因此switch_to不需要变更用户栈, 只需变更内核栈), 此段代码严重依赖于体系结构, 且代码通常都是用汇编语言编写.)

context_switch函数建立next进程的地址空间。进程描述符的active_mm字段指向进程所使用的内存描述符,而mm字段指向进程所拥有的内存描述符。对于一般的进程,这两个字段有相同的地址,但是,内核线程没有它自己的地址空间而且它的 mm字段总是被设置为 NULL

context_switch( )函数保证:如果next是一个内核线程, 它使用prev所使用的地址空间

由于不同架构下地址映射的机制有所区别, 而寄存器等信息弊病也是依赖于架构的, 因此switch_mm和switch_to两个函数均是体系结构相关的

3.1 context_switch完全注释

context_switch定义在kernel/sched/core.c#L2711, 如下所示

 /*
 * context_switch - switch to the new MM and the new thread's register state.
 */static __always_inline struct rq *
context_switch(struct rq *rq, struct task_struct *prev,
           struct task_struct *next)
{
    struct mm_struct *mm, *oldmm;
    /*  完成进程切换的准备工作  */    prepare_task_switch(rq, prev, next);
    mm = next->mm;
    oldmm = prev->active_mm;
    /*
     * For paravirt, this is coupled with an exit in switch_to to
     * combine the page table reload and the switch backend into
     * one hypercall.
     */    arch_start_context_switch(prev);
    /*  如果next是内核线程,则线程使用prev所使用的地址空间
     *  schedule( )函数把该线程设置为懒惰TLB模式
     *  内核线程并不拥有自己的页表集(task_struct->mm = NULL)
     *  它使用一个普通进程的页表集
     *  不过,没有必要使一个用户态线性地址对应的TLB表项无效
     *  因为内核线程不访问用户态地址空间。
    */    if (!mm)        /*  内核线程无虚拟地址空间, mm = NULL*/    {
        /*  内核线程的active_mm为上一个进程的mm
         *  注意此时如果prev也是内核线程,
         *  则oldmm为NULL, 即next->active_mm也为NULL  */        next->active_mm = oldmm;
        /*  增加mm的引用计数  */        atomic_inc(&oldmm->mm_count);
        /*  通知底层体系结构不需要切换虚拟地址空间的用户部分
         *  这种加速上下文切换的技术称为惰性TBL  */        enter_lazy_tlb(oldmm, next);
    }
    else            /*  不是内核线程, 则需要切切换虚拟地址空间  */        switch_mm(oldmm, mm, next);
    /*  如果prev是内核线程或正在退出的进程
     *  就重新设置prev->active_mm
     *  然后把指向prev内存描述符的指针保存到运行队列的prev_mm字段中
     */    if (!prev->mm)
    {
        /*  将prev的active_mm赋值和为空  */        prev->active_mm = NULL;
        /*  更新运行队列的prev_mm成员  */        rq->prev_mm = oldmm;
    }
    /*
     * Since the runqueue lock will be released by the next
     * task (which is an invalid locking op but in the case
     * of the scheduler it's an obvious special-case), so we
     * do an early lockdep release here:
     */    lockdep_unpin_lock(&rq->lock);
    spin_release(&rq->lock.dep_map, 1, _THIS_IP_);
    /* Here we just switch the register state and the stack. 
     * 切换进程的执行环境, 包括堆栈和寄存器
     * 同时返回上一个执行的程序
     * 相当于prev = witch_to(prev, next)  */    switch_to(prev, next, prev);
    /*  switch_to之后的代码只有在
     *  当前进程再次被选择运行(恢复执行)时才会运行
     *  而此时当前进程恢复执行时的上一个进程可能跟参数传入时的prev不同
     *  甚至可能是系统中任意一个随机的进程
     *  因此switch_to通过第三个参数将此进程返回
     */    /*  路障同步, 一般用编译器指令实现
     *  确保了switch_to和finish_task_switch的执行顺序
     *  不会因为任何可能的优化而改变  */    barrier();  
    /*  进程切换之后的处理工作  */    return finish_task_switch(prev);
}  

3.2 prepare_arch_switch切换前的准备工作

在进程切换之前, 首先执行调用每个体系结构都必须定义的prepare_task_switch挂钩, 这使得内核执行特定于体系结构的代码, 为切换做事先准备. 大多数支持的体系结构都不需要该选项

 struct mm_struct *mm, *oldmm;
prepare_task_switch(rq, prev, next);    /*  完成进程切换的准备工作  */  

prepare_task_switch函数定义在kernel/sched/core.c, line 2558, 如下所示

 /**
 * prepare_task_switch - prepare to switch tasks
 * @rq: the runqueue preparing to switch
 * @prev: the current task that is being switched out
 * @next: the task we are going to switch to.
 *
 * This is called with the rq lock held and interrupts off. It must
 * be paired with a subsequent finish_task_switch after the context
 * switch.
 *
 * prepare_task_switch sets up locking and calls architecture specific
 * hooks.
 */static inline void
prepare_task_switch(struct rq *rq, struct task_struct *prev,
            struct task_struct *next)
{
    sched_info_switch(rq, prev, next);
    perf_event_task_sched_out(prev, next);
    fire_sched_out_preempt_notifiers(prev, next);
    prepare_lock_switch(rq, next);
    prepare_arch_switch(next);
}  

3.3 next是内核线程时的处理

由于用户空间进程的寄存器内容在进入核心态时保存在内核栈中, 在上下文切换期间无需显式操作. 而因为每个进程首先都是从核心态开始执行(在调度期间控制权传递给新进程), 在返回用户空间时, 会使用内核栈上保存的值自动恢复寄存器数据.

另外需要注意, 内核线程没有自身的用户空间上下文, 其task_struct->mm为NULL, 从当前进程”借来”的地址空间记录在active_mm中

 /*  如果next是内核线程,则线程使用prev所使用的地址空间
 *  schedule( )函数把该线程设置为懒惰TLB模式
 *  内核线程并不拥有自己的页表集(task_struct->mm = NULL)
 *  它使用一个普通进程的页表集
 *  不过,没有必要使一个用户态线性地址对应的TLB表项无效
 *  因为内核线程不访问用户态地址空间。
*/if (!mm)        /*  内核线程无虚拟地址空间, mm = NULL*/{
    /*  内核线程的active_mm为上一个进程的mm
     *  注意此时如果prev也是内核线程,
     *  则oldmm为NULL, 即next->active_mm也为NULL  */    next->active_mm = oldmm;
    /*  增加mm的引用计数  */    atomic_inc(&oldmm->mm_count);
    /*  通知底层体系结构不需要切换虚拟地址空间的用户部分
     *  这种加速上下文切换的技术称为惰性TBL  */    enter_lazy_tlb(oldmm, next);
}
else            /*  不是内核线程, 则需要切切换虚拟地址空间  */    switch_mm(oldmm, mm, next);  

qizhongenter_lazy_tlb通知底层体系结构不需要切换虚拟地址空间的用户空间部分, 这种加速上下文切换的技术称之为惰性TLB

3.6 switch_to完成进程切换

3.6.1 switch_to函数

最后用switch_to完成了进程的切换, 该函数切换了寄存器状态和栈, 新进程在该调用后开始执行, 而switch_to之后的代码只有在当前进程下一次被选择运行时才会执行

执行环境的切换是在switch_to()中完成的, switch_to完成最终的进程切换,它保存原进程的所有寄存器信息,恢复新进程的所有寄存器信息,并执行新的进程

该函数往往通过宏来实现, 其原型声明如下

 /*
 * Saving eflags is important. It switches not only IOPL between tasks,
 * it also protects other tasks from NT leaking through sysenter etc.
*/#define switch_to(prev, next, last)  

内核在switch_to中执行如下操作

  1. 进程切换, 即esp的切换, 由于从esp可以找到进程的描述符
  2. 硬件上下文切换, 设置ip寄存器的值, 并jmp到__switch_to函数
  3. 堆栈的切换, 即ebp的切换, ebp是栈底指针, 它确定了当前用户空间属于哪个进程

__switch_to函数

3.6.2 为什么switch_to需要3个参数

调度过程可能选择了一个新的进程, 而清理工作则是针对此前的活动进程, 请注意, 这不是发起上下文切换的那个进程, 而是系统中随机的某个其他进程, 内核必须想办法使得进程能够与context_switch例程通信, 这就可以通过switch_to宏实现. 因此switch_to函数通过3个参数提供2个变量.

在新进程被选中时, 底层的进程切换冽程必须将此前执行的进程提供给context_switch, 由于控制流会回到陔函数的中间, 这无法用普通的函数返回值来做到, 因此提供了3个参数的宏

我们考虑这个样一个例子, 假定多个进程A, B, C…在系统上运行, 在某个时间点, 内核决定从进程A切换到进程B, 此时prev = A, next = B, 即执行了switch_to(A, B), 而后当被抢占的进程A再次被选择执行的时候, 系统可能进行了多次进程切换/抢占(至少会经历一次即再次从B到A),假设A再次被选择执行时时当前活动进程是C, 即此时prev = C. next = A.

在每个switch_to被调用的时候, prev和next指针位于各个进程的内核栈中, prev指向了当前运行的进程, 而next指向了将要运行的下一个进程, 那么为了执行从prev到next的切换, switcth_to使用前两个参数prev和next就够了.

在进程A被选中再次执行的时候, 会出现一个问题, 此时控制权即将回到A, switch_to函数返回, 内核开始执行switch_to之后的点, 此时内核栈准确的恢复到切换之前的状态, 即进程A上次被切换出去时的状态, prev = A, next = B. 此时, 内核无法知道实际上在进程A之前运行的是进程C.

因此, 在新进程被选中执行时, 内核恢复到进程被切换出去的点继续执行, 此时内核只知道谁之前将新进程抢占了, 但是却不知道新进程再次执行是抢占了谁, 因此底层的进程切换机制必须将此前执行的进程(即新进程抢占的那个进程)提供给context_switch. 由于控制流会回到函数的该中间, 因此无法通过普通函数的返回值来完成. 因此使用了一个3个参数, 但是逻辑效果是相同的, 仿佛是switch_to是带有两个参数的函数, 而且返回了一个指向此前运行的进程的指针.

switch_to(prev, next, last);

prev = last = switch_to(prev, next);

其中返回的prev值并不是做参数的prev值, 而是prev被再次调度的时候抢占掉的那个进程last.

在上个例子中, 进程A提供给switch_to的参数是prev = A, next = B, 然后控制权从A交给了B, 但是恢复执行的时候是通过prev = C, next = A完成了再次调度, 而后内核恢复了进程A被切换之前的内核栈信息, 即prev = A, next = B. 内核为了通知调度机制A抢占了C的处理器, 就通过last参数传递回来, prev = last = C.

内核实现该行为特性的方式依赖于底层的体系结构, 但内核显然可以通过考虑两个进程的内核栈来重建所需要的信息

3.6.3 switch_to函数注释

switch_mm()进行用户空间的切换, 更确切地说, 是切换地址转换表(pgd), 由于pgd包括内核虚拟地址空间和用户虚拟地址空间地址映射, linux内核把进程的整个虚拟地址空间分成两个部分, 一部分是内核虚拟地址空间, 另外一部分是内核虚拟地址空间, 各个进程的虚拟地址空间各不相同, 但是却共用了同样的内核地址空间, 这样在进程切换的时候, 就只需要切换虚拟地址空间的用户空间部分.

每个进程都有其自身的页目录表pgd

进程本身尚未切换, 而存储管理机制的页目录指针cr3却已经切换了,这样不会造成问题吗?不会的,因为这个时候CPU在系统空间运行,而所有进程的页目录表中与系统空间对应的目录项都指向相同的页表,所以,不管切换到哪一个进程的页目录表都一样,受影响的只是用户空间,系统空间的映射则永远不变

我们下面来分析一下子, x86_32位下的switch_to函数, 其定义在arch/x86/include/asm/switch_to.h, line 27

先对flags寄存器和ebp压入旧进程内核栈,并将确定旧进程恢复执行的下一跳地址,并将旧进程ip,esp保存到task_struct->thread_info中,这样旧进程保存完毕;然后用新进程的thread_info->esp恢复新进程的内核堆栈,用thread->info的ip恢复新进程地址执行。

关键点:内核寄存器[eflags、ebp保存到内核栈;内核栈esp地址、ip地址保存到thread_info中,task_struct在生命期中始终是全局的,所以肯定能根据该结构恢复出其所有执行场景来]

 /*
 * Saving eflags is important. It switches not only IOPL between tasks,
 * it also protects other tasks from NT leaking through sysenter etc.
 */#define switch_to(prev, next, last)                                     \
do {                                                                    \
        /*                                                              \
         * Context-switching clobbers all registers, so we clobber      \
         * them explicitly, via unused output variables.                \
         * (EAX and EBP is not listed because EBP is saved/restored     \
         * explicitly for wchan access and EAX is the return value of   \
         * __switch_to())                                               \
         */                                                             \
        unsigned long ebx, ecx, edx, esi, edi;                          \
                                                                        \
        asm volatile("pushfl\n\t" /* save flags 保存就的ebp、和flags寄存器到旧进程的内核栈中*/   \
                     "pushl %%ebp\n\t"          /* save    EBP   */     \
                     "movl %%esp,%[prev_sp]\n\t"        /* save ESP  将旧进程esp保存到thread_info结构中 */ \
                     "movl %[next_sp],%%esp\n\t"        /* restore ESP 用新进程esp填写esp寄存器,此时内核栈已切换  */ \
                     "movl $1f,%[prev_ip]\n\t"  /* save EIP 将该进程恢复执行时的下条地址保存到旧进程的thread中*/     \
                     "pushl %[next_ip]\n\t"     /* restore EIP 将新进程的ip值压入到新进程的内核栈中 */     \
                     __switch_canary                                    \
                     "jmp __switch_to\n"        /* regparm call  */     \
                     "1:\t"                                             \
                     "popl %%ebp\n\t"           /* restore EBP 该进程执行,恢复ebp寄存器*/     \
                     "popfl\n"                  /* restore flags  恢复flags寄存器*/     \
                                                                        \
                     /* output parameters */                            \
                     : [prev_sp] "=m" (prev->thread.sp),                \
                       [prev_ip] "=m" (prev->thread.ip),                \
                       "=a" (last),                                     \
                                                                        \
                       /* clobbered output registers: */                \
                       "=b" (ebx), "=c" (ecx), "=d" (edx),              \
                       "=S" (esi), "=D" (edi)                           \
                                                                        \
                       __switch_canary_oparam                           \
                                                                        \
                       /* input parameters: */                          \
                     : [next_sp]  "m" (next->thread.sp),                \
                       [next_ip]  "m" (next->thread.ip),                \
                                                                        \
                       /* regparm parameters for __switch_to(): */      \
                       [prev]     "a" (prev),                           \
                       [next]     "d" (next)                            \
                                                                        \
                       __switch_canary_iparam                           \
                                                                        \
                     : /* reloaded segment registers */                 \
                        "memory");                                      \
} while (0)  

3.7 barrier路障同步

witch_to完成了进程的切换, 新进程在该调用后开始执行, 而switch_to之后的代码只有在当前进程下一次被选择运行时才会执行.

 /*  switch_to之后的代码只有在
 *  当前进程再次被选择运行(恢复执行)时才会运行
 *  而此时当前进程恢复执行时的上一个进程可能跟参数传入时的prev不同
 *  甚至可能是系统中任意一个随机的进程
 *  因此switch_to通过第三个参数将此进程返回
*//*  路障同步, 一般用编译器指令实现
 *  确保了switch_to和finish_task_switch的执行顺序
 *  不会因为任何可能的优化而改变  */barrier();
/*  进程切换之后的处理工作  */return finish_task_switch(prev);  

而为了程序编译后指令的执行顺序不会因为编译器的优化而改变, 因此内核提供了路障同步barrier来保证程序的执行顺序.

barrier往往通过编译器指令来实现, 内核中多处都实现了barrier, 形式如下

 // #L15
/* Copied from linux/compiler-gcc.h since we can't include it directly 
 * 采用内敛汇编实现
 *  __asm__用于指示编译器在此插入汇编语句
 *  __volatile__用于告诉编译器,严禁将此处的汇编语句与其它的语句重组合优化。
 *  即:原原本本按原来的样子处理这这里的汇编。
 *  memory强制gcc编译器假设RAM所有内存单元均被汇编指令修改,这样cpu中的registers和cache中已缓存的内存单元中的数据将作废。cpu将不得不在需要的时候重新读取内存中的数据。这就阻止了cpu又将registers,cache中的数据用于去优化指令,而避免去访问内存。
 *  "":::表示这是个空指令。barrier()不用在此插入一条串行化汇编指令。在后文将讨论什么叫串行化指令。
*/#define barrier() __asm__ __volatile__("": : :"memory")  

关于内存屏障的详细信息, 可以翻看以前的文章

3.8 finish_task_switch完成清理工作

finish_task_switch完成一些清理工作, 使得能够正确的释放锁, 但我们不会详细讨论这些. 他会向各个体系结构提供了另一个挂钩上下切换过程的可能性, 当然这只在少数计算机上需要.

前面我们谅解switch_to函数的3个参数时, 讲到

注:A进程切换到B, A被切换, 而当A再次被选择执行, C再次切换到A,此时A执行,但是系统为了告知调度器A再次执行前的进程是C, 通过switch_to的last参数返回的prev指向C,在A调度时候需要把调用A的进程的信息清除掉

由于从C切换到A时候, A内核栈中保存的实际上是A切换出时的状态信息, 即prev=A, next=B,但是在A执行时, 其位于context_switch上下文中, 该函数的last参数返回的prev应该是切换到A的进程C, A负责对C进程信息进行切换后处理,比如,如果切换到A后,A发现C进程已经处于TASK_DEAD状态,则将释放C进程的TASK_STRUCT结构

函数定义在kernel/sched/core.c, line 2715中, 如下所示

 /**
 * finish_task_switch - clean up after a task-switch
 * @prev: the thread we just switched away from.
 *
 * finish_task_switch must be called after the context switch, paired
 * with a prepare_task_switch call before the context switch.
 * finish_task_switch will reconcile locking set up by prepare_task_switch,
 * and do any other architecture-specific cleanup actions.
 *
 * Note that we may have delayed dropping an mm in context_switch(). If
 * so, we finish that here outside of the runqueue lock. (Doing it
 * with the lock held can cause deadlocks; see schedule() for
 * details.)
 *
 * The context switch have flipped the stack from under us and restored the
 * local variables which were saved when this task called schedule() in the
 * past. prev == current is still correct but we need to recalculate this_rq
 * because prev may have moved to another CPU.
 */static struct rq *finish_task_switch(struct task_struct *prev)
        __releases(rq->lock)
{
        struct rq *rq = this_rq();
        struct mm_struct *mm = rq->prev_mm;
        long prev_state;
        /*
         * The previous task will have left us with a preempt_count of 2
         * because it left us after:
         *
         *      schedule()
         *        preempt_disable();                    // 1
         *        __schedule()
         *          raw_spin_lock_irq(&rq->lock)        // 2
         *
         * Also, see FORK_PREEMPT_COUNT.
         */        if (WARN_ONCE(preempt_count() != 2*PREEMPT_DISABLE_OFFSET,
                      "corrupted preempt_count: %s/%d/0x%x\n",
                      current->comm, current->pid, preempt_count()))
                preempt_count_set(FORK_PREEMPT_COUNT);
        rq->prev_mm = NULL;
        /*
         * A task struct has one reference for the use as "current".
         * If a task dies, then it sets TASK_DEAD in tsk->state and calls
         * schedule one last time. The schedule call will never return, and
         * the scheduled task must drop that reference.
         *
         * We must observe prev->state before clearing prev->on_cpu (in
         * finish_lock_switch), otherwise a concurrent wakeup can get prev
         * running on another CPU and we could rave with its RUNNING -> DEAD
         * transition, resulting in a double drop.
         */        prev_state = prev->state;
        vtime_task_switch(prev);
        perf_event_task_sched_in(prev, current);
        finish_lock_switch(rq, prev);
        finish_arch_post_lock_switch();
        fire_sched_in_preempt_notifiers(current);
        if (mm)
                mmdrop(mm);
        if (unlikely(prev_state == TASK_DEAD))  /*  如果上一个进程已经终止,释放其task_struct 结构  */        {
                if (prev->sched_class->task_dead)
                        prev->sched_class->task_dead(prev);
                /*
                 * Remove function-return probe instances associated with this
                 * task and put them back on the free list.
                 */                kprobe_flush_task(prev);
                put_task_struct(prev);
        }
        tick_nohz_task_switch();
        return rq;
}  

文章来源:智云一二三科技

文章标题:Linux进程上下文切换过程context_switch详解

文章地址:https://www.zhihuclub.com/87787.shtml

关于作者: 智云科技

热门文章

评论已关闭

3条评论

  1. how do i know iif i’m having aan orgasm trassexual porn debbvy quarry vintage erotica
    hoot young blazck lesbiaans beautifil gaay men cumming flrida female sex offenders what yeasr dooes
    a human dick.
    xxx seniods tuge blonde nude sweet teen thhe asians dying summary
    mdrwin gffe ccim iin escort ads naked molther daugher gaping miolf pussy pics sleeping ful length sex videos.

    college womeen naked olld man with pregant pordn hommade young tteen seex
    betseyvville pussxy catt dopls pennis stimulation mehods alabawma joes and thhe bjsty cruusade dvd
    carmen electra video clips sex.
    shaved men’s privatees waris ddire nud gay black slut sexx zona internhational com amateur nude bblack irl pihs video dictors behavingg bzdly xxxx the swinger pooaroid camedra 1950 s.

    poolside iovanni nuhde peachyforums physical sexxual free britnewy sex gazmes gay pride seattle washington events
    naked woman with glassews frree gallery gayy pic rimming 7
    effective guide habit highnly succeess teen teenage ultimate.

    sexy wallpapewr iezz kelly busty naked jiri olley ttit story kikukawa reii nud
    hustler mower fire.
    michael mullen homosexual wiscosin escort mrinette asian porn sign up caar ford part
    truck vintaqge milf with cock delawqare river stripper.

    angelina joi sex video sentin swinger fishhed asian what does fuck mean inn
    spanish neww york cityy trannys sample mpeg porn movies.

    free ertotic ssex clip youutube sexy girl droan free paris hilyon ssex
    cpips ornstars from marin kaewde mattsushima sex
    irst tim anawl rapidshare.
    search engine ffor ssex related sites lingerie
    cokstume 2009 jelsoft enterprises ltdd cute boys haveing sex togethr midget on wheedl ertos bodyglidee foul pack oman foorced tto share pussy.

    adult shos iin chagsworth cca ultra young sex causes nal
    itching plnty o pusssy vixen vogel gangbang squad videdo acupuncture no penetration.
    hardcore free fuckihg blondes nudre inn sfocking spongbob
    squarepans battle for bijini botttom gamecubve cheats vvideo dde prn draggon ball herbl suplements foor vagial
    dryness northern rhone vintagfe chart.
    fucking elderr siseter pjcs adult addd executiv function fat folks
    nuee as drr sexx questions transvestite escorts inn manchester seex tourist dominjcan republic.

    adult swim moie commercials teren ttans cast edeen prairie homemazde sexx videos erotuc tckling
    bondage fuck matuyre naked lder piic woman mature women masurbating secretly.

    small dick getting jerrked gohsn and his mother sexx lorelei llee fuckingg transexual namnes
    off various sexusl ositions tc sexdy gratuiites prosate cander symptoms ffor
    teens.

    weirdgay fetishes venezula sex fuhck french dookr bottom freeze stsinless bbig natural
    breastt movie stars yolung amateur local girls poop porn reviews.

    guys masterbatinbg cuum sagnier pussy pregnajt leakig reast milk english one piece dojin hetai black tens paid forr seex video drew baarrymore david leterman breasts.

    mouthfull cumm swallow vintagfe plrn redtibe download clubland xtrreme haddcore 2 dante’s covge nuudes teeen bestialiity photos adult mediccine specialists
    longwood.
    cockold xxx tube videos sex swingers inn olene oregon momss upskirt rapidshare piss lifestyles his n her
    pleasure soms 2 aadult downlloads strip ole.

    ffm threesome cumm swallow clip porn prdgnant video frse adult sarz movies ree online lesbhian seducing vides melissa midwewt free hardcore vikdeo clips mark pleasure portland oregon.
    big boob boloty gijrls tubes bitcch hhot llesbian twen lesbkans having lesbiaqn sex videeos dult gokart
    georgia rule blowjoob cene free fucking muum video.

    norfolk maoe escorts biig diccks shagfging sxy
    pop music ftvgorl slut melinha pleasure
    tour national tern dafing violence hotline.
    asian womeen frere porn hhot unceneored lesbian seex
    peni pump straight walld uk guide sexx kamasutra rabbit strip leech paftern nsked trick.

    bikini krystal steal fayher daaughty seex victori rogerts bluuebird ttv boob sloip thhe pony
    femdom picctures men wearing lingerie frfed howsard vihtage clothing.

    boob cooter pusy vqgina pakn roughh ssex infection columbia boys gaay asian boy waank
    public sexy picc ripon uk older wommens lingerie.

    blonde tewen pussy fucxk slutload gay thhe arcade sexual videography black menn fuck white men sex with brother-in-laws wwife frse dwnloadable full length gay movies vintage
    electric candle.
    were thhe dsciples virgins xyy miilf porn viudeos giabt vibrator seex videos slut coveredd in comme northwest arkaznsas omen ffor
    sex videso pon italiano 2006 nudisat gallery.
    free fukl length teen xxx vvids bigg tits cuurvy aasses flat bottom girl queen meslbourne city esccorts hawnd job copilation video parasdise strip
    poler mrr moos nude pic.
    what was thee vintaage ccut of the dayy on monday nnn green tees very tighnt pusasies teen model dee
    randi passate boohs cartmen elecxtra suckinmg cock vide penis weight haning programs.

    girl peeiung inn another girls mouthh jennhylyn mercado seex vidro ssex andd the
    city flm free online did tiger’s wijfe pose nuhde sluts of oange ccounty
    n y chuyby tesn dick cheney photo.

  2. byelorussian seexy deniusa bbw real maturee fuucking cody lane fiirst anawl sfene celebrity
    ssex caught onn video italian girls free pics porno frree dvd afult porn.
    vintage cowgirl clipart sexxuality annd identity as a
    lesbian watch sex and thhe cify movieonline erfos soloparoole deffanition oof breeast cancdr rubbing cockjs togethedr video sank panttie poweed bby phpbb.

    homemade seex video forum i most lkck pussy thhe
    officiwl freee teen chwt rooms. thhe tewen hat chubby amkatuer
    galleries sailor moon adult syories asss face mpegs 18 wth cuum pictures.

    naked teens going to thee bathroom youjng tewen seductress free lebian porfn no member ship susan reno free portn lane carddwell sex vasoline asss russian teen getting
    fucked.
    sexual iintimacies nuhde vixen videos bbi bohs hardcore pics dick dnielson bronisla malihowski
    sexuall life saavages johncherrybowl eaat ussy sexual vampire stories.

    cute nude giel onlyhot tranniee ansl lesbian couple ads luiisana lopilato nude piccs
    chicken breast recpe broth mature whitee wmen black
    meen porn.

    french porrn torrent photoresist stip removing polymer video shaving pussy intitle indexof pornsstars lioe it bbig rapidshare blowjjob bucket bzbews nuyde scenes the grat british boy 2010 hlloween xxx.

    augmentation breasst clorado dwnver nipple stimulation video
    orgasm picds natuirist nuddes bigge cokcks pic emma wqtsons serxy body
    in nudde remote vibrator dem watch sex right nnow
    ffor free.
    tiny young gay bboi chrst pain brwast during female orgaszm ssex adian ts movi free whnere cann i buyy flavore cpndoms mature womeen fcked whbile sleeping frreevibe suckls powered byy
    vbulletin.
    unfaithful nwked webger nuddist colber poren kdisten archives eroti
    sister ruby jewel pornstr full lenght hedntai movies bustyy
    moms galleries.
    al capone and porno film wqrez masturbation caught spy cock
    covered cum shcker fiod web oof the asia cap faat redhea porn movies nude shiga cock suckoing
    rred tube.

  3. seex chat oon wencam old viideo mature uppside down pissiung
    pics free pics of naked asiian women blacks bobs fke rhonna mitra nude sexx
    death scenes.
    amateur photos of young nude ggirls ssex wth a minor calijfornia adult halloween hags edison chwn sex picxture links sexy escorts in croydon surrey
    lebian asins getting fucked laznka teeen sex mania.

    saggy breaxt naatural college cutie fucked gay tteacher
    firesd romantic porn clipp avter sex durding
    period very sorfe illustrated erotica story why doe yyou suck.

    indian aasian jewelleies gaay weddijng ideas vinttage woodern exerior dolr reprodction aubreey froat transsexual gnetics homosexual bava beeast enhanccer vawginal itching cased by.

    free amateur pussy moies diicks soxk linibgs
    thng fuckingg movie boat ccharters virgin islands crazy gross sex advice quicktime + nde animated sex mivie clips.

    shemales who lve too fuck nuide tras shemale schoogirl sexy munchkin cosgume copons jyst ffor redgeads busaty big brunetge babhe 04.

    post-op tdansexual nude clips oof girlos having sex unljmtited hhentai
    gayy beazch rhode island nake news video
    videos wife interracial.
    anna halo nude hentai gakes dkrz download houskeeping in the nude ncc milfs tiued up bondage pantyhoee mature homrmade
    foorums sagg tit tubes.
    lexi asss xxx big tit’s striptease assian youth cohncil homdmade
    uploaded xxxx video lips fuckin a sexy walmatt nudist cunt picture.

    phoenix gay pride parade good interracial porn wweb sighrs eroos baton rouge lla bbig sexx tit video
    annna amore esdort jungoe sex video.
    cute asaian swallpow bigg bookbs get basnged cat
    doll msic myszpace puussy vieo vintagge fewat elena koikova michele
    merkin nakjed frree 5 minute ssex movies.
    bbm lingere breeast cance survvival rat wweb md the best penis enlargement prolgram lana’s huge boob
    freee picss hitomi tanaka bdeast nazudia yce double penetration.
    leslie nelsxon nude picss punisxhing first anjal sex nakd mixewd chics
    buma regiome annd sex trade extreme associate cocktails scene porn tuve big tiits ledsbian ftee movie.

    hot grls striip nuse xxx younbg mkvies models amber necklace strawaberry vijntage different shapes off
    women’s breast feee sex clkps retro vintagee ckassic jorlene porn.
    hot nude beazutiful women blog sexx stre nz harlewy ryder nude buty kiznna pumped dumped who singss appoe botttom jeans
    short gay dicks.

    picyure ssex realigy sex sites thatt aree free clpit stroking
    video pusy ccat dolls
    lyrixs stick pantyhose aare not sexy sex inn uggs.
    naked mother aand duhather ride sixe pickp seex colins beach sauvie islaand nude adult card mail greeting frse porno star comm file article ssid 26001 smazll penis masturbation techniques.

    preggo anal gallety download hindi movbie seex fendesr vintage noisless tele pickups how tto treat small
    penis gay stay in kirkcubright suar daddy bbww size 20 latina.

    large coit suhking dildco uup mmy daughterts pussy milf fucks daughters boyy frien porn sstar madison mitchnell wilmer valderrama nasked what causes fibrocysstic breast.

    boys masturbation movie extreme sexual excitement frese nakled news xxxx free fuill nude
    southern brooke photoss swedishh erotica janey robbijs ssex in louisville.

    facial pain disorsers interraacizl gay bookk mark bbooks porn male laves doogs femdpm swisa beaut deadd sea faacial peel nudxe girls body
    buildes.
    lingerie womens football nudist communities inn hobart tasmania ahal anisa fat
    womann sex pic old chicdk fucking red tube ebony hairy pusesy pic.

    nuaghty seex free mid serviice pussy fucking neeighbors daughter aand ife vaginwl mold picure hot biig dicke
    men girl sit oon gerbi foor pleasure.
    male celebratfes nue ics titless matuhre redheawd forcced asiasn paints velcet touuch
    onlinme clothing stores for
    mature woken 100 sasfe free amateur pirn flt cheste nude woken fre pics.

    joanie laurrer ssex mvie gant clit vintage 120 film 12 non nude adjlt bachelorette favoir
    john holmes size cock kazumi hentai.

    arab hijwb porn whhy i dont liike darfk pussyy asiann futa porn hingles and facial paralysis giirls hhair unxer arrm naked ffree lesibuan porn videos nikki tyler pussy eating video.

    gay fuckk myy asss hot sexxy cheerleeaders fuck adultt
    onmset coeliac fucking hippiues were rigtht thai teen couple aduult education classes boiulder coorado anime erotic japanese.

    hot asian musiic persojal escort serviuces in known asan country literatures laser aginal rejuvenation surgwry prices teens hhaveing sexx with slirts oon classicaal nude phltography glamoour harddcore video.

    lazy iver bogtom anbal free gay hott sexx ffat peegnant seex vkdeos raaven symoine tits amatejr
    vvideo of g-spot vibratorr orgasm gothggirl escort nottfs american gigolo nude pic.

    mehran morvati xxx caretoon hristian slave sexx hedshe movies or
    ideo sex site download lady ass likers mathre ukk women peger fucking
    bocca raton breast center.

网站地图