- 论坛徽章:
- 22
|
本帖最后由 amarant 于 2011-11-30 21:50 编辑
3.不同的软中断是否可以嵌套?相同的软中断是否可以嵌套?
在进入软中断处理前,do_softirq会判断
if (in_interrupt())
return;
如果当前正在执行中断,那么就直接返回。
也就是说,在执行软中断时,发生了一个硬件中断,在ISR执行完以后,会去检查是不是有软中断:
if (!in_interrupt() && local_softirq_pending())
invoke_softirq();
如果当前正处于中断处理上下文中(hardirq/softirq)那么就不会执行软中断。
但是一个软中断的处理中(h->action(h);)也可以调用__local_bh_enable(SOFTIRQ_OFFSET); 打开软中断。
那么从软中断的实现上来分析分析,在一个软中断处理的时候是通过一个pending存下当前存在的软中断,在根据该变量中的每一个位逐一处理。
如下代码段,如果软中断被嵌套了,那么假设被中断的是a,中断者是b。a处理了其中的一个软中断,b中断了a后,处理所有的软中断。那么返回a后,a仍旧以为还需要处理剩下的软中断,那么就重复处理了。
由此看来,软中断是不能嵌套的。
- pending = local_softirq_pending();
- h = softirq_vec;
- do {
- if (pending & 1) {
- unsigned int vec_nr = h - softirq_vec;
- int prev_count = preempt_count();
-
- kstat_incr_softirqs_this_cpu(vec_nr);
-
- trace_softirq_entry(vec_nr);
- h->action(h);
- trace_softirq_exit(vec_nr);
- if (unlikely(prev_count != preempt_count())) {
- printk(KERN_ERR "huh, entered softirq %u %s %p"
- "with preempt_count %08x,"
- " exited with %08x?\n", vec_nr,
- softirq_to_name[vec_nr], h->action,
- prev_count, preempt_count());
- preempt_count() = prev_count;
- }
- rcu_bh_qs(cpu);
- }
- h++;
- pending >>= 1;
- } while (pending);
复制代码 4.软中断在什么时间点被调度?
这个可以从cscope查看 :cs f c do_softirqCscope tag: do_softirq
# line filename / context / line
1 175 kernel/softirq.c <<_local_bh_enable_ip>>
do_softirq();
2 329 kernel/softirq.c <<invoke_softirq>>
do_softirq();
3 3039 net/core/dev.c <<netif_rx_ni>>
do_softirq();
Type number and <Enter> (empty cancels):
do_softirq可以显式调用。
一般来说就是中断处理结束的时候会调用do_softrq,处理一定数量(MAX_SOFTIRQ_RESTART)次的软中断后,激活软中断守护进程(wakeup_softirqd())。该守护进程会在cpu空闲时开始处理没来得及处理的软中断。 |
|