【Linux内核】Linux软中断处理机制-ksoftirqd
1.前言
软中断(softirq)是中断处理程序在开启中断的情况下执行的部分,可以被硬中断抢占。把延迟函数叫做软中断并不是因为它是一个真正的中断,而是因为延迟函数主要在中断上下文环境中运行。Linux中最多可以支持32种软中断操作,但目前Linux只实现了其中的几种。
中断号 | 名称 | 作用 |
---|---|---|
0 | HI_SOFTIRQ | 高优先级tasklet |
1 | TIMER_SOFTIRQ | 定时器软中断 |
2 | NET_TX_SOFTIRQ | 网络发送软中断 |
3 | NET_RX_SOFTIRQ | 网络接收软中断 |
4 | SCSI_SOFTIRQ | SCSI设备驱动专用软中断 |
5 | TASKLET_SOFTIRQ | 常规tasklet |
include/linux/interrupt.henum{HI_SOFTIRQ=0,TIMER_SOFTIRQ,NET_TX_SOFTIRQ,NET_RX_SOFTIRQ,BLOCK_SOFTIRQ,IRQ_POLL_SOFTIRQ,TASKLET_SOFTIRQ,SCHED_SOFTIRQ,HRTIMER_SOFTIRQ, /* 没有使用,但是保留,因为有些工具依赖这个编号 */RCU_SOFTIRQ, /* RCU软中断应该总是最后一个软中断 */NR_SOFTIRQS};
2.关键函数
- 函数open_softirq()用来注册软中断的处理函数,在软中断向量表中为指定的软中断编号设置处理函数。
kernel/softirq.cvoid open_softirq(int nr, void (*action)(struct softirq_action *)){softirq_vec[nr].action = action;}
- 函数raise_softirq用来触发软中断,参数是软中断编号。
void raise_softirq(unsigned int nr);
3.执行软中断
内核执行软中断的地方如下。
- (1)在中断处理程序的后半部分执行软中断,对执行时间有限制:不能超过2毫秒,并且最多执行10次。
- (2)每个处理器有一个软中断线程,调度策略是SCHED_NORMAL,优先级是120。
- (3)开启软中断的函数local_bh_enable()。
在中断处理程序的后半部分,调用函数irq_exit()以退出中断上下文,处理软中断,其代码如下:
kernel/softirq.cvoid irq_exit(void){…preempt_count_sub(HARDIRQ_OFFSET);if (! in_interrupt() && local_softirq_pending())invoke_softirq();…}
如果正在处理的硬中断没有抢占正在执行的软中断,没有禁止软中断,并且当前处理器的待处理软中断位图不是空的,那么调用函数invoke_softirq()来处理软中断。
kernel/softirq.c1 static inline void invoke_softirq(void)2 {3 if (ksoftirqd_running())4 return;56 if (! force_irqthreads) {7 __do_softirq();8 } else {9 wakeup_softirqd();10 }11 }
第3行代码,如果软中断线程处于就绪状态或运行状态,那么让软中断线程执行软中断。第6行和第7行代码,如果没有强制中断线程化,那么调用函数__do_softirq()执行软中断。第8行和第9行代码,如果强制中断线程化,那么唤醒软中断线程执行软中断。函数__do_softirq是执行软中断的核心函数,其主要代码如下:
kernel/softirq.c1 #define MAX_SOFTIRQ_TIME msecs_to_jiffies(2)2 #define MAX_SOFTIRQ_RESTART 103 asmlinkage __visible void __softirq_entry __do_softirq(void)4 {5 unsigned long end = jiffies + MAX_SOFTIRQ_TIME;6 unsigned long old_flags = current->flags;7 int max_restart = MAX_SOFTIRQ_RESTART;8 struct softirq_action *h;9 bool in_hardirq;10 __u32 pending;11 int softirq_bit;1213 …14 pending = local_softirq_pending();15 …16 __local_bh_disable_ip(_RET_IP_, SOFTIRQ_OFFSET);17 …1819 restart:20 set_softirq_pending(0);2122 local_irq_enable();2324 h = softirq_vec;2526 while ((softirq_bit = ffs(pending))) {27 …28 h += softirq_bit - 1;29 …30 h->action(h);31 …32 h++;33 pending >>= softirq_bit;34 }3536 …37 local_irq_disable();3839 pending = local_softirq_pending();40 if (pending) {41 if (time_before(jiffies, end) && ! need_resched() &&42 --max_restart)43 goto restart;4445 wakeup_softirqd();46 }4748 …49 __local_bh_enable(SOFTIRQ_OFFSET);50 …51 }
第14行代码,把局部变量pending设置为当前处理器的待处理软中断位图。第16行代码,把抢占计数器的软中断计数加1。第20行代码,把当前处理器的待处理软中断位图重新设置为0。第22行代码,开启硬中断。第26~34行代码,从低位向高位扫描待处理软中断位图,针对每个设置了对应位的软中断编号,执行软中断的处理函数。第37行代码,禁止硬中断。第40行代码,如果软中断的处理函数又触发软中断,处理如下。❑ 第41~43行代码,如果软中断的执行时间小于2毫秒,不需要重新调度进程,并且软中断的执行次数没超过10,那么跳转到第19行代码继续执行软中断。第45行代码,唤醒软中断线程执行软中断。第49行代码,把抢占计数器的软中断计数减1。
4.ksoftirqd
软中断线程每个处理器有一个软中断线程,名称是“ksoftirqd/”后面跟着处理器编号,调度策略是SCHED_NORMAL,优先级是120。软中断线程的核心函数是run_ksoftirqd(),其代码如下:
kernel/softirq.cstatic void run_ksoftirqd(unsigned int cpu){local_irq_disable();if (local_softirq_pending()) {__do_softirq();local_irq_enable();…return;}local_irq_enable();}
5.参与讨论
==================================
新的文章内容和分享已更新在:
|工|·-·|重|·-·|号|:协议森林
==================================
【Linux内核】Linux软中断处理机制-ksoftirqd相关推荐
- linux kernel and user space通信机制,Linux内核与用户空间通信机制研究.pdf
ISSN 1009-3044 E-mail:info@CCCC.net.CR ComputerKnowledgeandTechnology电脑知识与技术 http://www.dnzs.net.cn ...
- 【Linux 内核】宏内核与微内核架构 ( 操作系统需要满足的要素 | 宏内核 | 微内核 | Linux 内核动态加载机制 )
文章目录 一.操作系统需要满足的要素 二.宏内核 三.微内核 四.Linux 内核动态加载机制 一.操作系统需要满足的要素 电脑上运行的 操作系统 , 是一个 软件 ; 设备管理 : 操作系统需要 为 ...
- Linux内核中的platform机制
Linux内核中的platform机制 从Linux 2.6起引入了一套新的驱动管理和注册机制:platform_device和platform_driver.Linux中大部分的设备驱动,都可以使用 ...
- linux 信号优先级,linux内核中的信号机制
linux内核中的信号机制--信号处理 Kernel version:2.6.14 CPU architecture:ARM920T Author:ce123(http://blog.csdn.net ...
- linux 内核 工作队列,Linux内核新旧工作队列机制的剖析和比较
摘要:在中断驱动的程序设计中,工作队列是一种强有力的工具.但是在Linux2.6.35及其以前的内核版本中,每创建一个工作队列就创建与CPU数目相同的内核线程,耗费大量的内核资源:工作只能严格串行的处 ...
- Linux内核中断系统处理机制-详细分析
原文地址::https://blog.csdn.net/weixin_42092278/article/details/81989449 相关文章 1.Linux中断管理 (1)Linux中断管理机制 ...
- Linux内核笔记--软中断
Linux软中断 1.软中断介绍 2.软中断的使用 2.1.注册软中断处理函数 2.2.触发软中断 1.软中断介绍 Linux 内核使用结构体 softirq_action 表示软中断, softir ...
- Linux内核中的RCU机制
http://blog.chinaunix.net/uid-23769728-id-3080134.html RCU的设计思想比较明确,通过新老指针替换的方式来实现免锁方式的共享保护.但是具体到代码的 ...
- 浅析linux内核中的idr机制
idr在linux内核中指的就是整数ID管理机制,从本质上来说,这就是一种将整数ID号和特定指针关联在一起的机制.这个机制最早是在2003年2月加入内核的,当时是作为POSIX定时器的一 ...
最新文章
- Xamarin ios C#苹果应用开发第二讲配置环境和编写代码
- 一个项目搞定支付宝,微信支付!
- python最适合做什么生意赚钱投资小_2018做什么投资小赚钱快(适合穷人做的简单生意)...
- 不要“个人英雄主义”,物联网安全共同体更稳固
- SAP Spartacus如何判断用户是否已经成功登录
- mysql 开启引擎命令_MySql中启用InnoDB数据引擎的方法
- Oracle访问数据的存取方法
- 第一张信用卡,该选哪家的?
- oracle中文加密算法,Oracle数据库替代加密算法
- processing作品代码_创意编程 | Processing的初步学习
- 空循环和无穷循环的区别
- PermissionError: [Errno 13] in python
- java.io.InvalidClassException
- 史上最全的ocr文字识别体验,让你一次用个够
- Olly's Shadow
- 一次使用 Go 语言编写脚本的经历
- 诺基亚安卓手机_诺基亚手机,为什么宁可走向衰弱,也不愿采用谷歌的安卓系统?...
- 小班关于计算机运用的教案,实用的小班教案四篇
- 小伙用C++代码实现P2P穿透文件传输,网友集体打call!
- 综合复习(五)——网络编程
热门文章
- 大力普及“他妈的”有助于语言交流
- Win11资源管理器(文件夹)出现的工具栏怎么隐藏?
- 解决问题最高明的方法:打开自己
- 【Faster R-CNN论文精度系列】从Faster R-CNN源码中,我们“学习”到了什么?
- 求解1+1/2+1/3+...1/99+1/100的和
- 小米雷军打出王炸,始料未及的华为余承东一下子懵了
- NOI Online 2020 Round1 准备计划
- js复制本地文件(单条和批量)
- 测试知识之:黑盒白盒和灰盒测试
- Vue-DataV 数据可视化工具