Soft Irq & work queue & tasklet

Linux下中断机制之tasklet执行过程(详细)总结 一、简介 由于中断会打断内核中进程的正常调度运行,所以要求中断服务程序尽可能的短小精悍;但是在实际系统中,当中断到来时,要完成工作往往进行大量的耗时处理。因此期望让中断处理程序运行得快,并想让它完成的工作量多,这两个目标相互制约,诞生——顶/底半部机制,本文主要介绍tasklet的执行过程。 读者可根据情况了解以下知识: 软中断过程总结 中断机制详细总结 由于软中断必须使用可重入函数,这就导致设计上的复杂度变高,作为设备驱动程序的开发者来说,增加了负担。而如果某种应用并不需要在多个CPU上并行执行,那么软 阅读详情

Soft Irq、tasklet和work queue并不是Linux内核中一直存在的机制,而是由更早版本的内核中的“下半部”(bottom half)演变而来。下半部的机制实际上包括五种,但2.6版本的内核中,下半部和任务队列的函数都消失了,只剩下了前三者。本文重点在于介绍这三者之间的关系。(函数细节将不会在本文中出现,可以参考文献,点这里)

(1)上半部和下半部的区别
上半部指的是中断处理程序,下半部则指的是一些虽然与中断有相关性但是可以延后执行的任务。举个例子:在网络传输中,网卡接收到数据包这个事件不一定需要马上被处理,适合用下半部去实现;但是用户敲击键盘这样的事件就必须马上被响应,应该用中断实现。
两者的主要区别在于:中断不能被相同类型的中断打断,而下半部依然可以被中断打断;中断对于时间非常敏感,而下半部基本上都是一些可以延迟的工作。由于二者的这种区别,所以对于一个工作是放在上半部还是放在下半部去执行,可以参考下面四条:
a)如果一个任务对时间非常敏感,将其放在中断处理程序中执行。
b)如果一个任务和硬件相关,将其放在中断处理程序中执行。
c)如果一个任务要保证不被其他中断(特别是相同的中断)打断,将其放在中断处理程序中执行。
d)其他所有任务,考虑放在下半部去执行。

(2)为什么要使用软中断?
软中断作为下半部机制的代表,是随着SMP(share memory processor)的出现应运而生的,它也是tasklet实现的基础(tasklet实际上只是在软中断的基础上添加了一定的机制)。软中断一般是“可延迟函数”的总称,有时候也包括了tasklet(请读者在遇到的时候根据上下文推断是否包含tasklet)。它的出现就是因为要满足上面所提出的上半部和下半部的区别,使得对时间不敏感的任务延后执行,而且可以在多个CPU上并行执行,使得总的系统效率可以更高。它的特性包括:
a)产生后并不是马上可以执行,必须要等待内核的调度才能执行。软中断不能被自己打断,只能被硬件中断打断(上半部)。
b)可以并发运行在多个CPU上(即使同一类型的也可以)。所以软中断必须设计为可重入的函数(允许多个CPU同时操作),因此也需要使用自旋锁来保护其数据结构。

(3)为什么要使用tasklet?(tasklet和软中断的区别)
由于软中断必须使用可重入函数,这就导致设计上的复杂度变高,作为设备驱动程序的开发者来说,增加了负担。而如果某种应用并不需要在多个CPU上并行执行,那么软中断其实是没有必要的。因此诞生了弥补以上两个要求的tasklet。它具有以下特性:
a)一种特定类型的tasklet只能运行在一个CPU上,不能并行,只能串行执行。
b)多个不同类型的tasklet可以并行在多个CPU上。
c)软中断是静态分配的,在内核编译好之后,就不能改变。但tasklet就灵活许多,可以在运行时改变(比如添加模块时)。
tasklet是在两种软中断类型的基础上实现的,但是由于其特殊的实现机制(将在4.3节详细介绍),所以具有了这样不同于软中断的特性。而由于这种特性,所以降低了设备驱动程序开发者的负担,因此如果不需要软中断的并行特性,tasklet就是最好的选择。

(4)可延迟函数(软中断及tasklet)的使用
一般而言,在可延迟函数上可以执行四种操作:初始化/激活/执行/屏蔽。屏蔽我们这里不再叙述,前三个则比较重要。下面将软中断和tasklet的三个步骤分别进行对比介绍。

