Linux内核——中断机制

中断机制

为什么需要中断?

如果让内核定期对设备进行轮询,以便处理设备,那会做很多无用功,因为外设的处理速度一般慢于CPU,而CPU不能一直等待外部事件。所以能让设备在需要内核时主动通知内核,会是一个聪明的方式,这便是中断。

中断处理程序

在响应一个特定中断时,内核会执行一个函数——中断处理程序。中断处理程序与其他内核函数的区别在于,中断处理程序是被内核调用来响应中断的,而它们运行于我们称之为中断上下文的特殊上下文中。

中断处理程序就是普通的C代码。特别之处在于中断处理程序是在中断上下文中运行的,它的行为受到某些限制:

1)不能向用户空间发送或接受数据

2)不能使用可能引起阻塞的函数

3)不能使用可能引起调度的函数

注册与释放中断

设备驱动程序利用request_irq()注册中断处理程序,并激活给定的中断线。返回0表示成功,或者返回一个错误码。

卸载设备驱动程序时,需要注销相应的中断处理程序,并释放中断线,这时需要调用free_irq——如果在给定的中断线上没有中断处理程序,则注销响应的处理程序,并禁用其中断线。

上下半部机制

我们期望让中断处理程序运行得快,并想让它完成的工作量多,这两个目标相互制约,如何解决——上下半部机制。

我们把中断处理切为两半。中断处理程序是上半部——接受中断,他就立即开始执行,但只有做严格时限的工作。能够被允许稍后完成的工作会推迟到下半部去,此后,在合适的时机,下半部会被开终端执行。上半部简单快速,执行时禁止一些或者全部中断。下半部稍后执行,而且执行期间可以响应所有的中断。这种设计可以使系统处于中断屏蔽状态的时间尽可能的短,以此来提高系统的响应能力。上半部只有中断处理程序机制,而下半部的实现有软中断实现,tasklet实现和工作队列实现。

我们用网卡来解释一下这两半。当网卡接受到数据包时,通知内核,触发中断,所谓的上半部就是,及时读取数据包到内存,防止因为延迟导致丢失,这是很急迫的工作。读到内存后,对这些数据的处理不再紧迫,此时内核可以去执行中断前运行的程序,而对网络数据包的处理则交给下半部处理。

上下半部划分原则

1)      如果一个任务对时间非常敏感,将其放在中断处理程序中执行;

2)      如果一个任务和硬件有关,将其放在中断处理程序中执行;

3)      如果一个任务要保证不被其他中断打断,将其放在中断处理程序中执行;

4)      其他所有任务,考虑放置在下半部执行。

下半部实现机制之软中断

软中断作为下半部机制的代表,是随着SMP(share memoryprocessor)的出现应运而生的,它也是tasklet实现的基础(tasklet实际上只是在软中断的基础上添加了一定的机制)。软中断一般是“可延迟函数”的总称,有时候也包括了tasklet(请读者在遇到的时候根据上下文推断是否包含tasklet)。它的出现就是因为要满足上面所提出的上半部和下半部的区别,使得对时间不敏感的任务延后执行,软中断执行中断处理程序留给它去完成的剩余任务,而且可以在多个CPU上并行执行,使得总的系统效率可以更高。它的特性包括:

a)产生后并不是马上可以执行,必须要等待内核的调度才能执行。软中断不能被自己打断,只能被硬件中断打断(上半部)。

b)可以并发运行在多个CPU上(即使同一类型的也可以)。所以软中断必须设计为可重入的函数(允许多个CPU同时操作),因此也需要使用自旋锁来保护其数据结构。

下半部实现机制之tasklet

tasklet是通过软中断实现的,所以它本身也是软中断。

软中断用轮询的方式处理。假如正好是最后一种中断,则必须循环完所有的中断类型,才能最终执行对应的处理函数。显然当年开发人员为了保证轮询的效率,于是限制中断个数为32个。

为了提高中断处理数量,顺道改进处理效率,于是产生了tasklet机制。

Tasklet采用无差别的队列机制,有中断时才执行,免去了循环查表之苦。Tasklet作为一种新机制,显然可以承担更多的优点。正好这时候SMP越来越火了,因此又在tasklet中加入了SMP机制,保证同种中断只能在一个cpu上执行。在软中断时代,显然没有这种考虑。因此同一种软中断可以在两个cpu上同时执行,很可能造成冲突。

总结下tasklet的优点:

(1)无类型数量限制;

(2)效率高,无需循环查表;

(3)支持SMP机制;

它的特性如下:

1)一种特定类型的tasklet只能运行在一个CPU上,不能并行,只能串行执行。

2)多个不同类型的tasklet可以并行在多个CPU上。

3)软中断是静态分配的,在内核编译好之后,就不能改变。但tasklet就灵活许多,可以在运行时改变(比如添加模块时)。

下半部实现机制之工作队列(work queue)

上面我们介绍的可延迟函数运行在中断上下文中(软中断的一个检查点就是do_IRQ退出的时候),于是导致了一些问题:软中断不能睡眠、不能阻塞。由于中断上下文出于内核态,没有进程切换,所以如果软中断一旦睡眠或者阻塞,将无法退出这种状态,导致内核会整个僵死。但可阻塞函数不能用在中断上下文中实现,必须要运行在进程上下文中,例如访问磁盘数据块的函数。因此,可阻塞函数不能用软中断来实现。但是它们往往又具有可延迟的特性。

上面我们介绍的可延迟函数运行在中断上下文中,于是导致了一些问题,说明它们不可挂起,也就是说软中断不能睡眠、不能阻塞,原因是由于中断上下文出于内核态,没有进程切换,所以如果软中断一旦睡眠或者阻塞,将无法退出这种状态,导致内核会整个僵死。因此,可阻塞函数不能用软中断来实现。但是它们往往又具有可延迟的特性。而且由于是串行执行,因此只要有一个处理时间较长,则会导致其他中断响应的延迟。为了完成这些不可能完成的任务,于是出现了工作队列,它能够在不同的进程间切换,以完成不同的工作。

如果推后执行的任务需要睡眠,那么就选择工作队列,如果不需要睡眠,那么就选择软中断或tasklet。工作队列能运行在进程上下文,它将工作托付给一个内核线程。工作队列说白了就是一组内核线程,作为中断守护线程来使用。多个中断可以放在一个线程中,也可以每个中断分配一个线程。我们用结构体workqueue_struct表示工作者线程,工作者线程是用内核线程实现的。而工作者线程是如何执行被推后的工作——有这样一个链表,它由结构体work_struct组成,而这个work_struct则描述了一个工作,一旦这个工作被执行完,相应的work_struct对象就从链表上移去,当链表上不再有对象时,工作者线程就会继续休眠。因为工作队列是线程,所以我们可以使用所有可以在线程中使用的方法。

 Linux软中断和工作队列的作用是什么

Linux中的软中断和工作队列是中断上下部机制中的下半部实现机制。

1.软中断一般是“可延迟函数”的总称,它不能睡眠,不能阻塞,它处于中断上下文,不能进城切换,软中断不能被自己打断,只能被硬件中断打断(上半部),可以并发的运行在多个CPU上。所以软中断必须设计成可重入的函数,因此也需要自旋锁来保护其数据结构。

2.工作队列中的函数处在进程上下文中,它可以睡眠,也能被阻塞,能够在不同的进程间切换,以完成不同的工作。

可延迟函数和工作队列都不能访问用户的进程空间,可延时函数在执行时不可能有任何正在运行的进程,工作队列的函数有内核进程执行,他不能访问用户空间地址。

参考

Linux内核设计与实现

http://www.cnblogs.com/li-hao/archive/2012/01/12/2321084.html

http://blog.csdn.net/bluecloudmatrix/article/details/29180095

http://blog.csdn.net/dlutbrucezhang/article/details/8699776

http://blog.csdn.net/chdhust/article/details/12227383

Linux内核——中断机制

时间: 2024-10-14 18:50:17

Linux内核——中断机制的相关文章

《linux 内核分析》 第二周 实验

