Windows/Linux/Solaris 软中断处理机制

在非中断线程化的 OS 中,如果把响应中断的所有工作都在 ISR 中完成,系统
是无法忍受的,我们要做的是在 ISR 中尽量的减少代码,只做一些必要性的工作,
如 in / out 操作,把一些其他不必要在 ISR 中工作放到其他地方,比如数据的
处理,这也就是软中断目的所在。其实即使在中断线程化的 OS 当中(如:SOLARIS)
也一样有软中断,但这里的软中断含义和那种推迟调度不是一个概念了。以下仅针
对此帖题目举例说明硬件中断如何触发软中断,关于如何注册软中断和注册步骤就不
说了。这里所说的软中断是与题目相关的。

在 NT KERNEL 中把软件运行环境又分为三个软件中断 IRQL 等级,DISPATCH_LEVEL
(DPC_LEVEL),APC_LEVEL,PASSVIE_LEVEL。系统提供的 DPC 是为了处理硬件中断
后续工作提供的一种机制,DPC 与 Linux Kernel 提供的基于 tasklet 实现的 Bottom
Half 作用上有些相似,但又不一样。在使用 DPC 处理硬件中断后续的工作前,需显示
调用相关的 kernel api 注册 DPC。关于硬件中断如何触发 DPC 调用,可以看
HalEndSystemInterrupt() 这个函数,在这个函数中,首先确定没有其他嵌套硬件
中断后(没有高于 DPC_LEVEL 的 IRQL),把 IRQL 降低,并判断是否有 DPC 调用
(之前使用 IoRequestDpc() 向系统注册的 DPC 回调函数,当把 DPC 回调函数插入
DPC LIST 后,系统调用 HalRequestSoftwareInterrupt() 设置当前 IRQL 为
DPC_LEVEL,如果当前有硬件级的 IRQL 高于 DPC_LEVEL 则 pending DPC),
如果有则设置 IRQL 为 DPC_LEVEL 并调用 KiDispatchInterrupt() 处理之前注册
的 DPC 回调函数。KiDispatchInterrupt() 函数本身是在 IRQL == DPC_LEVEL 上
运行的,它同样是处理线程调度的主函数。也就是说 DPC 调用点不光是在所有硬件
ISR 处理完成后调用 DPC。还有是处理任务调度时也会判断是否需要执行 DPC。这
里注意,DPC 与 DPC_LEVEL 不是一回事,DPC 回调函数运行级别在 DPC_LEVEL,
但并不是说所有 DPC_LEVEL 级别都是要运行 DPC 回调函数的。在非 SMP 环境下
spinlock 的实现就是简单的提升当前 IRQL 为 DPC_LEVEL,因为在这个级别的
IRQL 下所有其他软件级别运行的代码都将被阻塞,所以说线程调度主函数运行在这个
级别是不会被任何线程抢占的,另 DPC_LEVEL 虽然不是中断上下文,但在这个级别
下,任何引起睡眠的机制都将导致系统崩溃。扯的有点远了。再简单说下 APC(
Asynchronous Procedure Call),故名思意,既然是“异步过程调用”那么当前执
行环境很可能是任意线程上下文。其实到了 APC 这里就跟硬件中断扯不上边了,
虽然是这样系统还是把 APC 实现也定位为一种软中断,APC 运行在 APC_LEVEL 级
别(同样系统调用 HalRequestSoftwareInterrupt() 函数设置当前IRQL 为
APC_LEVEL)。关于如何触发 APC 可以去看一些读/写函数,当一个读/写函数设置了
异步标志时,有几种情况(因为是异步的),首先说一下触发条件,条件是:“系
统处理的当前线程是调用者线程且 IRQL 小于 APC_LEVEL 时从当前线程 APC 队列里
取出 APC 回调函数并把 IRQL 提升到 APC_LEVEL 进行调用”。继续看这几种情况,
如果系统当前处理线程不是调用者者线程,则清除 APC_LEVEL 标志,并将此 APC(
回调函数)插入调用者线程的 APC 列然后返回。如果系统当前处理线程正是调用者
线程,那么判断当前 IRQL 是否高于 APC_LEVEL,如果高于则插入调用者线程 APC
队列,此次 APC 中断被记录并返回。如果系统当前处理线程是调用者线程且 IRQL
小于 APC_LEVEL 则满足调用条件,APC 回调函数立刻被调用。处理 APC 的调用点
是在 syscall 返回时检查。

