作者 | 小南瓜地瓜
责编 | 郭芮

中断引发的面试教训









什么是中断?


中断:(英语:Interrupt)指当出现需要时,CPU暂时停止当前程序的执行转而执行处理新情况的程序和执行过程。

即在程序运行过程中,系统出现了一个必须由CPU立即处理的情况,此时,CPU暂时中止程序的执行转而处理这个新的情况的过程就叫做中断。

中断 在嵌入式软件中几乎不能离开它,你看到的几乎所有的芯片都有中断功能,不管是裸机程序STC89C51还是嵌入式Linux系统,还是其他的RTOS系统都有中断。每个外接设备申请一个唯一的中断号,让外设发生中断时,向CPU报告自己的中断号,CPU知道是哪个设备发生中断,然后执行相对应的操作。



为什么要用中断?



Linux中断子系统


4.1、中断系统相关硬件描述





4.1.1、多个Interrupt controller和多个cpu之间的拓扑结构



  • 第一种,就是有一个Root GIC(Generic Interrupt Controller)连接多个CPU,然后second GIC 接在 Root GIC上,Sencond GIC只负责上报中断信息给Root GIC,Root GIC负责接收Second GIC中断信息然后给CPU汇报中断信息。



  • 第二种就是Root GIC 负责给cpu0-cpu4汇报工作,Second GIC负责给cpu3-cpu7汇报工作。这样设计的弊端就是Second GIC上的中断信号不能传给Cpu0-Cpu3,这样的设计理论上不是很完美。


4.1.2、Interrupt controller把中断事件送给哪个CPU?



在 SMP 体系结构中(cpu三大架构 numa smp mpp 之一),我们可以通过调用系统调用和一组相关的宏来设置 CPU 亲和力(CPU affinity),将一个或多个进程绑定到一个或多个处理器上运行。

中断在这方面也毫不示弱,也具有相同的特性。中断亲和力是指将一个或多个中断源绑定到特定的 CPU 上运行。中断亲和力最初由 Ingo Molnar 设计并实现。

在 /proc/irq 目录中,对于已经注册中断处理程序的硬件设备,都会在该目录下存在一个以该中断号命名的目录 IRQ# ,IRQ# 目录下有一个 smp_affinity 文件(SMP 体系结构才有该文件),它是一个 CPU 的位掩码,可以用来设置该中断的亲和力, 默认值为 0xffffffff,表明把中断发送到所有的 CPU 上去处理。如果中断控制器不支持 IRQ affinity,不能改变此默认值,同时也不能关闭所有的 CPU 位掩码,即不能设置成 0x0。

举个栗子

我们以网卡(eth1,中断号 44 )为例,在具有 8 个 CPU 的服务器上来设置网卡中断的亲和力(以下数据出自内核源码 Documentation\IRQ-affinity.txt):

[root@moon 44]# cat smp_affinity
ffffffff
[root@moon 44]# echo 0f > smp_affinity
[root@moon 44]# cat smp_affinity
0000000f
[root@moon 44]# ping -f h
PING hell (195.4.7.3): 56 data bytes
...
--- hell ping statistics ---
6029 packets transmitted, 6027 packets received, 0% packet loss
round-trip min/avg/max = 0.1/0.1/0.4 ms
[root@moon 44]# cat /proc/interrupts | grep 44:
 44:   0   1785   1785   1783   1783   1   1   0   IO-APIC-level   eth1
[root@moon 44]# echo f0 > smp_affinity
[root@moon 44]# ping -f h
PING hell (195.4.7.3): 56 data bytes
..
--- hell ping statistics ---
2779 packets transmitted, 2777 packets received, 0% packet loss
round-trip min/avg/max = 0.1/0.5/585.4 ms
[root@moon 44]# cat /proc/interrupts | grep 44:
 44:  1068  1785  1785  1784   1784   1069   1070   1069   IO-APIC-level  eth1
[root@moon 44]#

在上例中,我们首先只允许在 CPU0-3 上处理网卡中断,接着运行 ping 程序,不难发现在 CPU4-7 上并没有对网卡中断进行处理。然后只在 CPU4-7 上对网卡中断进行处理, CPU0-3 不对网卡中断进行任何处理,运行 ping 程序之后,再次查看 /proc/interrupts 文件时,不难发现 CPU4~7 上的中断次数明显增加,而 CPU0~3 上的中断次数没有太大的变化


4.2、中断子系统相关的软件框架


4.2.1、中断上半部分和下半部分

中断处理程序的这两个目标相互冲突:

  • 快点执行

  • 执行大量工作

