土法炼钢兴趣小组的算法知识备份

【操作系统百科】softirq/tasklet/workqueue

文章导航

分类入口
os
标签入口
#softirq#tasklet#workqueue#bottom-half#ksoftirqd

目录

hardirq 要快——关中断时间越短越好。延迟工作交给下半部(bottom half)。Linux 有三条路。

一、先看图

flowchart TD
    HARDIRQ[硬中断 handler<br/>最小化工作] --> RAISE[raise_softirq<br/>或 schedule_work]
    RAISE --> SOFTIRQ[softirq<br/>静态 10 个<br/>原子上下文]
    RAISE --> TASKLET[tasklet<br/>基于 softirq<br/>退役中]
    RAISE --> WQ[workqueue<br/>内核线程<br/>可睡眠]

    SOFTIRQ --> KSD[ksoftirqd<br/>长尾时接管]

    classDef hard fill:#f85149,stroke:#f85149,color:#adbac7;
    classDef soft fill:#388bfd22,stroke:#388bfd,color:#adbac7;
    classDef wq fill:#3fb95022,stroke:#3fb950,color:#adbac7;
    class HARDIRQ hard
    class RAISE,SOFTIRQ,TASKLET,KSD soft
    class WQ wq

二、softirq

2.1 静态编号

enum {
    HI_SOFTIRQ,
    TIMER_SOFTIRQ,
    NET_TX_SOFTIRQ,
    NET_RX_SOFTIRQ,
    BLOCK_SOFTIRQ,
    IRQ_POLL_SOFTIRQ,
    TASKLET_SOFTIRQ,
    SCHED_SOFTIRQ,
    HRTIMER_SOFTIRQ,
    RCU_SOFTIRQ,
};

只有 10 个固定编号——不能动态添加。

2.2 执行

hardirq 返回时检查 pending softirq → __do_softirq() 处理。

特点:

2.3 ksoftirqd

softirq 处理时间过长 → 避免饿死用户进程 → 切换到 ksoftirqd 内核线程(以 nice 19 运行)。

三、tasklet

DECLARE_TASKLET(my_tasklet, my_func);
tasklet_schedule(&my_tasklet);

基于 TASKLET_SOFTIRQ,动态创建。

特点:

退役趋势:内核社区正在移除 tasklet,替换为 workqueue 或 threaded IRQ。

四、workqueue

DECLARE_WORK(my_work, my_func);
schedule_work(&my_work);           // 系统默认 workqueue
queue_work(my_wq, &my_work);      // 自定义 workqueue

4.1 类型

类型 特点
bound 绑定到提交 CPU
unbound 可在任意 CPU 运行
ordered 串行执行
WQ_POWER_EFFICIENT 低功耗(可能迁移)

4.2 线程池

workqueue 使用 kworker 线程池——不是每 workqueue 一个线程。

ps aux | grep kworker

4.3 可睡眠

workqueue handler 可以睡眠 → 可以分配内存、做 I/O、获取 mutex。

五、threaded NAPI

网络收包高频 → softirq 长尾 → ksoftirqd 延迟高。

Threaded NAPI(5.x+):每 NAPI 实例一个内核线程 → 可调度、可设优先级。

echo 1 > /sys/class/net/eth0/threaded

六、选择指南

场景 推荐
网络收发 softirq(NET_RX/TX)
块 I/O 完成 softirq(BLOCK)
设备驱动通用 workqueue 或 threaded IRQ
需要睡眠 workqueue
旧代码 tasklet 迁移到 workqueue

七、softirq 长尾问题

# 观察 softirq CPU 占用
cat /proc/softirqs
mpstat -P ALL 1 | grep -i soft

NET_RX 占用过高 → 考虑:

八、delayed_work

DECLARE_DELAYED_WORK(my_dwork, my_func);
schedule_delayed_work(&my_dwork, msecs_to_jiffies(100));

延迟执行 + workqueue 能力。

九、观察

cat /proc/softirqs              # per-CPU softirq 计数
cat /proc/interrupts            # hardirq 计数
ps -eo pid,comm | grep kworker  # workqueue 线程
perf top -e irq:softirq_entry   # softirq 热点

十、小结


参考文献

工具


上一篇中断架构 下一篇线程化中断

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-05-06 · os

【操作系统百科】内核内存调试

内核内存 bug 是最难追的:UAF、OOB、double free、leak 都可能沉默数月。本文讲 KASAN 三种模式、KFENCE 生产采样、kmemleak、SLUB_DEBUG、UBSAN/KCSAN 联动。

2026-05-08 · os

【操作系统百科】VFS 四层抽象

Linux 的一切皆文件靠 VFS 实现——superblock、inode、dentry、file 四层抽象加 ops 表。本文讲 VFS 核心数据结构、dcache、inode cache、RCU lookup,以及文件系统如何插入 VFS。

2026-04-22 · os

操作系统百科

Linux 6.x 视角下的操作系统系列索引:110 篇覆盖调度、虚拟内存、文件系统与 I/O、并发、隔离、可观测性,按主题、阅读路径与关键问题三种入口组织。

2026-05-27 · os

【操作系统百科】用户态分配器:jemalloc vs tcmalloc

jemalloc 与 tcmalloc 都想解决多线程分配器的老问题:锁争抢、碎片、RSS 膨胀与回收抖动。但两者把优化重点放在了不同位置:tcmalloc 更激进地把热路径推到 per-CPU,jemalloc 则把 arena、extent、decay 和 profiling 做成了一套更完整的内存治理工具箱。


By .