中断——linux内核设计与实现读书笔记

1、第一部分 中断处理程序(异步执行) :

1)任务特性:时间敏感、硬件相关、需要屏蔽其它中断。一般完成通过硬件确认中断、从硬件拷贝数据等功能。

硬件产生中断电信号,中断处理器发送至处理器——>处理器接收并向操作系统反应——>操作系统处理数据

与异常差别:异常(同步中断)产生必须与处理器时钟同步,由软件引起。但是两者的处理方式相似。

2)中断处理程序(中断服务例程,ISR)<linux/interrupt.h>

C函数,被内核调用来响应中断,是管理硬件的驱动程序的组成部分。运行在中断上下文中(又称原子上下文),该上下文中执行的代码不可阻塞。

上半部:主要负责通知硬件设备中断已经被接收,以及将硬件数据拷贝到内存,将处理交给协议栈或者应用程序。

注册:驱动程序通过request_irq(IRQ,handler,flags,name,dev)注册一个中断处理程序,得到中断线。

 参数:irq 分配的中断号;handler 指向实际的中断处理程序

flags 标志; name 与中断相关设备的文本表示; dev 用于共享中断线

释放中断处理函数:free(irg,dev)

编写中断处理函数 irqreturn_t handler(irq,dev) 返回至:IRQ_NONE,IRQ_HANDLED

共享中断处理函数需要设置标志位IRQF_SHARED,dev参数也必须唯一指定,以及硬件支持。

3)中断上下文

由于没有后备进程,中断上下文不能睡眠,因此不能从中断上下文调用可能睡眠的函数。

中断处理程序打断其它程序执行,因此应该迅速简洁。

中断处理程序栈是可配置选项,大小为一页。

4)实现机制

设备产生中断——总线(电信号)——>中断控制器(中断线处于激活状态)——中断(电信号)——>处理器没有禁止中断,关闭中断系统跳入内核预定义位置(每条中断线对应一个位置)执行代码。初始入口点在栈中存放IRQ号并存放当前寄存器的值,然后内核调用do_IRQ()。do_IRQ()应答所中断,禁止线上的中断传递。

5)proc/interrupt

procfs虚拟文件系统,存在于内核内存,安装在proc目录。通过内核函数读写文件,模拟真实文件读写。

例子:/proc/interrupts文件存放系统中与中断相关的统计信息。

6)中断控制

与体系结构相关,用于操作中断的接口,在<asm/system.h><asm/system.h>

禁止和激活当前处理器本地中断 local_irq_enable/disable; 禁止中断以及恢复到原来状态:local_irq_save/restore 保存中断前系统状态

禁止特定中断线:禁止给定中断向所有处理器传递 / 中断函数返回前中断线上没有处理程序

中断系统的状态:当前系统处于中断禁止或者激活状态irqs_disable(<asm/system.h>),检查内核当前上下文接口 <linux/hardirq.h>


2、第二部分 下半部

实现机制:

1)软中断 由softirq_action结构表示,定义于<linux/interrupt.h>,每个被注册的软中断都为kernel/softirq.c中数组中一项。

软中断处理程序:执行acton函数;执行:注册软中断——>被标记后触发,在do_softirq()中执行。中断处理程序在返回前标记软中断,使其稍后被执行。

使用:<linux/interrupt.h>静态声明软中断——>注册软中断处理程序open_softirq(索引号,函数)——>触发 raise_softirq()将软中断设置为挂起状态,调用do_softirq运行

2)tasklets

利用软中断实现的下半部机制。软中断一般用于执行频率很高和连续性要求很高的情况。

由tasklet_struct结构表示,包括链表指针、状态、处理函数、参数等。

由两类优先级不同的软中断实现:HI_SOFTIRQ,TASKLET_SOFTIRQ。分别由tasklet_schedule()和tasklet_hi_schedule()函数调度。

调度过程:检查链表中的tasklet状态——>调用_tasklet_schedule()——>保存中断状态,禁止本地状态——>将需要调度的tasklet加到处理器tasklet_vec链表表头——>唤起TASKLET_SOFTIRQ或HI_SOFTIRQ软中断——>恢复中断到原状态返回。

使用:声明tasklet(动态或者静态方式)——>编写tasklet处理程序tasklet_handler(data) 使用软中断实现——>调用tasklet_schedule(&my_tasklet),可以禁止、激活、去掉

是否及时处理所有软中断或者给用户执行事件的折中:当大量软中断出现——>内核唤醒处于最低优先级的内核线程处理负载 kesofirqd/n。

3)工作队列

推后工作,交由内核线程执行,在进程上下文执行,允许重新调度、睡眠。

实现:有创建内核线程的接口,创建的工作者线程负责执行队列中的任务。可以由驱动程序创建专门工作者线程处理工作,或者由缺省工作者线程events/n。

工作线程的数据结构:workqueue_struct,包含cpu_workqueue结构体。执行worker_thread()函数,循环&被唤醒&休眠。

工作的数据结构:<linux/workqueue.h>中的work_struct表示,连成链表供工作者线程执行。

使用工作队列:

I 创建工作 DECLARE_WORK(name,fun,data)。

II 工作队列处理函数 work_handler(data),由工作现场执行。

III 调度 。把给定的工作函数work给缺省events,调用schedule_work(&work)

IV 刷新操作。调用下面的函数或者防止竞争条件。

V 创建新的工作队列与之相应的工作者线程。workqueue_struct *create_workqueue(name)


3、三种机制的选择:

软中断:序列化保障少,性能最高。必须静态创建,三者中较难使用的。上下文是中断。

tasklet:不能并发运行的软中断。上下文是中断。

任务队列:把任务推后到进程上下文中完成。开销最大,易于使用。


下半部禁止: 一般有进程共享时,需要先得到锁再禁止下半部的处理。local_bh_enable(disable) 与硬件体系结构相关,能禁止异步的软中断和tasklet,位于<asm/softirq.h>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值