網卡軟中斷綁定過程
軟中斷是什么
內核的軟中斷系統是一種在硬中斷處理上下文(驅動中)之外執行代碼的機制。硬中斷處理函數(handler)執行時,會屏蔽部分或全部(新的)硬中斷。中斷被屏蔽的時間越長,丟失事件的可能性也就越大。所以,所有耗時的操作都應該從硬中斷處理邏輯中剝離出來,硬中斷因此能盡可能快地執行,然后再重新打開硬中斷。
內核中也有其他機制將耗時操作轉移出去,不過對於網絡棧,我們接下來只看軟中斷這種方式。
可以把軟中斷系統想象成一系列內核線程(每個 CPU 一個),這些線程執行針對不同事件注冊的處理函數(handler)。如果你執行過 top
命令,可能會注意到ksoftirqd/0
這個內核線程,其表示這個軟中斷線程跑在 CPU 0 上。
內核子系統(比如網絡)能通過 open_softirq
函數注冊軟中斷處理函數。接下來我們會看到網絡系統是如何注冊它的處理函數的。現在先來學習一下軟中斷是如何工作的。
ksoftirqd
軟中斷對分擔硬中斷的工作量非常重要,因此軟中斷線程在內核啟動的很早階段就 spawn
出來了。
·kernel/softirq.c
展示了 ksoftirqd
系統是如何初始化的:
static struct smp_hotplug_thread softirq_threads = {
.store = &ksoftirqd,
.thread_should_run = ksoftirqd_should_run,
.thread_fn = run_ksoftirqd,
.thread_comm = "ksoftirqd/%u",
};
static __init int spawn_ksoftirqd(void)
{
register_cpu_notifier(&cpu_nfb);
BUG_ON(smpboot_register_percpu_thread(&softirq_threads));
return 0;
}
early_initcall(spawn_ksoftirqd);
看到注冊了兩個回調函數: ksoftirqd_should_run
和 run_ksoftirqd
。這兩個函數都會從kernel/smpboot.c
里調用,作為事件處理循環的一部分。
kernel/smpboot.c
里面的代碼首先調用 ksoftirqd_should_run
判斷是否有 pending 的軟中斷,如果有,就執行 run_ksoftirqd
,后者做一些 bookeeping 工作,然后調用__do_softirq
。
__do_softirq
__do_softirq
做的幾件事情:
- 判斷哪個 softirq 被 pending
- 計算 softirq 時間,用於統計
- 更新 softirq 執行相關的統計數據
- 執行 pending softirq 的處理函數
查看 CPU 利用率時,si
字段對應的就是 softirq,度量(從硬中斷轉移過來的)軟中斷的 CPU 使用量。
監控
軟中斷的信息可以從 /proc/softirqs
讀取:
$ cat /proc/softirqs
CPU0 CPU1 CPU2 CPU3
HI: 0 0 0 0
TIMER: 2831512516 1337085411 1103326083 1423923272
NET_TX: 15774435 779806 733217 749512
NET_RX: 1671622615 1257853535 2088429526 2674732223
BLOCK: 1800253852 1466177 1791366 634534
BLOCK_IOPOLL: 0 0 0 0
TASKLET: 25 0 0 0
SCHED: 2642378225 1711756029 629040543 682215771
HRTIMER: 2547911 2046898 1558136 1521176
RCU: 2056528783 4231862865 3545088730 844379888
監控這些數據可以得到軟中斷的執行頻率信息。
例如,NET_RX
一行顯示的是軟中斷在 CPU 間的分布。如果分布非常不均勻,那某一列的值就會遠大於其他列,這預示着下面要介紹的 Receive Packet Steering / Receive Flow
Steering 可能會派上用場。但也要注意:不要太相信這個數值,NET_RX
太高並不一定都是網卡觸發的,下面會看到其他地方也有可能觸發之。
調整其他網絡配置時,可以留意下這個指標的變動。
綁定軟中斷
第一步:確定要綁定的網卡
enP1p3s0f0
enP1p3s0f1
b.關閉irq,systemctl stop irqbalance.service
第二步:確定local_cpu序號
[root@node-1 ~]# cat /sys/class/net/enP1p3s0f0/device/local_cpulist
64-71
第三部:查詢網卡的中斷號
[root@node-1 ~]# ll /sys/class/net/enP1p3s0f0/device/msi_irqs/
total 0
drwxr-xr-x 2 root 0 Mar 23 17:37 .
drwxr-xr-x 6 root 0 Mar 23 16:30 ..
-r--r--r-- 1 root 65536 Mar 23 21:15 266
-r--r--r-- 1 root 65536 Mar 23 21:15 267
-r--r--r-- 1 root 65536 Mar 23 21:15 268
-r--r--r-- 1 root 65536 Mar 23 21:15 269
|
|
|
-r--r--r-- 1 root 65536 Mar 23 20:29 328
-r--r--r-- 1 root 65536 Mar 23 20:29 329
[root@node-1 ~]#
第四部綁定:
[root@node-1 ~]# echo 64 > /proc/irq/266/smp_affinity_list
[root@node-1 ~]# cat /proc/irq/266/smp_affinity_list
64
[root@node-1 ~]#
綁定的腳本
a=63
for i in {267..330};
do
a=$(($a+1))
echo $a > /proc/irq/$i/smp_affinity_list
if [ $a -ge 71 ];then
a=63
fi
done