(转)linux中断 软中断

在分析linux内核的中断,软中断时,先应该明确这样一个派生关系:

irq ==> softirq ==> tasklet ==> bottom half ==> task queue------------------------|==> timer

中断是最初的原动力。分时系统依赖于时钟中断来定时重新调度可以运行的程序。外设通过中断来通知cpu处理相关的任务。中断处理程序是内核中一段特殊的,独立的,可运行实体。这个实体,某种程度上,是和进程或线程类似的。

由于中断需要快速处理,因此派生出来软中断softirq来处理中断没有处理完的事情。比如在网卡的驱动程序里,在中断环境里,只是把包放到一个队列里,然后由软中断来把包传递给进程,或者转发包等。

linux的softirq是不可重入的,因此,在单cpu的系统上,一次只能有一个软中断在运行。而在多cpu系统上,可以同时有多个softirq在运行。softirq可以处理更多的任务,一般如协议栈,文件系统等,都可以放到软中断里面处理。

tasklet是在softirq上的一个扩展。它是一段可以执行的代码片断,但是,一个tasklet同时只能在一个cpu上执行(一个tasklet只能有一个活动实体,而一个softirq可以有多个活动实体,但是softirq的活动实体是不可重入的)。

bottom half是linux 2.2.x以前的系统所采用的软中断机制,由于在smp上扩展性不好,现在已经不用了。bh也是一个可执行的代码片断,但是全局只能有一个bh在运行,多个bh之间是线性执行的,所以在smp系统上,浪费比较严重。

task queue是在bh机制上的一个扩展。也是一个可执行的代码片断。其目的是突破bh的数目限制(只有32个)。但是它的执行也是线性的,因此在smp上,也没什么优势。

timer也是bh上的一个扩展。每个timer都是一个可执行的片断,但是它更灵活,所以,如果有优先级高的任务,可以考虑使用timer。

在编写设备驱动时, tasklet 机制是一种比较常见的机制,通常用于减少中断处理的时间,将本应该是在中断服务程序中完成的任务转化成软中断完成。

为了最大程度的避免中断处理时间过长而导致中断丢失,有时候我们需要把一些在中断处理中不是非常紧急的任务放在后面执行,而让中断处理程序尽快返回。在老版本的 linux 中通常将中断处理分为 top half handler 、 bottom half handler 。利用 top half handler 处理中断必须处理的任务,而 bottom half handler 处理不是太紧急的任务。

但是 linux2.6 以后的 linux 采取了另外一种机制,就是软中断来代替 bottom half handler 的处理。而tasklet 机制正是利用软中断来完成对驱动 bottom half 的处理。 Linux2.6 中软中断通常只有固定的几种:HI_SOFTIRQ( 高优先级的 tasklet ,一种特殊的 tasklet) 、 TIMER_SOFTIRQ (定时器)、 NET_TX_SOFTIRQ(网口发送)、 NET_RX_SOFTIRQ (网口接收) 、 BLOCK_SOFTIRQ (块设备)、 TASKLET_SOFTIRQ (普通tasklet )。当然也可以通过直接修改内核自己加入自己的软中断,但是一般来说这是不合理的,软中断的优先级比较高,如果不是在内核处理频繁的任务不建议使用。通常驱动用户使用 tasklet 足够了。

软中断和 tasklet 的关系如下图:

上图可以看出, ksoftirqd 是一个后台运行的内核线程,它会周期的遍历软中断的向量列表,如果发现哪个软中断向量被挂起了( pend ),就执行对应的处理函数,对于 tasklet 来说,此处理函数就是tasklet_action ,这个处理函数在系统启动时初始化软中断的就挂接了。

Tasklet_action 函数,遍历一个全局的 tasklet_vec 链表(此链表对于 SMP 系统是每个 CPU 都有一个),此链表中的元素为 tasklet_struct 。此结构如下 :

struct tasklet_struct

{

struct tasklet_struct *next;

unsigned long state;

atomic_t count;

void (*func)(unsigned long);

unsigned long data;

};

每个结构一个函数指针,指向你自己定义的函数。当我们要使用 tasklet ,首先新定义一个tasklet_struct 结构,并初始化好要执行函数指针,然后将它挂接到 task_vec 链表中,并发一个软中断就可以等着被执行了。

原理大概如此,对于 linux 驱动的作者其实不需要关心这些,关键是我们如何去使用 tasklet 这种机制。

Linux 中提供了如下接口:

DECLARE_TASKLET(name,function,data) :此接口初始化一个 tasklet ;其中 name 是 tasklet 的名字,function 是执行 tasklet 的函数; data 是 unsigned long 类型的 function 参数。

static inline void tasklet_schedule(struct tasklet_struct *t) :此接口将定义后的 tasklet 挂接到cpu 的 tasklet_vec 链表,具体是哪个 cpu 的 tasklet_vec 链表,是根据当前线程是运行在哪个 cpu 来决定的。此函数不仅会挂接 tasklet ,而且会起一个软 tasklet 的软中断 , 既把 tasklet 对应的中断向量挂起(pend) 。

