本文是学习《Linux内核设计与实现》相关章节的笔记
让硬件在需要的时候向内核发出信号,这就是中断机制,而不是采用polling的方式,浪费过多的资源。由硬件产生的中断为异步中断,处理器自身产生的中断为同步中断。
目录
中断处理程序
对于特定中断,内核会执行相应的函数(中断处理程序ISR),中断处理程序是硬件驱动设备的一部分。再次说明,中断处理程序不和特定的设备关联,而是中断,有些设备能会产生多个中断。
注册中断处理程序
驱动程序通过request_irq()函数注册一个中断处理函数,并且激活(分配)给定的中断线。
int request_irq(unsigned int irq,
irq_handler_t handler,
unsigned long flags,
const char *name,
void *dev)
irq: 分配的中断号
handler: 指向中断处理函数。 typedef irqreturn_t (*irq_handler_t) (int, void *)
flags: 标志掩码,主要的两个参数是IRQF_DISABLED (中断处理期间,禁止所有其他中断),IRQF_SHARED (多个中断处理函数间共享中断线)
name: 中断相关设备的ASCII文本表示,如查看/proc/irq 或 /proc/interrupts
root@john-virtual-machine:/proc/irq# cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
0: 3 0 0 0 IO-APIC 2-edge timer
1: 0 0 35 12 IO-APIC 1-edge i8042
8: 1 0 0 0 IO-APIC 8-edge rtc0
9: 0 0 0 0 IO-APIC 9-fasteoi acpi
12: 0 0 1833 45 IO-APIC 12-edge i8042
14: 0 0 0 0 IO-APIC 14-edge ata_piix
15: 0 0 0 0 IO-APIC 15-edge ata_piix
16: 0 18818 749 0 IO-APIC 16-fasteoi vmwgfx, snd_ens1371
17: 227753 0 0 0 IO-APIC 17-fasteoi ehci_hcd:usb1, ioc0
18: 0 150 0 0 IO-APIC 18-fasteoi uhci_hcd:usb2
19: 0 4380 0 1058169 IO-APIC 19-fasteoi ens33
24: 0 0 0 0 PCI-MSI 344064-edge PCIe PME, pciehp
25: 0 0 0 0 PCI-MSI 346112-edge PCIe PME, pciehp
26: 0 0 0 0 PCI-MSI 348160-edge PCIe PME, pciehp
27: 0 0 0 0 PCI-MSI 350208-edge PCIe PME, pciehp
28: 0 0 0 0 PCI-MSI 352256-edge PCIe PME, pciehp
29: 0 0 0 0 PCI-MSI 354304-edge PCIe PME, pciehp
30: 0 0 0 0 PCI-MSI 356352-edge PCIe PME, pciehp
31: 0 0 0 0 PCI-MSI 358400-edge PCIe PME, pciehp
32: 0 0 0 0 PCI-MSI 360448-edge PCIe PME, pciehp
33: 0 0 0 0 PCI-MSI 362496-edge PCIe PME, pciehp
34: 0 0 0 0 PCI-MSI 364544-edge PCIe PME, pciehp
35: 0 0 0 0 PCI-MSI 366592-edge PCIe PME, pciehp
36: 0 0 0 0 PCI-MSI 368640-edge PCIe PME, pciehp
dev: 当公用中断线时,要通过这个标志信息(设备结构),确定调用哪一个中断处理程序。
request_irq()执行成功会返回0,否则非0。
free_irq(unsigned int irq, void *dev) 释放中断处理程序
当内核相应某一个中断线时,这个中断线在所有CPU都会被屏蔽掉,其他中断线可以相应。所以同一个中断处理程序绝对不会被同时调用。
对于共享中断线的情况,当有中断到来时,对应链表的所有中断都将被调用,每个中断处理程序的内部先检查(参数信息和硬件设备提供的状态寄存器)是不是这个中断处理程序对应的硬件产生的中断。
中断处理程序要求要在有限的时间内对中断进行处理,但是有些硬件的中断请求,很难在短时间内处理完,所以需要延后处理,例如网卡,数据包要从网卡缓存转移到内存中,这是很费时的。所以总的要求就是快速、异步、简单的机制负责对硬件做出迅速响应。
如果一个任务对时间非常敏感,将其放在中断处理程序中。
如果一个任务和硬件相关,将其放在中断处理程序中。
如果一个任务要保证不被其他中断打断,将其放在中断处理程序中。
下半部机制
用于指代中断处理流程中推后执行的那一部分。目前只需知道以下三种机制:
软中断、tasklet、工作队列
软中断
软中断是在编译期间静态分配的,由struct softirq_action 表示。Linux目前定义了32个该结构体的数组,使用了10个。
struct softirq_action
{
void (*action)(struct softirq_action *);
};
static struct softirq_action softirq_vec[NR_SOFTIRQS]
const char * const softirq_to_name[NR_SOFTIRQS] = {
"HI", "TIMER", "NET_TX", "NET_RX", "BLOCK", "IRQ_POLL",
"TASKLET", "SCHED", "HRTIMER", "RCU"
};
中断处理程序会在返回前标记它的软中断(触发软中断),使其在稍后合适的时候被执行。
从一个硬件中断代码处返回时
在ksoftirqd内核线程中
显示检查执行待处理的软中断
软中断保留给系统中对时间要求最严格以及最重要的下半部使用,目前只有网络和scsi直接使用软中断。内核定时器和tasklet都是建立在软中断上的。
关于tasklet和任务队列 以后有时间在记录。。。
未完待续