问题:单板上电加载交换芯片驱动后,PC与单板ping不通。
原因:网络收发包中断挂在T2080的CPU2(核2),网络风暴导致T2080的CPU2一直忙于处理收发包中断,导致CPU2占用率到100%,无法处理ping请求。
解决办法:交换芯片端口划分vlan,阻止网络风暴的发生。
中断亲和性和线程亲和性很像~
--------------------------------------------------------------------------------------------------------------------------------------
Linux 多核下绑定硬件中断到不同 CPU
转载于 https://www.cnblogs.com/iteemo/p/5399881.html
硬件中断发生频繁,是件很消耗 CPU 资源的事情,在多核 CPU 条件下如果有办法把大量硬件中断分配给不同的 CPU (core) 处理显然能很好的平衡性能。现在的服务器上动不动就是多 CPU 多核、多网卡、多硬盘,如果能让网卡中断独占1个 CPU (core)、磁盘 IO 中断独占1个 CPU 的话将会大大减轻单一 CPU 的负担、提高整体处理效率。VPSee 前天收到一位网友的邮件提到了 SMP IRQ Affinity,引发了今天的话题:D,以下操作在 SUN FIre X2100 M2 服务器+ 64位版本 CentOS 5.5 + Linux 2.6.18-194.3.1.el5 上执行。
什么是中断
中文教材上对 “中断” 的定义太生硬了,简单的说就是:
每个硬件设备(如:硬盘、网卡等)都需要和 CPU 有某种形式的通信以便 CPU 及时知道发生了什么事情,这样 CPU 可能就会放下手中的事情去处理应急事件,硬件设备主动打扰 CPU 的现象就可称为硬件中断。
就像你正在工作的时候受到 QQ 干扰一样,一次 QQ 摇头就可以被称为中断。
中断是一种比较好的 CPU 和硬件沟通的方式。
还有一种方式叫做轮询(polling):
就是让 CPU 定时对硬件状态进行查询然后做相应处理。
就好像你每隔5分钟去检查一下 QQ 看看有没有人找你一样,这种方式是不是很浪费你(CPU)的时间?所以中断是硬件主动的方式,比轮询(CPU 主动)更有效一些。
好了,这里又有了一个问题,每个硬件设备都中断,那么如何区分不同硬件呢?
不同设备同时中断如何知道哪个中断是来自硬盘、哪个来自网卡呢?这个很容易,不是每个 QQ 号码都不相同吗?
同样的,系统上的每个硬件设备都会被分配一个 IRQ 号,通过这个唯一的 IRQ 号就能区别张三和李四了。
在计算机里,中断是一种电信号,由硬件产生,并直接送到中断控制器(如 8259A)上,然后再由中断控制器向 CPU 发送信号,CPU 检测到该信号后,就中断当前的工作转而去处理中断。
然后,处理器会通知操作系统已经产生中断,这样操作系统就会对这个中断进行适当的处理。
现在来看一下中断控制器,常见的中断控制器有两种:可编程中断控制器 8259A 和高级可编程中断控制器(APIC),中断控制器应该在大学的硬件接口和计算机体系结构的相关课程中都学过。
传统的 8259A 只适合单 CPU 的情况,现在都是多 CPU 多核的 SMP 体系,所以为了充分利用 SMP 体系结构、把中断传递给系统上的每个 CPU 以便更好实现并行和提高性能,Intel 引入了高级可编程中断控制器(APIC)。
光有高级可编程中断控制器的硬件支持还不够,Linux 内核还必须能利用到这些硬件特质,所以只有 kernel 2.4 以后的版本才支持把不同的硬件中断请求(IRQs)分配到特定的 CPU 上,这个绑定技术被称为 SMP IRQ Affinity.
更多介绍请参看 Linux 内核源代码自带的文档:linux-2.6.31.8/Documentation/IRQ-affinity.txt
如何使用
先看看系统上的中断是怎么分配在 CPU 上的,很显然 CPU0 上处理的中断多一些:
cat /proc/interrupts
CPU0 CPU1
0: 918926335 0 IO-APIC-edge timer
1: 2 0 IO-APIC-edge i8042
8: 0 0 IO-APIC-edge rtc
9: 0 0 IO-APIC-level acpi
12: 4 0 IO-APIC-edge i8042
14: 8248017 0 IO-APIC-edge ide0
50: 194 0 IO-APIC-level ohci_hcd:usb2
58: 31673 0 IO-APIC-level sata_nv
90: 1070374 0 PCI-MSI eth0
233: 10 0 IO-APIC-level ehci_hcd:usb1
NMI: 5077 2032
LOC: 918809969 918809894
ERR: 0
MIS: 0
为了不让 CPU0 很累怎么把部分中断转移到 CPU1 上呢?
或者说如何把 eth0 网卡的中断转到 CPU1 上呢?
先查看一下 IRQ 90 中断的 smp affinity,看看当前中断是怎么分配在不同 CPU 上的(ffffffff 意味着分配在所有可用 CPU 上):
cat /proc/irq/90/smp_affinity
# cat /proc/irq/90/smp_affinity
7fffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff
在进一步动手之前我们需要先停掉 IRQ 自动调节的服务进程,这样才能手动绑定 IRQ 到不同 CPU,否则自己手动绑定做的更改将会被自动调节进程给覆盖掉。
如果想修改 IRQ 90 的中断处理,绑定到第2个 CPU(CPU1):
# /etc/init.d/irqbalance stop
# echo "2" > /proc/irq/90/smp_affinity
(上面的 echo “2” 是怎么来的?为什么是 ”2“?
请参考这篇:计算 SMP IRQ Affinity)过段时间在看 /proc/interrupts,是不是 90:eth0 在 CPU1 上的中断增加了(145)、在 CPU0 上的中断没变?
不断打印 /proc/interrupts 就会发现 eth0 在 CPU0 上的中断数始终保持不变,而在 CPU1 上的中断数是持续增加的,这正是我们想要的结果:
# cat /proc/interrupts
CPU0 CPU1
0: 922506515 0 IO-APIC-edge timer
1: 2 0 IO-APIC-edge i8042
8: 0 0 IO-APIC-edge rtc
9: 0 0 IO-APIC-level acpi
12: 4 0 IO-APIC-edge i8042
14: 8280147 0 IO-APIC-edge ide0
50: 194 0 IO-APIC-level ohci_hcd:usb2
58: 31907 0 IO-APIC-level sata_nv
90: 1073399 145 PCI-MSI eth0
233: 10 0 IO-APIC-level ehci_hcd:usb1
NMI: 5093 2043
LOC: 922389696 922389621
ERR: 0
MIS: 0
有什么用
在网络非常 heavy 的情况下,对于文件服务器、高流量 Web 服务器这样的应用来说,把不同的网卡 IRQ 均衡绑定到不同的 CPU 上将会减轻某个 CPU 的负担,提高多个 CPU 整体处理中断的能力;
对于数据库服务器这样的应用来说,把磁盘控制器绑到一个 CPU、把网卡绑定到另一个 CPU 将会提高数据库的响应时间、优化性能。合理的根据自己的生产环境和应用的特点来平衡 IRQ 中断有助于提高系统的整体吞吐能力和性能。
VPSee 经常收到网友来信问到如何优化 Linux、优化 VPS、这个问题不太好回答,要记住的是性能优化是一个过程而不是结果,不是看了些文档改了改参数就叫优化了,后面还需要大量的测试、监测以及持续的观察和改进。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
[Linux 性能调优] 网卡中断与CPU的绑定问题
在Linux的网络调优方面,如果你发现网络流量上不去,那么有一个方面需要去查一下:网卡处理网络请求的中断是否被绑定到单个CPU(或者说跟处理其它中断的是同一个CPU)。
先说一下背景
网卡与操作系统的交互一般有两种方式,
- 一种是中断(IRQ,网卡在收到了网络信号之后,主动发送中断到CPU,而CPU将会立即停下手边的活以便对这个中断信号进行分析),
- 另一种叫DMA(Direct Memory Access, 也就是允许硬件在无CPU干预的情况下将数据缓存在指定的内存空间内,在CPU合适的时候才处理)
——记得在10多年前开始玩电脑的时候就知道DMA是效率比较高的方式了。但是,这么多年过去了,在网卡方面,大部分还是在用IRQ方式(据说DMA技术仅仅被应用在少数高端网卡上; 另一个说法是:DMA方式会使外部设备的控制器独占PCI总线,从而CPU无法与外部设备进行交互,这对通用型操作系统Linux来说,是很难接收的,所以DMA方式在Linux内核里使用得很少)。
但是(再来一个但是),在现在的对称多核处理器(SMP)上,一块网卡的IRQ还是只有一个CPU来响应,其它CPU无法参与,如果这个CPU还要忙其它的中断(其它网卡或者其它使用中断的外设(比如磁盘)),那么就会形成瓶颈。
问题判定
网上不少讲这个问题的文章都是直接让查询IRQ跟CPU的绑定情况,甚至直接修改。但我们应该先判断我们的系统是不是受这个问题影响,然后再来看怎么解决。
首先,让你的网络跑满(比如对于MySQL/MongoDB服务,可以通过客户端发起密集的读操作; 或者执行一个i大文件传送任务)
第一个要查明的是:是不是某个CPU在一直忙着处理IRQ?
这个问题我们可以从 mpstat -P ALL 1
的输出中查明:里面的 %irq
一列即说明了CPU忙于处理中断的时间占比
18:20:33 CPU %user %nice %sys %iowait %irq %soft %steal %idle intr/s
18:20:33 all 0,23 0,00 0,08 0,11 6,41 0,02 0,00 93,16 2149,29
18:20:33 0 0,25 0,00 0,12 0,07 0,01 0,05 0,00 99,49 127,08
18:20:33 1 0,14 0,00 0,03 0,04 0,00 0,00 0,00 99,78 0,00
18:20:33 2 0,23 0,00 0,02 0,03 0,00 0,00 0,00 99,72 0,02
18:20:33 3 0,28 0,00 0,15 0,28 25,63 0,03 0,00 73,64 2022,19
上面的例子中,第四个CPU有25.63%时间在忙于处理中断(这个数值还不算高,如果高达80%(而同时其它CPU这个数值很低)以上就说明有问题了),后面那个 intr/s 也说明了CPU每秒处理的中断数(从上面的数据也可以看出,其它几个CPU都不怎么处理中断)。
然后我们就要接着查另外一个问题:这个忙于处理中断的CPU都在处理哪个(些)中断?
cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
0: 245 0 0 7134094 IO-APIC-edge timer
8: 0 0 49 0 IO-APIC-edge rtc
9: 0 0 0 0 IO-APIC-level acpi
66: 67 0 0 0 IO-APIC-level ehci_hcd:usb2
74: 902214 0 0 0 PCI-MSI eth0
169: 0 0 79 0 IO-APIC-level ehci_hcd:usb1
177: 0 0 0 7170885 IO-APIC-level ata_piix, b4xxp
185: 0 0 0 59375 IO-APIC-level ata_piix
NMI: 0 0 0 0
LOC: 7104234 7104239 7104243 7104218
ERR: 0
MIS: 0
这里记录的是自启动以来,每个CPU处理各类中断的数量(第一列是中断号,最后一列是对应的设备名)[详细说明: E.2.10 /proc/interrupts - Deployment Guide - RedHat Enterprise Linux 6 ),从上面可以看到: eth0
所出发的中断全部都是 CPU0
在处理,而CPU0所处理的中断请求中,主要是eth0和LOC中断。(有时我们会看到几个CPU对同一个中断类型所处理的的请求数相差无几(比如上面的LOC一行),这并不一定是说多个CPU会轮流处理同一个中断,而是因为这里记录的是“自启动以来”的统计,中间可能因为irq balancer重新分配过处理中断的CPU——当然,也可能是谁手工调节过)。
解决问题
首先说明几点:
- 首先应该根据上面的诊断方法查明当前系统是不是受这个原因影响,如果不是,那么就没有必要往下看了;
- 现在的多数Linux系统中已经有了IRQ Balance这个服务(服务程序一般是
/usr/sbin/irqbalance
),它可以自动调节分配各个中断与CPU的绑定关系,以避免所有中断的处理都集中在少数几个CPU上; - 在某些情况下,这个IRQ Balance反而会导致问题,会出现 irqbalance 这个进程反而自身占用了较高的CPU(当然也就影响了业务系统的性能)[参考: mongodb性能问题及原理分析 ]
下面来说手工将中断限定到少数几个CPU的方法。
首先当然要查明,该网卡的中断当前是否已经限定到某些CPU了?具体是哪些CPU?
根据上面 /proc/interrupts
的内容我们可以看到 eth0 的中断号是74,然后我们来看看该中断号的CPU绑定情况(或者说叫亲和性 affinity)
$ sudo cat /proc/irq/74/smp_affinity
ffffff
这个输出是一个16进制的数值,0xffffff = ‘0b111111111111111111111111’
,这就意味着这里有24个CPU,所有位都为1表示所有CPU都可以被该中断干扰。
另一个例子:
$ sudo cat /proc/irq/67/smp_affinity
00000001
这个例子说明,只有CPU0处理编号为67的中断。
修改配置的方法:
我们可以用 echo 2 > /proc/irq/74/smp_affinity
的方法来修改这个设置(设置为2表示将该中断绑定到CPU1上,0x2 = 0b10,而第一个CPU为CPU0)