Linux软中断实现详解(2.6.26.3)


Linux软中断的类型:

  1. enum  
  2.   
  3.         HI_SOFTIRQ=0,   
  4.         TIMER_SOFTIRQ,   
  5.         NET_TX_SOFTIRQ,   
  6.         NET_RX_SOFTIRQ,   
  7.         BLOCK_SOFTIRQ,   
  8.         TASKLET_SOFTIRQ,   
  9.         SCHED_SOFTIRQ,  
  10. #ifdef CONFIG_HIGH_RES_TIMERS   
  11.         HRTIMER_SOFTIRQ,  
  12. #endif   
  13.         RCU_SOFTIRQ,    /* Preferable RCU should always be the last softirq */  
  14. ;  

关键数据结构和函数介绍:

in_interrupt()函数:

  1. #define in_interrupt()          (irq_count())     
  2. #define irq_count()     (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK ))     
  3. #define preempt_count() (current_thread_info()->preempt_count)     
  4. #define SOFTIRQ_MASK    (__IRQ_MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT)     
  5. #define HARDIRQ_MASK    (__IRQ_MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT)     
  6. #define NMI_MASK        (__IRQ_MASK(NMI_BITS)     << NMI_SHIFT)     
  7. #define __IRQ_MASK(x)   ((1UL << (x))-1)     
  8. #define PREEMPT_BITS    8     
  9. #define SOFTIRQ_BITS    8     
  10. #define HARDIRQ_BITS    12     
  11. #define PREEMPT_SHIFT   0     
  12. #define SOFTIRQ_SHIFT   (PREEMPT_SHIFT + PREEMPT_BITS)     
  13. #define HARDIRQ_SHIFT   (SOFTIRQ_SHIFT + SOFTIRQ_BITS)  

可见,宏in_interrupt()检查当前进程thread_info结构中的preempt_count字段中硬中断和软中断计数器,其全为0,才返回0.

preempt_count字段的含义:

0-7:抢占计数器,记录显示禁用本地CPU内核抢占的次数,值等于0表示允许内核抢占。

8-15:表示软中断被禁用的程度,同样值为0表示处于激活状态。

16-27:表示本地CPU中断处理程序的嵌套数。

表示软中断的主要数据结构为softirq_action类型的数组,数组名为softirq_vec。

  1. 01.struct softirq_action      
  2. 02.{      
  3. 03.       void    (*action)(struct softirq_action *);      
  4. 04.       void    *data;      
  5. 05.};      
  6. 06.static struct softirq_action softirq_vec[32] __cacheline_aligned_in_smp;  

另外一个实现软中断的数据结构是irq_cpustat_t。

  1. 01.typedef struct {      
  2. 02.         unsigned int __softirq_pending;      
  3. 03.         unsigned long idle_timestamp;      
  4. 04.         unsigned int __nmi_count;       /* arch dependent */     
  5. 05.         unsigned int apic_timer_irqs;   /* arch dependent */     
  6. 06.         unsigned int irq0_irqs;      
  7. 07.         unsigned int irq_resched_count;      
  8. 08.         unsigned int irq_call_count;      
  9. 09.         unsigned int irq_tlb_count;      
  10. 10.         unsigned int irq_thermal_count;      
  11. 11.         unsigned int irq_spurious_count;      
  12. 12.} ____cacheline_aligned irq_cpustat_t;  

相关内容