(4.1)初始化
初始化是指在可延迟函数准备就绪之前所做的所有工作。一般包括两个大步骤:首先是向内核声明这个可延迟函数,以备内核在需要的时候调用;然后就是调用相应的初始化函数,用函数指针等初始化相应的描述符。
如果是软中断则在内核初始化时进行,其描述符定义如下:

    struct softirq_action
                   {
                                      void (*action)( struct softirq_action *);
                                      void*data;
                   };

在\kernel\softirq.c文件中包括了32个描述符的数组static struct softirq_action softirq_vec[32];但实际上只有前6个已经被内核注册使用(包括tasklet使用的HI_SOFTIRQ/TASKLET_SOFTIRQ和网络协议栈使用的NET_TX_SOFTIRQ/NET_RX_SOFTIRQ,还有SCSI存储和系统计时器使用的两个),剩下的可以由内核开发者使用。需要使用函数:
         void open_softirq(int nr, void (*action)(struct softirq_action*), void *data)
初始化数组中索引为nr的那个元素。需要的参数当然就是action函数指针以及data。例如网络子系统就通过以下两个函数初始化软中断(net_tx_action/net_rx_action是两个函数):

       open_softirq(NET_TX_SOFTIRQ,net_tx_action);
         open_softirq(NET_RX_SOFTIRQ,net_rx_action);

这样初始化完成后实际上就完成了一个一一对应的关系:当内核中产生到NET_TX_SOFTIRQ软中断之后,就会调用net_tx_action这个函数。
tasklet则可以在运行时定义,例如加载模块时。定义方式有两种:
静态声明

DECLARE_TASKET(name, func, data)
DECLARE_TASKLET_DISABLED(name, func, data)

动态声明

voidtasklet_init( struct tasklet_struct *t,  void (*func)(unsigned  long), unsigned  long data)

其参数分别为描述符,需要调用的函数和此函数的参数—必须是unsigned long类型。也需要用户自己写一个类似net_tx_action的函数指针func。初始化最终生成的结果就是一个实际的描述符,假设为my_tasklet(将在下面用到)。

(4.2)激活
激活标记一个可延迟函数为挂起(pending)状态,表示内核可以调用这个可延迟函数(即使在中断过程中也可以激活可延迟函数,只不过函数不会被马上执行);这种情况可以类比处于TASK_RUNNING状态的进程,处在这个状态的进程只是准备好了被CPU调度,但并不一定马上就会被调度。
软中断使用raise_softirq()函数激活,接收的参数就是上面初始化时用到的数组索引nr。
tasklet使用tasklet_schedule()激活,该函数接受tasklet的描述符作为参数,例如上面生成的my_tasklet:

tasklet_schedule(&my_tasklet)

(4.3)执行
执行就是内核运行可延迟函数的过程,但是执行只发生在某些特定的时刻(叫做检查点,具体有哪些检查点?详见《深入》p.177)。
每个CPU上都有一个32位的掩码__softirq_pending,表明此CPU上有哪些挂起(已被激活)的软中断。此掩码可以用local_softirq_pending()宏获得。所有的挂起的软中断需要用do_softirq()函数的一个循环来处理。
而对于tasklet,由于软中断初始化时,就已经通过下面的语句初始化了当遇到TASKLET_SOFTIRQ/HI_SOFTIRQ这两个软中断所需要执行的函数:

       open_softirq(TASKLET_SOFTIRQ, tasklet_action, NULL);
         open_softirq(HI_SOFTIRQ, tasklet_hi_action, NULL);

因此,这两个软中断是要被区别对待的。tasklet_action和tasklet_hi_action内部实现就是为什么软中断和tasklet有不同的特性的原因(当然也因为二者的描述符不同,tasklet的描述符要比软中断的复杂,也就是说内核设计者自己多做了一部分限制的工作而减少了驱动程序开发者的工作)。

(5)为什么要使用工作队列work queue?(work queue和软中断的区别)
上面我们介绍的可延迟函数运行在中断上下文中(软中断的一个检查点就是do_IRQ退出的时候),于是导致了一些问题:软中断不能睡眠、不能阻塞。由于中断上下文出于内核态,没有进程切换,所以如果软中断一旦睡眠或者阻塞,将无法退出这种状态,导致内核会整个僵死。但可阻塞函数不能用在中断上下文中实现,必须要运行在进程上下文中,例如访问磁盘数据块的函数。因此,可阻塞函数不能用软中断来实现。但是它们往往又具有可延迟的特性。
因此在2.6版的内核中出现了在内核态运行的work queue(替代了2.4内核中的任务队列)。它也具有一些可延迟函数的特点(需要被激活和延后执行),但是能够能够在不同的进程间切换,以完成不同的工作。

