- 论坛徽章:
- 2
|
本帖最后由 wLiu2007 于 2014-08-12 20:56 编辑
假设当前有3个softirq处于pending状态,然后__do_softirq正在处理第1个软中断,这个时候硬中断发生了,硬中断里面trigger了1个新的更高优先级的softirq,当中断返回的时候,检查in_interrupt不为0,所以不会重新调用do_softirq,而是返回中断前的__do_softirq中,
被中断的地方如果是在do_while这个循环中的话,只有等将pending标记的那些softirq都处理完了,才会处理新触发的softirq, 即这个时候需要将前3个softirq都处理完了才会处理这个新的softirq,尽管新触发的softirq优先级更高一些,不知道理解是否正确?
- asmlinkage void __do_softirq(void)
- {
- struct softirq_action *h;
- __u32 pending;
- int max_restart = MAX_SOFTIRQ_RESTART;
- int cpu;
- unsigned long old_flags = current->flags;
- /*
- * Mask out PF_MEMALLOC s current task context is borrowed for the
- * softirq. A softirq handled such as network RX might set PF_MEMALLOC
- * again if the socket is related to swap
- */
- current->flags &= ~PF_MEMALLOC;
- pending = local_softirq_pending();
- account_system_vtime(current);
- __local_bh_disable((unsigned long)__builtin_return_address(0),
- SOFTIRQ_OFFSET);
- lockdep_softirq_enter();
- cpu = smp_processor_id();
- restart:
- /* Reset the pending bitmask before enabling irqs */
- set_softirq_pending(0);
- local_irq_enable();
- 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); ///////////////////////////////////////////////////////////////////////////////////////while
- local_irq_disable();
- pending = local_softirq_pending();
- if (pending && --max_restart)
- goto restart;
- if (pending)
- wakeup_softirqd();
- lockdep_softirq_exit();
- account_system_vtime(current);
- __local_bh_enable(SOFTIRQ_OFFSET);
- tsk_restore_flags(current, old_flags, PF_MEMALLOC);
- }
复制代码
|
|