两个工作完成后,基本上可以了, tasklet 机制并不复杂,很容易的使程序尽快的响应中断,避免造成中断丢失。

(转)linux中断 软中断

时间: 2024-10-01 04:40:48

(转)linux中断 软中断的相关文章

Linux中断(interrupt)子系统之二:arch相关的硬件封装层【转】

转自:http://blog.csdn.net/droidphone/article/details/7467436 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] CPU的中断入口 初始化 中断控制器的软件抽象struct irq_chip 进入流控处理层 中断控制器的级联 Linux的通用中断子系统的一个设计原则就是把底层的硬件实现尽可能地隐藏起来,使得驱动程序的开发人员不用关注底层的实现,要实现这个目标,内核的开发者们必须把硬件相关的内容剥离出来,然后定义一些列标准

linux中断源码分析 - 中断发生(三)

本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 回顾 上篇文章linux中断源码分析 - 初始化(二)已经描述了中断描述符表和中断描述符数组的初始化,由于在初始化期间系统关闭了中断(通过设置CPU的EFLAGS寄存器的IF标志位为0),当整个中断和异常的初始化完成后,系统会开启中断(设置CPU的EFLAGS寄存器的IF标志位为1),此时整个系统的中断已经开始可以使用了.本篇文章我们具体研究一次典型中断发生时的运行流程. 中断产生 我们需要先明确一下,中断控

Linux中断技术、异常控制技术总结归类

相关学习资料 <深入理解计算机系统(原书第2版)>.pdf http://zh.wikipedia.org/zh/%E4%B8%AD%E6%96%B7 独辟蹊径品内核:Linux内核源代码导读 李云华著 中文 PDF版 https://www.kernel.org/ http://blog.csdn.net/orange_os/article/details/7485069 http://blog.csdn.net/sunnybeike/article/details/6958473 目录 1

Linux中断管理 (3)workqueue工作队列

目录: <Linux中断管理> <Linux中断管理 (1)Linux中断管理机制> <Linux中断管理 (2)软中断和tasklet> <Linux中断管理 (3)workqueue工作队列> 关键词: 工作队列的原理是把work(需要推迟执行的函数)交由一个内核线程来执行,它总是在进程上下文中执行. 工作队列的优点是利用进程上下文来执行中断下半部操作,因此工作队列允许重新调度和睡眠,是异步执行的进程上下文,它还能解决软中断和tasklet执行时间过长导

linux中断子系统:中断号的映射与维护

写在前沿: 好久好久没有静下心来整理一些东西了,开始工作已有一个月,脑子里想整理的东西特别多.记录是一种很好的自我学习方式,静下来多思考多总结,三年的工作目标不能发生变化,作为职场菜鸟即将进入全世界半导体第一的Intel working,是机遇更是一种挑战,困难也是可想而知.脚踏实地.仰望星空,以结果为导向,以目标为准则,争取每天进步一点点. Linux内核版本:3.4.39 一. linux中断子系统的irq_desc初始化 linux内核最初的中断初始化过程入口为start_kernel.在

Linux中断(interrupt)子系统之一:中断系统基本原理

这个中断系列文章主要针对移动设备中的Linux进行讨论,文中的例子基本都是基于ARM这一体系架构,其他架构的原理其实也差不多,区别只是其中的硬件抽象层.内核版本基于3.3.虽然内核的版本不断地提升,不过自从上一次变更到当前的通用中断子系统后,大的框架性的东西并没有太大的改变. /*****************************************************************************************************/ 声明:本博内容

linux中断流程详解

异常体系比较复杂,但是linux已经准备了很多的函数和框架,但是因为中断是和具体的开发板相关,所以中断需要我们自己来处理一些方面,但是这也是很少的一部分,很多公用的处理函数内核已经实现,linux内核搭建了一个非常容易扩充的中断处理体系. 中 断系统结构涉及的方面很多,而且分布在很多的函数中,这里我主要理清一些结构和流程顺序已经在哪些函数中实现,我不知道其他人怎么样?但是我自己一开始怎 是找不到linux内核是怎么把GPIO设置成中断的,我找了很久都找不到,还有我们很多的设置,初始化等等东西好像

Linux中断(interrupt)子系统之一:中断系统基本原理【转】

转自:http://blog.csdn.net/droidphone/article/details/7445825 这个中断系列文章主要针对移动设备中的Linux进行讨论,文中的例子基本都是基于ARM这一体系架构,其他架构的原理其实也差不多,区别只是其中的硬件抽象层.内核版本基于3.3.虽然内核的版本不断地提升,不过自从上一次变更到当前的通用中断子系统后,大的框架性的东西并没有太大的改变. /***************************************************

Linux中断(interrupt)子系统

Linux中断(interrupt)子系统之一:中断系统基本原理 Linux中断(interrupt)子系统之二:arch相关的硬件封装层 Linux中断(interrupt)子系统之三:中断流控处理层 Linux中断(interrupt)子系统之四:驱动程序接口层 & 中断通用逻辑层 Linux中断(interrupt)子系统之五:软件中断(softIRQ) http://blog.csdn.net/droidphone/article/details/7497787