1. 中断基础概念

中断(Interrupt)是现代操作系统响应异步事件的基石。在 Linux 内核中,中断机制允许 CPU 暂停当前执行流,转而处理更高优先级的硬件或软件事件,处理完成后再恢复原执行流。理解中断的基础概念是掌握中断负载均衡与调度延迟分析的先决条件。

1.1 中断定义与核心作用

中断是一种由硬件或软件触发的信号,用于通知 CPU 发生了需要立即关注的事件。其核心作用包括:

  • 异步响应:CPU 无需轮询设备状态,由设备主动通知,大幅提升 CPU 利用率。
  • 优先级抢占:高优先级中断可打断低优先级中断或普通进程,保证实时性。
  • 系统调用入口:x86 架构下,int 0x80 或 syscall 指令本质上是软件中断,用于陷入内核。
性能视角: 中断处理的开销直接影响系统吞吐量。每次中断涉及上下文保存、中断向量查找、中断服务例程执行、上下文恢复等步骤,微秒级的延迟在高频 I/O 场景下会累积为显著的性能瓶颈。

1.2 中断类型:硬件中断与软件中断

Linux 内核将中断分为两大类,其触发源、处理方式和性能特征存在本质差异:

特性 硬件中断 (Hardware Interrupt) 软件中断 (Software Interrupt)
触发源 外部硬件设备(网卡、磁盘、定时器) CPU 执行指令(int、syscall、异常)
触发方式 异步,与 CPU 当前执行流无关 同步,由当前执行指令主动触发
可屏蔽性 可屏蔽中断(INTR)可通过 cli 指令关闭 不可屏蔽(异常、陷阱)或通过软件标志控制
处理上下文 中断上下文(不可睡眠、不可调度) 进程上下文(系统调用)或中断上下文(软中断)
典型例子 网卡 RX/TX 中断、磁盘 DMA 完成中断 int 0x80 系统调用、缺页异常、软中断 NET_RX_SOFTIRQ
关键区分: 硬件中断是“外来的”,CPU 被动响应;软件中断是“内生的”,CPU 主动触发。在 Linux 中断负载均衡中,我们主要关注硬件中断在多个 CPU 之间的分发策略,因为软件中断通常跟随触发它的 CPU 执行。

1.3 中断向量表 (Interrupt Vector Table, IVT)

中断向量表是 CPU 用于将中断号映射到对应处理程序入口地址的数据结构。在 x86 架构的保护模式下,该表称为 中断描述符表 (IDT),由 lidt 指令加载。

IDT 的每个表项(门描述符)包含以下关键字段:

  • 段选择子:指向代码段描述符,用于确定中断处理程序所在的代码段。
  • 偏移量:处理程序在代码段内的起始地址。
  • 门类型:任务门、中断门、陷阱门,决定中断处理时的 CPU 行为(是否自动关中断)。
  • DPL:描述符特权级,控制用户态能否通过 int 指令触发该中断。

Linux 内核在启动阶段初始化 IDT,典型的中断号分配如下:

中断号 (Vector) 用途 类型
0 – 19 CPU 异常(除零、缺页、保护错误等) 软件中断(同步)
32 – 255 外部硬件中断(IRQ 0 – IRQ 223) 硬件中断(异步)
128 (0x80) 系统调用入口(传统模式) 软件中断(同步)
性能陷阱: 中断向量表的查找是中断处理的第一级延迟。现代 CPU 使用 中断重定向(如 Intel VT-d)和 MSI/MSI-X 机制绕过传统的 PIC/IOAPIC 路由,直接向指定 CPU 发送中断,减少向量查找和总线仲裁开销。
中断向量表 (IDT) 与中断处理流程 硬件设备 CPU 指令 I/O APIC 中断路由 向量映射 中断描述符表 (IDT) Vector 0: #DE 除零 Vector 14: #PF 缺页 Vector 32: IRQ 0 定时器 Vector 128: syscall CPU 执行 ISR 中断处理流程 ① 硬件设备/CPU 指令触发中断 → ② I/O APIC 根据中断号查找路由表,确定目标 CPU 和向量 ③ CPU 根据向量号在 IDT 中查找门描述符 → ④ 跳转到中断服务例程 (ISR) 执行

1.4 中断上下文 (Interrupt Context)

中断上下文是 Linux 内核中一个特殊的执行环境,与进程上下文有严格区别。当 CPU 响应中断时,内核会从当前进程上下文切换到中断上下文,执行中断服务例程 (ISR)。

中断上下文的核心约束:

  • 不可睡眠:中断上下文不关联任何进程,没有 task_struct,无法调用 schedule() 或等待队列。
  • 不可持有锁:如果 ISR 中获取自旋锁,必须使用 spin_lock_irqsave() 等变体,防止死锁。
  • 栈空间有限:每个 CPU 有独立的中断栈(通常 4KB – 16KB),栈溢出会导致内核崩溃。
  • 不可访问用户空间:中断上下文无法访问当前进程的用户态地址空间。
性能优化要点: 中断上下文应尽可能短小。Linux 内核通过 下半部机制(软中断、tasklet、工作队列)将耗时操作推迟到更宽松的上下文中执行,从而降低中断关闭时间,减少调度延迟。

1.5 中断上下文 vs 进程上下文对比

对比维度 中断上下文 进程上下文
关联进程 无,current 宏指向被中断的进程 有,current 指向当前运行进程
可睡眠 否 是
可调度 否 是
可访问用户空间 否 是
栈大小 4KB – 16KB(独立中断栈) 8KB – 16KB(内核栈)
典型操作 ACK 中断、拷贝数据、触发软中断 系统调用、文件读写、内存分配
中断上下文切换流程 时间轴 进程上下文 用户态/内核态 中断发生 中断入口 保存寄存器 ISR 执行 中断上下文 中断 出口 恢复寄存器,返回原进程 中断上下文生命周期 ① 中断触发 → CPU 自动保存 EFLAGS、CS、EIP 到内核栈 ② 进入中断上下文,执行 ISR → ③ ISR 返回后,CPU 执行 iret 恢复上下文 ④ 整个过程中,当前进程被“冻结”,调度器不会切换进程

1.6 中断处理中的性能关键指标

在后续章节的中断负载均衡分析中,以下指标将反复出现:

指标 定义 对性能的影响
中断延迟 从硬件触发中断到 ISR 开始执行的时间 影响实时性和 I/O 吞吐量
中断处理时间 ISR 从开始到返回的总执行时间 过长会阻塞其他中断和进程调度
中断频率 单位时间内中断触发的次数 高频中断可能导致 CPU 被“淹没”
中断亲和性 中断被路由到特定 CPU 的配置 不合理的亲和性导致 CPU 负载不均
学习路径提示: 掌握中断基础概念后,下一章将深入分析 /proc/interrupts、/proc/softirqs 等内核接口,以及如何通过 smp_affinity 实现中断负载均衡。建议读者在实验环境中运行 cat /proc/interrupts 观察实际中断分布。