自旋锁引起的死锁问题

gewenbin
gewenbin
gewenbin
188
文章
15
评论
2020年12月26日20:40:25 1 1,195

调试GPU时,遇到的死锁问题,具体的序列如下:

  • cpu0上某线程T1调用了系统含有__KERNEL_ENTER的接口
  • __KERNEL_ENTER中会获得内核锁,然后使能中断,这时内核锁是归T1线程持有
  • 就在使能中断后,GPU中断来了,接着执行GPU中断程序(在cpu0上执行)
  • 这时在cpu1上的线程T2获取了用户自定义的锁B
  • 线程T2同样调用了系统含有__KERNEL_ENTER的接口
  • 由于内核锁已经被cpu0上的T1线程持有,所以cpu1上的T2线程此时卡住
  • 这时GPU中断程序中也要去获取用户自定义的锁B,但是锁B已经被cpu1上的T2线程持有
  • 中断程序卡住
  • 由于中断程序卡死,所以不会执行API_InterExit,也就不会调用调度程序,从而T1线程再也没有机会被调度执行
  • 由于之前cpu0上的中断程序没退出,cpu0上的中断还处于关闭状态,可怜的tick中断也无法被执行了,更没法调度了
  • 由于T1线程没可能再次执行,也就没可能释放内核锁了,此时整个系统GG

自旋锁引起的死锁问题

分析:

  • 死锁的诱发原因是T1线程无法被调度执行,从而无法释放内核锁
  • 在中断上下文中程序被spinlock卡死,从而导致中断程序无法正常结束(在实际案例中是由于在lock和unlock之间调用了信号量post操作)
  • 如果中断程序能正常结束,那么T1线程就能被再次调度,从而解决死锁问题

解决方法:

  • 第一种方法就是修改spinlock保护的临界区代码逻辑,不要使用带__KERNEL_ENTER的系统接口
  • 第二种方法就是将中断处理放到中断延迟队列中去执行

在实际的案例中,使用了第二种方法,因为由于驱动程序的复杂性,可能导致用第一种方法会导致驱动逻辑的较大改动,从而带来较大的工作量。

gewenbin
  • 本文由 发表于 2020年12月26日20:40:25
  • 转载请务必保留本文链接:http://www.databusworld.cn/9893.html
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

评论:1   其中:访客  1   博主  0
    • 我爱文彬 我爱文彬 4

      不错不错