为什么在Linux中禁用spin_lock和spin_unlock之间的中断?
作者:互联网
我正在阅读Linux信号量的实现.由于原子性,信号和等待(在源代码中上下移动)使用自旋锁.然后我看到Linux在spin_lock_irqsave中禁用了中断,并在spin_unlock中重新启用了中断.这让我感到困惑.我认为,在关键部分禁用中断确实没有意义.
例如,过程A(当前处于活动状态)获取了锁定,过程B(已阻止)正在等待锁定,而过程C正在执行一些无关的操作.在A和B之间的关键部分中将上下文切换到C是非常有意义的.即使C也试图获取该锁,由于该锁已经被A锁定,结果将是C被阻塞并且A恢复执行.
因此,我不知道为什么Linux决定在自旋锁保护的关键区域内禁用中断.它可能不会造成任何问题,但对我来说似乎是多余的操作.
解决方法:
首先,请允许我声明我不是Linux专家,所以我的回答可能不是最准确的.请指出您可能发现的任何缺陷和问题.
想象一下,内核的各个部分是否使用了某些共享数据,包括需要快速且不能阻塞的操作,例如中断处理程序.假设系统调用foo当前处于活动状态,并且已获取了使用/访问共享数据栏的锁定,并且在获取该锁定之前/之前没有禁用中断.
现在是(硬件)中断处理程序,例如键盘,弹起,并且还需要使用bar(硬件中断的优先级高于系统调用的优先级).由于bar当前被syscall foo锁定,因此中断处理程序无法执行任何操作.中断处理程序确实需要快速&尽管没有被阻止,所以它们只是在尝试获取锁的同时保持旋转状态,这将导致死锁(即系统冻结),因为syscall foo永远不会获得完成并释放其锁的机会.
但是,如果在尝试获取foo中的锁之前禁用了中断,则foo将能够完成其所做的任何工作并最终释放锁(并恢复中断).在foo保持自旋锁的同时试图进入的所有中断都将留在队列中,并且能够在释放锁时启动.这样,您就不会遇到上述问题.但是,还必须注意确保锁定杆的锁定时间尽可能短,以便在需要时可以接管其他更高优先级的操作.
标签:atomicity,interrupt,mutex,synchronization,linux 来源: https://codeday.me/bug/20191118/2029993.html