调度时机分析之被动调度(之系统调用返回)

分析基于内核版本2.6.12.6

在什么情况下,会触发调度?

Linux进程的调度主要分为主动调度和被动调度两大类。

◆主动调度

主动调度就是进程自己缺少相应的所申请的资源,显示调用schedule,让出处理器。

◆被动调度

在整个linux运行过程中,被动调度又可细分为两种:

●用户态抢占调度

●内核态抢占调度

下面就结合内核代码分析上述各种调度时机的详细情况。

被动调度

整个linux运行过程中,被动调度分为用户态抢占调度和内核态抢占调度。

用户态抢占调度

用户态抢占调度发生在当系统调用、中断处理、异常处理等返回用户态时,或者进程的时间片用完时。

系统调用返回

当一个进程由于系统调用进入内核态,在系统调用处理完,返回用户态时,是一个调度点。这个时候会检测有没有设置TIF_NEED_RESCHED标志。下面分析下内核中系统调用返回相关的代码片段。

上面代码片段是系统调用的入口。这个系统调用的入口是在syscall_init函数里调用wrmsrl(MSR_LSTAR,system_call)设置的,通过一个MSR寄存器来保存系统调用的地址,而不再像I386架构下面是通过中断。

用户进程和内核都使用

x8664_pda

SAVE_ARGS宏主要是将一些寄存器压栈。

下面接着分析系统调用代码:

.globlret_from_sys_call

ret_from_sys_call:

sysret_check:

sysret_careful*/

swapgs

sysretq

/*Handlereschedules*/

sysret_careful:

TIF_NEED_RESCHED标志*/

sti

pushq%rdi

popq%rdi

上面代码是系统调用后的处理部分。在处理完系统调用返回用户态前,首先检查是否还有其他工作需要完成,如果有其他工作,则跳转到

sysret_careful开始就检测是否有设置TIF_NEED_RESCHED标志,如果没有设置此标志,则跳转到sysret_signal标签处执行。如果有设置此标志,则首先开中断,然后调用schedule函数。

下面接着分析sysret_signal标签处的代码:

sysret_signal:

jz1f

/*Reallyasignal*/

/*edx:workflags(arg3)*/

callptregscall_common

1:movl$_TIF_NEED_RESCHED,%edi

jmpsysret_check

上面代码片段是处理信号部分代码。首先检测是否有信号需要处理,有信号处理的情况下,将do_notify_resume函数的地址赋给ptregscall_common函数处执行。在ptregscall_common中会调用call*%rax,,进入do_notify_resume函数执行。

下面是上面分析的系统调用相关代码的流程图。

图-systemcall流程图

图-ret_from_sys_call流程图

版权声明:本文为博主原创文章,未经博主允许不得转载。

最美不过偷瞄你是你忽然转头,看见你的微笑

调度时机分析之被动调度(之系统调用返回)

相关文章:

你感兴趣的文章:

标签云: