2. 中断基础回顾:中断概念、中断类型与处理流程
中断是硬件与操作系统之间进行异步通信的核心机制。在 Linux 驱动开发与性能调优中,理解中断的底层原理是配置中断亲和性、优化多核负载均衡的前提。本节将系统回顾中断的基本概念、分类方式以及 Linux 内核中的经典处理模型——上半部与下半部。
2.1 中断概念
中断(Interrupt)是一种由硬件或软件触发的信号,用于通知处理器发生了需要立即关注的事件。与轮询(Polling)不同,中断机制允许 CPU 在无事时执行其他任务,仅在事件发生时暂停当前工作并响应中断,从而大幅提升系统效率。
核心特性:
- 异步性:中断的发生与 CPU 当前执行的指令流无关。
- 优先级:不同中断源具有不同的优先级,高优先级中断可抢占低优先级中断。
- 可屏蔽性:部分中断可通过 CPU 的标志位暂时屏蔽(Maskable),非可屏蔽中断(NMI)则不可屏蔽。
2.2 中断类型
Linux 内核将中断分为三大类:硬件中断(IRQ)、非可屏蔽中断(NMI)和软中断(SoftIRQ)。它们在触发源、处理方式和应用场景上存在显著差异。
| 中断类型 | 触发源 | 可屏蔽性 | 典型用途 | 处理上下文 |
|---|---|---|---|---|
| IRQ(硬件中断) | 外部硬件设备(网卡、磁盘、键盘等) | 可屏蔽(IF 标志位) | I/O 完成通知、DMA 传输结束 | 中断上下文(原子、不可睡眠) |
| NMI(非可屏蔽中断) | 硬件故障(内存 ECC 错误、看门狗超时) | 不可屏蔽 | 系统崩溃转储、硬件错误处理 | 特殊中断上下文 |
| 软中断(SoftIRQ) | 软件主动触发(内核代码调用) | 可延迟/可抢占 | 网络协议栈处理、定时器、任务调度 | 软中断上下文(可睡眠受限) |
调优注意:NMI 通常用于硬件故障诊断,在正常调优中较少直接干预。IRQ 和软中断是多核中断亲和性配置的主要对象,尤其是高吞吐网卡和存储设备的 IRQ 分配。
2.3 中断处理流程:上半部与下半部
Linux 内核将中断处理拆分为两个阶段,以平衡响应速度与处理复杂度:
- 上半部(Top Half):在中断上下文中立即执行,必须快速完成(通常微秒级)。负责确认中断、保存关键硬件状态、调度下半部。不可睡眠、不可持有锁。
- 下半部(Bottom Half):在更宽松的上下文中延迟执行,可处理复杂逻辑。Linux 提供三种下半部机制:软中断(SoftIRQ)、Tasklet、工作队列(Workqueue)。
2.4 下半部机制对比与选择
在驱动开发中,选择正确的下半部机制直接影响系统吞吐量和延迟。下表总结了三种机制的关键差异:
| 特性 | 软中断 (SoftIRQ) | Tasklet | 工作队列 (Workqueue) |
|---|---|---|---|
| 执行上下文 | 软中断上下文 | 软中断上下文 | 进程上下文 |
| 可睡眠 | 否 | 否 | 是 |
| 并发性 | 同一类型可多核并行 | 同一 Tasklet 串行执行 | 可多 worker 并行 |
| 延迟要求 | 极低(网络关键路径) | 低 | 中等 |
| 典型场景 | 网络协议栈、块 I/O 层 | 简单设备驱动下半部 | 复杂处理、文件系统操作 |
调优提示:在多核系统中,软中断的并行执行能力使其成为高性能网络驱动的首选。但软中断处理函数必须可重入,且不能持有自旋锁过长。对于需要睡眠或持有互斥锁的操作,必须使用工作队列。
2.5 中断上下文与进程上下文
理解中断上下文与进程上下文的区别,是编写正确驱动代码的基础:
- 中断上下文:运行在中断服务程序(ISR)或软中断中,不可睡眠,不可访问用户空间,不可持有可睡眠锁。当前进程指针(current)不可靠。
- 进程上下文:运行在用户进程或内核线程中,可睡眠,可访问用户空间,可使用所有锁机制。
在中断亲和性调优中,我们主要关注 IRQ 和软中断在 CPU 核心上的分布。错误的亲和性配置会导致某些核心过载,而其他核心空闲,从而引发性能瓶颈。