您的位置:首页 > 其它

【中断异常】软中断与Bottom Half

2014-05-10 20:28 148 查看
中断服务一般都是将中断请求关闭的条件下进行的,以避免嵌套而使控制复杂化;但是如果关中断的时间持续太长就可能因为CPU不能及时响应其他的中断,而导致其他的中断请求丢失;为此,linux内核允许在将具体的中断服务程序挂入中断请求队列及时将SA_INTERRUPT标志设成0,是这个中断服务程序在开的条件下执行;开中断造成复杂,关中断造成性能低下;一般来说,一次的中断的服务过程可以分为两部分。开头的部分往往是必须在关中断的条件进行的,这样相应的多次的中断请求不能合并在一起来处理;下半部,在开中断的条件下进行,这样才不会使中断关的太久造成其他中断的丢失;而且下半部的操作往往允许延迟稍后再执行;

(1)后半部通常被称为“bottom half”,在内核代码成为bh,它来自RISC系统结构,通常有大量的寄存器;当中断发生时,要将所有的这些寄存器的内容都压入堆栈,并在返回时加以恢复,为此会付出相当高的代价,因此RISC系统结构通常将中断服务分成两部分,第一部分使用为数不多的寄存器,第二部分就是bh;在i386的CISC,面临的问题虽然不尽相同,但有bh也是有必要性的;

(2)其实,早起的bh的使用,它的实现设置了一个函数指针bh_base[](最多只能代表一个bh函数,而irq_desc[]是一个中断服务队列),和两个无符号整数bh_active(相当于中断请求控制器)和bh_mask(相当于中断屏蔽控制器)相对应,在do_bottom_half()类似do_IRQ执行相应的bh函数;但这种机制给多CPU
SMP结构有性能影响,因为同一时间内只允许一个CPU执行bh函数;bh函数不允许嵌套,但它的串行化是全局性的,而do_IRQ()是针对某一个通道的串行化;为此增设了一个新的机制softirq;而softirq字面意思是软中断的意思,它是“硬中断服务程序”针对内核的中断,而信号(也是用户空间定义的软中断,要根据上下文来加以区分)是内核(或其他进程)针对某个进程的中断,而硬中断通常是外部设备对CPU的中断;

(3)系统初始化时通过softirq_init()对内核的软中断机制进行初始化;软中断本身是一种机制,它是一个框架,它包含一个TASKLET_SOFTIRQ,被称为tasklet机制,还有NET_TX_SOFTIRQ和NET_TX_SOFTIRQ两种软中断是为网络操作而设置的;softirq_init()只对TASKLET_SOFTIRQ和HI_SOFTIRQ两种软中断进行初始化的


(4)tasklet_struct没有bh那样严格的串行化;不同的CPU都可执行不同的tasklet;一个tasklet_struct代表一个tasklet;func指向其服务程序;bh也是使用这个结构体,只要加严格的限制,就可到到达原始bh的目的了;

(5)bh_task_vec[]中包含32个tasklet_struct,在tasklet_init全部指向bh_action();对于TASKLET_SOFTIRQ和HI_SOFTIRQ是通过open_softirq()来初始化的;

(6)在open_softirq()中,设置一软中断号为下标的softirq_vec[](全局变量),所以各个CPU看到是相同的,但各个CPU都有自己的以CPU编号的irq_stat[cpu_nums](软中断控制/状态结构),并设置TASKLET_SOFTIRQ和HI_SOFTIRQ的处理程序tasklet_action()和tasklet_hi_action();

(7)tasklet_hi_vec[]就是每一个CPU的tasklet_struct结构的队列头;具体的bh_action()是由init_bh()来设置的,用相应的bh向量(如TIMER_BH),和内核内置的time_bh来设置的;当需要执行一个特定的bh函数时,可以通过一个inline函数mark_bh()提出请求,后会调用tasklet_hi_schedule()来找到相应的的tasklet_struct结构(bh_task_vec+br);

(8)在tasklet_hi_schedule()中,先通过smp_processor_id()找到CPU的编号,取对应编号的tasklet_hi_vec[num].list队列头,将上述的tasklet_struct结构列入该队列,使得他同一时间内只能在一个CPU上执行,如果已经执行是不会链入的;通过__cpu_raise_softirq()正式发出软中断请求,从而设置irq_stat[cpu_nums](软中断控制/状态结构);

(9)内核在do_IRQ()曾经有检查它的条件,看是否要执行do_softirq的情况;系统调用返回执行时也会有所检查;在do_softirq()中,首先判断是否有硬中断程序和软中断程序在执行,用in_interrupt()来检测,这个串行化措施;只有这一个关卡,因此不同的CPU可以执行不同的软中断程序;

(10)如果执行的是bh_action(),则就会有第二条关卡,有防止了一次硬中断程序的调用,接下来是单CPU的互斥测试,成功后就执行先前设置的bh_base[nr]();而在tasklet_struction()中没有这样的设置;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: