中断和异常-中断的下半部处理机制

Linux并不是一次性把中断所要求的事情全部做完,而是分两部分来做,下面具体描述内核如何处理中断的下半部。

一、为什么把中断分为两部分来处理

一般都是在中断请求关闭的条件下执行中断服务程序,以避免嵌套使中断控制复杂化。但是,中断是一个随机事件,随时会到来,如果关中断的时间太长,CPU不能响应其它的中断请求,会造成中断丢失。内核的目标是尽可能快地处理完中断请求,把更多的处理向后推迟。例如,假设一个数据块已到达网线,当中断控制器接收到这个中断请求信号时,Linux内核只是简单地标志数据到来,然后让处理器恢复到它以前运行的状态,其余的处理稍后再进行。因此,内核把中断处理分两部分:上半部和下半部上半部(中断服务程序)内核立即执行,下半部(就是一些内核函数)留着稍后处理,如图5.6所示。

首先,用一个快速的上半部来处理硬件发出的请求,它必须在一个新的中断产生之前终止。通常,除了在设备和一些内存缓冲区之间移动或传送数据,确定硬件是否处于健全的状态之外,这一部分的工作很少。

下半部运行时允许中断请求的,而上半部运行时是关中断的,这是二者之间的区别。

但内核到底什么时候执行下半部,以什么方式组织下半部?这是要讨论的下半部实现机制,这种机制在内核的演变过程中不断得到改进,在以前的内核中,这个机制叫做下半部,在2.4以后的版本中有新的发展和改进,改进的目标使下半部在多处理器上并发执行,有助于驱动程序的开发者进行驱动程序的开发,这种执行机制叫软中断机制。软中断中常用的小任务(Tasklet)机制及2.6版本内核中的工作队列机制。

二、小任务机制

小任务是指对要推迟执行的函数进行组织的一种机制。数据结构为tasklet_struct,每个结构代表一个独立的小任务,定义如下:

struct tasklet_struct
{
    struct tasklet_struct *next; /* 指向链表中的下一个元素 */
    unsigned long state;         /* 小任务的状态 */
    atomic_t count;                 /* 引用计数器 */
    void (*func)(unsigned long); /* 要调用的函数 */
    unsigned long data;             /* 传递给函数的参数 */
};

func域就是下半部中要推迟执行的函数,data是它唯一的参数。

state域的取值为TASKLET_STATE_SCHED或TASKLET_STATE_RUN。TASKLET_STATE_SCHED表示小任务已被调度,正准备投入运行,TASKLET_STATE_RUN表示小任务正在运行。TASKLET_STATE_RUN只有在多处理器系统上才使用,任何时候单处理器系统都清楚一个小任务是不是正在运行。

count域是小任务的引用计数器。如果它不为0,则小任务被禁止,不允许执行;只有当它为0,小任务才被激活,并且在被设置为挂起时,小任务才能够执行。

1、声明和使用小任务

大多数情况下,为了控制一个寻常的硬件设备,小任务机制是实现下半部的最佳选择。小任务可以动态创建,使用方便,执行起来比较快。

小任务可以静态创建,也可以动态创建。选择哪种方式取决于是到对小任务直接引用还是间接引用。如果静态创建一个小任务(也就是对它直接引用),可以使用如下两个宏中的任意一个:

#define DECLARE_TASKLET(name, func, data)

#define DECLARE_TASKLET_DISABLED(name, func, data)

这两个宏都能根据给定的名字静态创建一个tasklet_struct结构。当该小任务被调度后,给定的函数func被执行,其参数由data给出。这两个宏的区别在于引用计数器的初始值设置不同。DECLARE_TASKLET宏把创建的小任务的引用计数器设置为0,处于激活状态。

DECLARE_TASKLET_DISABLED宏把创建的小任务的引用计数器设置为1,处于禁止状态。例如:DECLARE_TASKLET(tasklet, taskl

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值