1. 概述
中断其实是一种异步的事件处理机制,可以提高系统的并发处理能力。Linux 将中断处理过程分成了两个阶段,也就是上半部和下半部:
- 上半部用来快速处理中断,它在中断禁止模式下运行,主要处理跟硬件紧密相关的或时间敏感的工作。
- 下半部用来延迟处理上半部未完成的工作,通常以内核线程的方式运行。
举个最常见的网卡接收数据包的例子。当网卡接收到数据包时,会通过硬件中断通知内核。内核响应这个中断,分为两个阶段:上半部和下半部。
上半部(硬中断):
- 任务:快速处理硬件请求。
- 过程:网卡的数据被读到内存中,硬件寄存器的状态被更新,随后发送软中断信号通知下半部进行进一步处理。
- 特点:上半部的处理必须尽快完成,以避免阻塞其他硬件中断,因此执行时间较短。
下半部(软中断):
- 任务:处理更复杂的工作,比如从内存中解析网络数据,逐层处理网络协议栈,最终将数据交给应用程序。
- 过程:由软中断内核线程(如
ksoftirqd/0)唤醒执行。每个 CPU 都有一个对应的软中断线程。 - 特点:软中断通常是延迟执行的,它不立即响应硬件请求,而是稍后在空闲时处理任务。
总结:
- 上半部(硬中断)快速响应硬件事件并完成基本处理。
- 下半部(软中断)延迟执行,处理更复杂的任务,通常由
ksoftirqd线程执行。
软中断不仅仅处理硬件中断的下半部,还包括内核调度、RCU 锁等任务。
如何查看?
- /proc/softirqs 提供了软中断的运行情况;
- /proc/interrupts 提供了硬中断的运行情况。
软中断
$ cat /proc/softirqs
CPU0 CPU1
HI: 0 0
TIMER: 811613 1972736
NET_TX: 49 7
NET_RX: 1136736 1506885
BLOCK: 0 0
IRQ_POLL: 0 0
TASKLET: 304787 3691
SCHED: 689718 1897539
HRTIMER: 0 0
RCU: 1330771 1354737
硬中断
root@calvin:~# cat /proc/interrupts
CPU0 CPU1
1: 9 0 IO-APIC 1-edge i8042
6: 23 0 IO-APIC 6-edge floppy
8: 0 0 IO-APIC 8-edge rtc0
9: 1 0 IO-APIC 9-fasteoi acpi
12: 0 163 IO-APIC 12-edge i8042
14: 0 0 IO-APIC 14-edge ata_piix
15: 49863 0 IO-APIC 15-edge ata_piix
NMI: 0 0 Non-maskable interrupts
LOC: 440 366 Local timer interrupts
SPU: 0 0 Spurious interrupts
PMI: 0 0 Performance monitoring interrupts
IWI: 387 355 IRQ work interrupts
RTR: 0 0 APIC ICR read retries
RES: 7176138 8463277 Rescheduling interrupts
CAL: 6861 6039 Function call interrupts
TLB: 0 0 TLB shootdowns
TRM: 0 0 Thermal event interrupts
THR: 0 0 Threshold APIC interrupts
DFR: 0 0 Deferred Error APIC interrupts
MCE: 0 0 Machine check exceptions
MCP: 161 161 Machine check polls
HYP: 6926152 4474577 Hypervisor callback interrupts
ERR: 0
MIS: 0
PIN: 0 0 Posted-interrupt notification event
NPI: 0 0 Nested posted-interrupt event
PIW: 0 0 Posted-interrupt wakeup event
软中断的注意事项
- 软中断的类型:
-
- 软中断分为多种类型,每种类型对应不同的工作任务。常见类型包括:
-
-
- NET_RX:网络接收中断。
- NET_TX:网络发送中断。
-
-
- 每种软中断类型都负责不同的工作,通常通过第一列标识。
- 软中断在不同 CPU 上的分布:
-
- 同一种软中断通常在不同 CPU 上的分布应该大致相同,累积次数相差不大。例如,NET_RX 在 CPU0 和 CPU1 上的中断次数应该差不多。
- 如果分布不均,可能说明某些 CPU 在处理软中断时不平衡。
- TASKLET 机制:
-
- TASKLET 是一种常用的软中断实现机制。每个 TASKLET 只会在其调用所在的 CPU 上执行一次。
- 问题:
-
-
- 调度不均衡:由于 TASKLET 只在一个 CPU 上运行,可能导致负载不均衡。
- 并行性问题:只能在单个 CPU 上运行,限制了并行处理能力,影响性能。
-
- 软中断内核线程(ksoftirqd) :
-
- 每个 CPU 上都对应一个软中断内核线程,线程名称为 ksoftirqd/CPU 编号(例如,ksoftirqd/0 对应 CPU 0)。
- ksoftirqd 负责执行软中断任务,确保软中断得以处理。
查看软终端线程运行状态
$ ps aux | grep softirq
root 7 0.0 0.0 0 0 ? S Oct10 0:01 [ksoftirqd/0]
root 16 0.0 0.0 0 0 ? S Oct10 0:01 [ksoftirqd/1]