软中断
ddatsh
软中断
点完外卖后,平台虽会显示配送进度,但也不会傻盯着,得去干别的事情,等外卖到了配送员会通过「电话」通知,电话响了,就停下手中地事情,去拿外卖
中断是一种 异步事件处理机制
,可以提高系统的并发处理能力
OS 收到中断请求,会打断其他进程的运行,中断处理程序,要尽可能快的执行完,减少对正常进程运行调度的影响
中断处理程序在响应中断时,可能还会「临时关闭中断」,意味着,如果当前中断处理程序没有执行完之前,系统中其他的中断请求都无法被响应,也就说中断有可能会丢失,所以中断处理程序要短且快
再以外卖为例,点了两份不同的外卖,由不同的配送员来配送
当第一份外卖送到时,配送员给我打了长长的电话,说了一些杂七杂八的事情,比如给个好评等等
如果这时另一位配送员也想给我打电话,因为我在通话中(相当于关闭了中断响应),自然就无法打通我的电话,他可能尝试了几次后就走掉了(相当于丢失了一次中断)
上半部/下半部
Linux 为解决中断处理程序执行过长和中断丢失的问题,将中断过程分成两个阶段,「上半部和下半部分」
- 上半部用来快速处理中断,一般会暂时关闭中断请求,主要负责处理跟硬件紧密相关或者时间敏感的事情
- 下半部用来延迟处理上半部未完成的工作,一般以「内核线程」的方式运行
前面的外卖例子,当接到第一位配送员的电话,可告诉配送员说我现在下楼,剩下等见面再说(上半部),然后就可挂断电话,到楼下后,再拿外卖,及跟配送员说其他的事情(下半部)
这样,第一位配送员就不会占用太多时间,当第二位配送员正好过来时,会有很大几率拨通电话
网卡接收网络包的例子
网卡收到网络包后,通过硬件中断通知内核有新数据到,内核调用对应中断处理程序来响应该事件,事件处理也分成上半部和下半部
上部分要快速处理,只把网卡数据读到内存,然后更新硬件寄存器状态
接着,内核触发软中断,较耗时且复杂的事情,交给「软中断处理程序」,也就是中断的下半部,从内存找到网络数据,按照网络协议栈,对网络数据进行逐层解析和处理,最后把数据送给应用程序
所以,中断处理程序的上部分和下半部可以理解为:
- 上半部直接处理硬件请求,也就是硬中断,主要是负责耗时短的工作,特点是快速执行
- 下半部是由内核触发,也就说软中断,主要是负责上半部未完成的工作,通常都是耗时比较长的事情,特点是延迟执行
硬中断(上半部)会打断 CPU 正在执行的任务,然后立即执行中断处理程序,软中断(下半部)以内核线程的方式执行,且每 CPU 对应一个软中断内核线程
软中断不只包括硬件设备中断处理程序的下半部,一些内核自定义事件也属于软中断,如内核调度等、RCU 锁等
查看中断
- 软中断
cat /proc/softirqs
CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7
HI: 0 0 0 0 0 0 0 0
TIMER: 3235 243 1748 86 7518 264 1329 140
NET_TX: 0 0 0 0 0 0 0 0
NET_RX: 20 32 0 3 8 42 4 9
BLOCK: 2207 0 807 0 0 0 0 0
IRQ_POLL: 0 0 0 0 0 0 0 0
TASKLET: 2834 0 807 0 0 1 0 0
SCHED: 3779 252 1750 89 7522 273 1322 143
HRTIMER: 0 0 0 0 0 0 0 0
RCU: 2910 236 643 75 7372 259 1197 118
- 硬中断
cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7
8: 0 0 0 0 0 0 0 0 IO-APIC 8-edge rtc0
9: 0 0 0 0 0 0 0 0 IO-APIC 9-fasteoi acpi
NMI: 0 0 0 0 0 0 0 0 Non-maskable interrupts
LOC: 16 16 2 16 16 16 16 16 Local timer interrupts
SPU: 0 0 0 0 0 0 0 0 Spurious interrupts
PMI: 0 0 0 0 0 0 0 0 Performance monitoring interrupts
IWI: 0 0 0 0 0 0 0 0 IRQ work interrupts
RTR: 0 0 0 0 0 0 0 0 APIC ICR read retries
RES: 2250 709 2216 376 464 282 358 290 Rescheduling interrupts
CAL: 384 397 378 380 267 164 381 375 Function call interrupts
TLB: 0 0 0 0 0 0 0 0 TLB shootdowns
HYP: 2871 32 807 3 8 42 4 9 Hypervisor callback interrupts
HRE: 0 0 0 0 0 0 0 0 Hyper-V reenlightenment interrupts
HVS: 3295 297 1780 158 8912 312 1354 174 Hyper-V stimer0 interrupts
ERR: 0
MIS: 0
PIN: 0 0 0 0 0 0 0 0 Posted-interrupt notification event
NPI: 0 0 0 0 0 0 0 0 Nested posted-interrupt event
PIW: 0 0 0 0 0 0 0 0 Posted-interrupt wakeup event
这些数值是累计中断次数,大小没什么参考意义,中断次数的变化速率才是我们要关注的,可用 watch -d cat /proc/softirqs
查看中断次数的变化速率
软中断以内核线程方式执行,可用 ps -ef|grep softirq
看到内核线程,一般中括号内线线程都可以认为是内核线程
一般网络 I/O 比较高的 Web 服务器,NET_RX
中断变化速率相比其他中断类型快很多
sar -n DEV
查看网卡包接收速率情况,然后分析是哪个网卡有大量的网络包进来
再通过 tcpdump
抓包等,分析来源,非法的地址可考虑加防火墙,正常流量,要考虑硬件升级等