【信息科学与工程学】【产品体系】计算机科学与自动化——第一百八十九篇 操作系统内核(微内核/宏内核)函数与算法02 宏内核(Linux)更多典型内核函数/算法,从编号271开始,覆盖中断管理、热插拔、PCI、ACPI、固件、崩溃转储、kexec、休眠、watchdog、RTC、hwmon、LED、backlight、input子系统、remoteproc等更多领域。编号类型领域内核类型内核中的函数/算法/模块/模组模块的调用关系模块/函数/算法逐步推理思考的数学表达式及参数列表及参数数值设计模块的C/C++/其他代码关联知识271中断管理中断描述符宏内核 / (中断子系统核心)驱动申请中断 → → → 分配irq_ 阅读详情

相关推荐

软件测试学习笔记(二)图覆盖

软件测试学习笔记(二)图覆盖 课程链接软件测试_中国大学MOOC 2.1 测试中的图 2.2 图覆盖准则 1、什么是图? 点的集合和边的集合。点或者结点,有穷非空的集合。边是点对。 2、图为什么在软件测试中具有重要地位? 所谓软件测试就是将软件变作一张图,然后覆盖它,不仅仅是软件,图更是计算机科学重要的结构。 3、软件测试中的图是如何得到的? 常见的图可以来自源代码,常见的是控制流图,还有各种各样...

DZFinder的博客 1420

Linux的tasklet函数详解

tasklet主要用在中断函数中。它对于中断处理特别有用,由于硬件中断必须尽快处理, 但大部分的数据管理可以延后到以后安全的时间执行。所以可以使用tasklet。 tasklet的使用比较简单,只需要定义tasklet及其处理函数并将两者关联即可,在定义时可以采用两种形式。 例子: struct tasklet_struct my_tasklet; Void my...

Android/Linux驱动开发传帮带学习,让驱动入门门槛更低! 3505

十、强势股的起爆点:第三类买点的实战精解

本文深入解析强势股交易中的第三类买点(三买)实战技巧,涵盖两种经典模式:突破首个中枢后的回踩和底部反转后的直接脱离下跌中枢。通过详细案例和数据分析,揭示三买在捕捉主升浪起爆点时的黄金信号作用,帮助投资者优化风险收益比,提升短线交易成功率。

weixin_30260191的博客 310

中断机制以及中断上下部运行和内核代码分析

中断也称外中断,指来自CPU执行指令以外的事件发生(这里的中断是狭义上的中断)异常也称内中断、例外或陷入,指源自CPU执行指令内部的事件。

qq_58538265的博客 1242

记一次完整的RPG Maker MV游戏逆向过程(思路一)

了解RPG Maker MV的文件建构 上一篇文章,我们已经成功在PC上运行了游戏,那我们如何对游戏进行逆向呢? 首先要了解正常的RPG Maker MV制作的游戏应该具有哪些文件,以及他的结构 那如何了解他的结构呢,很简单,我们只需要用RPG Maker MV创建一个默认工程,来看看一个游戏的最简结构是怎么样的 创建新项目 项目创建完成 查看项目目录结构 是不是和之前解包出来的很像呢? 通...

Ciiiiiing的博客 1万+

ESP32学习,驱动LED点阵屏,SD卡播放GIF动图

搬运就可以实现效果,如果有不足,请批评指正。下步该学一下如何文章上视频了,老是截图不方便展示效果。

u011625956的博客 1868

linux内核源码分析之中断tasklet

硬件中断(hardware interrupt):由系统自身和与之连接的外设自动产生。它们用于支持更高效 地实现设备驱动程序,也用于引起处理器自身对异常或错误的关注 软中断(SoftIRQ):用于有效实现内核中的延期操作。 同步中断和异常: 这些由CPU自身产生,针对当前执行的程序 异常可能因种种原因触发: 运行时发生的程序设计错误(典型的例子是除0); 出现了异常的情况或条件。 异步中断:这是经典的中断类型,由外部设备产生,可能发生在任意时间。 ...

1600

