softirq机制分析

软中断的含义就是模仿硬中断的实现方式,软就是软件模拟的意思。它处于中断的下半部执行,目的是想要使中断上半部快速执行完毕。耗时的一些工作放到下半部去执行。避免丢中断和系统响应慢的问题。

 

在interrupt.h中定义了软中断号。

enum

{

HI_SOFTIRQ=0,

TIMER_SOFTIRQ,

NET_TX_SOFTIRQ,

NET_RX_SOFTIRQ,

BLOCK_SOFTIRQ,

TASKLET_SOFTIRQ,

SCHED_SOFTIRQ,

#ifdef CONFIG_HIGH_RES_TIMERS

HRTIMER_SOFTIRQ,

#endif

RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */

};

softirq机制分析_第1张图片

softirq-daemon会遍历pending的softirq,如果存在,会相应执行对应的action.

void open_softirq(int nr, void (*action)(struct softirq_action *))

{

       softirq_vec[nr].action = action;

}//注册软中断

如果发现有pending状态,do_softirq会调用__do_softirq函数

asmlinkage void __do_softirq(void)

{

       struct softirq_action *h;

       __u32 pending;

       int max_restart = MAX_SOFTIRQ_RESTART;

       int cpu;

 

       pending = local_softirq_pending();

       account_system_vtime(current);

 

       __local_bh_disable((unsigned long)__builtin_return_address(0));

       trace_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) {

                     h->action(h);           //执行中断处理函数。

                     rcu_bh_qsctr_inc(cpu);

              }

              h++;

              pending >>= 1;

       } while (pending);

 

       local_irq_disable();

 

       pending = local_softirq_pending();

       if (pending && --max_restart)

              goto restart;

 

       if (pending)

              wakeup_softirqd();

 

       trace_softirq_exit();

 

       account_system_vtime(current);

       _local_bh_enable();

}

Softirq调用时机

CPU空闲的时候:

void idle_loop(void)

{

    for ( ; ; )

    {

        page_scrub_schedule_work();

        default_idle();

        do_softirq();

    }

}

每次中断返回的时候:

arch/x86/x86_32/entry.S

 

ENTRY(ret_from_intr)

        GET_CURRENT(%ebx)

        movl  UREGS_eflags(%esp),%eax

        movb  UREGS_cs(%esp),%al

        testl $(3|X86_EFLAGS_VM),%eax

        jnz   test_all_events

        jmp   restore_all_xen

test_all_events:

        xorl %ecx,%ecx

        notl %ecx

        cli                             # tests must not race interrupts

/*test_softirqs:*/ 

        movl VCPU_processor(%ebx),%eax

        shl  $IRQSTAT_shift,%eax

        test %ecx,irq_stat(%eax,1)

        jnz  process_softirqs

        btr  $_VCPUF_nmi_pending,VCPU_flags(%ebx)

        jc   process_nmi

process_softirqs:

        sti      

        call do_softirq

        jmp  test_all_events


对于XEN虚拟环境,还有两处:

domain_crash_synchronous()->__domain_crash_synchronous()-> do_softirq()

arch_vmx_do_resume()-->hvm_do_resume()->wait_on_xen_event_channel(port, condition)->do_softirq()

 

 

你可能感兴趣的:(System,domain,action,Crash,xen,events)