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


硬中断与软中断

        先从中断说起,因为进程调度的时机都与中断相关。中断有很多种,都是程序执行过程中的强制性转移,转移到操作系统内核相应的处理程序。中断在本质上都是软件或者硬
件发生了某种情形而通知处理器的行为,处理器进而停止正在运行的指令流(当前进程),对这些通知做出相应反应,即转去执行预定义的中断处理程序人内核代码),
除了主动让出 CPU 外,进程的调度都需要在进程外(内核)进行,这就需要从进程的指令流里切换出来。中断能起到切出进程指令流的作用,中断处理程序是与进程无关的内核
指令流。进程调度的时机基本都是中断处理后,相当于已经在进程之外了。运行完内核代码后,CPU顺带检查一下是否需要进程调度。需要则切换进程(本质上是切换两个进程的内核堆
栈),不需要则一路顺着函数调用堆栈正常中断返回 iret,这样就自然回到原进程继续运行了。
ntel定义的中断类型主要有以下几种。

硬中断

        硬中断就是CPU 的两根引脚(可屏蔽中断和不可屏蔽中断)。CPU 在执行每条指令后检利这两根引脚的电乎,如果是高电平,说明有中断请求,CPU 就会中断当前程序的执行去处理中断。一脱外拔都是以这种方式与CPU进行信号传递的,如时钟、键盘、硬盘等。

软中断

        包括除零错误、系统调用、调试断点等在 CPU执行指令过程中发生的各种特殊情况统称为异常。异常会导致程序无法继续执行,而跳转到CPU 预设的处理函数。

故障:故障就是有问题了,但可以恢复到当前指令。例如除0错误、缺页中断等。

退出:简单说是不可恢复的严重故障,导致程序无法继续运行,只能退出了。例如连续发生故障。

陷阱:程序主动产生的异常,在执行当前指令后发生。简单说就是程序自己要借用中断这种机制进行转移。从 CPU的视角,其处理机制与其他中断处理方式并无区别,本书只是以系统调用为例介绍一般的中断机制。

进程调度时机

schedule函数

        Linux内核通过schedule函数实现进程调度,schedule函数在运行队列中找到一个进程,把 CPU 分配给它。所以调用schedule函数一次就是调度一次,调用schedule函数的时候就是进程调度的时机。调用schedule函数的两种方法如下。
        进程主动调用schedule(),如进程调用阻塞的系统调用等待外设或主动睡眠等,最终都会在内核中调用到schedule函数。

schedule函数代码

#define switch_to(prev, next, last)                    
do {                                 

unsigned long ebx, ecx, edx, esi, edi;              

asm volatile("pushfl\n\t"      
       "pushl %%ebp\n\t"        
       "movl %%esp,%[prev_sp]\n\t"  
       "movl %[next_sp],%%esp\n\t"  
       "movl $1f,%[prev_ip]\n\t"     
       "pushl %[next_ip]\n\t"     
       __switch_canary                   
       "jmp __switch_to\n" 
       "1:\t"                        
      "popl %%ebp\n\t"    
       "popfl\n"       

       : [prev_sp] "=m" (prev->thread.sp),     
         [prev_ip] "=m" (prev->thread.ip),        
         "=a" (last),                 

         "=b" (ebx), "=c" (ecx), "=d" (edx),      
         "=S" (esi), "=D" (edi)             

         __switch_canary_oparam                

       : [next_sp]  "m" (next->thread.sp),        
         [next_ip]  "m" (next->thread.ip),       


         [prev]     "a" (prev),              
         [next]     "d" (next)               

         __switch_canary_iparam                

      "memory");                  
} while (0)

调度策略与算法

进程的指针,是指同被中断过任中子中断的级别不同,有不可屏蔽中断、可屈代以换信息调度算法就是从就绪队列中选一个进程。一般来说就是挑最重要的、最需要的(最着急的)、等了最长时间的(排队)等,和人类排队抢资源很相似。也存储于该进程的内楼堆化T个系然的运行效率,中断上下文中调用其他内权T斯、陷阱(系统调用)、异常等。为EI小观P0心内核代码有一定的限制。

进程调度的时机

         进程调度时机就是内核调用schedule函数的时机。核即将及回用尸空间时,内核时间复杂度可以接受吗?这些具体的实现就是调度算法会检查need_resched标志是否设置。
        处理程序返回用户空间的时间点作为一个固定的调度时机点。除了这个固定的调度时机外,内核线程和中断处理程序中任何需要暂时中止当前执从不同的视角看,进程可以有多种不同的分类方式。这里选取两种和调度相关的分行路径的位置都可以直接调用schedule(),比如等待某个资源就绪。
        用户进程通过特定的系统调用主动让出 CPU。I/O消耗型进程。典型的像需要大量文件读写操作的或网络读写操作的,如文件服务器的服务进程。这种进程的特点就是CPU 负载不高,大量时间都在等待读。中断处理程序在内核返回用户态时进行调度。

进程调度相关源代码和分析

设置断点

gdb
file linux-3.18.6/vmlinux
target remote:1234
b schedule
b context_switch
b switch_to
b pick_next_task


运行到schedule断点

运行到context_switch断点

运行到pick_nexy_task断点

运行到switch_to断点

总结

        schedule函数的作用非常重要,是进程调度的主体函数。其中 pick_next_task函数是schedule函数中重要的函数,负责根据调度策略和调度算法选择下一个进程。context_switch函数schedule函数中实现进程切换的函数。switch_to是context_switch函数中进行进程关键上下文切换的函数。

遇到的问题

        switch_to需要通过单步调试才可分析查看。


 


 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值