关于linux中断

发布时间:2024年01月20日

????????在Linux的世界里,中断是一种特殊的艺术,它们就像是不请自来的客人,打断了内核的日常工作,但却是为了告诉它一些重要的消息。

初窥中断

????????中断处理程序是中断的核心部分,它负责根据中断类型执行相应的处理逻辑。在 Linux 中,中断处理程序是以中断服务例程(ISR)的形式存在。当中断被触发时,硬件会发送相应的中断信号给处理器,处理器会在硬件设计的中断控制器的控制下,将中断事件传递给操作系统内核。内核根据中断号找到对应的中断处理程序,然后执行相应的操作。

????????中断使得硬件得以发出通知给处理器。例如,在你敲击键盘的时候,键盘控制器 (控制键盘 的硬件设备)会发送一个中断,通知操作系统:“嗨!我有新的按键等待处理呢~”。中断本质上是一种特殊的电信号,由硬件设备发向处理器。处理器接收到中断后,会马上向操作系统反映此信号的到来,然后就由操作系统负责处理这些新到来的数据。

? ? ? ? 然鹅硬件设备生成中断的时候并不考虑与处理器的时钟同步一一换句话说就是中断随时可以产生。因此,内核随时可能因为新到来的中断而被打断

问题来了

????????在Linux中,中断处理程序就是普普通通的C函数。中断处理程序与其他内核函数的真正区别在于,中断处理程序是被内核调用来响应中断的,而它们运行于我们称之为中断上下文的特殊上下文中。
????????需要注意的是,中断上下文偶尔也称作原子上下文,因为正如我们看到的,该上下文中的执行代码不可阻塞。中断可能随时发生,因此中断处理程序也就随时可能执行。特别是,中断处理程序在响应中断时,还会临时禁用中断。这就会导致上一次中断处理完成之前,其他中断都不能响应,也就是说中断有可能会丢失。所以必须保证中断处理程序能够快速执行,这样才能保证尽可能快地恢复被中断代码的执行,并减少中断的丢失。

????????因此,不管是对硬件或是操作系统来说,让中断处理程序在尽可能短的时间内完成运行非常重要。

怎么搞

????????还是要一步一步走呀~linux把一次完整的中断处理分为两个步骤:硬中断(上半步)和软中断(下半步)。

硬中断

? ? ? ? 还是以一个网络包的视角来看下怎么走~当网卡接收到一个来自网络的数据包时,需要通知内核数据包到了。网卡需要立即完成这件事,从而优化网络的吞吐量和传输周期,以避免超时。因此,网卡立即发出中断:嗨,内核,。内核通过执行网卡已注册的中断处理程序来做出应答。
????????中断开始执行,通知硬件,拷贝最新的网络数据包到内存,然后读取网卡更多的数据包。这些都是重要、紧迫而又与硬件相关的工作。内核通常需要快速的拷贝网络数据包到系统内存,因为网卡上接收网络数据包的缓存大小固定,而且相比系统内存也要小得多。所以上述拷贝动作一旦被延迟,必然造成缓存溢出—进入的网络包占满了网卡的缓存,后续的人包只能被丢弃。当网络数据包被拷贝到系统内存后,内核会复位硬件状态,告知硬件处理完成:,然后发送一个软中断信号,通知下半步做进一步处理。

????????上半步的任务算是完成了,这时内核会将控制权交还给系统被中断前原先运行的程序。

软中断

????????下半步通常由内核线程来执行,一般每个CPU都对应一个软中断内核线程,名字为“ksoftirqd/CPU编号”。

root@gl:/home/gl# ps aux | grep softirqd
root          12  0.0  0.0      0     0 ?        S    06:46   0:00 [ksoftirqd/0]
root          20  0.0  0.0      0     0 ?        S    06:46   0:00 [ksoftirqd/1]

????????下半部被软中断信号唤醒后,就会从内存中找到网络数据,再经过网络协议栈,对数据进行逐层解析和处理,直到把它送给应用程序。

怎么看

? ? ? ? linux的proc虚拟文件系统提供了查看硬中断、软中断发生次数的接口,使得我们可以方便的观察内核的中断发生情况。

查看硬中断

root@gl:/home/gl# cat /proc/interrupts  
           CPU0       CPU1       
  0:         31          0   IO-APIC   2-edge      timer
...
 19:       6652        101   IO-APIC  19-fasteoi   ehci_hcd:usb1, enp0s3
...
NMI:          0          0   Non-maskable interrupts
LOC:     237418    2845797   Local timer interrupts
SPU:          0          0   Spurious interrupts
PMI:          0          0   Performance monitoring interrupts
IWI:          0          0   IRQ work interrupts
RTR:          0          0   APIC ICR read retries
RES:        868        642   Rescheduling interrupts
CAL:      30215      50147   Function call interrupts
TLB:        123        252   TLB shootdowns
TRM:          0          0   Thermal event interrupts
THR:          0          0   Threshold APIC interrupts
DFR:          0          0   Deferred Error APIC interrupts

上面的输出中:

0号中断为系统定时器中断,用于内核的时间管理,如调度器的时间片轮转、更新系统时钟等;
19号中断为网卡中断,通常是网卡接收到数据包时触发;
RES为重新调度中断,用于内核的调度器,当一个CPU需要告诉另一个CPU停止当前任务并重新调度时,会使用这种中断。这通常发生在多处理器系统中,当一个进程的优先级发生变化,或者有更重要的任务需要立即执行时。

查看软中断

root@gl:/home/gl# cat /proc/softirqs 
                    CPU0       CPU1       
          HI:          1          3
       TIMER:      83486    1861647
      NET_TX:      21384          0
      NET_RX:       7302        114
       BLOCK:       6286       8886
    IRQ_POLL:          0          0
     TASKLET:        122         34
       SCHED:     116829    1811710
     HRTIMER:          0          0
         RCU:      66529     109253

上面的输出中:

TIMER: 定时器软中断。用于处理定时器到期事件,例如调度器的时间片到期;
NET_TX: 网络传输软中断。当网络设备完成数据包的发送时,会触发此软中断来处理发送完成的后续工作;
NET_RX: 网络接收软中断。当网络设备接收到数据包时,会触发此软中断来处理接收到的数据包;
TASKLET: tasklet是常用的软中断实现机制。用于执行低优先级的底层任务,这些任务可以被推迟并在软中断上下文中执行;
SCHED: 调度软中断。用于处理调度器的工作,例如在多处理器系统中迁移进程到其他CPU。
????????每个软中断类型后面的数字表示在对应的CPU上该软中断被触发的次数。每个软中断类型后面的数字表示在对应的CPU上该软中断被触发的次数。软中断是内核性能调优的一个重要方面,因为它们的处理可能会对系统的响应时间和吞吐量产生影响。

????????一般而言,需要重点观察网络和调度相关的软中断,以及其在不同CPU上的中断次数是否均衡。例如,若NET_TX在CPU0上中断次数远远超过CPU1的数量级,就要考虑,数据包的分发是否均衡,一般来说,一条socket连接会分配在一个CPU上处理,可以考虑增加多条连接。

最后

????????在Linux内核中,硬中断和软中断共同协作,保证了系统能够高效而稳定地运行。硬中断负责处理那些需要立即响应的紧急任务,而软中断则负责处理可以稍微等待的任务。这就像是一个优秀的团队,有人负责火速解决突发事件,有人负责处理日常事务,共同确保了整个系统的有序运作。

文章来源:https://blog.csdn.net/qq_33724710/article/details/135698865
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。