Linux内核同步:自旋锁与中断处理深度解析
1. 内核测试与自旋锁规则
在标准“发行版”系统和内核(如Ubuntu 22.04 LTS VM)上进行测试时,即使未将内核配置为“调试”内核(即未设置 CONFIG_DEBUG_ATOMIC_SLEEP
内核配置选项),较新的发行版内核仍能捕获原子调度时的错误。例如,在Ubuntu 22.04(内核版本5.19.0 - 45 - generic)和Fedora 38(内核版本6.5.6 - 200.fc38.x86_64)上测试时就有此现象,而在早期的Ubuntu 20.04 VM标准内核(5.4)上则未捕获该错误。
LDV项目有关于自旋锁的规则:
- 不允许两次获取 spin_lock
。
- 不允许释放未获取的 spin_lock
。
- 所有 spin_lock
最后都应被释放。
- 不允许通过 spin_unlock
/ spin_unlock_irqrestore
函数重复释放锁。
违反这些规则可能导致系统不稳定,如驱动程序中尝试两次释放自旋锁的实际错误示例。
2. 锁与中断的场景分析
在驱动程序开发中,当实现读取方法时,可能会遇到非阻塞的关键部分,通常使用自旋锁来保护。但如果在读取方法的关键部分期间,设备的硬件中断触发,就可能出现问题。下面分析几种场景:
| 场景 | 描述 | 是否有数据竞争 |
| ---- | ---- | ---- |