https://www.cnblogs.com/my_life/articles/14360605.html
https://rootw.github.io/2017/03/%E4%B8%AD%E6%96%AD/
从计算机系统内部看,中断无时无刻不在,这篇博文就和大家一起探讨中断的原理,并以x86_64平台上的linux 3.10内核为例来分析底层实现细节。
什么是中断?
中断是一个系统过程,是计算系统中外部设备向CPU(或CPU之间)通知事件发生的一种机制。
这种说法也许有些偏底层,可以从上层更直观的角度来理解:想象你正面对你的个人电脑,当你按下一个键盘按键时,你就触发了一个中断,随后屏幕上会出现你期望的字母;或者当你移动鼠标时,你也会触会一个中断,随后光标会随鼠标的移动而移动。
严格意义上说,中断只是一个系统过程(系统调用过程如果抛开其核心处理函数的执行,也是一个系统过程),是系统的一个部分,而不是一个完整系统,因为它不具备完整系统所应有的功能、性能、可靠性、可扩展性、安全性、兼容性、可维护性等各方面的属性。比如,通过按动键盘,你以中断的方式向计算系统发送命令,但真正执行命令并返回结果的是计算机系统而不是按键动作本身。
为什么需要中断?
计算机是个“死脑筋”,从打开电源键开始,就算你不向她发送任何指令,她也会按设定的程序开始忙禄,大多时候都在执行一个叫做IDEL的无聊程序。如何让她听命于你呢?
两种方法,要么让她随时可被打断,去做你想让她做的事,随后再去干原来被打断的事;
要么让她不停地一直问你想让她做什么,其它的事啥也不干,这样你一发话,她可以立刻响应你的命令。
第一种方式,便是中断(interrupt),第二种方式叫轮询(polling)。
在大多数场景下,中断都是一种更为高效的(从完成任务数来看)通知方式,因为计算机干了更多有意义的事,而不是一直在“傻问”;
轮询时,如果你想让计算机干得活不是很多,那么计算机大多数问询得到结果都是“谢谢,我不需要你做什么”,这就白白浪费了她的宝贵精力,但是每次你想让计算机做事时,她总是先主动地询问你,之后便立刻进入工作状态了,这比下达命令之后才慢吞吞开始行动的中断方式更为高效(从任务响应时间来看)。
因此中断和轮询各有优点,各有各的适用场景:中断适用大多数设备通知场景,而在处理时延敏感场景下(如高性能网络转发),轮询表现得更好。
如何实现中断?
下面我们深入系统内部,更细致地理解中断过程。前期的博文介绍过intel i440fx体系的基本组成,这里我们做些简化,只看和中断过程相关的几个部分,并按中断发生后的时序对中断过程作一个概括性的描述:

