什么是软中断,软中断和内部中断的区别

最近,某团外卖的大数据销售火爆。 所谓大数据的销售历史,就是平台用户的数据,分析你是不是钱多的人,或者是不讲究价格的人。 如果是这样的话,买同样的东西会比普通用户贵一些。 一般情况下,不特意比较价格很难发现,所以平台利用它额外赚钱。 说来很可笑,我们作为平台的资深用户,从平台背后偷偷获利。

但大数据成熟已经屡见不鲜,实际上,大多数大平台都存在这种现象,没办法,这才是真正的互联网。

刹车,大数据杀戮的话题到此为止,我们还是回到今天的技术主题:什么是软中断?

什么是中断? 我们先看看什么是中断吧? 在计算机中,中断是系统用来响应硬件设备请求的机制,操作系统从硬件接收中断请求,中断正在运行的进程,调用内核中的中断处理程序来响应请求

这样的说明可能太学术了,容易云里雾里,但我会举出在生活中送外卖的例子。

舒适的时间中午运完砖,肚子饿了,点了白切鸡外卖。 这次带来了闪光点。 我对某个群体的大数据不太熟悉。 虽然平台会显示配送的进展情况,但我也不能一直当傻瓜。 时间很重要。 当然还得做点别的。 配送到达后,配送人员会用“电话”通知我们。 电话响了,停下手里的事去拿外卖。

这里的电话,其实是应对电脑里的中断。 没接电话的时候,我可以做其他的。 我刚接到电话,也就是发生了中断,我就停下目前的事情,去拿别的事情,也就是外卖。

通过该实例可以看出,中断是一种异步事件处理机制,可以提高系统的并发处理能力。

操作系统接收到中断请求,中断其他进程的执行,因此请参阅中断请求的响应程序,也就是中断处理程序,要尽可能快的执行完,这样可以减少对正常进程运行调度地影响。

另外,当中断处理程序响应中断时,它可能会“暂时关闭”中断。 这意味着中断处理程序既短又快,因为在当前中断处理程序未运行之前,它无法响应系统中的其他中断请求,这意味着可能会丢失中断。

还是回到外卖的例子吧。 在舒适的时间一到晚上又点了外卖。 这次为了犒劳自己,点了龙虾和奶茶两个外卖。 然后,不同的配送员配送。 问题是,第一个外卖送到的时候,送货员给我打了很长时间的电话,说了很多杂七杂八的话。 例如,获得好评的时候,另一个配送员也想给我打电话。

很明显,此时,第二个配送员因为我正在通话,所以当然无法挂断我的电话。 他试了几次之后,可能就走了。

什么是软中断? 如前所述,中断请求的处理程序应该短而快,以减少对正常进程执行时间表的影响。 此外,中断处理程序可能会临时关闭中断。 在这种情况下,如果中断处理程序运行时间过长,则在未运行中断处理程序之前,当前来自其他设备的中断请求可能会丢失。

其Linux系统为了解决中断处理程序执行过长和中断丢失的问题,将中断过程分成了两个阶段,分别是「上半部和下半部分」

上半部用来快速处理中断一般暂时关闭中断请求,主要处理与硬件密切相关或时间敏感的事情。

下半部用来延迟处理上半部未完成的工作通常作为“内核线程”工作。

在刚才的外卖例子中,因为第一个配送员长时间和我通话,所以第二个配送员没能打我的电话。 其实,当我接到第一个送货员的电话时,我现在下楼,剩下的事情,等我们见面再说(上半部分),挂了电话,到了楼下,可以送外卖,或者跟送货员说点别的

这样的话,第一个送货员就不会在我的手机上占用太多时间,第二个送货员正好来的时候,大概率会打我的电话。

再举一个计算机的例子,一个常见的网卡接收网络数据包的例子。

当网卡收到网络包时,它通过硬件中断通知内核新数据已到达,内核调用相应的中断处理程序来响应事件。 这个活动的处理也分为上半部分和下半部分。

上面部分为了进行高速处理,请将网卡的数据读取到内存中,将状态更新为表示数据已读取到内存中的状态值等,更新硬件寄存器的状态。

然后,内核调用软中断,将耗时复杂的事情交给“软中断处理程序”。 也就是说,中断的下半部分主要是从内存中查找网络数据,根据网络协议栈对网络数据进行分层分析和处理,最后将数据发送到APP应用程序。

因此,中断处理程序的上半部分和下半部分可以理解为如下。

上半部直接处理硬件请求,也就是硬中断

下半部是由内核触发,也就说软中断主要负责上半部分未完成的工作,通常是一件很费时间的事情,特点是延迟执行;

另一个区别在于,硬中断(上半部分)会中断CPU正在执行的任务,然后立即运行中断处理程序。 软中断(下半部分)在内核线程上运行,每个CPU对应一个软中断内核线程。 名字通常是“ksoftirqd/CPU号码”,例如

