1.前言
Linux 6.12版本中,Peter Zijlstra提交了任务调度器的delayed dequeue特性。该特性通过在sched entity中控制专用标志字段的方式取代相对冗长的进/出运行队列的逻辑从而提高内核的运行效率。
本文简单分析一下该特性的改进点以及因此带来的正负面影响。
2.sched entity
本特性很重要的一点是在sched entity结构体增加sched_delayed字段。该字段的利用方式在下面段落分析。
3.任务dequue从此变得简单
6.12以前的Linux内核中,将就绪态的任务“踢出”运行队列使其变成阻塞态往往是一件在操作系统运行中高频率发生的事情。6.12内核对于就绪态任务的出队处理相对简单,在dequeue_entity函数中对其sched entity的sched_delayed字段做个标记就完成了“出队”。
4.再次入队也不难
如果任务再次从阻塞态转换为就绪态,需要将任务再次加入运行队列。这种情况下在delayed dequeue特性开启的情况下变得特别简单。
首先,sched entity的sched_delayed被标记过的任务调用入队函数enqueue_task的时候flag参数需要包含ENQUEUE_DELAYED标记。这样在enqueue_task_fair中执行的时候,会首先检查是否包含这个标记。如果包含这个标记,不会执行后面相对冗长的入队逻辑,而是直接调用更简短的requeue_delayed_entity函数。
requeue_delayed_entity函数的实质内容特别简单,更新sched_avg结构体的内容然后将sched_delayed标记清除。
5.还是会被踢出队列的
开启delayed dequeue特性并非意味着任务不会被真正的踢出运行队列。在下面两种情况下,任务仍然要实质性的出队。
a.任务结束(task_dead_fair中的调用)。
b.任务再次被调度器选中(pick_next_entity中的调用)。
6.总结
事实上,delayed dequeue特性确实对部分情况下的调度逻辑做出了明显的优化,最突出的就是减少了相对冗长的进出运行队列的逻辑执行。但是另一方面,任务实质性出队的时候往往都是给原本调度逻辑增加了部分运行负担。