在 Linux Kernel 里引入 softirq 机制后,使用 tasklet 来实现 Bottom Half。
tasklet 也是 softirq 的一种应用,在使用 Bootom Half(tasklet)处理硬件
中断后续工作前,需显示调用相关的 kernel api 注册 Bootom Half(tasklet)。
关于硬件中断如何触发 softirq,可以看 do_IRQ() 这个函数,这个函数在处理
完设备驱动程序调用 request_irq() 注册的 ISR 后,会接着调用 irq_exit(),在
irq_exit() 中会检测是否注册了 softirq 回调函数,且在确定所有硬件中断都返
回后调用 do_softirq(),在这个函数当中会遍历软中断向量表,并调用相应的回
调函数,被调用的函数就是 tasklet 注册的回调函数,也就是你注册的 Bottom
Half。上面只是针对硬件中断而言,其实处理软中断的调用点,不光是在硬件中断
后触发,还有一些地方也调用了 do_softirq()。如在任务调度中 schedule() 函
数里也会判断是否需要执行软中断。还有在 syscall 调用时也有判断是否需要执
行软中断的地方。软中断的运行环境同样是中断上下文,在中断上下文中任何引起
睡眠的机制都将导致系统崩溃。

在 SOLARIS Kernel 中,有很大一部分硬件中断被线程化,如磁盘和网络中断,包
括时钟中断。实现中断上下文可阻塞。被线程化的中断,与普通线程共用一个
dispatcher。中断线程使用区别于 TS/IA/RT 调度等级的优先级,即全局优先级最
高的等级。我个人认为在这种响应硬件中断时可阻塞的中断线程化的处理机制中无
需提供像 DPC,Bottom Half 这种机制,这也是跟以上两种非中断线程化 OS 主要
区别。以上两种 OS 的中断处理机制,是为了不让在 ISR 中处理过多耗时操作,
而提供了一个系统回调函数接口,把那些相对耗时的处理操作放在回调函数中延迟
调用。而现在中断线程化并可阻塞了,我完全可以创建一个中断线程,所有处理工
作由系统负责,这样就无需再提供这种回调函数的接口了。既然不需要 DPC /
tasklet 的Bootom Half 的这种推迟机制那么在 SOLAIRS 内核中软中断的实现自
然也就不一样,它本身也是作为一种中断线程形式存在。关于软中断(softint)
的调用可以查看 interrupt.s 的代码。在中断处理的入口中首先判断了是否为软
中断调用 T_SOFTINT。如果是,则跳转到 dosoftint() 去执行,首先会判断如果
有比自身更高级的 pending 软中断,则直接返回。如果没有则判断当前处理线程
优先级比自身高的话马上返回。如果可以处理当前软中断则先 lock BUS 防止其他
CPU 重入这个软中断,设置当前 IPL 为软中断级。然后比较当前要中断的线程是
否是一个中断线程,如果不是则再继续判断是否要设置时间片。如果需要则进行设
置。如果当前是中断线程,则没有以上的步骤。然后就是中断当前线程,并使用被
中断线程的 LWP。接下来保存被中断的线程,切换到新软中断线程运行,继续使用
av_dispatch_softvect() 函数来执行被注册到 struct autovec 结构里的软中断
回调函数。等到调用完成后,退出软中断线程返回。以上步骤是在没有更高级的硬
件中断线程在运行。如果当前有更高级别的硬件中断正在执行的话,那么会在处理
完硬件中断后无条件的跳转到软中断处理中执行。注意,这里没有判断。从以上流
程可以看出软中断是有优先级的,即可以进行抢占。软中断的调用是无条件调用的,
即我可以直接显示的调用。这样我们可以看出系统在处理软中断时,从处理机制来
讲是与硬中断平级的,当然有优先级之分。这也意味着与 DPC 和 Bootom Half 这
种被动调用机制有这明显的不同。之所以设计成可以直接显示调用,应该是为了某
种性能调优而考虑的。在 SOLAIRS 的解释中,软中断是为一些伪设备所提供的。

