自旋锁临界区禁用函数类型、可重入函数安全性及中断关联咨询
自旋锁临界区函数使用规则及与中断的关联
如何判断函数是否可在自旋锁临界区使用
你之前的认知存在偏差,可重入函数并非都不能在自旋锁临界区使用,自旋锁临界区的核心限制是不能主动或被动触发调度阻塞:默认配置下持有自旋锁时会关闭内核抢占,一旦当前进程阻塞,内核无法调度其他进程替换持有锁的进程,会直接导致死锁。
判断标准可遵循以下规则:
- 首先排除所有可能触发阻塞的函数:比如
copy_from_user、带GFP_KERNEL标志的kmalloc、mutex_lock、msleep这类,只要函数内部可能调用调度器让当前进程睡眠,一律不能使用。 - 可重入只是函数的并发安全属性,和是否会阻塞没有必然联系:比如
memcpy是纯内存操作的可重入函数,完全没有阻塞逻辑,当然可以安全使用;常规路径下的kfree只是将内存归还到slab缓存,不会触发阻塞,也可以在自旋锁临界区使用。 - 拿不准函数是否合规时,直接查内核文档或者函数实现,确认是否存在
schedule类调度接口调用、是否持有互斥类锁、是否依赖会触发阻塞的用户上下文操作。
可重入函数和阻塞的关系
你提到的「可能阻塞的函数都不安全」这个判断是完全正确的,但并非所有可重入函数都存在阻塞可能性:
- 无阻塞的可重入函数:纯运算、纯内存操作的函数,比如
memcpy、strlen、位操作封装、简单算术运算函数,这类完全没有阻塞逻辑,可以在自旋锁临界区随意使用。 - 带阻塞的可重入函数:比如带
GFP_KERNEL标志的kmalloc,它本身是可重入的,但内存不足时会触发内存回收逻辑进入阻塞,因此不能在自旋锁中使用。
简单来说,可重入是函数的并发安全属性,阻塞是函数的调度行为属性,二者没有绑定关系。
中断处理程序与自旋锁的作用及关联
二者核心作用
- 中断处理程序是内核响应硬件中断的执行流,优先级高于所有进程上下文,执行期间默认关闭当前CPU的同类型中断,全程不允许阻塞。
- 自旋锁是轻量级同步锁,拿不到锁时会在原地循环等待,不会触发调度,适合保护执行时间极短的临界区。
二者关联
- 如果某自旋锁会被中断处理程序访问,进程上下文持有该自旋锁时,必须先关闭当前CPU的对应中断,否则会触发死锁:比如进程上下文刚拿到锁,CPU触发中断,中断处理程序也要申请同一个锁,就会在中断上下文无限自旋,锁永远无法被释放。这种场景需要使用
spin_lock_irqsave/spin_unlock_irqrestore接口,拿锁的同时关闭中断。 - 中断处理程序本身只能用自旋锁做同步,因为中断上下文不允许阻塞,不能使用互斥量、信号量这类会触发睡眠的同步机制。
- 中断处理程序要求执行时间极短,因此对应保护的自旋锁临界区也必须足够小,避免长时间自旋浪费CPU资源。
内容的提问来源于stack exchange,提问作者Shisui
相关产品推荐
相关产品推荐

