中断处理之中断上下文、中断上下部和共享中断
1、中断上下部
- 设备的中断会打断内核中进程的正常调度和运行。
- 如上图描述了linux内核中断的处理机制。
- 在中断执行时间尽可能短和中断处理大量工作中找到一个
平衡点
,linux将中断处理函数分为上部(top half)和下部(botoom half)
。 - 上部完成尽可能少的紧急的中断,往往只是简单的寄存器读写操作并触发中断,将需要中断处理的程序放到下部的队列中,等待中断处理。
- 这样一来工作的中心就处于下部,下部来完成中断的绝大多数任务。下部中断处理程序可以被新的中断打断,上部中断不可被中断。
- 一句话总结是“上部中断触发,下部中断处理”。
总结
- 如果一个任务对时间十分敏感,将其放在上部。
- 如果一个任务和硬件有关,将其放在上部。
- 如果一个任务保证不能被其他中断打断,将其放在上部。
- 其他所有任务,考虑放在下部。
1.1 实现下部中断的三种机制
软中断
- 软中断不能被其他软中断抢占,唯一可以抢占软中断的是中断处理程序,所以软中断允许响应中断
- 软中断留给对时间要求最严格的下部使用,目前只有网络、内核定时器和tasklet建立在软中断上。
tasklet
- 基于软中断实现,不允许睡眠(处于中断上下文)。
工作队列
- 实现一些tasklet不能实现的中断处理,比如睡眠。
- 工作队列执行中断程序时会表现出进程的特性,可以被重新调度,所以允许睡眠。
2、中断上下文
- 中断发生以后,cpu跳转到内核设置好的中断处理代码中去,由这部分内核代码处理中断,这个处理中断的上下文就是中断上下文。
- 进程睡眠与运行的状态是保存在task_struct结构体中,内核中断以后通过结构体判断进程的状态进行调度,但是中断上下文不是一个进程,不存在结构体存储状态,不能够被调度,所以中断上下文不能睡眠。
3、共享中断
- linux可以让多个设备共享同一个中断号,共享同一中断的中断处理程序会形成一个链表。
- 当中断产生,如果是共享的中断号,则对应链表的所有中断处理被调用,挨个遍历,内部检查参数信息和设备硬件支持,是不是这个中断程序对应的设备产生的中断,如果不是,立即返回,如果是,则调用该中断处理函数,如果链表中没有一个是,则说明出现错误。
- 判断是哪一个设备产生的中断,取决于第四个参数dev_id,这个参数必须唯一。