带挂牵引车前向运动模型推导及仿真实现

牵引车-半挂车的车辆结构与普通的车辆相比增加了一个半挂车,它们之间通过鞍座相连接,为了分析半挂牵引车运动过程中的位姿和状态,本文将基于车辆的机械结构建立对应的运动学模型,该模型基于以下假设: 车辆行驶过程中,道路平坦且无凸凹; 车辆低速行驶,且运行过程中车身无侧倾和俯仰运动; 车辆行驶过程中,轮胎无形变,无侧向滑动,且无侧向力; 牵引车和半挂车均满足阿克曼转向几何原理; 牵引车与半挂车不会发现折叠。

jianmo的博客 3181

Linux中断(tasklet,工作队列,内核线程的使用)

本篇文章来讲解在Linux中tasklet,工作队列,内核线程的使用。本篇文章就讲解到这里,需要大家好好理解并进行实践。

m0_49476241的博客 1622

Altium Designer应用技巧13: 四层板的拼版方法

本文介绍在Altium Designer中,进行4层板的拼版方法。Altium Designer有多种拼版方法,本文选择最直观的复制、删帖方法来完成,步骤如下: 1、看一下原始文件,如下图所示,我们要对该板进行拼版操作。 2、通过菜单“报告”-“板子信息”得到板子大小,在这里一般切换为mm比较好操作,我们可以使用快捷键"q"。 3、如果是水平拼版,我们需要关心水平长度;如果是垂直拼版...

snmplink的博客 1万+

LIS2DH三轴加速度传感器原理图设计,已量产(加速度传感器)

最近在做一款可穿戴设备原型时,选了 LIS2DH 这款加速度计 —— 比起之前常用的 ADXL345,它在低功耗和稳定性上的优化刚好戳中了可穿戴设备 “续航 + 可靠” 的核心需求。下面结合这次画的原理图,聊聊这个小模块的硬件设计细节。

不脱发的程序猿 388

softIRQ tasklet work_queue

Soft Irq、tasklet和work queue并不是Linux内核中一直存在的机制,而是由更早版本的内核中的“下半部”(bottom half)演变而来。下半部的机制实际上包括五种,但2.6版本的内核中,下半部和任务队列的函数都消失了,只剩下了前三者。本文重点在于介绍这三者之间的关系。(函数细节将不会在本文中出现,可以参考文献,点这里) (1)上半部和下半部的区别 上半部指的是中断

ssmale的专栏 1655

【时时三省】tessy 集成测试 总论

序论不积跬步无以至千里,不积小流无以成江海。正文。

时时三省的博客 1147

深入理解Linux网络技术内幕 P1-P2

细品

西门吹雪 540

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

中断API之tasklet_init/tasklet_kill

