本文主要是介绍Linux kernel 软中断机制之软中断执行,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
软中断处理函数在函数__do_softirq()中被调用:
asmlinkage void __do_softirq(void) {unsigned long end = jiffies + MAX_SOFTIRQ_TIME;unsigned long old_flags = current->flags;int max_restart = MAX_SOFTIRQ_RESTART;struct softirq_action *h;bool in_hardirq;__u32 pending;int softirq_bit;
/** 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_irq_enter_time(current);
__local_bh_disable_ip(_RET_IP_, SOFTIRQ_OFFSET);in_hardirq = lockdep_softirq_start();
restart:/* Reset the pending bitmask before enabling irqs */set_softirq_pending(0);
local_irq_enable();
h = softirq_vec;
while ((softirq_bit = ffs(pending))) {unsigned int vec_nr;int prev_count;
h += softirq_bit - 1;
vec_nr = h - softirq_vec;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())) {pr_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_set(prev_count);}h++;pending >>= softirq_bit;}
rcu_bh_qs();local_irq_disable();
pending = local_softirq_pending();if (pending) {if (time_before(jiffies, end) && !need_resched() && --max_restart) goto restart;
wakeup_softirqd();}
lockdep_softirq_end(in_hardirq);account_irq_exit_time(current);__local_bh_enable(SOFTIRQ_OFFSET);WARN_ON_ONCE(in_interrupt());tsk_restore_flags(current, old_flags, PF_MEMALLOC); }
注意这里的对软中断处理线程的唤醒。
wakeup_softirqd();
static void wakeup_softirqd(void) {/* Interrupts are disabled: no need to stop preemption */struct task_struct *tsk = __this_cpu_read(ksoftirqd);
if (tsk && tsk->state != TASK_RUNNING)wake_up_process(tsk); }
这篇关于Linux kernel 软中断机制之软中断执行的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!