上节我们只介绍了tasklet的用法,本节我们更进一步稍微看一下它的工作原理,那自然离不开软中断;实际上tasklet只是为方便用户使用,对软中段的一种包装。
在上节中通过 tasklet_schedule(&isr_tasklet) 就激活了tasklet,处理器就能择机尽快执行tasklet绑定的函数了;实际上它是向系统发送了软中段,触发了软中断的do_softing()函数。
软中断
首先说明,在驱动程序中我们应该避免使用软中断,只有中枢的内核代码才会用到软中断,因为软中断是很稀缺的资源;
软中断是相对于硬中断而言的;由于硬中断执行期间不能被调度且会屏蔽同类型的中断,所以它的执行时间要特别短,就需要把不紧急的任务放在所谓的“下半部”延后处理;软中断就是内核延期执行任务的手段。
软中的类型和编号如下,可见其资源确实比较稀缺,但由于它主要作为其他延时机制的基础,所以其限制不算大;比如用户常用的tasklet只占用其中的一个类型:
enum
{
HI_SOFTIRQ=0, // 高优先级的tasklet
TIMER_SOFTIRQ, // 定时器
NET_TX_SOFTIRQ, // 网络收
NET_RX_SOFTIRQ, // 网络发
BLOCK_SOFTIRQ, // 块层收到I/O返回
IRQ_POLL_SOFTIRQ, // 也是块层使用
TASKLET_SOFTIRQ, // 用于常规tasklet
SCHED_SOFTIRQ, // 用于调度
HRTIMER_SOFTIRQ, // 高精度定时器
RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */
NR_SOFTIRQS
};
软中断(即使是同类型)可以并发的执行在多个cpu上;但内核对tasklet做了更多的限制,同类型的tasklet只能串行的在一个cpu上执行;
这里看到有两种tasklet:常规tasklet、高优先级tasklet;我们上节介绍的是常规tasklet;它俩在本职上没有区别;在使用上高优先级tasklet使用:tasklet_hi_schedule()函数进行激活;
软中断的触发
在前文介绍tasklet时,用户只需要调用tasklet_schedule(),处理器就会择机执行处理函数,这是因为tasklet_schedule()通过调用raise_softirq()触发了软中断,从而执行软中断的处理函数do_softirq();
可见tasklet任务的触发与执行,就是采用的软中断。