上一章讲了中断为何要分成上下文:中断处理程序中要禁止所有中断,,如果isr处理时间长,那么系统响应能力差,所以将isr分为上下文两部分,当上文结束后触发一个软中断,该软中断的处理程序可以是中断下文。
本章主要讲下文如何实现,总体有3种实现方式。首先想想最简单的方式当上文结束后设置一个定时器,一定时间之后再处理下文即可。
1 软中断:内核中有段代码实现软中断的处理,使用时只要注册调用open_softirq注册中断的处理函数,然后在中断上文结束的时候触发中断raise_sofirq,这样当内核那段代码得到执行时刚才注册的下文处理函数就能得到执行了
2 tasklet:基于软中断实现。创建一个tasklet对象,中断上文结束之后调用tasklet_schedule即可让自己刚才创建的那个tasklet对象中的回调函数得到执行。【由此可见tasklet使用简单】
3 工作队列:这里确切的是指工作队列系统,这个系统会创建一个内核线程,这个内核线程会处理我们添加到队列中的任务。其实系统已经为我们提供了这么一个默认的线程,它叫做event线程(当然我们也可以自己调用内核接口创建一个内核线程。)它的使用很简单:创建对象,实现中断处理函数(实际上是一个回调函数,该回调函数的指针保存在对象中),调用schedule_work。
一般tasklet完全能满足要求,但需要把任务退后到进程上下文中执行或者执行的函数有睡眠,那么使用工作队列。软中断需要我们自己加锁保证时序,比较复杂但性能较tasklet好。工作队列开销是它们3者最大的。
睡眠、阻塞、锁、中断,它们之间的关系?
如果一个函数获得了锁,但又被阻塞或者睡觉去了,那是不行的。
如果禁止了中断,那么跑去睡觉也是不好的。
关于为何中断线程为何不能睡觉:
这个问题我不去深究了

本文详细探讨了Linux内核中断处理的上下文切换,包括软中断、tasklet和工作队列三种实现方式。中断上下文分为两部分以提高系统响应能力,软中断通过注册处理函数并在上文结束后触发,tasklet简化了软中断的使用,而工作队列则适用于需在进程上下文执行或可能睡眠的任务。中断处理中不能睡眠以避免资源记账问题和降低外部设备利用率。
最低0.47元/天 解锁文章
1272

被折叠的 条评论
为什么被折叠?



