Linux设备驱动程序:重温睡眠锁定

皮特

我一直被教导,在内核代码中按住自旋锁的同时睡觉是不行的。原因如下:

  1. 线程A获取锁,执行一些工作,然后调用进入睡眠状态的内核函数,释放CPU。
  2. 线程B现在运行,尝试获取该锁,但是由于线程A持有该锁而无法执行。
  3. 这是一个僵局。由于线程B不断旋转,因此无法唤醒线程A,并且由于无法获取锁,因此线程B无法取得任何进展。

我正在维护一个使用大量锁的驱动程序,并且在某些锁定的部分内是显而易见的事情,例如内存分配copy_to_user()等。

但是,我并不完全相信自己手上有一个错误。在上述情况下,线程A是用户上下文(即在的实现内read()),而线程B是中断上下文(在ISR内)。锁通过锁定spin_lock_irqsave()结果,线程B无法在线程A持有锁的同时运行,从而使死锁变得不可能。

我还考虑了以下内容:

  1. 线程A =中断上下文。在这里线程A无法睡眠(也不会),因此我们永远不会陷入死锁状态。
  2. 线程A和B都是用户上下文(即对的并发调用read())。由于其他适当的机制,这不可能发生。

有什么我想念的吗?在我上面所描述的内容中,握住锁时是否有与睡觉有关的真正危险?

本月员工

这个问题不累加。

使用上面的场景,线程A是用户上下文(即在read()的实现内),而线程B是中断上下文(在ISR内)。该锁通过spin_lock_irqsave()锁定。结果,线程B无法在线程A持有锁的同时运行,从而使死锁变得不可能。

如果您在copy_to_user和friends之间保持自旋锁,则带有debug的内核会警告您您做错了。如果需要使线程进入睡眠状态,它将进入睡眠状态。然后,您回到第一个方框。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章