2021-2022-1 20212823《Linux内核原理与分析》第九周作业

实验八

一、Linux 系统中进程调度的时机

1、进程调度的时机:

中断处理过程(时钟中断、I/O中断、系统调用和异常)中或返回用户态根据need_resched标记调用。
内核线程直接调用进行进程切换,也可以在中断处理过程中进行调度,内核线程可以主动调度,也可以被动调度。
用户态进程无法实现主动调度,仅能通过陷入内核态后的某个时机点进行调度,在中断处理过程中调度。

2、schedule()函数

schedule()函数开始,禁用内核抢占并初始化一些局部变量,此时,schedule()检查运行队列中剩余的可运行进程数,如果有可调用进程,开始调用。
schedule()函数中在switch_to宏之后紧接着的指令并不由next进程立即执行,而是稍后当调度程序选择prev又执行时由prev执行。 prev局部变量并不指向开始描述schedule()时所替换出去的原来的那个进程,而是指向prev被调度时由prev替换出的原来那个进程。
紧接着context_switch()函数调用之后,宏barrier()产生一个代码优化屏障。执行finish_task_switch()函数。
schedule()函数最后执行的是:重新获得大内核锁,重新启动内核抢占,并检查是否其他进程设置了当前进程的TIF_RESCHED标志,如果是,整个schedule()函数重新开始执行。

3、swtich_to关键代码:

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

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

"jmp __switch_to\n" jmp通过prev和next寄存器的方式传递参数

"popl %%ebp\n\t"恢复上下文,next曾经push过ebp

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()函数

cd LinuxKernel
rm menu -rf
git clone https://github.com/mengning/menu.git
cd menu
mv test_exec.c test.c
make rootfs
shell1
qemu -kernel ../linux-3.18.6/arch/x86/boot/bzImage -inird rootfs.img -s -S

shell2
gdb
file linux-3.18.6/vmlinux
target remote:1234
b schedule
c

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

三、总结

通过本次课程的学习,我对进程调度时机及进程调度与进程切换的过程有了一定的认识。进程调度的时机:中断处理过程中,直接调用schedule,或者返回用户态时根据need_resched标记调用schedule;内核线程可以直接调用schedule进行进程切换,也可以在中断处理过程中进行调度,即内核线程作为一类特殊的进程可以主动调度,也可别动调度;用户态进程无法实现主动调度,只能在中断处理过程中进行调度。进程切换:schedule函数选择一个新的进程来运行,并调用context_switch进行上下文的切换,这个宏调用switch_to来进行关键上下文的切换。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值