softirq 与tasklet:从irq_exit 到__do_softirq 的下半部路径

硬中断里只做「应答 + 调度下半部」,重活放到 softirq / tasklet / workqueue 。若把耗时逻辑塞进 hardirq,会出现关抢占过久、延迟尖刺、甚至 soft lockup。本文沿 irq_exit()__do_softirq() 说明下半部何时跑、和 NAPI/定时器的关系,并给出可执行的绑核与观测手段。

源码锚点

路径 作用
kernel/softirq.c __do_softirq()irq_exit 触发、open_softirq
include/linux/interrupt.h request_irqtasklet、softirq 向量声明
kernel/irq/manage.c IRQ 申请与线程化中断
net/core/dev.c NET_RX_SOFTIRQ、NAPI 轮询
kernel/time/timer.c TIMER_SOFTIRQ
Documentation/core-api/irq/irq-domain.rst 中断子系统文档

软中断执行核心(概念):

c 复制代码
/* kernel/softirq.c */
asmlinkage __visible void __softirq_entry __do_softirq(void)
{
	unsigned long end = jiffies + MAX_SOFTIRQ_TIME;
	/* 按 pending mask 依次调用 softirq_vec[nr].action() */
}

注册与触发:

c 复制代码
open_softirq(NET_RX_SOFTIRQ, net_rx_action);
raise_softirq(NET_RX_SOFTIRQ);	/* 或 raise_softirq_irqoff */

调用链

text 复制代码
硬件 IRQ
  → 架构入口 → handle_irq_event
      → action->handler()          /* hardirq:短、不可睡 */
          → 常 raise_softirq / napi_schedule
  → irq_exit()
      → 若不在中断嵌套且有 pending softirq
          → invoke_softirq
              → __do_softirq()
                  → softirq_vec[i].action()
                      ├─ NET_RX_SOFTIRQ → net_rx_action → NAPI poll
                      ├─ TIMER_SOFTIRQ  → run_timer_softirq
                      ├─ TASKLET_SOFTIRQ → tasklet_action
                      └─ ...

若 softirq 跑太久 / ksoftirqd 接管:
  → wake ksoftirqd/<cpu>

驱动常用分层:

text 复制代码
request_irq(handler)
  handler: 清状态、读关键寄存器、napi_schedule / tasklet_schedule
  下半部: 组包、协议栈、耗时处理
更重或可能睡眠: queue_work(system_wq, ...)

重点知识

1. 为何要下半部

hardirq 期间通常关(或延迟)同线中断,逻辑越长,同设备与同 CPU 延迟越大。softirq 仍在软中断上下文(不可睡眠),但可批量、可延期到 ksoftirqd

2. softirq vs tasklet vs workqueue

机制 可睡眠 典型用途
softirq 网络 RX/TX、timer、block 等高频
tasklet 驱动轻量延后(同 CPU 串行化语义)
workqueue 可能阻塞的收尾、与用户态交互

新代码更常见 threaded IRQrequest_threaded_irq)或 NAPI,而不是手写 tasklet。

3. 中断亲和与多队列

bash 复制代码
# IRQ 绑核
cat /proc/interrupts
echo <mask> > /proc/irq/<n>/smp_affinity
# 网卡多队列 + XPS/RPS(按需)
ls /sys/class/net/eth0/queues/

IRQ 全堆 CPU0 时,同核 softirq 也会挤在一起,表现为单核 100%、其它核空闲。

4. 时间与观测

bash 复制代码
cat /proc/softirqs
watch -n1 cat /proc/softirqs
perf top -e irq:softirq_entry
# 延迟
cyclictest -p 90 -i 1000 -l 10000   # 实时评估环境

5. 设计意图与踩坑

  • 意图:硬中断极短,吞吐型工作在 softirq/NAPI 批处理。
  • :在 hardirq 里 mutex_lock / 打印刷屏。
  • :softirq 里睡------直接 BUG。
  • :忽略 ksoftirqd 占满,只盯硬中断计数。
  • :时间相关逻辑用可回拨的 wall clock;超时用 CLOCK_MONOTONIC

Checklist

  • hardirq handler 只做应答与调度下半部,无睡眠 API
  • 能指出 irq_exit__do_softirq 的触发条件
  • 按场景选 softirq / threaded IRQ / workqueue
  • /proc/interrupts/proc/softirqs 确认未单核打满
  • 高 PPS 网卡检查 NAPI 与中断聚合(coalescing)
  • 延迟敏感线程验证未与重 softirq 同核恶性争抢
相关推荐
tqs_1234519 分钟前
值传递与引用传递
java·开发语言·python
YsyaaabB21 分钟前
Deep Agents 实战课程
python·langchain
金銀銅鐵21 分钟前
斐波那契数列中连续10项的和总是能被11整除吗?
python·数学
databook23 分钟前
用 Python 计算联合概率和条件概率
python·数据分析
葡萄成熟时 !1 小时前
泛型知识笔记
开发语言·笔记·python
fengyangaiGEO1 小时前
GEO 如何分析竞品的 AI 引用情况?
人工智能·python·信息可视化
2601_966949652 小时前
实时行情中的成交量 Volume 到底是什么?包含盘中撤单量吗?从交易数据语义到 QuantDash 实战解析
开发语言·人工智能·python·量化·quantdash·量化数据源
you鬰2 小时前
datawhale--llm-algo-leetcode9️⃣ SFT Training Loop
python·datawhale
叫我:松哥2 小时前
基于flask仿小米商城管理系统,使用flask开的一个商场网站
数据库·后端·python·flask