Windows/Linux/Solaris 软中断处理机制相关推荐

  1. Linux内核抢占实现机制分析【转】

    Linux内核抢占实现机制分析 转自:http://blog.chinaunix.net/uid-24227137-id-3050754.html [摘要]本文详解了Linux内核抢占实现机制.首先介 ...

  2. linux 信号没有被处理方法,[计算机]Linux 信号signal处理机制.doc

    [计算机]Linux 信号signal处理机制 Linux 信号signal处理机制 信号是Linux编程中非常重要的部分,本文将详细介绍信号机制的基本概念.Linux对信号机制的大致实现方法.如何使 ...

  3. Linux内核的Softirq机制

    前言  中断服务程序往往都是在CPU关中断的条件下执行的,以避免中断嵌套而使控制复杂化.但是CPU关中断的时间不能太长,否则容易丢失中断信号.为此,Linux将中断服务程序一分为二,各称作" ...

  4. 哪些是Linux内核的同步机制,Linux内核的同步机制(1)

    Linux内核的同步机制(1) yanqin | 2009-04-16 14:51:09    阅读:791 发布文章 一. 引言 %A %A 在现代操作系统里,同一时间可能有多个内核执行流在执行,因 ...

  5. 大话Linux内核中锁机制之原子操作、自旋锁【转】

    转自:http://blog.sina.com.cn/s/blog_6d7fa49b01014q7p.html 多人会问这样的问题,Linux内核中提供了各式各样的同步锁机制到底有何作用?追根到底其实 ...

  6. Unix/Linux 中的 shell 机制

    Unix/Linux 中的 shell 机制 对于初次接触 Unix/Linux 系统的同学来说,Unix/Linux 系统与 Windows 系统最大的不同就是,操作 Unix/Linux 系统更多 ...

  7. Linux内核中断处理“下半部”机制(超详细~)

    Linux内核中断处理"下半部"机制(超详细~) ///插播一条:我自己在今年年初录制了一套还比较系统的入门单片机教程,想要的同学找我拿就行了免費的,私信我就可以哦~点我头像黑色字 ...

  8. Linux内存管理回收机制

    Linux内存管理回收机制 1.Linux内存管理简介     Linux将所管理的内存划分为内存节点(node).内存分区(zone)和页框(page). 1.1.内存节点(node)     依据 ...

  9. 【嵌入式Linux学习七步曲之第五篇 Linux内核及驱动编程】Linux内核抢占实现机制分析

    Linux内核抢占实现机制分析 Sailor_forever  sailing_9806@163.com 转载请注明 http://blog.csdn.net/sailor_8318/archive/ ...

  10. windows进程管理器_面向Windows,Linux,Mac ,安卓, 木马,密码破解内存提取基于KPCR结构的技术研究...

    Windows内存分析原理 内存镜像存储的是二进制数据,内存取证分析的任务就是从这些貌似毫无意义的二进制数据中找到系统的运行信息.这些二进制数据从根本上说,其来源都是操作系统的内存分配.为何分配.如何 ...

最新文章

  1. 种子之父--布莱恩-科恩
  2. ggplot2 图形排版:patchwork 包简单入门
  3. 使用Java让android手机自动执行重复重启
  4. openStack使用宿主机监控
  5. rest资源设计_REST资源何时应获得其自己的地址?
  6. 离职是一件利国利民的大好事
  7. python自动化学习之语法学习(判断语句和循环语句)
  8. linux下tomcat缓存磁盘文件,Linux环境下清理Tomcat缓存
  9. [机器学习实战] 机器学习基础
  10. 我们从UNIX之父丹尼斯身上学到了什么
  11. matlab sae模型,发动机平均值模型的三篇SAE论文
  12. 麦森数 OpenJ_Bailian - 2706
  13. 4.加载FeatureLayer
  14. EnPass+WebDAV(一个跨平台密码管理解决方案)
  15. android 语言的设置与获取
  16. Android穿山甲SDK接入信息流广告
  17. springboot网络微小说 毕业设计-附源码031758
  18. menuconfig 配置选项详解
  19. 企业管理软件开发XP
  20. TFN新推出手持式无线电综合测试仪 让测试更方便

热门文章

  1. react-redux的todolist(b站笔记)-(四)
  2. vscode中自动修复eslint的项目语法错误
  3. 东芝2505扫描软件_如何识别LED显示屏的扫描方式?-美亚迪分享
  4. apache如何加载系统环境变量_游学电子:windows10系统如何用cmd指令设置环境变量...
  5. word图片嵌入式为何只能看到一部分_如何巧妙选择打印Word文档内容?
  6. bpm js 计算 音乐_构建Node.js和Arduino执行控制
  7. Introduction to Computer Networking学习笔记(十四):网络中为什么使用packet switching
  8. python字符串输入拼接_20200930 024.字符串_转义字符_字符串拼接_字符串复制_input()获得键盘输入...
  9. SpringBoot系列(1):Spring和SpringBoot常用注解总结
  10. c#自带类实现的多文件压缩和解压