cpu0 SCHED_SOFTIRQ异常升高的问题解释
如果在一个非0的cpu上绑定2个任务,top -1可能观察到cpu0 si升高的问题。严重的可能为10~20%。
watch "cat /proc/softirqs | awk '{print \$1,\$2}'"
观察到是SCHED类型的软中断。该类型的软中断是load balance引起的。由于周期性的load balance发生在有timer中断的cpu上,newidle发生在频繁进出idle状态的cpu。对于cpu0的情形,唯一的可能是nohz idle。那么必然有cpu在向cpu0发生nohz idle load balance请求。无疑这个cpu就是我们之前绑定两个task的那个cpu。
在下面的kernel代码中,我们可以发现nohz idle在发生时的选核逻辑。
static inline int find_new_ilb(void) { int ilb; for_each_cpu_and(ilb, nohz.idle_cpus_mask, housekeeping_cpumask(HK_FLAG_MISC)) { if (idle_cpu(ilb)) return ilb; } return nr_cpu_ids; }
也就是从小往大选择cpu,如果cpu0处在nohz状态,cpu0第一个被选中。由于每次发生timer中断的时候才会发出nohz idle balance,于是每次都会向cpu0发出请求。cpu0 si升高就可以理解了。
大家下意识地会认为si升高必然会导致性能下降,但是对于SCHED softirq,它是发生在nohz的cpu上,也就是该cpu处在idle状态,并没有什么任务,做点load balance出来费电似乎也不会带来什么性能损失。一旦有任务到来,nohz状态退出,SCHED softirq就会转移到别的core上。
但是,如果cpu0正在处理si,想要快速进入到处理workload的状态还是需要一点时间的。于是,潜在的影响性能的可能在于它会引发调度延迟。
浙公网安备 33010602011771号