超强的Linux中断分析

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

超强的Linux中断分析[日期:2008-09-13] 来源:作者:

1) IPI中断的初始化。

intr_init_hook调用apic_intr_init(),后者再调用──如果CONFIG_SMP──smp_intr_init(),

这个函数设置IPI中断的处理,然后,apic_intr_init()为另外两个IPI:SPURIOUS_APIC_VECTOR和

ERROR_APIC_VECTOR设置ISR。

2) irq_desc[NR_IRQS]

struct irq_desc,亦即irq_desc_t,描述了一个irq的属性,如irqaction、depth、

pending_mask等。

include/linux/irq.h:

struct irq_desc {

irq_flow_handler_t handle_irq;

struct irq_chip *chip;

struct msi_desc *msi_desc;

void *handler_data;

void *chip_data;

struct irqaction *action; /* IRQ action list */

unsigned int status; /* IRQ status */

unsigned int depth; /* nested irq disables */

unsigned int wake_depth; /* nested wake enables */

unsigned int irq_count; /* For detecting broken IRQs */

unsigned int irqs_unhandled;

spinlock_t lock;

#ifdef CONFIG_SMP

cpumask_t affinity;

unsigned int cpu;

#endif

#if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE)

cpumask_t pending_mask;

#endif

#ifdef CONFIG_PROC_FS

struct proc_dir_entry *dir;

#endif

const char *name;

} ____cacheline_internodealigned_in_smp;

Linux有一个全局变量,包含了了所有的IRQ:(kernel/irq/handle.c)

struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned = {

[0 ... NR_IRQS-1] = {

.status = IRQ_DISABLED,

.chip = &no_irq_chip,

.handle_irq = handle_bad_irq,

.depth = 1,

.lock = SPIN_LOCK_UNLOCKED,

#ifdef CONFIG_SMP

.affinity = CPU_MASK_ALL

#endif

}

}

3) irq_chip(即在genericirq之前的hw_interrupt_type)

>以下这段是genericirq之前的:

>Linux支持N种可编程中断控制器PIC,所以有一个struct hw_interrupt_type,对于i8259A

>来说,这个结构是i8259A_irq_type,对于IOAPIC来说,根据设置为电平触发或边沿触发的方式,

>分别有ioapic_level_type和ioapic_edge_type两个不同的结构。

在引入genericirq补丁之后,定义了几个irq_chip结构:

针对i386和x86-64各有一个定义的:

ioapic_chip,

i8259A_chip,

lapic_chip,

msi_chip,

ht_irq_chip,

vmi_chip,

针对visw体系的:

cobalt_irq_chip,

piix4_master_irq_type,

piix4_virtual_irq_type

针对voyager体系的:

vic_chip

其它目的的:

no_irq_chip,

dummy_irq_chip

4) irq_stat[NR_CPUS]

Linux定义了一个全局的数组,用来描述每个CPU上的irq处理状态:(arch/i386/kernel/irq.c)

DEFINE_PER_CPU(irq_cpustat_t, irq_stat) __cacheline_internodealigned_in_smp;

EXPORT_PER_CPU_SYMBOL(irq_stat);

irq_stat_t的定义。

typedef struct {

unsigned int __softirq_pending;

unsigned long idle_timestamp;

unsigned int __nmi_count; /* arch dependent */

unsigned int apic_timer_irqs; /* arch dependent */

} ____cacheline_aligned irq_cpustat_t;

5). 中断共享

我们知道,多个中断源可以共享一个irq线。Linux的实现方式是,每个中断源都有自己的

一个struct irqaction,

irqaction结构的定义:

struct irqaction {

irq_handler_t handler;

unsigned long flags;

cpumask_t mask;

const char *name;

void *dev_id;

struct irqaction *next;

int irq;

struct proc_dir_entry *dir;

};

同一个irq可能有多个irqaction,组成一个链表。struct irq_desc中有个域:

相关文档
最新文档