由于这些竞争目标,中断的处理分为两部分或一半:

  • 上半部分。中断处理程序是上半部分。上半部分在收到中断后立即运行,仅执行对时间要求严格的工作,例如确认收到中断或重置硬件。

  • 下半部分。可以在以后执行的工作推迟到下半部分。下半部分将在更方便的时间运行,并启用所有中断。

4.2.2、中断分类

中断如果分为两大类,那就是同步中断和异步中断,如果根据中断原因来分,可以分为四种。具体如下图:


4.2.3、中断上下文

执行中断处理程序时,内核处于中断上下文中

与进程上下文的区别:

  • 进程上下文是内核在代表进程执行时所处的操作模式,例如执行系统调用或运行内核线程。

  • 在进程上下文中,current宏(在内核中,可以通过current宏来获得当前执行进程的task_struct指针)指向关联的任务。

  • 由于进程在进程上下文中耦合到内核,因此进程上下文可以休眠或以其他方式调用调度程序。

current宏在发生中断的时候,它指向中断的进程。

没有后备进程,中断上下文无法休眠,无法重新安排。因此,您无法从中断上下文中调用某些函数。如果函数休眠,则不能从中断处理程序中使用它:这限制了可以从中断处理程序调用的函数。中断上下文是时间关键的,因为中断处理程序会中断其他代码。

应该记住,中断处理程序已经中断了其他代码(可能甚至是另一行上的另一个中断处理程序)。由于异步性质,所有中断处理程序必须尽可能快速和简单。应尽可能地将工作从中断处理程序中推出,并在下半部分执行,后者在更方便的时间运行。

4.2.4、linux kernel的中断子系统

架构图如下所示:


由上面的block图,我们可知linux kernel的中断子系统分成4个部分:

  • 硬件无关的代码,我们称之Linux kernel通用中断处理模块。无论是哪种CPU,哪种controller,其中断处理的过程都有一些相同的内容,这些相同的内容被抽象出来,和HW无关。此外,各个外设的驱动代码中,也希望能用一个统一的接口实现irq相关的管理(不和具体的中断硬件系统以及CPU体系结构相关)这些“通用”的代码组成了linux kernel interrupt subsystem的核心部分。

  • CPU architecture相关的中断处理。 和系统使用的具体的CPU architecture相关。

  • Interrupt controller驱动代码 。和系统使用的Interrupt controller相关。

  • 普通外设的驱动。这些驱动将使用Linux kernel通用中断处理模块的API来实现自己的驱动逻辑。

4.2.5、中断调试

  • 用示波器查看硬件是否真实产生了中断;

  • cat /proc/interrupts  里面列举了系统申请的所有中断,查看自己注册的中断是否在里面;

  • cat cat /proc/irq/[num]/  里面很多可以查看和调试的参数。

4.2.6、Linux中断是否可以嵌套吗?



它的commit log清晰地解释中断嵌套可能引入的一些risk,比如stack溢出等。也就是说,从这个commit开始,实际Linux已经不再支持中断的嵌套, 也没有快慢中断的概念了,IRQF_DISABLED标记也作废了。在IRQ HANDLER里面,无论一个中断设置还是不设置IRQF_DISABLED, 内核都不会开启CPU对中断的响应。

具体查看链接:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e58aa3d2d0cc

作者简介:韦启发,从事十余年嵌入式领域学习与工作,曾就职于TCL、中兴,从0开始创业开发过产品。目前在500强企业从事嵌入式系统软件开发工作。

本文系作者投稿,版权归作者所有。


 热 文 推 荐 

春运车票为谁“秒空”?第三方软件的困与危

编程 25 年后,现实将我打回菜鸟程序员的起点

前方 Bug 出没?盘他!

☞“离开360时,它只给了我一块钱”

☞ 原子互换:一统公链江湖的神来之笔

☞ AI找Bug,一键快速预测

☞ 5G大规模商用来临之前,你必须知道的几个知识点

☞ 女程序员:我敲代码养家,老公负责貌美如花!

print_r('点个好看吧!');
var_dump('点个好看吧!');
NSLog(@"点个好看吧!");
System.out.println("点个好看吧!");
console.log("点个好看吧!");
print("点个好看吧!");
printf("点个好看吧!\n");
cout << "点个好看吧!" << endl;
Console.WriteLine("点个好看吧!");
fmt.Println("点个好看吧!");
Response.Write("点个好看吧!");
alert("点个好看吧!")
echo "点个好看吧!"

喜欢就点击“好看”吧!

