温暖的电波  

背景

有一次无意间发现/proc/sched_debug中有一个nr_uninterruptible指标特别奇怪,有正数,有负数:

cat /proc/sched_debug | grep nr_uninterruptible
  .nr_uninterruptible            : 18606
  .nr_uninterruptible            : -19061
  .nr_uninterruptible            : 21195
  .nr_uninterruptible            : -20740

我的理解nr_uninterruptible这个不表示状态为(D)TASK_UNINTERRUPTIBLE的任务个数吗,为什么会这样,有点奇怪。

分析

在/proc/sched_debug中的nr_uninterruptible取自于各个cpu的就绪队列rq->nr_uninterruptible。但是它是怎么计算的呢?

代码分析

nr_uninterruptible在任务离开就绪队列时,如果任务是D状态(实际上并不准确,其实还有其他状态的判断,参考task_contributes_to_load(task)函数),则将这个任务当前所在rq->nr_uninterruptible++;

在任务被唤醒的时候都时候,会检查这个任务是否是D状态(同上),如果是则将任务将要运行的目标cpu对应的rq->nr_uninterruptible--

这里有一个情况,任务前一次D状态移出队列的时候可能是在cpuA,此时cpuA对应的就行队列rq[A]->nr_uninterruptilble就会++;但是下一次该任务被唤醒时是调度到cpuB运行,此时是对rq{B}->nr_uninterruptible--;这就造成了各个cpu的nr_uninterruptilble可能会有正值、负值的情况出现。

结论

各个cpu上rq->nr_uninterruptible有正有负是因为任务阻塞离开就绪队列前的cpu与被唤醒时调度运行的cpu并不是绝对一样的;如果一个cpu经常被唤醒的D状态任务调度到上面那rq->nr_uninterruptilble很可能就会变成负数,而一个cpu如果经常有任务发生D状态睡眠,那rq->nr_uninterruptilble很可能就是一个正数。

各个cpu上rq->nr_uninterruptible的总和就是系统中真实的D状态任务个数。

各个cpu上就绪各个cpu上rq->nr_uninterruptible的总和理论上就是系统中D状态任务的总数。

posted on 2022-10-29 08:46  温暖的电波  阅读(159)  评论(0编辑  收藏  举报