拿着螺旋锁时避免睡觉

时间:2010-09-09 13:07:14

标签: linux-kernel sleep atomic spinlock

我最近阅读了LDDv3书中的5.5.2部分(自旋锁和原子上下文):

  

在握住锁定时避免睡眠可能会更困难;许多内核函数都可以睡眠,这种行为并不总是记录良好。将数据复制到用户空间或从用户空间复制数据是一个明显的例子:在复制可以继续之前,可能需要从磁盘交换所需的用户空间页面,并且该操作显然需要休眠。几乎任何必须分配内存的操作都可以睡眠; kmalloc可以决定放弃处理器,等待更多内存可用,除非明确告知不要。睡觉可能发生在令人惊讶的地方;编写将在自旋锁下执行的代码需要关注您调用的每个函数

我很清楚自旋锁必须始终保持最短时间,我认为从头开始编写正确的自旋锁代码相对容易。

但是,假设我们有一个大型项目,其中自旋锁被广泛使用。 我们怎样才能确保从自旋锁保护的关键部分调用的函数永远不会睡觉?

提前致谢!

2 个答案:

答案 0 :(得分:5)

如何为内核启用“Sleep-inside-spinlock checking”?当您运行make config时,通常可以在Kernel Debugging下找到它。您也可以尝试在代码中复制其行为。

答案 1 :(得分:-2)

我在许多项目中注意到的一件事是人们似乎滥用自旋锁,而是使用它们而不是应该使用的其他锁定原语。

linux spinlock仅存在于多处理器构建中(在单个进程构建中,自旋锁预处理器定义为空)自旋锁用于多处理器平台上的短时间锁定。

如果代码无法获取自旋锁,则只需旋转处理器直到锁定空闲。因此,在另一个处理器上运行的另一个进程必须释放锁,或者可能由中断处理程序释放,但等待事件机制是等待中断的更好方法。

irqsave自旋锁原语是一种禁用/启用中断的整洁方式,因此驱动程序可以锁定一个中断处理程序,但这应该只保持足够长的时间,以便进程更新与中断处理程序共享的一些变量,如果禁用中断你不会被安排。

如果您需要锁定中断处理程序,请使用带有irqsave的自旋锁。

对于一般内核锁定,您应该使用互斥锁/信号量api,如果需要,它将在锁上休眠。

要锁定在其他进程中运行的代码,请使用muxtex / semaphore 要锁定在中断上下文中运行的代码,请使用irq save / restore或spinlock_irq save / restore

要锁定在其他处理器上运行的代码,请使用自旋锁并避免长时间持有锁。

我希望这会有所帮助