📄 softirq.txt
字号:
any questions,send email to netxiong@263.net
do_bottom_half已经完全重写了。取而代之的事softirq,一种系统独立的中断系统,主要完成了计算机体系结构的分离,并加强了对多处理器的更好的支持。而且保持了和原来的bh_base系统的兼容性。
其中牵涉到的文件有
/asm/hardirq.h 其中定义了 irq_cpustat_t,其中包含了irq中的mask和active两个子段。
/linux/irq_cpustat.h 其中定义了对irq_cpustat_t中的字段的处理,其实就是返回各个字段。
/linux/interrupt.h 定义了irqaction和softirq_action结构。以及tasklet
/kernel/softirq.c 定义了softirq的大部分函数。
/linux/asm/softirq.h 定义了一些宏。
软中断在2.4.2中是一个极为复杂的结构,相对于前一些版本,更具有可扩展性。
原有的do_bottom_half已经被do_softirq所代替。
在schedule调度中,调用do_softirq来对bottom half进行处理。只是bottom half的唯一处理入口。
系统中有一个static struct softirq_action softirq_vec[32]定义。代表至多有32种处理类型。
这里的softirq_vec已经不是代表某一个处理的函数了,它的每一个向量代表一类软中断。其中的mask和active位都被移到一个新的结构irq_cpustat_t irq_stat[NR_CPUS]中了。
所以由
irq_stat(bh_mask和bh_active)
softirq_vec(bh_base)
两者共同组成了类似于原来的bottom half结构。
系统预先定义如下几类软中断,
HI_SOFTIRQ=0, //处理函数对应tasklet_hi_action
NET_TX_SOFTIRQ,
NET_RX_SOFTIRQ,
TASKLET_SOFTIRQ //处理函数对应tasklet_action(tasklet类的软中断)
对于tasklet类软中断,首先定义了一个struct tasklet_head tasklet_vec[NR_CPUS],这个tasklet_vec向量数组对每一个cpu指定一个向量,每一个向量的类型是tasklet_head型,里面其实只包含一个指针。这个指针后面就接着一个链表,这个链表中的每一个元素都是tasklet_struct型的。在do_softirq中就会依次从链表中取出这些元素,然后执行tasklet中的func。如果想要添加一个新的tasklet,使用tasklet_schedule(),把一个tasklet加入到这个列表的头部。这个函数会自动对active位进行值位。
对于tasklet_hi类中断,这个中断是一个兼容原来的bottom half的一个软中断。首先定义了一个struct tasklet_hi_head tasklet_vec[NR_CPUS],也是一个链表,结构和tasklet_head完全一样,如果想要添加一个新的tasklet_hi,使用tasklet_hi_schedule(),把一个tasklet_hi加入到这个列表的头部。另外对于原先的一些软中断,比如timer,immediate等,原有的bh_base还保留,然后又定义另一个tasklet_struct bh_task_vec[]的结构,每一个bh_task_vec中的处理函数都是bh_action,而其中的data存储的就是bh_task_vec[n]中的下标值n。而在bh_action,就是使用这个n值来调用bh_base[n]中相应的函数,实际的效果就是一个bh_task_vec对应一个bh_base函数。这里有一个重要的函数:mark_bh,已经完全改变了原来的定义方法,这个函数调用tasklet_hi_schedule(),把bh_task_vec加入到链表中,这就相当于原来的效果了。这个函数就是现在和未来的连接点。
结构图见softirq.jpg
*********************************使用方法********************************************
(1):tasklet的使用方法
#首先使用DECLARE_TASKLET声明一个tasklet变量(无需实现定义),并把func和data也都赋给他。
例如DECLARE_TASKLET (jiq_tasklet, jiq_print_tasklet, (unsigned long) &jiq_data);
#再要进行使用的时候tasklet_schedule把声明好的tasklet加入到调度队列中去。
例如tasklet_schedule(&jiq_tasklet);
#完毕
*************************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -