64位x86体系Linux内核进程切换

首先简单提一下这个宏和函数的被调用关系:   schedule() --> context_switch() --> switch_to --> __switch_to() 这里面,schedule是唯一调用switch_to的函数,涉及到一些调度算法,这里不讨论。当schedule()需要暂停A进程的执行而继续B进程的执行时,就发生了进程之间的切换。进程切换主要有两大步:1、
摘要由CSDN通过智能技术生成

首先简单提一下这个宏和函数的被调用关系:

    schedule() --> context_switch() --> switch_to --> __switch_to()

 

这里面,schedule是唯一调用switch_to的函数,涉及到一些调度算法,这里不讨论。当schedule()需要暂停A进程的执行而继续B进程的执行时,就发生了进程之间的切换。进程切换主要有两大步:1、切换全局页表项;2、切换内核堆栈和硬件上下文。这个切换工作由context_switch()完成。其中switch_mm完成第一步,而switch_to__switch_to()主要完成第二步。更详细的,__switch_to()主要完成硬件上下文切换switch_to主要完成内核堆栈切换

 

阅读switch_to时请注意:这是一个宏,不是函数,它的参数prev, next, last不是值拷贝,而是它的调用者context_switch()的局部变量。局部变量是通过%ebp寄存器来索引的,也就是通过n(%ebp)n是编译时决定的,在不同的进程的同一段代码中,同一局部变量的n是相同的。switch_to中,发生了堆栈的切换,即ebp发生了改变,所以要格外留意在任一时刻的局部变量属于哪一个进程。关于__switch_to()这个函数的调用,函数参数并不是通过堆栈来传递,而是通过寄存器来传递。

 

在下文中提到一些局部变量和寄存器值,为了不引起混淆,在名字后面加上_X,表示是X进程的成员。如esp_A表示进程Aesp的值,prev_B,表示进程B中的prev变量,等等。

 

switch_to切换主要有以下三部分:

进程切换

esp的切换

由于从esp可以找到进程的描述符

硬件上下文切换

_switch_to()

以前通过x86硬件支持,现在使用软件切换

堆栈的切换

ebp的切换

ebp是栈底指针,它确定了当前变量空间属于哪个进程

 

上面的四个步骤中,有三个是在switch_to宏中完成,硬件上下文切换由__switch_to()函数完成。

 

下面来具体看switch_toA进程切换到B进程的步骤。

/* Save restore flags to clear handle leaking NT */

#define switch_to(prev, next, last) \

         asm volatile(SAVE_CONTEXT                                            \

              "movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */          \

              "movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */      \

              "call __switch_to\n\t"                                             \

              "movq "__percpu_arg([current_task])",%%rsi\n\t"              \

              __switch_canary                                                       \

              "movq %P[thread_info](%%rsi),%%r8\n\t"                             \

              "movq %%rax,%%rdi\n\t"                                                \

              "testl  %[_tif_fork],%P[ti_flags](%%r8)\n\t"                \

              "jnz   ret_from_fork\n\t"                                                \

              RESTORE_CONTEXT                                                   \

              : "=a" (last)                                                     \

                __switch_canary_oparam                                            \

              : [next] "S" (next), [prev] "D" (prev),                  

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值