背景
有一次无意间发现/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状态任务的总数。
标签:uninterruptible,rq,percpu,状态,任务,nr,cpu From: https://www.cnblogs.com/liuhailong0112/p/16832149.html