记一次频繁使用spinlock接口函数导致的无法开机问题

banner

问题现象

售后出现一台无法开机的机器,现象是卡白米

问题分析


set_frame 0x00后没有ack
set_frame 0x03后没有ack

同时kernel启动3s后,stick驱动一直反复打印日志,从3s到34s之间几乎全部是stick驱动读写的报错日志
1731476533850.png

34s的时候发现misc分区没有挂载,init发起了reboot的指令
1731476632054.png

而misc分区没有挂载的原因就是cpu一直被stick占用,导致mountFstab无法挂载分区。检查读写函数,发现如下异常
1731476930998.png
这是一个嵌套循环,也就是100*10=1000次的反复调用spinlock的接口获取和释放锁。

问题原因

此问题的原因在于spinlock的频繁获取和释放,导致CPU被占用,性能下降导致无法开机。

下面总结一下自旋锁被频繁申请释放的风险和问题:
在Linux内核中,自旋锁(spinlock)是一种用于保护共享资源的锁机制,主要用于短时间的锁定操作,不会引起线程调度。频繁地启用(enable)和禁用(disable)自旋锁可能带来以下风险和问题:

  1. 性能开销
    每次获取和释放自旋锁都会涉及内存屏障和CPU指令,以确保内存操作的顺序性和锁的正确性。这会导致性能开销,特别是在高频率下操作时。
  2. CPU资源浪费
    自旋锁在等待时不会使线程进入睡眠状态,而是不断轮询检查锁的状态。这可能会导致CPU周期的浪费,尤其是在锁被长时间持有的情况下。
  3. 死锁
    如果多个线程以不当的顺序获取多个锁,可能导致死锁情况,尤其是在复杂的锁定逻辑中。
  4. 优先级反转
    当高优先级任务被低优先级任务锁住的资源阻塞时,会导致优先级反转问题,可能影响系统的实时性能。
  5. 中断禁用(如果使用中断安全自旋锁)
    如果使用的是中断安全的自旋锁,频繁禁用和启用中断可能会影响系统的中断响应能力,导致延迟。
  6. 缓存一致性问题
    自旋锁导致的频繁内存屏障可能影响缓存一致性协议的效率,进而影响系统性能。

为了减轻这些风险,开发人员应尽量减少自旋锁的持有时间,并在可能的情况下使用其他同步机制(如互斥锁)来替代自旋锁,以避免长时间占用CPU资源。此外,应仔细设计锁定逻辑,以避免死锁和优先级反转问题。