Skip to content

中断处理

中断处理的流程还算清楚,linux 中有中断上下部的机制,也就是尽快处理紧急的部分,将一些不是很紧急的部分延后执行,让操作系统能够更快的处理嵌套的中断或者说更快的回到用户态。下部有三种常见的工作机制,软中断、tasklet、workqueue。

软中断

软中断在编译的时候就要放一个软中断的跳转表,在中断上部的时候,中断处理将软中断号保存,并继续处理,等这个中断要返回到用户态的时候,会尝试把刚刚记录的软中断处理掉,如果时间过长,还是会交给专用的内核线程进行处理。

tasklet

软中断的毛病在于,编译时期软中断的处理函数就定了,当有一些新的内核模块想要注册新的时候,就不能加了。tasklet 就是解决这个问题的,tasklet 是软中断中的一个中断处理函数。他提供了接口,这个接口接受接收一个回调函数和参数,在处理下部的时候会调用这个回调函数,相当于巧妙的实现了动态的功能。tasklet 的问题在于多个核可能会同时访问下部的代码,虽然 tasklet 有机制实现不会产生冲突,但是多块核同时访问一个区域,很容易会有一些竞争的情况出现,或者其他核进行等待。同时 tasklet 仍然处在软中断的上下文中,不能进行睡眠。也不能多个 cpu 同时调度之类的。

workqueue

workqueue 继续解决 tasklet 的问题,workqueue 是每个 cpu 都有的,同时还对 NUMA 进行过专用的设计,cpu 亲和性更好,每个 cpu 也能并行的处理 workqueue 之间的问题。同时 workqueue 不在中断的上下文中,而是在内核进程的上下文中,可以持有锁可以睡眠。