• 正文
  • 推荐器件
  • 相关推荐
申请入驻 产业图谱

Linux记一次spin_lock死锁优化经验

2024/05/28
2090
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

哈喽,大家好,我是程序员秘书LittleG。

上篇:虹膜识别技术原理以及现状和未来

前言

死锁是很常见的一种内核故障。最常见的,就是如果一个task在已经持有某个锁的情况下,再次尝试获取同一个锁,就会形成死锁局面。发生死锁的场景有很多,常见的情况可能有,可能是在同一个task中锁使用不当;也可能是两个task有资源竞争和依赖,形成互锁互等;也可能是某个task拿了锁后又被某个中断抢占,之后又在等拿相同的锁。

最近刚分析和处理了一个死锁问题,就是一个task和一个中断拿相同锁出现的死锁问题,最后是通过替换拿锁接口函数解决的。主要是涉及到spin_trylock_irq() 和 spin_trylock() 这两个函数的使用场景和差别,记录学习之。

正文

spin_trylock_irq() 和 spin_trylock() 都是Linux内核中用于尝试获取自旋锁的函数,但它们在使用场景和行为上有所区别,主要体现在对中断的处理上。

spin_trylock()

功能说明:

spin_trylock() 是一个非阻塞的自旋锁获取函数,会尝试立即获取自旋锁。如果锁已被其他CPU持有,该函数会立即返回失败(通常返回0),而不会让调用者进入等待状态。主要用于那些无法承受阻塞开销或不适合睡眠的上下文。

中断处理:

调用 spin_trylock() 时,当前CPU的中断状态不变。也就是说,如果在中断上下文中调用此函数,中断仍然保持禁止状态;而在进程上下文中调用,则中断是启用的。

spin_trylock_irq()

功能说明:

spin_trylock_irq() 与 spin_trylock() 类似,也是尝试立即获取自旋锁,如果不能立即获取则返回失败。但是,它还额外包含了一层对中断的管理。

中断处理:

在尝试获取锁之前,spin_trylock_irq() 会临时禁用本地中断(如果之前是启用状态),并在操作完成后恢复中断的原始状态。这意味着,无论是在中断上下文还是进程上下文中调用,它都会确保在尝试获取锁期间中断是被禁止的,从而避免了在获取锁的过程中被中断打断的复杂性。这样设计实现显而易见提高了锁操作的原子性和安全性,但需要注意的是,可能会在某些对中断响应时间敏感的场景中引入延迟。

总结

spin_trylock_irq() 与 spin_trylock() 两个函数都是非阻塞式的自旋锁获取操作,不成功即返回,都不会引起调用者睡眠。

主要区别在于对中断的处理上。spin_trylock() 不改变当前中断状态,而 spin_trylock_irq() 则会在操作前临时禁用中断,操作后恢复中断状态,确保了操作的原子性。

至于选择使用哪个函数取决于具体的上下文需求

如果明确不希望在锁获取过程中被中断打断的情况下,或者处于一个可能需要明确控制中断状态的上下文中,则需要使用spin_trylock_irq() 。而在不需要特别处理中断,或者明确知道当前中断状态已满足要求的情况下,以及追求性能的情况下,可以考虑使用 spin_trylock()

推荐器件

更多器件
器件型号 数量 器件厂商 器件描述 数据手册 ECAD模型 风险等级 参考价格 更多信息
6N137 1 Avago Technologies 1 CHANNEL LOGIC OUTPUT OPTOCOUPLER, 10Mbps, 0.300 INCH, DIP-8
$0.99 查看
ISO1050DUB 1 Texas Instruments Isolated 5-V CAN transceiver 8-SOP -55 to 105

ECAD模型

下载ECAD模型
$6.62 查看
ASEMB-8.000MHZ-LY-T 1 Abracon Corporation MEMS OSC XO 8.0000MHZ CMOS SMD

ECAD模型

下载ECAD模型
$3.65 查看

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录