漫画 | 中断引发的面试教训相关推荐

  1. 微软亚洲研究院实习生面试教训

    约好的是今天中午1:00中面试,还提前安装好了Office Live Meeting.感觉一切准备就绪了,却没想到开始面试之后怎么也连不到live meeting的server,不管是关掉防火墙还是使 ...

  2. 漫画:小白为了面试如何刷题?(呕心沥血算法指导篇)

    来自:小浩算法 三年高考,五年刷题.leetcode不算从其他各处收录的题目,单就自己的题库,总共有1600+,如果按照每天刷一道的话,总共需要5年.那我们真的需要把这些题目全部刷完吗?如果不是,刷多 ...

  3. 漫画:以后有面试官问你快速排序,你就干脆把我这篇熬夜写的文章扔给他!

    这篇文章,以对话的方式,详细着讲解了快速排序以及排序排序的一些优化. 一禅:归并排序是一种基于分治思想的排序,处理的时候可以采取递归的方式来处理子问题.我弄个例子吧,好理解点.例如对于这个数组arr[ ...

  4. 漫画-Linux中断子系统综述

    1.中断引发的面试教训 2.什么是中断? 中断: (英语:Interrupt)指当出现需要时,CPU暂时停止当前程序的执行转而执行处理新情况的程序和执行过程. 即在程序运行过程中,系统出现了一个必须由 ...

  5. java中断响应时间_Java多线程 sleep方法响应中断 sleep面试问题(与wait/notify的

    Java多线程 sleep方法响应中断 sleep面试问题(与wait/notify的 Java多线程 sleep方法响应中断 & sleep面试问题(与wait/notify的比较) 文章目 ...

  6. 【OS学习笔记】二十七 保护模式八:任务切换的方法之----jmp与call的区别以及任务的中断嵌套

    上一篇文章学习了任务门的概念:任务门-任务切换.主要学习了以下内容: 使用任务门进行任务切换的一般工作原理(和中断有关的任务切换) 本篇文章接着上一篇文章学习以下内容: 利用jmp进行任务切换 利用c ...

  7. 面试精讲之面试考点及大厂真题 - 分布式专栏 20 降级组件Hystrix的功能特性

    20 降级组件Hystrix的功能特性 知识是一种快乐,而好奇则是知识的萌芽. --培根 引言 之前在一个公众号一个妹子分享了自己的面试经历,关于 Hystrix 的问题先后在美团.滴滴.京东都有提到 ...

  8. 如果面试时大家都说真话

    本文转载自画漫画的程序员 面试造火箭 入职拧螺丝 是当前职场的中最美风景线 面试时的高标准.严要求 实际工作却是修修补补或做着忙碌但无关紧要的事情 为什么会出现这种现象呢? 那么,你不防试想一下 如果 ...

  9. 漫画:算法如何验证合法数独 | 全世界最难的数独?

    今天是小浩算法 "365刷题计划" 第95天 .数独相信在座的各位都玩过,那我们如何使用程序去验证一个 9×9 的数独是有效的呢?一起看下! 01 PART 有效的数独 数独是源自 ...

最新文章

  1. 机器学习集成学习与模型融合!
  2. Koa 中实现 chunked 数据传输
  3. Oracle 索引概述
  4. oracle加密表空间,加密表空间
  5. mvc ajax提交html标签,Mvc提交表单的四种方法全程详解
  6. Introduction to Web MIDI
  7. guns使用注意问题
  8. 危险无处不在 Html标签带来的安全隐患
  9. 案例 | 省去繁琐简历筛选,「微伴助手」选择 ShowMeBug 在线笔试提高人才精准度
  10. tar: Exiting with failure status due to previous errors
  11. 查找手机号绑定的百度账号
  12. 嫌犯被抓!12306 用户信息泄露案
  13. Golang 错误处理机制详解
  14. SpringSecurity退出登录logout报错404
  15. table标签中cellspacing和cellpadding,border的意思?
  16. 20.2 Java写文件之OutputStream学习
  17. 系统盘的制作和安装系统的操作流程
  18. ​Hello Qt(四十七)——QtQuick基础​
  19. 【GAL中的标注弹窗功能——Renpy系列1】
  20. 女大学生深度揭露大学最露骨生活,值得我们深思!

热门文章

  1. pytorch的图像通道变换,torchvision.transforms.Compose,T.ToTensor
  2. LSTM及其改进用于视觉任务中
  3. 退出android app时界面残留影响,【Android】App 或 Activity 销毁重建的状态恢复对回调带来的影响...
  4. 鸡蛋掉落(动态规划)
  5. 剑指offer之构建乘积数组
  6. Ubuntu18.04构建Go语言项目
  7. vscode格式化 java_VS CODE中配置JAVA格式化细节
  8. Java 获取项目文件路径
  9. 朗读评价语言集锦_表扬朗读好的评语简短
  10. SwiftUI 很难赶上 UIKit?