- 首先,我们可以看到在南桥芯片上集成了一个称为IOAPIC的部件,它共有24根中断引脚可以接收来自外部设备(如键盘、鼠标)的中断请求;当外设触发中断请求后,IOAPIC芯片会根据设备驱动初始化时设定的内容(一个内存地址Address和一个数据Data)向总线发送中断信息(将Data值写入Address地址代表的内存),如图中绿色线条所示,直观地理解,这个Address指明了接收本次中断的具体CPU,而Data代表中断向量号(粗略地讲,可以认为这是不同中断相互区别的一个整数值,0~255)。
- 其次,对于PCI设备而言,有两种中断触发方式:一种是通过intx中断引脚触发(最终通过IOAPIC发送中断信号,如图中虚线所示);另一种是MSI/MSI-X方式(Message Signal Interrupt),PCI设备通过驱动初始化时设定的内容直接向总线发送中断,如图中蓝线所示,其发送原理类似IOAPIC,由于外部设备中断过程并非本文讨论的重点,有兴趣的同学可以查阅PCI规范中相关内容来获得更深入的理解。
- 此外,CPU之间可以通过写ICR寄存器发送IPI(Inter Processors Interrupt)中断来进行核间通信,如图中粉色线条所示。
- 最后,每个CPU逻辑核都有一个称为LAPIC的子部件,它负责接收总线上的中断信息,当确认是发送给本地逻辑核时,便会引发本地CPU的中断过程:CPU会对保存当前正在执行任务的状态信息,之后会根据中断信息找到具体的中断处理逻辑函数;在完成中断处理函数后,CPU便会恢复先前保存的任务状态,继续处理原先的作务。
CPU如何处理中断?
介绍完系统内部整体的中断过程后,我们把焦点放到CPU上,更深入地从代码级别看看它是如何处理中断的。
1、硬件自动完成动作
x86_64 CPU在中断发生时会执行一系列硬件动作,完成执行上下文的切换,这些都是硬件自动完成的,不受软件控制,如下图所示:
图中上半部分表示中断发生前寄存器状态(这里以用户态上下文状态举例):
- CS(代码段寄存器)和rip(指令指针寄存器)指向了当前正在执行的用户态指令的位置(绿色线条所示);
- SS(堆栈段寄存器)和rsp(栈指针寄存器)指向了当前用户态堆栈的栈项位置;
- rflags(标志寄存器)中的IF位为1,表示允许中断发生;
- TR(Task Register)任务寄存器指向当前任务的任务状态段TSS(Task State Segment),其中的rsp0域指向了内核态栈顶位置(内核特权级为0);
- IDTR(Interrupt Descriptor Table Register)指向了全局中断描述符表(Interrupt Descriptor Table),表中共有256个中断描述符(Interrupt Descriptor),每个描述符指向一个中断处理函数入口,中断描述符在表中的索引(下标)称为中断向量(Interrupt Vector)。
中断发生后(只能发生在指令边界,不能打断单条指令的执行),寄存器状态将发生变化,如上图下半部分所示:
- 对于运行在用户态的程序,中断发生后需要切换到内核态执行中断处理函数,出于安全的考虑,堆栈也需要切换到内核态(注意,每个进程在内核态都有一个独立的栈空间,3.10内核中有16K大小,栈项指针保存在TSS);
- 切换到内核态栈后,CPU自动将用户态SS、rsp、rflags、CS、rip压入栈中(从上到下,栈顶在下,栈底在上);
- CPU根据中断向量,取出中断描述符表中对应的中断描述符,将CS:rip指向中断描述符中的函数入口地址;
- 对于类型为Interrupt Gate的中断描述符,rflags中的IF标置位将被清零,表示CPU此时开始不响应外部中断。
细心的同学可能会问如果程序正好在执行系统调用进入内核态,那中断的硬件过程是怎样的?除了不用进行栈切换外,其它的过程和上面的一样,因为系统调用已经完成了栈切换的动作。
2、中断描述符表
https://blog.csdn.net/u011391839/article/details/107504147
1、概念说明
CPU 是一种硬件资源,和任何其他硬件设备一样也需要驱动和管理程序才能使用,我们可以把内核的进程调度看作是 CPU 的管理程序,用来管理和分配CPU 资源,合理安排进程抢占 CPU,并决定哪个进程该使用 CPU、哪个进程该等待。
操作系统内核里的进程调度主要用来调度两类资源:进程(或线程)和中断,进程调度给不同的资源分配了不同的优先级,优先级最高的是硬件中断,其次是内核(系统)进程,最后是用户进程。
每个 CPU 都维护着一个可运行队列,用来存放那些可运行的线程。
线程要么在睡眠状态(blocked 正在等待 IO)要么在可运行状态,如果 CPU 当前负载太高而新的请求不断,就会出现进程调度暂时应付不过来的情况,这个时候就不得不把线程暂时放到可运行队列里。
1.1 Interrupt rate
中断简介:
中断其实就是由硬件或软件所发送的一种称为IRQ(中断请求)的信号。
中断允许让设备,如键盘,串口卡,并口等设备表明它们需要CPU。
一旦CPU接收了中断请求,CPU就会暂时停止执行正在运行的程序,并且调用一个称为中断处理器或中断服务程序(interrupt service routine)的特定程序。
中断服务程序或中断处理器可以在中断向量表中找到,而这个中断向量表位于内存中的固定地址中。
中断被CPU处理后,就会恢复执行之前被中断的程序。其实,在机器启动的时候,系统就已经识别了所有设备,并且也把相应的中断处理器加载到中断表中。
Interrupt rate:
每秒内的设备中断数。CPU接收硬件驱动发出的中断请求数。当一个驱动器有一个时间需要被kernel操作时。
例如:如果一个磁盘控制器从磁盘上取得了一个数据块,kernel需要读取使用这个块,那么磁盘控制器会触发一个中断; kernel接收每个中断。
在系统中,中断处理器的优先级非常高,而且执行速度非常快。
很多时候,有些中断处理并不需要很高的处理优先级,所以也有soft-interrupt handler。如果有很多的中断,kernel需要花费大量的时间去处理中断。可以检查/proc/interrupts能够知道中断发生在哪个CPU 上。
Interrupt Rate中包括内核由于进程的时间片中断,内核的时钟频率可以通过如下命令知道,每秒总的时钟中断数就是 = cpu个数 * 核数 * CONFIG_HZ
cat /boot/config-`uname -r` | grep '^CONFIG_HZ='
CONFIG_HZ=100
通过cat /proc/interrupts可以查看中断的类型以及次数,用vmstat查看的 in(Interrupt)就是这个参数
1.2 Context Switch Rate
大部分现在的CPU在同一时间只能运行一个process,虽然也有一些CPU,例如超线程技术的CPU,能实现同时运行超过一个process。
linux把这种CPU看作多个单线程CPU,linux内核不断的在不同process间切换,造成一个错觉,让人感觉一个单CPU同时处理多个任务,不同process之间的切换称作 Context Switch。
当系统做Context Switch时,CPU保存所有old process的context信息并获得new process的所有context信息,Context信息包括大量的linux追踪每个process信息,尤其是一些资源:
那些process正在执行,被分配了哪些内存,它打开了那些文件,等等。切换Context会触发大量的信息移动,这是比较高的开销。
首先,kernel调度触发context switches。
为了保证每个process平等的共享CPU时间,kernel周期性中断running的process,如果合适kernel调度器会开始一个其他的process而不是让当前的process继续执行,每次的周期性中断或者定时中断都可能触发context switch。
每秒定时中断的次数因不同架构和不同的kernel版本而不同。
获取每秒中断次数的一个简单办法是通过监控 /proc/interrupts文件,通过命令cat /proc/interrupts | grep timer; sleep 10 ; cat /proc/interrupts | grep timer 可以看到在指定的时间内timer次数的变化。
如果你的context switch比timer中断大很多。那么context switch更多的可能是I/O请求或者其他长时间的系统调用(比如sleep)产生。
当一个应用请求一个操作不能立即实现时,kernel开始 context switch操作:
存入请求的process并且试着切换到其他runnable process。这将使得CPU保持工作状态。
Context Switch大体上由两个部分组成:中断和进程(包括线程)切换,一次中断(Interrupt)会引起一次切换,进程(线程)的创建、激活之类的也会引起一次切换。
Context Switch 的值也和TPS(Transaction Per Second)相关的,假设每次调用会引起N次CS,那么就可以得出
Context Switch Rate = Interrupt Rate + TPS* N
CSR减掉IR,就是进程/线程的切换,假如主进程收到请求交给线程处理,线程处理完毕归还给主进程,这里就是2次切换。
也可以用CSR、IR、TPS的值代入公式中,得出每次事物导致的切换数。因此,要降低CSR,就必须在每个TPS引起的切换上下功夫,只有N这个值降下去,CSR就能降低,理想情况下N=0,但是无论如何如果N >= 4,则要分析。用vmstat查看 cs(Context Switch)就是这个参数
2、CPU中断过程
2.1 cpu中断技术的定义
计算机处于执行期间
系统内发生了非寻常或非预期的急需处理事件
CPU暂时中断当前正在执行的程序而转去执行相应的事件处理程序
处理完毕后返回原来被中断处继续执行
举个现实中的例子:
你正在看书,突然你的朋友打来电话,于是你放下书本去接电话,电话打完接着看书。电话响->放下书本->接电话->继续看书这一个过程,就类似于CPU中断的处理过程。
2.2 CPU中断的作用
早期的CPU处理外设的事件(比如接收键盘输入),往往采用“轮询”的方式。
即CPU像个查岗的一样轮番对外设顺序访问,比如它先看看键盘有没被按下,有的话就处理,没的话继续往下看鼠标有没有移动,再看看打印机……这种方式使CPU的执行效率很低,且CPU与外设不能同时工作(因为要等待CPU来“巡查”)。
中断模式时就是说CPU不主动访问这些设备,只管处理自己的任务。
如果有设备要与CPU联系,或要CPU处理一些事情,它会给CPU发一个中断请求信号。这时CPU就会放下正在进行的工作而去处理这个外设的请求。处理完中断后,CPU返回去继续执行中断以前的工作。
中断模式的作用和优点
可以使CPU和外设同时工作,使系统可以及时地响应外部事件,外设的处理速度一般慢于cpu,cpu不能一直等待外部事件
可允许多个外设同时工作,大大提高了CPU的利用率,也提高了数据输入、输出的速度。
可以使CPU及时处理各种软硬件故障(比如计算机在运行过程中,出现了难以预料的情况或一些故障,如电源掉电、存储出错、运算溢出等等。计算机可以利用中断系统自行处理,而不必停机或报告工作人员。)
2.3 CPU中断的类型
在计算机系统中,根据中断源的不同,通常将分为硬件中断和软件中断
(1)硬件中断
硬件中断又称外部中断,分为:可屏蔽中断、非屏蔽中断。
可屏蔽中断。
常由计算机的外设或一些接口功能产生,如键盘、打印机、串行口等;
这种类型的中断可以在CPU要处理其它紧急操作时,被软件屏蔽或忽略。
例如打印机中断,CPU对打印机中断请求的响应可以快一些,也可以慢一些,因为让打印机稍等待一会也是完全合理的。
非屏蔽中断。
由意外事件导致,如电源断电、内存校验错误等;对于这种类型的中断事件,无法通过软件进行屏蔽,CPU必须无条件响应。
例如电源断电,一旦出现此中断请求,必须立即无条件地响应,否则进行其他任何工作都是没有意义的。
在x86架构的处理器中,CPU的中断控制器由两根引脚(INTR和NMI)接收外部中断请求信号。其中: 1. INTR接收可屏蔽中断请求;2. NMI接收非屏蔽中断请求
(2)软件中断
软件中断又称内部中断、异常,是指在程序中调用INTR中断指令引起的中断。比如winAPI中,keybd_event和mouse_event两个函数,就是用来模拟键盘和鼠标的输入(只是猜测)。
2.4 CPU中断的过程
(1)中断请求
中断请求是由中断源向CPU发出中断请求信号。
外部设备发出中断请求信号要具备以下条件:外部设备的工作已经告一段落。
例如输入设备只有在启动后,将要输入的数据送到接口电路的数据寄存器(即准备好要输入的数据)之后,才可以向CPU发出中断请求;系统允许该外设发出中断请求。
如果系统不允许该外设发出中断请求,可以将这个外设的请求屏蔽。当这个外设中断请求被屏蔽,虽然这个外设准备工作已经完成,也不能发出中断请求。
(2)中断响应、处理和返回
当满足了中断的条件后,CPU就会响应中断,转入中断程序处理。关闭中断信号接收器;保存现场(context);给出中断入口,转入相应的中断服务程序;处理完成,返回并恢复现场(context);开启中断信号接收器
(3)中断排队和中断判优
中断申请是随机的,有时会出现多个中断源同时提出中断申请。CPU每次只能响应一个中断源的请求。CPU不可能对所有中断请求一视同仁,它会根据各中断源工作性质的轻重缓急,预先安排一个优先级顺序。当多个中断源同时申请中断时,即按此优先级顺序进行排队,等候CPU处理。
3、中断处理机制
Linux中断下半部处理有三种方式:软中断、tasklet、工作队列。
3.1 下半部
中断处理函数所做的第一件事情就是屏蔽中断(或者是什么都不做,因为常常是如果不清除IF位,就等于屏蔽中断了),当然只屏蔽同一种中断。
之所以要屏蔽中断,是因为新的中断会再次调用中断处理函数,导致原来中断处理现场的破坏。即破坏了interrupt context。
随着系统的不断复杂,中断处理函数要做的事情也越来越多,多到都来不及接收新的中断了。
于是发生了中断丢失,这显然不行,于是产生了新的机制:分离中断接收与中断处理过程。
系统为了解决中断程序执行过长和中断丢失的问题,Linux将中断处理过程分成了两个阶段,也就是上半部和下半部
Linux中断分为两个半部:上半部(tophalf)和下半部(bottom half)。
上半部的功能是"登记中断",当一个中断发生时,它进行相应地硬件读写后就把中断例程的下半部挂到该设备的下半部执行队列中去。
因此,上半部 执行的速度就会很快,可以服务更多的中断请求。但是,仅有"登记中断"是远远不够的,因为中断的事件可能很复杂。
因此,Linux引入了一个下半部,来完 成中断事件的绝大多数使命。
下半部和上半部最大的不同是下半部是可中断的,而上半部是不可中断的,下半部几乎做了中断处理程序所有的事情,而且可以被新的中断打断!
下半部则相对来说并不是非常紧急的,通常还是比较耗时的,因此由系统自行安排运行时机,不在中断服务上下文中执行。
总之:
1.上半部用来快速处理中断,它在中断禁止模式下运行,主要处理跟硬件紧密相关或者时间敏感的工作
2.下半部用来延迟处理上半部未完成的工作,通常以内核线程的方式运行
3.2 软中断
linux中断处理。作为一个操作系统显然不能任由每个中断都各自为政,统一管理是必须的。
不可中断部分的共同部分放在函数do_IRQ中,需要添加中断处理函数时,通过request_irq实现。
下半部放在do_softirq中,也就是软中断,通过open_softirq添加对应的处理函数。
3.3 Tasklet
随着中断数的不停增加,软中断不够用了,于是下半部又做了进化。软中断用轮询的方式处理。假如正好是最后一种中断,则必须循环完所有的中断类型,才能最终执行对应的处理函数。显然当年开发人员为了保证轮询的效率,于是限制中断个数为32个。为了提高中断处理数量,顺道改进处理效率,于是产生了tasklet机制。
Tasklet采用无差别的队列机制,有中断时才执行,免去了循环查表之苦。Tasklet作为一种新机制,显然可以承担更多的优点。正好这时候SMP越来越火了,因此又在tasklet中加入了SMP机制,保证同种中断只在一个cpu上执行。在软中断时代,显然没有这种考虑。因此同一种中断可以在两个cpu上同时执行,很可能造成冲突。tasklet的优点无类型数量限制;效率高无需循环查表;支持SMP机制;
3.4工作队列
前面的机制不论如何折腾,有一点是不会变的。它们都在中断上下文中。即它们不可挂起。而且由于是串行执行,因此只要有一个处理时间较长,则会导致其他中断响应的延迟。为了完成这些不可能完成的任务,于是出现了工作队列。工作队列说白了就是一组内核线程,作为中断守护线程来使用。多个中断可以放在一个线程中,也可以每个中断分配一个线程。工作队列对线程作了封装,使用起来更方便。因为工作队列是线程,所以我们可以使用所有可以在线程中使用的方法。
Tasklet其实也不一定是在中断上下文中执行,它也有可能在线程中执行。假如中断数量很多,而且这些中断都是自启动型的(中断处理函数会导致新的中断产生),则有可能cpu一直在这里执行中断处理函数,会导致用户进程永远得不到调度时间。为了避免这种情况,linux发现中断数量过多时,会把多余的中断处理放到一个单独的线程中去做,就是ksoftirqd线程。这样又保证了中断不多时的响应速度,又保证了中断过多时不会把用户进程饿死。
问题是我们不能保证我们的tasklet或软中断处理函数一定会在线程中执行,所以还是不能使用进程才能用的一些方法,如放弃调度、长延时等。
Linux实现下半部的机制主要有tasklet和工作队列
示例:
以网卡接收数据为例
网卡接收到数据包后,会通过硬件中断的方式,通知内核有新的数据到了,这时内核就应该调用中断处理程序来响应它;
对于上半部分来说,要把网卡的数据读到内存中,然后更新硬件寄存器的状态(表示数据已经读好了),最后再发送一个软中断信号,通知下半部做进一步的处理
下半部被软中断信号唤醒后,需要从内存中找到网络数据,再按照网络协议栈,对数据进行逐层解析和处理,直到把它送给应用程序
上半部分直接处理硬件请求,也就是硬件中断,特点是快速执行
下半部分则是由内核处理,也就是软中断,特点是延迟执行
上半部会打断CPU正在执行的人物,然后立即执行中断处理程序,而下半部以内核线程的方式执行,并且每个CPU都对应一个软中断内核线程,名字为 ksoftireqd/CPU编号
比如0号CPU对应的软中断内核线程名字是 ksoftirqd/0
一些内核自定义的事件也属于软中断,比如内核调度和RCU锁(Read-Copy Update的缩写,是Linux内核中最常用的锁之一)
4. 指标范围
4.1 Interrupt rate
应该与cpu利用率结合分析,如果cpu利用率在合理范围内,大量的中断也是可以接受的。一个巨大的中断值,同时伴随着缓慢的系统性能表现,指示存在硬件问题
4.2 Context Switch Rate
应该与cpu利用率结合分析,如果cpu利用率在合理范围内,大量的中断也是可以接受的。
当每次调用引起的上下文切换大于等于4时,需要结合分析
网上也有说,需要少于5000*cpu个数
https://blog.51cto.com/noican/1355357
- /proc/interrupts 文件
在linux的机器上,/proc/interrupts这个文件包含有关于哪些中断正在使用和每个处理器各被中断了多少次的信息。
● 第一列表示IRQ号, 最后一列中断名称
● 第二、三、四列表示相应的CPU核心被中断的次数。在上面的例子中,timer表示中断名称(为系统时钟)。3710374484表示CPU0被中断了3710374484次。i8042表示控制键盘和鼠标的键盘控制器。
● 对于像rtc(real time clock)这样的中断,CPU是不会被中断的。因为RTC存在于电子设备中,是用于追踪时间的。
● NMI和LOC是系统所使用的驱动,用户无法访问和配置。
IRQ号决定了需要被CPU处理的优先级。IRQ号越小意味着优先级越高。
例如,如果CPU同时接收了来自键盘和系统时钟的中断,那么CPU首先会服务于系统时钟,因为他的IRQ号是 0 。
● IRQ0 :系统时钟(不能改变)
● IRQ1 :键盘控制器(不能改变)
● IRQ3 :串口2的串口控制器(如有串口4,则其也使用这个中断)
● IRQ4 :串口1的串口控制器(如有串口3,则其也使用这个中断)
● IRQ5 :并口2和3 或 声卡
● IRQ6 :软盘控制器
● IRQ7 : 并口1。它被用于打印机或若是没有打印机,可以用于任何的并口。
- RES: 2450431 5279697 Rescheduling interrupts; 重调度中断(RES)个中断类型表示,唤醒空闲状态的 CPU 来调度新的任务运行,通常也被称为处理器间中断(Inter-Processor Interrupts,IPI)
而对于像操作杆(或称为游戏手柄)上的CPU,它并不会等待设备发送中断。
因为操作杆主要用于游戏,操作杆的移动必须非常快,因此使用轮询的方式检测设备是否需要CPU的关注还是比较理想的。
使用轮询方式的缺点是CPU就处于了忙等状态,因为CPU会不停的多次检查设备。但是需要注意的是在linux中,这种处理信号的方式也是必不可少的。
硬中断
对于上文所讨论的场景都是属于硬中断的例子。硬中断主要分为两种类别:
1. 非屏蔽中断(Non-maskable interrupts,即NMI):就像这种中断类型的字面意思一样,这种中断是不可能被CPU忽略或取消的。
NMI是在单独的中断线路上进行发送的,它通常被用于关键性硬件发生的错误,如内存错误,风扇故障,温度传感器故障等。
2. 可屏蔽中断(Maskable interrupts):这些中断是可以被CPU忽略或延迟处理的。
当缓存控制器的外部针脚被触发的时候就会产生这种类型的中断,而中断屏蔽寄存器就会将这样的中断屏蔽掉。我们可以将一个比特位设置为0,来禁用在此针脚触发的中断。
软中断
这些中断是在CPU执行指令(也就是说在进程正在运行的时候)的时候产生的,因为在执行指令时,CPU(确切的说应是在CPU中的运算器)自身会产生一个异常(此处的异常也可理解为软中断)。
例如,一个数字除以0(当然这是不可能的),此时就会导致一个divide-by-zero的异常,从而导致计算机将此计算取消或者显示一个错误的信息。
在文件/proc/stat中,包含了一些关于系统内核的统计信息,也包含了一些中断信息。
SMP_AFFINITY
SMP是指对称多处理器。smp_affinity文件主要用于某个特定IRQ要绑定到哪个CPU核心上。
在/proc/irq/IRQ_NUMBER/目录下都有一个smp_affinity文件,这个文件中,所表示的CPU核心以十六进制来表示的。
例如,网卡的中断号是:
上面的十六进制对应的十进制是1,也就是说所有的和网卡驱动相关的中断都是有CPU0来提供服务的。
我们可以通过手动改变smp_affinity文件中的值来将IRQ绑定到指定的CPU核心上,或者启用irqbalance服务来自动绑定IRQ到CPU核心上。
IRQ Balance
Irqbalance是一个linux的实用程序,它主要是用于分发中断请求到CPU核心上,有助于性能的提升。它的目的是寻求省电和性能优化之间的平衡。你可以使用yum进行安装:
启动irqbalance服务后,中断在CPU上的分布如下: