目录
4 IPI(Interrupt-Procecesorr Interrupt):处理器中间的中断
1 基础知识
1.1 同步中断和异步中断
同步中断是指当指令执行时由 CPU 控制单产生的,之所以称为同步,是因为只有在一条指令终止执行后 CPU 才会发出中断。异步中断是由其他硬件设备依照 CPU 时钟信号随机产生的。 《深入理解 LINUX 内核》P135
异常与中断不同,它在产生时必须考虑与处理器时钟同步。实际上,异常也常常称为同步中断。在处理器执行到由于编程失误而导致的错误指令的时候,或者在执行棋局出现特殊情况(如缺页),必须由内核来处理的时候,处理器就会产生一个异常。 《Linux 内核设计与实现》P92
1.2 中断上下文
当执行一个中断处理程序时,内核处于中断上下文 (interrupt context) 中。
因为没有后备进程,所以中断上下文不可以睡眠,否则有怎能再对它重新调度呢?因此,不能在中断上下文中调用某些函数。如果一个函数睡眠,就不能在你的中断处理程序中使用它——这是对什么样的函数可以在中断处理程序中使用的限制。
中断上下文具有较为严格的时间限制,因为它打断了其它代码。中断上下文的代码应当迅速、简洁,尽量不要使用循环去处理繁重的工作。
《Linux 内核设计与实现》P99
1.3 中断处理程序栈
《Linux 内核设计与实现》P99 《Linux 内核设计与实现》P203
1.4 中断处理程序的重入
linux 中的中断处理程序是无须重入的。当一个给定的中断处理程序正在执行时,相应的中断线在所有处理器上都会被屏蔽,以防止在同一中断线上接收另一个新的中断。通常情况下,所有其他的中断都是打开的,所以这些不同中断线上的其它中断都能被处理,但当前中断线是被禁止的。由此可以看出,同一个中断处理程序绝对不会被同时调用以处理嵌套的中断。这极大地简化了中断处理程序的编写。
《Linux 内核设计与实现》P97
1.5 中断的返回
从中断处理程序或系统调用返回的返回路径都是体系结构相关的,在 entry.S 文件中通过汇编语言来实现。《Linux 内核设计与实现》P53
1.6 中断控制器
2 顶半部和底半部(推后执行的工作)
2.1 简介
中断处理的一个主要问题是怎样在处理例程内完成耗时的任务。响应一次设备中断需要完成一定量的工作,但是中断处理例程需要尽快结束而不能使中断阻塞的时间过长,这两个需求(工作和速度)彼此冲突,让驱动程序的作者多少有点困扰。
Linux (连同很多其他的系统)通过将中断处理例程分成两部分来解决这个问题。称为”顶半部“的部分,是世纪响应中断的例程,也就是 request_irq() 注册的中断例程;而”底半部“是一个被顶半部调度,并在稍后更安全的时间内执行的例程。
顶半部处理例程和底半部处理处理例程之间最大的不同,就是底半部处理例程执行时,所有的中断都是打开的——这就是所谓的在更安全的时间内运行。
《LINUX 设备驱动程序》(第三版)P274
底半部机制的演化历程
下半部机制 |
状态 |
BH |
kernel 2.5中移除 |
任务队列(Task queues) |
kernel 2.5中移除 |
软中断 |
kernel 2.3开始引入 |
tasklet |
kernel 2.3开始引入 |
工作队列(Work queues) |
kernel 2.5开始引入 |
2.2 软中断
《深入理解 LINUX 内核》P174
软中断保留给系统中对时间要求最严格以及最重要的底半部使用。目前,只用两个子系统(网络和 SCSI)直接使用软中断。
《Linux 内核设计与实现》P113
软中断的代码位于 kernel/softirq.c 文件中。
kernel/softirq.c 中定义了一个包含有 32 个 softirq_action 结构体的数组:
static struct softirq_action softirq_vec[NR_SOFTIRQS];
因此最多可能有 32 个软中断。
在当前版本的内核中,这 32 个中只用到 9 个。 // 《深入理解 LINUX 内核》P175 上介绍只用了 6 个。
一个软中断不会抢占另一个软中断。实际上,唯一可以抢占软中断的是中断处理程序。不过,其它的软中断(甚至是相同类型的软中断)可以在其它处理器上同时执行。
《Linux 内核设计与实现》P111
2.3 tasklet
《LINUX 设备驱动程序》(第三版)P275
两个不同类型的 tasklet 可以在不同的处理器上同时运行,但类型相同的 tasklet 不能同时执行。tasklet 其实是一种在性能和易用性之间寻求平衡的产物。 《Linux 内核设计与实现》P109
内核对 tasklet 的执行进行了更加严格的控制。相同类型的 tasklet 总是被串行地执行,换句话说:不能在两个 CPU上同时运行相同类型的 tasklet。tasklet 的串行化使 tasklet 函数不必是可重入的,因此简化了设备驱动开发者的工作。 《深入理解 LINUX 内核》P174
tasklet 是利用软中断实现的一种底半部机制。它和进程没有任何关系。《Linux 内核设计与实现》P114
2.4 工作队列
工作队列工作在进程上下文,因此可在必要的时休眠。《LINUX 设备驱动程序》(第三版)P277
工作队列可以把工作推后,交由一个内核线程去执行——这个底半部总是会在进程上下文中执行。这样,通过工作队列执行的代码占尽进程上下文的所有优势。最重要的就是工作队列允许重新调度甚至是睡眠。 《Linux 内核设计与实现》P120
2.5 内核定时器
不像 软中断、tasklet 和工作队列,内核定时器把操作推迟到某个确定的时间段之后执行。 《Linux 内核设计与实现》P114
2.6 底半部机制的选择
对于大部分底半部的处理来说,用 tasklet 就足够了,像网络这样对性能要求非常高的情况才需要用软中断。可是,使用软中断需要特别小心,因为两个相同的软中断有可能同时执行。此外,然中断还必须在编译期间就进行静态注册。与此相反,tasklet 可以通过代码进行动态注册。
《Linux 内核设计与实现》P109
软中断保留给系统中对时间要求最严格以及最重要的底半部使用。目前,只用两个子系统(网络和 SCSI)直接使用软中断。
《Linux 内核设计与实现》P113
《Linux 内核设计与实现》P120
3 中断亲和性
在多处理器系统中,管理员可以设置中断亲和性,允许中断控制器把某个中断转发给哪些处理器,有两种配置方法。
<1> 写文件”/proc/irq/irq_id/smp_affinity”,参数是位掩码。
<2> 写文件“/proc/irq/irq_id/smp_affinity_list”,参数是处理器列表
例如,管理员允许中断控制器把 Linux 中断号为 32 的中断转发给处理器 0~3,配置方法有两种
<1> echo 0f > /proc/irq/32/smp_affinity
<2> echo 0-3 > /proc/irq/32/smp_affinity_list
《Linux 内核深度解析》P431
4 IPI(Interrupt-Procecesorr Interrupt):处理器中间的中断
处理器间中断是一种特殊的中断,在多处理器系统中,一个处理器可以向其它处理器发送中断,要求目标处理器执行某件事情。
常见的使用处理器间中断的函数
<1> int smp_call_function(smp_call_func_t func, void *info, int wait);在所有其它处理器上执行一个函数。
<2> int smp_call_function_single(int cpu, smp_call_func_t func, void *info, int wait);在指定的处理器上执行一个函数。
<3> void smp_send_reschedule(int cpu);要求指定的处理器重新调度进程。
《Linux 内核深度解析》P432
5 中断线程化
6 软中断
7 中断计数
a 调试
a.1 /proc/ 目录下中断相关的文件
a.1.1 /proc/interrupts
root@ubuntu:~# cat /proc/interrupts
CPU0 CPU1
0: 59 0 IO-APIC 2-edge timer
1: 7543 5860 IO-APIC 1-edge i8042
4: 10500 20397 IO-APIC 4-edge
6: 2 0 IO-APIC 6-edge floppy
7: 0 0 IO-APIC 7-edge parport0
8: 1 0 IO-APIC 8-edge rtc0
9: 0 0 IO-APIC 9-fasteoi acpi
12: 83474 85761 IO-APIC 12-edge i8042
14: 59071 30683 IO-APIC 14-edge ata_piix
15: 13283 11485 IO-APIC 15-edge ata_piix
16: IO-APIC 16-fasteoi vmwgfx, snd_ens1371
17: 44 0 IO-APIC 17-fasteoi ehci_hcd:usb1, ioc0
18: 70 0 IO-APIC 18-fasteoi uhci_hcd:usb2
19: 31649 15122 IO-APIC 19-fasteoi eth0
......
该文件只会显示那些已经安装了中断处理程序的中断。 //如果想看所有中断的中断计数,请看/proc/stat 文件
a.1.2 /proc/stat
root@ubuntu:~# cat /proc/stat
cpu 1644 33456 0 5679 0 0 0
cpu0 901 17343 0 2680 0 0 0
cpu1 742 16113 0 2999 0 0 0
intr 59 13490 0 0 30957 0 2 0 1 0 0 0 0 89830 24818 44 70 46841 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ctxt
btime
processes 10868
procs_running 4
procs_blocked 0
softirq 1 5072 0 13168 0
root@ubuntu:~#
/proc/stat 记录了一些系统活动的底层统计信息,包括(但不仅限于)从系统启动开始接收到的中断数量,stat 每一行都以一个字符串开始,它是这行的关键字。intr 标记正是我们需要的 《LINUX 设备驱动程序》(第三版)P263
......
intr 59 2275 0 0 11404 0 2 0 1 0 0 0 37025 0 48738 9364 1649 45 72 55296 0 0 0 0 0 0 0 0 0 0......
......
第一个数是所有中断的总数,而其它的每个数都代表一个单独的 IRQ 信号线,从中断 0 开始。
上面的数据显示:
0 号中断发生了 59 次
1 号中断发生了 2275 次
2 号中断发生了 0 次
3 号中断发生了 0
4 号中断发生了 11404 次
a.1.3 /proc/softirqs
a.2 统计处理 硬中断 的时间
BCC工具:hardirqs-bpfcc
命令:mpstat
a.3 统计处理 软中断 的时间
BCC工具:softirqs-bpfcc
命令:mpstat
今天的文章 linux中断,中断亲和性,IPI中断,中断线程化,中断计数,软中断 和 调试方法分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/96375.html