void tasklet_init(struct tasklet_struct *t,void (*func)(unsigned long), unsigned long data) 用于初始化一个tasklet. 其源码分析如下: void tasklet_init(struct tasklet_struct *t, void (*func)(unsigned long), unsign

jason的笔记 4955

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

linux驱动34:tasklet小任务机制

tasklet小任务机制

dongyoubin的博客 532

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Linux tasklet 分析笔记(转载)

Linux tasklet 分析笔记(转载)     原文作者:不详     原文地址:不详    Chapter 1:驱动程序在初始化时,通过函数task_init建立一个tasklet,然后调用函数tasklet_schedule将这个tasklet放在 tasklet_vec链表的头部,并唤醒后台线程ksoftirqd。当后台线程ksoftirqd运行调用__do_softi

言兼的专栏 1万+

软中断/tasklet/工作队列

《深入理解Linux内核》笔记4:软中断/tasklet/工作队列2009年06月02日 星期二 10:48软中断、tasklet和工作队列并不是Linux内核中一直存在的机制,而是由更早版本的内核中的“下半部”(bottom half)演变而来。下半部的机制实际上包括五种,但2.6版本的内核中,下半部和任务队列的函数都消失了,只剩下了前三者。本文重点在于介绍这三者之间

gchen_nj的专栏 854

linux内核tasklet机制

前言 前面讲了linux中断编程:顶半部、底半部 中断顶半部:做紧急的,耗时短的事情,同时还启动中断底半部(如果有)。 中断底半部:做耗时的事情,这个事件可以被中断 实现方法:tasklet、工作队列、软中断等机制。实际上是把耗时的事件推后执行,不在中断程序中执行。 内核tasklet机制tasklet机制是一种比较特殊的软中断,tasklet一词原意是“小片任务”的意思,这里

笔记用 1306

Linux下中断下文tasklet的应用

Linux把中断分为两个部分,一个是上半部分,一个是下半部分,在上半部分只处理紧急的事情,同时调用tasklet来启动中断下文,比较耗时的就放到下文来处理,调用tasklet以后,tasklet绑定的函数并不会立刻执行,而是中断出现以后,经过一个很短的不确定时间再执行。tasklet是中断处理中断下文常用的一种方法,tasklet是一种特殊的软中断,处理中断下文的机制还有工作队列和软中断。

西岸贤 1879

中断管理常用API详解(一)

通过此 tasklet_schedule () 函数修改中断状态值,设置 state 字段的值为 1,证明此中断被调用,将它加入中断等待队列当中。然后调用函数 __tasklet_schedule 将中断加入 tasklet_vec 中断向量链表的尾部,等待获取 CPU 资源并被调度处理。不管动态还是静态,都需要传递一个函数地址,此函数就是每个 tasklet 自己需要实现的处理函数 func 来改变一个 tasklet 对象状态。一、tasklet_init(...),本质是一个 per-CPU 的。

m0_74186706的博客 690

驱动程序使用tasklet机制

驱动程序在初始化时,通过函数task_init建立一个tasklet,然后调用函数tasklet_schedule将这个tasklet放在tasklet_vec链表的头部,并唤醒后台线程ksoftirqd。当后台线程ksoftirqd运行调用__do_softirq时,会执行在中断向量表softirq_vec里中断号TASKLET_SOFTIRQ对应的tasklet_action函数,

RichardYSteven的专栏 1761

深入理解 Linux 内核---中断和异常

中断或异常会改变处理器执行的指令顺序。 异常: 来源:CPU 控制单元, 时机:只有在一条指令终止执行后 CPU 才会发出中断。 原因:程序产生错误,或内核必须处理的异常条件。 中断: 来源:间隔定时器或 I/O 设备。 时机:随机产生。 原因:依照 CPU 时钟信号。 中断信号的作用 为什么要引入中断信号?因为中断信可使得处理器转而去运行正常控制流之外的代码。 当中断信号到来时,CPU ...

新博客:https://aping-dev.com/ 3159

Linux嵌入式驱动开发-linux中断

GIC 是 ARM 公司给 Cortex-A/R 内核提供的一个中断控制器,类似 Cortex-M 内核中的NVIC。当 GIC 接收到外部中断信号以后就会报给 ARM 内核,但是ARM 内核只提供了四个信号给 GIC 来汇报中断情况:VFIQ、VIRQ、FIQ 和 IRQ,他们之间的关系如下:GIC 接收众多的外部中断,然后对其进行处理,最终就只通过四个信号报给 ARM 内核,这四个信号的含义如下:GIC 将众多的中断源分为分为三类:SPI(Shared Peripheral Interrupt),共享中

小白的学习笔记 1100

linux中断下文之tasklet(中断二)

在申请 GPIO 中断时使用 request_irq,但是request_irq绑定的中断服务程序指的是中断上文。在 Linux 内核中,tasklet 是一种特殊的软中断机制,被广泛用于处理中断下文相关的任务。它是一种常见且有效的方法,在多核处理系统上可以避免并发问题。Tasklet 绑定的函数在同一时间只能在一个 CPU 上运行,因此不会出现并发冲突。然而,需要注意的是,tasklet 绑定的函数中不能调用可能导致休眠的函数,否则可能引起内核异常。

123 556

【系列文章】Linux系统中断的应用02-中断下文 tasklet

在 Linux 内核中,tasklet 是一种特殊的软中断机制,被广泛用于处理中断下文相关的任务。它是一种常见且有效的方法,在多核处理系统上可以避免并发问题。Tasklet 绑定的函数在同一时间只能在一个 CPU 上运行,因此不会出现并发冲突。然而,需要注意的是,tasklet 绑定的函数中不能调用可能导致休眠的函数,否则可能引起内核异常。在 Linux 内核中,tasklet 结构体的定义位于 include/linux/interrupt.h 头文件中。

qq_56861680的博客 737
上一篇: 深入理解linux内核v4l2框架之videobuf
下一篇: linux内核SPI总线驱动分析(一)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值