0 号 CPU 对应的软中断内核线程的名字是 ksoftirqd/0

不过,软中断不只是包括硬件设备中断处理程序的下半部,一些内核自定义事件也属于软中断,比如内核调度等、RCU 锁(内核里常用的一种锁)等。

系统里有哪些软中断?

在 Linux 系统里,我们可以通过查看 /proc/softirqs 的 内容来知晓「软中断」的运行情况,以及 /proc/interrupts 的 内容来知晓「硬中断」的运行情况。

接下来,就来简单的解析下  /proc/softirqs 文件的内容,在我服务器上查看到的文件内容如下:

你可以看到,每一个 CPU 都有自己对应的不同类型软中断的累计运行次数,有 3 点需要注意下。

第一点,要注意第一列的内容,它是代表着软中断的类型,在我的系统里,软中断包括了 10 个类型,分别对应不同的工作类型,比如 NET_RX 表示网络接收中断,NET_TX 表示网络发送中断、TIMER 表示定时中断、RCU 表示 RCU 锁中断、SCHED 表示内核调度中断。

第二点,要注意同一种类型的软中断在不同 CPU 的分布情况,正常情况下,同一种中断在不同 CPU 上的累计次数相差不多,比如我的系统里,NET_RX 在 CPU0 、CPU1、CPU2、CPU3 上的中断次数基本是同一个数量级,相差不多。

第三点,这些数值是系统运行以来的累计中断次数,数值的大小没什么参考意义,但是系统的中断次数的变化速率才是我们要关注的,我们可以使用 watch -d cat /proc/softirqs 命令查看中断次数的变化速率。

前面提到过,软中断是以内核线程的方式执行的,我们可以用 ps 命令可以查看到,下面这个就是在我的服务器上查到软中断内核线程的结果:

可以发现,内核线程的名字外面都有有中括号,这说明 ps 无法获取它们的命令行参数,所以一般来说,名字在中括号里到,都可以认为是内核线程。

而且,你可以看到有 4 个 ksoftirqd 内核线程,这是因为我这台服务器的 CPU 是 4 核心的,每个 CPU 核心都对应着一个内核线程。

如何定位软中断 CPU 使用率过高的问题?

要想知道当前的系统的软中断情况,我们可以使用 top 命令查看,下面是一台服务器上的 top 的数据:

上图中的黄色部分 si,就是 CPU 在软中断上的使用率,而且可以发现,每个 CPU 使用率都不高,两个 CPU 的使用率虽然只有 3% 和 4% 左右,但是都是用在软中断上了。

另外,也可以看到 CPU 使用率最高的进程也是软中断 ksoftirqd,因此可以认为此时系统的开销主要来源于软中断。

如果要知道是哪种软中断类型导致的,我们可以使用 watch -d cat /proc/softirqs 命令查看每个软中断类型的中断次数的变化速率。

一般对于网络 I/O 比较高的 Web 服务器,NET_RX 网络接收中断的变化速率相比其他中断类型快很多。

如果发现 NET_RX 网络接收中断次数的变化速率过快,接下里就可以使用 sar -n DEV 查看网卡的网络包接收速率情况,然后分析是哪个网卡有大量的网络包进来。

接着,在通过 tcpdump 抓包,分析这些包的来源,如果是非法的地址,可以考虑加防火墙,如果是正常流量,则要考虑硬件升级等。

总结

为了避免由于中断处理程序执行时间过长,而影响正常进程的调度,Linux 将中断处理程序分为上半部和下半部:

上半部,对应硬中断,由硬件触发中断,用来快速处理中断;

下半部,对应软中断,由内核触发中断,用来异步处理上半部未完成的工作;

Linux 中的软中断包括网络收发、定时、调度、RCU 锁等各种类型,可以通过查看 /proc/softirqs 来观察软中断的累计中断次数情况,如果要实时查看中断次数的变化率,可以使用 watch -d cat /proc/softirqs 命令。

每一个 CPU 都有各自的软中断内核线程,我们还可以用 ps 命令来查看内核线程,一般名字在中括号里面到,都认为是内核线程。

如果在 top 命令发现,CPU 在软中断上的使用率比较高,而且 CPU 使用率最高的进程也是软中断 ksoftirqd 的时候,这种一般可以认为系统的开销被软中断占据了。

这时我们就可以分析是哪种软中断类型导致的,一般来说都是因为网络接收软中断导致的,如果是的话,可以用 sar 命令查看是哪个网卡的有大量的网络包接收,再用 tcpdump 抓网络包,做进一步分析该网络包的源头是不是非法地址,如果是就需要考虑防火墙增加规则,如果不是,则考虑硬件升级等。

Published by

风君子

独自遨游何稽首 揭天掀地慰生平