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的状态还是需要一点时间的。于是,潜在的影响性能的可能在于它会引发调度延迟。

posted on 2025-04-27 20:51  半山随笔  阅读(38)  评论(0)    收藏  举报

导航