sched discussion
[PATCH 5.10 001/699] nvmet-tcp: fix race between ICReq handling and queue teardown
LLM 分析
Linux 稳定版:5.10.261-rc1 大规模补丁审查
系列概况
- 标题:
5.10.261-rc1 review - 作者:Greg Kroah-Hartman;各个补丁由不同子系统维护者和贡献者提供。
- 版本:5.10.261-rc1。
- 规模:cover letter 加 699 个补丁,共 700 个 patch 条目;输入线程另含 13 封回复/测试反馈,总计 713 封邮件。
- 修改文件:覆盖网络、文件系统、I2C、USB、Bluetooth、KVM、perf、sched、媒体、输入、存储、架构等大量目录;完整文件清单和总 diffstat 未在输入中可靠提供。
- 代码统计:cover letter 只说明包含 699 个补丁;本输入没有可用于重建全系列总增删行数的完整 diffstat。
- Message-ID:
20260721152355.667394603@linuxfoundation.org - 完整性:线程声明的 699 个 patch 和输入中的 13 封回复均出现;但许多 patch 邮件正文为空,无法对这些条目进行代码级翻译或逐行分析。
该线程虽然来自 sched 频道,也包含 sched/rt、sched/fair、net/sched、perf sched 等调度相关补丁,但整体不是单一 scheduler 设计讨论,而是一次跨子系统的 5.10 LTS 稳定版集中审查。
补丁目的
这组补丁的总体目标是把已经进入上游或相关稳定分支的修复回植到 Linux 5.10,形成 5.10.261 候选版本。
它重点处理:
- UAF、double-free、引用计数泄漏、竞态和死锁;
- 越界读写、整数溢出、未初始化数据和错误的边界校验;
- 设备注册、probe、remove、CPU hotplug 和 work/timer teardown 的生命周期问题;
- scheduler、qdisc 与 perf 工具在 CPU 亲和性、数据竞争、队列状态和回放路径上的正确性问题。
旧流程的问题
在旧代码中,很多问题并非正常路径立即触发,而是在 teardown、错误回滚、异步 work、RCU 或异常输入与正常操作交错时暴露:
- 对象已经进入释放阶段,但异步任务仍能把状态改回“活跃”。
- 外部输入提供的长度、计数、索引未经验证就参与数组或缓冲区访问。
- 资源注册顺序与 bus notifier、debugfs 或 IDR 查询顺序不一致。
- 回滚路径只恢复了部分状态,留下与实际缓冲区或引用计数不一致的状态机。
- scheduler/qdisc/perf 工具读取的数据可能属于不允许的 CPU、错误的队列状态或尚未初始化的对象。
新流程
稳定版采用“逐补丁回植、逐补丁审查”的方式:
- stable maintainer 发布 cover letter 和补丁列表。
- 每个补丁保留上游 commit message、Fixes、Reviewed-by、Tested-by 等元数据。
- 对 5.10 不存在的结构、字段或 API 做上下文适配。
- 通过编译、架构测试、功能测试和子系统维护者 review。
- 在候选版本中继续收集反对意见,必要时撤回或修正补丁。
典型修复模式是:先验证输入或对象状态,再在正确的锁/RCU/work 生命周期下更新状态,最后沿统一错误路径释放资源。
Patch 概览
- 生命周期与并发:
nvmet-tcp队列 teardown、I2C adapter 注册、PPP timer、Bluetooth、binder、USB disconnect、xfrm state 删除等。 - 文件系统与存储:nfsd、f2fs、xfs、btrfs、ocfs2、NFS flexfiles、FUSE、HFS/HFS+、UDF、device-mapper。
- 网络与安全:netfilter、ipset、GRE/tunnel netns 权限、BPF sockmap、SCTP、IPVS、BATMAN-adv、AppArmor。
- 调度相关:
sched/rt、sched/fair、net/sched的 HFSC/HTB/DRR/CODEL/FQ_CODEL/CAKE/MULTIQ,以及perf sched。 - 设备与工具:USB、IIO、ALSA、HID、PCI、RDMA、perf tools、tracing 和多种 SoC 驱动。
- 关联补丁:输入中明确标出若干
Stable-dep-of关系,例如 f2fs、nfsd、I2C 等;这些不是新的独立 scheduler 系列,而是为 5.10 回植补丁补齐依赖。
关键实现
1. nvmet-tcp:锁住队列状态转换
nvmet_tcp_handle_icreq() 在发送 ICResp 后修改 queue state。旧逻辑没有和 teardown 串行化,可能出现:
/* Conceptual flow */
send_icresp();
lock(state_lock);
if (queue->state == NVMET_TCP_Q_DISCONNECTING) {
unlock(state_lock);
return -ESHUTDOWN;
}
queue->state = NVMET_TCP_Q_LIVE;
unlock(state_lock);
如果 teardown 已经将状态改为 NVMET_TCP_Q_DISCONNECTING,处理路径不再把它改回 LIVE;内部 -ESHUTDOWN 也不会被误报为普通传输错误。接收状态保持 RECV_ERR,避免同一个 ICReq 被再次解析。
2. I2C:先初始化,再发布到 IDR
I2C 修复重新安排 adapter 生命周期:
- 先初始化嵌入的
struct device; - 创建 debugfs 目录;
- 把 adapter 放入 IDR,但暂时存放空值;
- 完成设备注册后再用
idr_replace()发布真正对象; - 任何失败路径统一注销 clients、释放 IRQ domain 和 device 引用。
这避免 i2c_get_adapter() 或 bus notifier 在对象尚未初始化时访问它。
3. f2fs:在 foreground GC 前提交缓存 BIO
f2fs 空间不足时,writeback 和 GC 可能同时等待同一 folio。补丁在触发 GC 前提交合并的 OPU/IPU DATA BIO,从而降低“持有 folio 锁的写回路径等待 GC,而 GC 又等待该 folio”的死锁风险。
同时,多个 f2fs 补丁将涉及 section 容量的计算从 BLKS_PER_SEC() 调整为 CAP_BLKS_PER_SEC(),并校验 orphan entry count、inline xattr 大小和 xattr 存储边界。
4. scheduler 与 perf 相关补丁
sched/rt:非PREEMPT_RT配置下,RT_PUSH_IPI默认关闭,避免不必要的实时任务 push IPI 行为。sched/fair:寻找目标调度组时,只更新允许 CPU 的统计信息,避免把 cpuset 外 CPU 的负载纳入决策。net/sched:为 qdisc 统计中的并发字段添加 data-race 注解,并修正 peek/dequeue 时 backlog 和队列长度的恢复顺序。perf sched:补齐mmap2事件处理,修复 idle histogram 的红黑树遍历方式,并在初始化失败或回放事件缺失时清理/检查 NULL。
这些改变不是重新设计调度器,而是让已有调度、队列和调试工具在边界状态下遵守原有不变量。
类比
可以把整个稳定版审查看成一座仍在营业的车站进行夜间检修:
state_lock像站长手里的总钥匙,列车关闭站台后,任何工作人员都不能偷偷把站台重新标成开放。kref、IDR 和 RCU 像车票、登记簿和候车区;对象已经从登记簿移除后,不能再凭旧票访问。- 长度、计数和索引校验像检票口检查票面范围,防止乘客拿着“999 号站台”的票闯入不存在的区域。
- scheduler/fair 的 allowed CPU 规则像只统计当前确实开放的站台,不能把封闭站台的客流量算进调度决策。
- stable review 则像逐辆列车验收,而不是一次性更换整座车站;每个补丁都必须适合老站房 5.10 的结构。
[5.10.261-rc1 cover]
|
v
[699 patches]
| |
v v
[build/test] [maintainer review]
| |
+---+---+
|
v
[apply to 5.10.y] ---> [release 5.10.261]
|
+--> [reject / revise]
Highlight:风险与注意点
- 这是跨子系统稳定版线程,不应把它误解为单一 scheduler RFC 或单个 scheduler bug。
- 大量邮件正文为空;对这些条目只能确认标题和序列位置,不能编造 diff、测试结果或具体实现。
- 5.10 回植包含上下文适配,例如缺少新字段/API 时删除对应 hunk;不能直接把上游源码逐字套回 5.10。
- 许多修复依赖严格的锁、RCU、引用计数或 work/timer teardown 顺序;只看新增的一行检查而忽略生命周期上下文,可能误判补丁安全性。
- cover letter 给出审查截止时间为 2026-07-23 15:23 UTC;线程中关于 tracing patch 137 的回复集中讨论了 5.10 上的回植语义和私有实现,说明 stable backport 仍需检查分支差异。
- 输入没有完整 aggregate diffstat,因此不能可靠报告整个 699-patch 系列的总增删行数。
版本变化
输入只显示 5.10.261-rc1,没有同一系列的 v2、v3 或 rc2 邮件,因此没有可比较的 vN→vN+1 演进记录。线程中的少量上下文适配和 Stable-dep-of 标记属于 5.10 回植处理,不应视为该系列的正式版本迭代。
一句话总结
这是一次包含 scheduler 相关修复在内的 5.10.261-rc1 跨子系统稳定版审查,核心价值是通过边界校验、正确的锁与生命周期顺序,消除大量并发、资源释放和异常输入问题。