Linux中断(interrupt)子系统之一:中断系统基本原理
才真正向硬件封装层发出关闭irq的调用,只有depth==1时才会向硬件封装层发出打开irq的调用。disable的嵌套次数可以比enable的次数多,此时depth的值大于1,随着enable的不断调用,当depth的值为1时,在向硬件封装层发出打开irq的调用后,depth减去1后,此时depth为0,此时处于一个平衡状态,我们只能调用disable_irq,如果此时enable_irq被调用,内核会报告一个irq失衡的警告,提醒驱动程序的开发人员检查自己的代码。 lock 用于保护irq_desc结构本身的自旋锁。 affinity_hit 用于提示用户空间,作为优化irq和cpu之间的亲缘关系的依据。 pending_mask 用于调整irq在各个cpu之间的平衡。 wait_for_threads 用于synchronize_irq(),等待该irq所有线程完成。 irq_data结构中的各字段: irq 该结构所对应的IRQ编号。 hwirq 硬件irq编号,它不同于上面的irq; node 通常用于hwirq和irq之间的映射操作; state_use_accessors 硬件封装层需要使用的状态信息,不要直接访问该字段,内核定义了一组函数用于访问该字段:irqd_xxxx(),参见include/linux/irq.h。 chip 指向该irq所属的中断控制器的irq_chip结构指针 handler_data 每个irq的私有数据指针,该字段由硬件封转层使用,例如用作底层硬件的多路复用中断。 chip_data 中断控制器的私有数据,该字段由硬件封转层使用。 msi_desc 用于PCIe总线的MSI或MSI-X中断机制。 affinity 记录该irq与cpu之间的亲缘关系,它其实是一个bit-mask,每一个bit代表一个cpu,置位后代表该cpu可能处理该irq。 这是通用中断子系统系列文章的第一篇,这里不会详细介绍各个软件层次的实现原理,但是有必要对整个架构做简要的介绍: 系统启动阶段,取决于内核的配置,内核会通过数组或基数树分配好足够多的irq_desc结构; 根据不同的体系结构,初始化中断相关的硬件,尤其是中断控制器; 为每个必要irq的irq_desc结构填充默认的字段,例如irq编号,irq_chip指针,根据不同的中断类型配置流控handler; 设备驱动程序在初始化阶段,利用request_threaded_irq() api申请中断服务,两个重要的参数是handler和thread_fn; 当设备触发一个中断后,cpu会进入事先设定好的中断入口,它属于底层体系相关的代码,它通过中断控制器获得irq编号,在对irq_data结构中的某些字段进行处理后,会将控制权传递到中断流控层(通过irq_desc->handle_irq); 中断流控处理代码在作出必要的流控处理后,通过irq_desc->action链表,取出驱动程序申请中断时注册的handler和thread_fn,根据它们的赋值情况,或者只是调用handler回调,或者启动一个线程执行thread_fn,又或者两者都执行; 至此,中断最终由驱动程序进行了响应和处理。 6. 中断子系统的proc文件接口 在/proc目录下面,有两个与中断子系统相关的文件和子目录,它们是: /proc/interrupts:文件 /proc/irq:子目录 读取interrupts会依次显示irq编号,每个cpu对该irq的处理次数,中断控制器的名字,irq的名字,以及驱动程序注册该irq时使用的名字,以下是一个例子:
/proc/irq目录下面会为每个注册的irq创建一个以irq编号为名字的子目录,每个子目录下分别有以下条目: smp_affinity irq和cpu之间的亲缘绑定关系; smp_affinity_hint 只读条目,用于用户空间做irq平衡只用; spurious 可以获得该irq被处理和未被处理的次数的统计信息; handler_name 驱动程序注册该irq时传入的处理程序的名字; 根据irq的不同,以上条目不一定会全部都出现,以下是某个设备的例子: # cd /proc/irq # ls ls 332 248 ...... ...... 12 11 default_smp_affinity # ls 332 bcmsdh_sdmmc spurious node affinity_hint smp_affinity # cat 332/smp_affinity 可见,以上设备是一个使用双核cpu的设备,因为smp_affinity的值是3,系统默认每个中断可以由两个cpu进行处理。 本章内容结束。接下来的计划: Linux中断(interrupt)子系统之二:arch相关的硬件封装层 Linux中断(interrupt)子系统之三:中断流控处理层 Linux中断(interrupt)子系统之四:驱动程序接口层 Linux中断(interrupt)子系统之五:软件中断(softirq)
- REDIce-Linux--灵活的实时Linux内核(11-12)
- linux文件系统基础(02-09)
- Linux标准趋向统一(11-12)
- linux基础技术(02-09)
- LINUX的目录树(02-09)
- 在Windows下启动Linux(02-09)