参考博客:
Linux CFS调度器之选择下一个需要调度的进程_liuhangtiant的博客-优快云博客前言CFS调度器选择下一个要执行的进程时,基本原则是选择vruntime最小的进程,vruntime小意味着应该受到CPU的优待。但是在某些情况下,会对该原则有所违背,比如某个进程睡眠了一段时间,时间到了以后理应尽可能快的被调度,这个过程可能会导致当前进程被抢占,好端端的被抢占了,CPU在补偿了刚刚醒来的进程后,理应再补偿下被抢占的进程。发生在进程唤醒过程中的抢占事件进程睡眠和进程唤醒的...https://blog.youkuaiyun.com/liuhangtiant/article/details/84455351Linux进程管理(四)进程调度之抢占式调度_JT同学的博客-优快云博客_抢占式进程调度Linux进程管理(四)进程调度之抢占式调度文章目录Linux进程管理(四)进程调度之抢占式调度一、抢占式调度二、设置需要重新调度的标志的时机(TIF_NEED_RESCHED)三、进程抢占的时机3.1 用户态的抢占时机3.2 内核态的抢占时机四、总结上篇文章我们将了内核调度分为主动调度和抢占式调度,主动调度我们已经讲解过了,这篇文章我们来讲解一下抢占式调度一、抢占式调度我们说过,进程真正...
https://blog.youkuaiyun.com/weixin_42462202/article/details/102954818声明:本篇文章充满了猜想,因为调度器/调度算法/CPU运行队列的知识储备还不够
1.在中断返回内核态时的抢占图示
简要描述下图就是:
1). 系统的抢占肯定是开启的,CONFIG_PREEMPT=y
2). 触发抢占:在中断ISR中唤醒了高优先级任务,触发了抢占(此时抢占还未真正执行)
3). 执行抢占:在中断返回内核态时迎来一个抢占点,低优先级任务被抢占
2. 抢占是怎么被触发的?
唤醒高优先级任务实际上就是在中断ISR中调用了wake_up系列函数唤醒等待队列上的进程,该系列函数的整个调用链如下图,代码参考./kernel/sched/core.c
这里p是要唤醒的进程,cpu是当前运行的CPU(不一定正确),而rq是CPU上的运行队列(run queue),接着看ttwu_do_active()->ttwu_do_wakeup()->check_preempt_curr()
这个函数看名字猜意思:检查当前进程的可抢占性,如果调度类是 fair_sched_class,那么 check_preempt_curr 就是 check_preempt_wakeup(./kernel/sched/fair.c)
这里的注释说得很清楚: 如果必要的话,用新唤醒的进程来抢占当前进程
因为这里的执行context是在中断上下文,所以我理解rq->curr是被中断的那个进程
se是被中断的那个进程的成员,pse则是新唤醒进程的成员
如果被中断的进程已经被设置了TIF_NEED_RESCHED标记,表明抢占已经被触发,被中断的进程可以被抢占,直接返回;
如果被中断的进程是IDLE进程而被唤醒的进程不是IDLE进程,则IDLE进程被NON-IDLE进程抢占
如果被中断的进程和被唤醒的进程都是普通进程的话:
如果被中断的进程的vruntime比较小,那么不能抢占,因为这意味着被中断的进程需要受到优待。
如果被中断的进程的vruntime比较大,而且相比于被唤醒的进程超过了一定的门限值,那么需要补偿被唤醒的进程,也就是允许被唤醒的进程抢占被中断的进程
preempt label实际上就是抢占的实际触发点,通过resched_curr()函数,将被中断进程的TIF_NEED_RESCHED置位
3. 抢占式如何被执行的?
假设在中断的ISR中唤醒高优先级的进程的时发现被中断进程可以被抢占,即按照第2点的调用流程走到了preempt标签,成功设置了被中断进程的TIF_NEED_RESCHED标志
这时到了中断结束返回内核态进程上下文的时候,出现了一个抢占点:
如果抢占使能且被中断的进程需要被调度出去(TIF_NEED_RESCHED置位),那么调用preempt_schedule_irq()函数实施抢占,
至此,就大概说清楚了在中断返回内核态时的抢占式如何发生的(怎么触发的抢占,怎么执行的抢占)