王一 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 本次课的核心是通过中断机制完成进程的调度 ,在本次课程中__init my_start_kernel作为入口函数,定义0号进程的tPCB结构体,通过复制来制造其他进程的tPCB数据结构,中断时间函数被 my_timer_handler周期性的调用来修改my_need_sched 的值,而0号进程一直在检测my_need_sched 的

Linux内核学习总结

李泽源 原创作品 转载请注明出处 <Linux内核分析>MOOC课程:http://mooc.study.163.com/course/USTC-1000029000 [Linux内核学习总结] 幸福来得很突然,这门课就快结束了…… 是时候,总结下这段时间的坚持了,也给同样对Linux内核有兴趣的你一个指南. 在这门课的学习过程中,按照老师的要求,每次课后都写一篇博文,这是一个很好的学习方式.每当写这些文章的时候,总是要多看几遍视频,再查查相关的资料,才能勉强凑成一个完整的文档:同时也把自己学

Linux内核工程导论——基础架构

基础功能元素 workqueue linux下的工作队列时一种将工作推后执行的方式,其可以被睡眠.调度,与内核线程表现基本一致,但又比内核线程使用简单,一般用来处理任务内容比较动态的任务链.workqueue有个特点是自动的根据CPU不同生成不同数目的队列.每个workqueue都可以添加多个work(使用queue_work函数). 模块支持 模块概述 可访问地址空间,可使用资源, 模块参数 用户空间通过"echo-n ${value} > /sys/module/${modulenam

《linux 内核分析》总结

王一+<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-100002900 一.linux 系统的理解和学习心得 操作系统作为一个运行任务和程序的平台,几乎所有的独立运行的计算平台上都有,小到一个51的最小系统,可以模拟简单的操作系统,大到超级计算机,平常最多的是Android系统,因为是目前为止大部分手机上所运行的操作系统,而这个操作系统的原型就是linux操作系统,它有很多优秀特性,多任务和多用户,开源和稳定.linux 操作系统

Linux内核分析期末总结

<Linux内核分析>期末总结 20135313吴子怡.北京电子科技学院 Chapter1 往期博客传送门 (1)计算机是如何工作的:Linux内核分析——第一周学习笔记 (2)操作系统是如何工作的:Linux内核分析——第二周学习笔记 (3)Linux系统启动过程:Linux内核分析——第三周学习笔记 (4)系统调用的方法: Linux内核分析——第四周学习笔记 Linux内核实验作业四 (5)分析system_call中断处理过程: Linux内核分析——第五周学习笔记 实验作业:使gdb

linux内核期中总结

一.计算机是如何工作的? 1.存储程序计算机工作模型 1)冯诺依曼体系结构 2)存储程序计算机工作模型 3)CPU识别什么样的指令?如何定义? API:程序员与计算机的接口界面. ABI:程序与CPU接口界面 2.X86汇编基础 1) X86 CPU的寄存器 2)常见汇编指令 http://www.cnblogs.com/20135132yoggie/p/5220003.html 二.操作系统是如何工作的 1.函数调用堆栈 1)三个法宝 计算机是如何工作的?(总结)——三个法宝(存储程序计算机.

Linux内核分析期末总结 20135115臧文君

Linux内核分析期末总结 注:作者:臧文君,原创作品转载请注明出处,<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.计算机是如何工作的 1.参考链接:http://www.cnblogs.com/CatherineZang/p/5218570.html 2.编译语句:gcc -S -o main.s main.c -m32 3.“三个法宝” (1)存储程序计算机工作模型,计算机系统最最基础性的逻辑结构:

Linux内核分析实验五

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 刘旸 + 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 在操作系统上运行的某个应用程序,如果

《Linux内核分析》 操作系统是如何工作的

范闻泽   原创作品转载请注明出处   <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 根据实验要求,在实验楼中的运行. 时间片轮转法 (输入vi main.c查看mykernel的源代码) mymain.c中最核心的代码 (myinterrupt.c的代码,每次时钟中断调用一次printk) 2.操作系统内核源代码[分析见注释] 1.mypcb.h//头文件,在其他的.c文件中引用:主要是数据结构的定义 1