云计算百科
云计算领域专业知识百科平台

Linux 内核锁机制:原理与实现 · 专栏目录

本专栏以"内核为什么需要这么多种锁,每一种到底怎么实现"为主线,从最底层的原子操作与内存屏障出发,逐层向上:先讲不睡眠的自旋类锁(spinlock/qspinlock/qrwlock/osq_lock),再讲可阻塞的睡眠类锁(mutex/rwsem),最后落到无锁与特化原语(ww_mutex/seqcount)。每一篇统一回答四个问题——守护什么、为什么用它、怎么实现(源码级)、误用与调试。本专栏与《MMU Notifier 深入解析》互为地基与用例:通用锁原理在此,GPU/HMM 场景应用见 mmu-notifier 专栏。

第一部分:地基

所有锁最终都建立在两块基石上:原子操作保证"读-改-写"不可分割,内存屏障约束多核间的可见顺序。不理解 acquire/release 语义,就无法理解任何一把锁的正确性。本部分是通读全专栏的前提。

章标题内容简介
1 原子操作与内存屏障:一切锁的地基 atomic_t/atomic64_t 的实现、READ_ONCE/WRITE_ONCE、smp_mb/rmb/wmb、acquire/release/fence 语义,以及"锁 = 原子操作 + 屏障 + 等待策略"的总纲。源码:include/linux/atomic.h、Documentation/memory-barriers.txt

第二部分:自旋类(不睡眠)

临界区极短、且可能处于不可睡眠上下文(中断、原子区)时,应当自旋而非睡眠。本部分从最朴素的 spinlock 讲到 qspinlock 如何用 MCS 队列消除多核 cache-line 争用,再看读写自旋锁 qrwlock 与乐观自旋的公共底座 osq_lock。

章标题内容简介
2 spinlock 与 qspinlock:从测试-设置到 MCS 队列 spinlock_t 的语义与不睡眠约束,qspinlock 的四字节状态编码与 MCS 队列如何把"所有 CPU 争一条 cache line"降为"各自自旋在本地节点"。源码:kernel/locking/spinlock.c、kernel/locking/qspinlock.c、kernel/locking/mcs_spinlock.h
3 rwlock 与 qrwlock:读者写者的自旋权衡 读多写少场景下的读写自旋锁,qrwlock 的读写计数编码与写者优先策略如何避免写者饥饿。源码:kernel/locking/qrwlock.c
4 osq_lock:乐观自旋队列 MCS 变体,mutex/rwsem 乐观自旋的底座:持锁者仍在运行时排队自旋而非立即睡眠,兼顾低延迟与可扩展。源码:kernel/locking/osq_lock.c、kernel/locking/mcs_spinlock.h

第三部分:睡眠类(可阻塞)

临界区较长、或临界区内需要阻塞(等 I/O、等 DMA、拿其它睡眠锁)时,应当睡眠让出 CPU。本部分拆解两把最主流的睡眠锁:mutex 的乐观自旋 + handoff 防饥饿,以及 rwsem 的读写计数编码与 writer 偷锁——后者正是 mmu-notifier 专栏附篇里 drm_gpusvm 那把 notifier_lock 的本体。

章标题内容简介
5 mutex:乐观自旋与 handoff mutex 的 owner 指针 + MUTEX_FLAG 低位编码、乐观自旋(持锁者在跑就自旋)、handoff 机制如何防止长期饥饿。源码:kernel/locking/mutex.c、kernel/locking/mutex.h
6 rwsem:读写信号量的计数编码与偷锁 count 字段的读者计数/写者位/等待位编码、writer 乐观偷锁、读者与写者的公平性。呼应 mmu-notifier 专栏附篇《drm_gpusvm 的 notifier_lock 深解》。源码:kernel/locking/rwsem.c、include/linux/rwsem.h

第四部分:无锁与特化

这两篇跳出"互斥"范式:ww_mutex 解决"一次要拿多把锁"的死锁避免,是 DRM/dma-resv 与 GPU 显存驱逐的基石;seqcount 则用序号碰撞重试实现读侧几乎零开销的一致性检查,与 mmu-notifier 专栏第 3 章的 invalidate_seq 一脉相承。

章标题内容简介
7 ww_mutex:wound/wait 死锁避免 多锁获取场景的死锁避免算法(wound-wait),ww_acquire_ctx 时间戳、-EDEADLK 回退重试,直连 DRM dma_resv 与 GPU 显存驱逐。源码:kernel/locking/ww_mutex.h、kernel/locking/ww_rt_mutex.c、kernel/locking/test-ww_mutex.c
8 seqlock 与 seqcount:序号驱动的无锁读 读侧 begin/retry 碰撞重试、写侧奇偶序号、内存屏障配对,以及它与 mmu-notifier invalidate_seq 的同源关系。源码:include/linux/seqlock.h

扩展部分

至此,核心八篇已沿"地基 → 自旋类 → 睡眠类 → 无锁与特化"一条主干走通,并在 GPU/HMM 场景落地。但主干为求聚焦,刻意搌置了三条支线:睡眠锁的历史前身、比"重试"更彻底的无锁范式、以及"验证与调试锁"本身的基础设施。下列扩展篇正是来补齐这些留白——每一篇都从某一核心章节延伸而出,不再从零铺陈,而是回答"在主干之外,它多补了哪一块":

章方向标题内容简介
9 睡眠锁 semaphore:最朴素的计数信号量 kernel/locking/semaphore.c,无 owner 的计数信号量,对比 mutex(第 5 章)看历史演进、彻底收口"名字误会"
10 无锁 RCU 与 SRCU 综述 kernel/rcu/,宽限期语义,补上 seqcount(第 8 章)"含指针须叠加 RCU"的伏笔,深挖回指 mmu-notifier 专栏 12.3
11 工具 lockdep 死锁检测原理 kernel/locking/lockdep.c,持有链与有向图环检测,前 12 章"误用与调试"背后的同一台引擎,回指 mmu-notifier 专栏 12.7 的伪锁
12 工具 locktorture:锁实现的压力验证 kernel/locking/locktorture.c,如何证明一把锁实现正确,呼应 ww_mutex(第 7 章)的 test-ww_mutex

说明:

  • 目录以"从地基到特化"的依赖顺序组织,建议按章序通读:第 1 章是理解后续所有锁的前提,第 2–6 章是主干,第 7–8 章连接 GPU/HMM 实际场景。
  • 每篇行文范式统一为"守护什么 / 为什么用它 / 怎么实现 / 误用与调试"。
  • 本专栏与《MMU Notifier 深入解析》互设引用:rwsem(第 6 章)↔ mmu-notifier 附篇 notifier_lock;seqcount(第 8 章)↔ mmu-notifier 第 3 章;ww_mutex(第 7 章)↔ GPU dma-resv/驱逐。
  • 技术交流和投稿,欢迎加入社区:GPUers。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » Linux 内核锁机制:原理与实现 · 专栏目录
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!