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); }

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值