为什么linux在内核代码持有自旋锁后禁用内核抢占?

Vis*_*dhi 4 kernel driver preemption spinlock

我是Linux的新手,正在阅读Rubini&Corbet的Linux设备驱动程序.我对一个与之相关的陈述感到困惑spinlocks; 这本书说明

如果一个非抢占式单处理器系统进入锁定旋转,它将永远旋转; 没有其他线程能够获得CPU来释放锁.出于这个原因,在没有启用抢占的单处理器系统上的自旋锁操作被优化为什么也不做,除了那些改变IRQ屏蔽状态的操作.

书还说明了这一点

内核抢占案例由自旋锁代码本身处理.只要内核代码持有自旋锁,就会在相关处理器上禁用抢占.即使是单处理器系统也必须以这种方式禁用抢占以避免竞争条件.

问题:在单处理器系统上,如果内核代码(代表用户进程执行)持有自旋锁,则禁用内核抢占,那么另一个进程怎么可能有机会运行并因此尝试获取自旋锁?为什么Linux内核会在内核代码持有自旋锁时禁用内核抢占?

sup*_*esk 7

你的第一个问题的答案是你的第二个问题背后的原因.

内核获取的自旋锁可以通过关闭抢占来实现,因为这可以确保内核在没有其他进程干扰的情况下完成其关键部分.整个问题是,在内核释放锁之前,另一个进程将无法运行.

没有理由必须以这种方式实施; 它只是一种实现它的简单方法,可以防止任何进程在内核持有的锁上旋转.但是这个技巧只适用于内核获得锁定的情况:用户进程无法关闭抢占,如果内核正在旋转(即它试图获取自旋锁,但另一个进程已经拥有它),最好先放弃抢占上!否则系统将挂起,因为内核正在等待一个不会被释放的锁,因为持有它的进程无法释放它.

内核获取自旋锁是一种特殊情况.如果用户级程序获取螺旋锁,则不会禁用抢占.