第93期 | 门铃响了,手头的活怎么办?
一、门铃响时,先认下人就走
门铃响了,主人正在书房写东西。最省事的待客之道不是放下笔去厨房烧水,而是去门厅打个照面:认下是谁,清掉门铃,记下"有事",转身回书房——手头的活不停。
中断的上半部就是这位门厅主人。只做三件事:认下(读设备状态寄存器,确认是谁敲的门)、清门铃(清除中断源,不然门铃会一直响)、记下(raise_softirq,告诉下半部"有事")。然后立刻返回。为什么必须走?一条铁律:硬中断上下文里没有进程上下文,没有"当前进程"可言,一旦睡眠,调度器无处安放它,整个系统直接僵死¹。
1997 年,Mogul 和 Ramakrishnan 在 DEC 的机器上量出了违反这条铁律的代价:收包越多,中断越密,CPU 全花在进出中断的路上,真正的收包活反而没时间干,吞吐不升反降——receive livelock²。他们的药方就是"上半部几乎不干活":只记下"该轮询了",关掉设备的中断使能,剩下的交给一个轮询线程慢慢干,排空队列再开门。
Linux 把这味药熬了三十年。2.2 的 bottom half 是 32 个静态槽位,串行着跑,简单粗暴;2.4 换成 softirq(可重入、按 CPU 分发)加 tasklet(同一个任务保证不同时跑在两个 CPU 上);2.6 又添了 workqueue——下半部终于也能进进程上下文,可以睡眠了¹。铁律没变,绕路的办法越来越多。
网卡有自己的版本:NAPI。2001 年,Salim、Olsson、Kuznetsov 在 ALS 上发表 "Beyond Softnet"³:第一个包敲门,之后关门转轮询,ksoftirqd 按预算(每轮 64 个包)排空收包队列,空了再开门。他们当年的测试机是双 PII 350MHz、128M 内存——今天手机里一颗小核都比它强,但"敲门转轮询"这招,二十五年没换过。
数一数今天的家底:内核源码里,软中断向量只剩 10 种⁴——HI、TIMER、NET_TX、NET_RX、BLOCK、IRQ_POLL、TASKLET、SCHED、HRTIMER、RCU。三十年前 32 个槽位抢破头,今天 10 种向量各安其位。门厅越小,房子越不堵。
中断处理的三层:硬中断上下文(门厅)只认下、清门铃、记下;下半部(走廊)排队干活;进程上下文(书房)真正执行。1997 年收包活锁的教训——门厅越小,房子越不堵。
二、中断也分轻重缓急
上周有个实测,值得放在本章里。2026 年 10 月 17 日,eunomia.dev 的一篇文章⁵:把 LLM serving 的请求循环搬进内核(BPF 循环 + io_uring),想省掉系统调用边界和一次内存拷贝。结果呢?总 CPU 开销只差 1.1%(FFT 负载)和 1.9%(GEMM 负载)。一个请求 38 微秒,大头是 TCP/IP 栈本身——中断、softirq、skb、TCP 状态机、ACK、发送。Sockmap 跑在 TCP 重组之后,两条路都要交这笔税;进内核省掉的,只是税单上最小的那一行。更扎心的是:GPU 不会主动敲内核的门,BPF 循环得靠一个服务线程去"感知 GPU 做完了",这个线程 71% 的内核采样花在循环协调和 BPF map 操作上;修掉忙轮询的 bug 后,从 1.70 降到 0.63 毫秒/请求;单核上它和网络 softirq 抢 CPU,P99 延迟差出 2.6 倍。
照见的一层是:1997 年 Mogul 点名的那头兽,今天披着 token 的皮回来了。大家默认"进内核=快",却没人问:贵的东西到底在哪一层?答案不在那道门(系统调用)上,在门后的 softirq 里。这篇 1997 年论文的标题,今天可以直接拿来当 LLM serving 的故障复盘标题——机制换了,结构没换。
活化石上周也出现了。2026 年 10 月 23 日,NVIDIA 开发者论坛⁶:Jetson Orin Nano 上双网口同时跑 iperf3 打 UDP,CPU0 被 softirq 淹没,GPU 驱动等 CPU 侧的锁等到 stall,监控显示 GPU 占用 100%——GPU 根本没在算,是在等一个被中断淹死的 CPU。这就是中断饱和,发生在 AI 边缘盒上,昨天。
反例也有:CVE-2026-98381⁷,10 月 9 日披露,veth 的 XDP 收包路径在软中断上下文里踩了空指针,调用栈从 veth_poll 经 __napi_poll、net_rx_action、handle_softirqs,一路走到 "Kernel panic - not syncing: Fatal exception in interrupt"。下半部再"下",也是内核态,没有安全网——下半部里翻车,整个内核陪葬。
推演一句:AI-native OS 的中断,不该再是"把 CPU 叫醒",而是事件流的订阅制。像 NAPI 把"每个包都敲门"变成"按预算轮询"一样,把"每个 token 完成都敲门"变成按预算消费的完成队列;中断亲和性不该按 CPU 时间片排,而该按算力阵列的占用排——GPU 正在跑的核,网卡中断别去凑热闹。范式之眼补一句:线性时代,中断=停下 CPU;向量阵列时代,停下整个阵列的代价大得多,中断的粒度该从"停 CPU"变成"停一路数据流"。
言外之物是这一层:三十年,大家一直在给中断"减负"——BH、softirq、NAPI、线程化中断,全是"怎么让打断更便宜"。却很少有人问:为什么通知必须打断别人?打断本身是一种权力结构:谁有权打断谁,决定了系统的形状。AI OS 的第一课,也许不是更快的中断,而是更少需要打断的设计。
三、数一数你机器上的软中断
手边任何一台 Linux 机器,今晚就能数。三条命令:
cat /proc/interrupts | grep -E 'eth|eno|ens',看网卡中断落在哪个 CPU 上;
watch -n1 'grep NET_RX /proc/softirqs',看收包软中断在各核的分布——全挤在一个核上,就是中断亲和性没调好;
mpstat -I SUM -P ALL 1,看 %softirq 那一列,中断吃掉了几个点的 CPU。
可观察的现象:找台机器跑 iperf3 打流,盯着 NET_RX 那一行往上窜;然后 echo 2 > /proc/irq/<中断号>/smp_affinity,把网卡中断换个核绑,再看分布跟着走。亲手拨一次,比看十遍文档记得牢。
同一张表有四种读法:一台跑本地模型的机器上,推理服务收请求走网卡中断,把网卡队列绑到推理线程之外的核——eunomia 实测里单核上 BPF 循环和 softirq 抢 CPU、P99 差 2.6 倍,就是反面教材;边缘盒上,视频流进、推理出,两路中断别挤在同一个小核上;视频 AI 平台里,摄像头事件走"有事才唤醒"而不是轮询拉流,省的正是 NAPI 当年省下的那笔账;企业私有智能中心里,告警与工单也该像中断一样带优先级进队,而不是让人在库里一遍遍轮询刷——轮询,是中断被发明之前人类唯一的办法。数一遍中断,就是把"系统在忙什么"从感觉变成数字。
觉 然 小 注
门铃响,是外面有事发生,不是麻烦。凡发生必有利于我——中断是系统在告诉你"外面有事",不是来捣乱的。上半部不住于"把活干完",认下就走;下半部不住于"中断上下文",回到可调度的世界。两处无住,门铃响得再密,房子也不堵,心里也不留。⁸
引 用 与 出 处
- [1] Robert Love. Linux Kernel Development. 3rd ed. Addison-Wesley, 2010.(第 7 章 Bottom Halves and Deferring Work)
- [2] J. C. Mogul & K. K. Ramakrishnan. Eliminating Receive Livelock in an Interrupt-driven Kernel. ACM Trans. Computer Systems 15(3):217–252, 1997. https://web.stanford.edu/class/archive/cs/cs240/cs240.1116/readings/cs240-annotated-livelock.pdf
- [3] J. H. Salim, R. Olsson & A. Kuznetsov. Beyond Softnet. Proc. 5th Annual Linux Showcase & Conference (ALS), 2001. https://web.sfc.wide.ad.jp/~irino/old20120217/tmp/usenix-paper/NAPI.pdf
- [4] Linux 内核源码. include/linux/interrupt.h(所核对的文件:软中断枚举 HI/TIMER/NET_TX/NET_RX/BLOCK/IRQ_POLL/TASKLET/SCHED/HRTIMER/RCU,以 NR_SOFTIRQS 收尾,共 10 种). https://git.zx2c4.com/wireguard-linux/plain/include/linux/interrupt.h?id=0685552f2c37531eb2f29faf7918a15b632175c5
- [5] eunomia.dev. Does moving a GPU server's request loop into the kernel save CPU? 2026-10-17. https://eunomia.dev/blog/2026/10/17/bpf-gpu-server/
- [6] NVIDIA Developer Forums. GPU utilization - Jetson Orin Nano. 2026-10-23(提问)/2026-10-27(官方回复). https://forums.developer.nvidia.com/t/gpu-utilization/386629
- [7] CVE-2026-98381. strix.ai. 2026-10-09(发布)/2026-10-24(更新). https://www.strix.ai/cve/CVE-2026-98381
- [8] 鸠摩罗什译《金刚般若波罗蜜经·离相寂灭分第十四》(思想化用)
· · ·