为什么可能会睡眠的函数不允许在中断中调用
如果有涉及到 Linux 内核开发的同学可能会知道,可能会睡眠的函数是不允许在中断中调用的(比如结合使用定时器回调与 vmalloc()),这种操作会触发内核的 BUG_ON(),造成内核崩溃。其原因就是中断是不允许睡眠的,而不允许睡眠的原因呢,简单来讲有两个方面:
-
会造成进程上下文混乱 首先,发生中断时,内核会保存被中断进程的上下文,而如果中断要睡眠,内核就要进行调度其他进程,需要保存中断的上下文。但中断不是操作系统的调度单位,没有中断描述符来描述,无法自己保存上下文,只能抢占进程的上下文保存位置。这样当中断结束,原进程保存的上下文就会混乱
-
睡眠无法唤醒 其次,由于中断不是操作系统的调度单位,唯一能打断中断的只有更高优先级的中断,因此执行调度无法唤醒中断,会永远睡眠下去。
此外,中断应该是一种紧急事务,需要操作系统立即处理,不应该睡眠,比如像 CPU 时钟的硬中断,如果睡眠了,又怎么保证时钟准确呢?