引子
使用qlogic QL45000网卡测试业务性能,发现cpu软中断分布不均衡,而且很有规律,导致cpu空闲也不是很均衡,
会影响业务稳定性。
设备使用3张网卡Qlogic网卡,配置为4*25G模式,也就是12个25G网口。三张网卡中其中两张接在物理cpu0上,
另一张接在物理cpu1上。笔者以为是由于三张网卡在物理架构上不均衡导致的cpu软中断不均衡,但是屏蔽了物理
cpu0上的其中一张网卡的四个网口后,cpu软中断仍然不均衡。所以,可能是其他原因导致的这个问题。
问题背景
我们的设备主要是提供高并发业务,出向流量带宽达到网口带宽的80%,为了提高服务器网卡发包性能,一般会
对网卡中断绑核,应用程序也会做发包绑核。我们一般的绑核原则是网卡中断依次绑定在各个cpu核上,中断和cpu核
是一对一的,也就是ethX-RxTx-0 对应cpu0,ethX-RxTx-1对应cpu1,ethX-RxTx-N 对应cpuN,N是最大的cpu核数。
一般网卡可用队列数(一般队列数和网卡中断数对应的)是与cpu核数对应的。但是也有网卡可配置最大队列数小于
cpu核数,比如Mellanox网卡和我们现在用到的Qlogic网卡。
当网卡可配置最大队列数小于cpu核数时,我们倾向于配置网卡队列数为cpu核数的一半,然后把网卡中断绑定到
该网卡所在numa节点对应的cpu上。目的是为了避免网卡NAPI poll跨numa节点处理中断(清理rx、tx队列),造成不
必要的系统消耗。
在使用Qlogic网卡做业务性能测试时,就是按照以上说明做网卡队列设置和绑核。但是出现了系统软中断不均衡
的问题。下面显示了系统CPU负荷,网口出向流量、perf top等数据信息。
相关数据信息
CPU负荷信息:
CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
15:56:00 all 8.58 0.00 15.00 0.00 2.15 14.84 0.00 0.00 0.00 59.43
15:56:00 0 18.45 0.00 9.22 0.00 2.43 14.08 0.00 0.00 0.00 55.83
15:56:00 1 8.43 0.00 8.99 0.00 2.81 14.04 0.00 0.00 0.00 65.73
15:56:00 2 7.21 0.00 21.63 0.00 1.92 12.02 0.00 0.00 0.00 57.21
15:56:00 3 8.20 0.00 18.58 0.00 2.19 13.11 0.00 0.00 0.00 57.92
15:56:00 4 4.79 0.00 5.99 0.00 2.40 14.37 0.00 0.00 0.00 72.46
15:56:00 5 6.82 0.00 8.52 0.00 2.84 14.20 0.00 0.00 0.00 67.61
15:56:00 6 6.74 0.00 10.67 0.00 2.81 13.48 0.00 0.00 0.00 66.29
15:56:00 7 7.73 0.00 21.74 0.00 2.42 11.59 0.00 0.00 0.00 56.52
15:56:00 8 7.22 0.00 16.49 0.00 2.06 12.89 0.00 0.00 0.00 61.34
15:56:00 9 11.11 0.00 13.13 0.00 2.02 12.12 0.00 0.00 0.00 61.62
15:56:00 10 13.36 0.00 17.05 0.00 2.30 11.06 0.00 0.00 0.00 56.22
15:56:00 11 8.51 0.00 12.77 0.00 2.66 12.77 0.00 0.00 0.00 63.30
15:56:00 12 9.76 0.00 16.10 0.00 1.95 12.20 0.00 0.00 0.00 60.00
15:56:00 13 6.70 0.00 10.06 0.00 2.23 13.41 0.00 0.00 0.00 67.60
15:56:00 14 6.99 0.00 27.51 0.00 1.75 10.92 0.00 0.00 0.00 52.84
15:56:00 15 11.00 0.00 18.18 0.00 2.39 11.96 0.00 0.00 0.00 56.46
15:56:00 16 7.83 0.00 23.04 0.00 1.84 11.06 0.00 0.00 0.00 56.22
15:56:00 17 6.54 0.00 23.36 0.00 1.87 11.68 0.00 0.00 0.00 56.54
15:56:00 18 9.38 0.00 13.54 0.00 2.08 12.50 0.00 0.00 0.00 62.50
15:56:00 19 5.88 0.00 7.65 0.00 2.35 14.12 0.00 0.00 0.00 70.00
15:56:00 20 7.69 0.00 12.64 0.00 2.20 13.74 0.00 0.00 0.00 63.74
15:56:00 21 6.25 0.00 10.23 0.00 2.27 13.64 0.00 0.00 0.00 67.61
15:56:00 22 8.25 0.00 19.07 0.00 2.58 17.53 0.00 0.00 0.00 52.58
15:56:00 23 7.89 0.00 13.68 0.00 2.63 18.42 0.00 0.00 0.00 57.37
15:56:00 24 8.59 0.00 21.21 0.00 2.02 16.67 0.00 0.00 0.00 51.52
15:56:00 25 16.75 0.00 12.81 0.00 1.97 16.75 0.00 0.00 0.00 51.72
15:56:00 26 9.09 0.00 12.83 0.00 2.14 17.65 0.00 0.00 0.00 58.29
15:56:00 27 8.33 0.00 8.89 0.00 2.22 18.89 0.00 0.00 0.00 61.67
15:56:00 28 7.85 0.00 14.66 0.00 2.62 17.80 0.00 0.00 0.00 57.07
15:56:00 29 11.61 0.00 23.66 0.00 1.79 14.73 0.00 0.00 0.00 48.21
15:56:00 30 7.94 0.00 13.76 0.00 2.12 16.40 0.00 0.00 0.00 59.79
15:56:00 31 8.99 0.00 13.23 0.00 2.12 17.46 0.00 0.00 0.00 58.20
15:56:00 32 10.95 0.00 19.05 0.00 1.90 15.71 0.00 0.00 0.00 52.38
15:56:00 33 12.25 0.00 13.73 0.00 1.96 16.18 0.00 0.00 0.00 55.88
15:56:00 34 7.07 0.00 13.59 0.00 2.17 16.85 0.00 0.00 0.00 60.33
15:56:00 35 6.32 0.00 8.05 0.00 2.30 18.39 0.00 0.00 0.00 64.94
15:56:00 36 9.84 0.00 13.47 0.00 2.07 16.06 0.00 0.00 0.00 58.55
15:56:00 37 7.22 0.00 12.78 0.00 2.78 18.33 0.00 0.00 0.00 58.89
15:56:00 38 8.38 0.00 17.80 0.00 2.62 18.32 0.00 0.00 0.00 52.88
15:56:00 39 17.73 0.00 15.45 0.00 2.27 14.55 0.00 0.00 0.00 50.00
15:56:00 40 6.52 0.00 14.67 0.00 2.72 16.85 0.00 0.00 0.00 59.24
15:56:00 41 7.22 0.00 15.98 0.00 2.06 16.49 0.00 0.00 0.00 58.25
15:56:00 42 6.91 0.00 13.83 0.00 2.66 17.02 0.00 0.00 0.00 59.57
15:56:00 43 6.84 0.00 17.89 0.00 2.63 17.89 0.00 0.00 0.00 54.74
15:56:00 44 8.08 0.00 15.66 0.00 2.53 16.16 0.00 0.00 0.00 57.58
15:56:00 45 5.36 0.00 10.12 0.00 2.38 19.64 0.00 0.00 0.00 62.50
15:56:00 46 6.63 0.00 14.36 0.00 2.21 17.13 0.00 0.00 0.00 59.67
15:56:00 47 7.50 0.00 17.00 0.00 2.00 17.50 0.00 0.00 0.00 56.00
15:56:00 48 6.88 0.00 16.40 0.00 2.12 16.93 0.00 0.00 0.00 57.67
15:56:00 49 7.21 0.00 21.63 0.00 1.92 16.35 0.00 0.00 0.00 52.88
15:56:00 50 8.57 0.00 20.95 0.00 2.38 15.71 0.00 0.00 0.00 52.38
15:56:00 51 4.52 0.00 13.56 0.00 2.26 18.64 0.00 0.00 0.00 61.02
15:56:00 52 6.91 0.00 14.36 0.00 2.13 16.49 0.00 0.00 0.00 60.11
15:56:00 53 7.14 0.00 9.89 0.00 1.65 17.03 0.00 0.00 0.00 64.29
15:56:00 54 14.04 0.00 18.86 0.00 1.75 14.47 0.00 0.00 0.00 50.88
15:56:00 55 10.00 0.00 21.82 0.00 1.82 15.00 0.00 0.00 0.00 51.36
15:56:00 56 9.36 0.00 15.76 0.00 1.97 15.76 0.00 0.00 0.00 57.14
15:56:00 57 6.78 0.00 9.60 0.00 2.26 17.51 0.00 0.00 0.00 63.84
15:56:00 58 6.56 0.00 10.38 0.00 2.19 18.03 0.00 0.00 0.00 62.84
15:56:00 59 8.78 0.00 19.02 0.00 1.95 16.59 0.00 0.00 0.00 53.66
15:56:00 60 7.89 0.00 12.11 0.00 2.11 16.84 0.00 0.00 0.00 61.05
15:56:00 61 5.08 0.00 9.04 0.00 2.26 18.08 0.00 0.00 0.00 65.54
15:56:00 62 5.65 0.00 8.47 0.00 1.69 17.51 0.00 0.00 0.00 66.67
15:56:00 63 4.19 0.00 5.99 0.00 2.40 19.76 0.00 0.00 0.00 67.66
15:56:00 64 6.42 0.00 13.37 0.00 2.14 18.18 0.00 0.00 0.00 59.89
15:56:00 65 8.63 0.00 13.71 0.00 2.54 17.26 0.00 0.00 0.00 57.87
15:56:00 66 7.80 0.00 21.95 0.00 1.95 11.71 0.00 0.00 0.00 56.59
15:56:00 67 9.39 0.00 11.05 0.00 2.21 13.26 0.00 0.00 0.00 64.09
15:56:00 68 8.29 0.00 14.92 0.00 2.21 14.36 0.00 0.00 0.00 60.22
15:56:00 69 13.74 0.00 20.38 0.00 1.90 11.85 0.00 0.00 0.00 52.13
15:56:00 70 14.80 0.00 21.08 0.00 1.79 10.76 0.00 0.00 0.00 51.57
15:56:00 71 16.91 0.00 12.08 0.00 1.93 11.59 0.00 0.00 0.00 57.49
15:56:00 72 8.51 0.00 13.30 0.00 1.60 12.77 0.00 0.00 0.00 63.83
15:56:00 73 9.90 0.00 16.34 0.00 1.98 12.38 0.00 0.00 0.00 59.41
15:56:00 74 8.25 0.00 12.37 0.00 2.06 12.89 0.00 0.00 0.00 64.43
15:56:00 75 6.38 0.00 14.36 0.00 2.13 13.30 0.00 0.00 0.00 63.83
15:56:00 76 9.80 0.00 17.16 0.00 1.96 12.25 0.00 0.00 0.00 58.82
15:56:00 77 7.11 0.00 15.23 0.00 2.03 12.18 0.00 0.00 0.00 63.45
15:56:00 78 6.56 0.00 11.48 0.00 1.64 13.66 0.00 0.00 0.00 66.67
15:56:00 79 6.63 0.00 9.94 0.00 1.66 13.81 0.00 0.00 0.00 67.96
15:56:00 80 4.65 0.00 7.56 0.00 2.33 14.53 0.00 0.00 0.00 70.93
15:56:00 81 5.75 0.00 8.62 0.00 2.30 13.79 0.00 0.00 0.00 69.54
15:56:00 82 8.25 0.00 16.49 0.00 2.06 13.40 0.00 0.00 0.00 59.79
15:56:00 83 5.63 0.00 23.00 0.00 1.88 11.74 0.00 0.00 0.00 57.75
15:56:00 84 5.75 0.00 8.05 0.00 1.72 14.37 0.00 0.00 0.00 70.11
15:56:00 85 12.99 0.00 21.21 0.00 1.73 10.39 0.00 0.00 0.00 53.68
15:56:00 86 6.56 0.00 10.38 0.00 2.19 13.66 0.00 0.00 0.00 67.21
15:56:00 87 8.54 0.00 17.59 0.00 2.51 12.06 0.00 0.00 0.00 59.30
网卡流量信息:
注意:屏蔽了其中一个网卡
2019-01-25 16:06:09 bond5: 3.64 Mb/s In 81292.31 Mb/s Out - 2732.2 p/s In 7362624.8 p/s Out
2019-01-25 16:06:09 bond6: 3.39 Mb/s In 93455.77 Mb/s Out - 1812.2 p/s In 8463913.5 p/s Out
2019-01-25 16:06:09 bond7: 0.00 Mb/s In 0.00 Mb/s Out - 0.0 p/s In 0.0 p/s Out
2019-01-25 16:06:09 bond8: 0.00 Mb/s In 0.00 Mb/s Out - 0.0 p/s In 0.0 p/s Out
2019-01-25 16:06:09 bond9: 0.00 Mb/s In 0.00 Mb/s Out - 0.0 p/s In 0.0 p/s Out
2019-01-25 16:06:09 enp1s0bak: 0.00 Mb/s In 0.00 Mb/s Out - 0.0 p/s In 0.0 p/s Out
2019-01-25 16:06:09 enp2s0bak: 0.00 Mb/s In 0.00 Mb/s Out - 0.0 p/s In 0.0 p/s Out
2019-01-25 16:06:09 eth0: 0.90 Mb/s In 19991.22 Mb/s Out - 686.5 p/s In 1810597.2 p/s Out
2019-01-25 16:06:09 eth1: 0.91 Mb/s In 20768.09 Mb/s Out - 675.0 p/s In 1880961.8 p/s Out
2019-01-25 16:06:09 eth10: 3.17 Mb/s In 23021.46 Mb/s Out - 1449.2 p/s In 2084982.0 p/s Out
2019-01-25 16:06:09 eth11: 0.07 Mb/s In 23860.54 Mb/s Out - 115.5 p/s In 2160935.5 p/s Out
2019-01-25 16:06:09 eth2: 0.07 Mb/s In 23031.12 Mb/s Out - 122.2 p/s In 2085820.0 p/s Out
2019-01-25 16:06:09 eth3: 0.07 Mb/s In 23538.46 Mb/s Out - 125.0 p/s In 2131795.0 p/s Out
2019-01-25 16:06:09 eth4: 0.00 Mb/s In 0.00 Mb/s Out - 0.0 p/s In 0.0 p/s Out
2019-01-25 16:06:09 eth5: 0.00 Mb/s In 0.00 Mb/s Out - 0.0 p/s In 0.0 p/s Out
2019-01-25 16:06:09 eth6: 0.00 Mb/s In 0.00 Mb/s Out - 0.0 p/s In 0.0 p/s Out
2019-01-25 16:06:09 eth7: 0.00 Mb/s In 0.00 Mb/s Out - 0.0 p/s In 0.0 p/s Out
2019-01-25 16:06:09 eth8: 0.93 Mb/s In 20218.63 Mb/s Out - 692.5 p/s In 1831241.0 p/s Out
2019-01-25 16:06:09 eth9: 0.90 Mb/s In 20313.86 Mb/s Out - 678.8 p/s In 1839829.0 p/s Out
perf top信息
采集cpu44和cpu0的内核热点情况
数据分析:
每个网口的出向流量基本一致,但是从CPU系统消耗来看,同一个物理cpu上cpu44-cpu65软中断
比cpu0-cpu21要高50%左右,cpu22-cpu43软中断比cpu66-cpu87也要高50%左右。
从perf top 内核热点数据看,qlogic网卡驱动的qede_free_tx_pkt占用有很大的差别。对比cpu44
和cpu0的热点数据可以看出,qede_free_tx_pkt相差在1倍。
qlogic驱动中qede_free_tx_pkt函数用于清理发送队列descriptor。这个函数是由驱动的qede_tx_int
函数调用,而qede_tx_int又由qede_poll函数调用。qede_poll用于NAPI接口做tx/rx完成清理descriptor
工作,该函数由软中断处理函数调用。
问题分析
从上面分析看出,问题集中在不同cpu核上qede_free_tx_pkt函数的调用热度,也就是qede_tx_int函数
的热度。为了得到更精确的数据,笔者修改了qlogic qede网卡驱动,统计所有cpu核上调用qede_tx_int的
次数和耗时。代码片段如下。
统计每个cpu上调用qede_tx_int函数的次数:
DEFINE_PER_CPU(atomic_t, qede_free_tx_cnt);
统计每个cpu上调用qede_tx_int函数消耗的时间:
DEFINE_PER_CPU(atomic64_t, qede_tx_time_use);
qede_poll函数
1 int qede_poll(struct napi_struct *napi, int budget) 2 { 3 struct qede_fastpath *fp = container_of(napi, struct qede_fastpath, 4 napi); 5 struct qede_dev *edev = fp->edev; 6 int rx_work_done = 0; 7 8 atomic_t *free_cnt = NULL; 9 atomic64_t *time_use = NULL; 10 unsigned long long pre_time = 0; 11 #ifdef TIME_FP_DEBUG /* ! QEDE_UPSTREAM */ 12 qede_log_time(edev, fp, QEDE_FP_TIME_START); 13 #endif 14 15 if (likely(fp->type & QEDE_FASTPATH_TX)) { 16 int cos; 17 18 for_each_cos_in_txq(fp->edev, cos) { 19 if (qede_txq_has_work(&fp->txq[cos])){ 20 free_cnt = &per_cpu(qede_free_tx_cnt, smp_processor_id()); 21 time_use = &per_cpu(qede_tx_time_use, smp_processor_id()); 22 atomic_inc(free_cnt); //增加调用次数 23 pre_time = qede_get_ms(); 24 qede_tx_int(edev, &fp->txq[cos]); 25 atomic64_add(qede_get_ms()-pre_time, time_use); //统计函数调用消耗时间 26 } 27 } 28 } 29 30 if ((fp->type & QEDE_FASTPATH_XDP) && 31 qede_txq_has_work(fp->xdp_tx)) 32 qede_xdp_tx_int(edev, fp); 33 34 rx_work_done = (likely(fp->type & QEDE_FASTPATH_RX) && 35 qede_has_rx_work(fp->rxq)) ? 36 qede_rx_int(fp, budget) : 0; 37 if (rx_work_done < budget) { 38 if (!qede_poll_is_more_work(fp)) { 39 napi_complete_done(napi, rx_work_done); 40 qede_log_napi(fp, 0); 41 42 /* Update and reenable interrupts */ 43 qede_log_intr(fp, IGU_INT_ENABLE); 44 qed_sb_ack(fp->sb_info, IGU_INT_ENABLE, 1); 45 } else { 46 rx_work_done = budget; 47 } 48 } 49 50 /* TODO - if NAPI is to be rescheduled, do we still want this now? */ 51 if (fp->xdp_xmit) { 52 u16 xdp_prod = qed_chain_get_prod_idx(&fp->xdp_tx->tx_pbl); 53 54 fp->xdp_xmit = 0; 55 fp->xdp_tx->tx_db.data.bd_prod = cpu_to_le16(xdp_prod); 56 qede_update_tx_producer(fp->xdp_tx); 57 } 58 59 #ifdef TIME_FP_DEBUG /* ! QEDE_UPSTREAM */ 60 qede_log_time(edev, fp, 61 (budget == rx_work_done) ? 62 QEDE_FP_TIME_END_RESCHEDULE : 63 QEDE_FP_TIME_END); 64 #endif 65 qede_log_napi(fp, rx_work_done); 66 return rx_work_done; 67 }
为了简化测试,只保留一张网卡,共4个25G网口参与发包测试,其中测试网卡中断绑核在cpu0-cpu21和
cpu44-cpu65上。进行两组独立测试,其中一组发包线程绑定在cpu0-cpu21和cpu44-cpu65上,即物理cpu0,
另一组发包线程绑定在cpu22-cpu43和cpu66-cpu87上,也就是物理cpu1上。
(1)测试发包线程都绑核在cpu0-cpu21和cpu44-cpu65上
qede_tx_int函数调用次数和消耗时间统计
qede_txint_count:
CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7 CPU8 CPU9 CPU10 CPU11 CPU12 CPU13 CPU14 CPU15 CPU16 CPU17 CPU18 CPU19 CPU20 CPU21
CPU22 CPU23 CPU24 CPU25 CPU26 CPU27 CPU28 CPU29 CPU30 CPU31 CPU32 CPU33 CPU34 CPU35 CPU36 CPU37 CPU38 CPU39 CPU40 CPU41 CPU42 CPU43
CPU44 CPU45 CPU46 CPU47 CPU48 CPU49 CPU50 CPU51 CPU52 CPU53 CPU54 CPU55 CPU56 CPU57 CPU58 CPU59 CPU60 CPU61 CPU62 CPU63 CPU64 CPU65
CPU66 CPU67 CPU68 CPU69 CPU70 CPU71 CPU72 CPU73 CPU74 CPU75 CPU76 CPU77 CPU78 CPU79 CPU80 CPU81 CPU82 CPU83 CPU84 CPU85 CPU86 CPU87
1280243 1269738 1311879 1311250 1335467 1263842 1254232 1267668 1305027 1305619 1260312 1308969 1320315 1308007 1280278 1309876 1313781 1301604 1266910 1277516 1304452 1310784
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
18 10 4 0 3 105 0 9 0 0 0 0 3 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
qede_txint_time:
736 753 754 745 767 749 699 723 758 738 746 715 782 749 723 722 772 765 705 708 715 747
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
(2)测试发包线程绑核在cpu22-cpu43和cpu66-cpu87上
qede_tx_int函数调用次数和消耗时间统计
qede_txint_count:
CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7 CPU8 CPU9 CPU10 CPU11 CPU12 CPU13 CPU14 CPU15 CPU16 CPU17 CPU18 CPU19 CPU20 CPU21
CPU22 CPU23 CPU24 CPU25 CPU26 CPU27 CPU28 CPU29 CPU30 CPU31 CPU32 CPU33 CPU34 CPU35 CPU36 CPU37 CPU38 CPU39 CPU40 CPU41 CPU42 CPU43
CPU44 CPU45 CPU46 CPU47 CPU48 CPU49 CPU50 CPU51 CPU52 CPU53 CPU54 CPU55 CPU56 CPU57 CPU58 CPU59 CPU60 CPU61 CPU62 CPU63 CPU64 CPU65
CPU66 CPU67 CPU68 CPU69 CPU70 CPU71 CPU72 CPU73 CPU74 CPU75 CPU76 CPU77 CPU78 CPU79 CPU80 CPU81 CPU82 CPU83 CPU84 CPU85 CPU86 CPU87
24 22 137 12 20 41 24 129 3 2 0 22 4 14 2 1 2 8 0 51 114 3
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
886594 849267 854321 868577 858135 880255 850917 826788 832024 839281 886634 826803 838126 856868 845269 840800 838523 860735 837077 850221 866948 851408
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
qede_txint_time:
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1429 1465 1405 1486 1473 1503 1477 1371 1400 1470 1486 1444 1414 1444 1400 1479 1427 1454 1404 1441 1479 1473
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
从两次测试数据看,当发包线程在物理cpu0时,网卡主要在cpu0-cpu21上发包,同时观察到网卡发包
在queue0到queue21上;当发包线程在物理cpu1时,网卡主要在cpu44-cpu65上发包,同时观察到网卡发包
在queue22-queue43上。
对比前后两次调用qede_tx_int函数次数和消耗时间看,在物理cpu1上发包时,qede_tx_int函数消耗更大。
由此可以看出,这个qlogic网卡选择队列算法有关,当发包线程与中断不在同一cpu核上时,qede_tx_int
函数消耗差距比较大。笔者将在分析网卡发包队列选择规则后进行说明。
Qlogic网卡队列选择规则
TX队列选择通过宏QEDE_NDEV_TXQ_ID_TO_TXQ决定,先通过QEDE_NDEV_TXQ_ID_TO_FP_ID选择FP队列,再通过
QEDE_NDEV_TXQ_ID_TO_TXQ_COS选择COS。
1 #define QEDE_NDEV_TXQ_ID_TO_FP_ID(edev, idx) 2 ((edev)->fp_num_rx + 3 ((idx) % (QEDE_BASE_TSS_COUNT(edev) + 4 (edev)->fwd_dev_queues))) 5 6 #define QEDE_NDEV_TXQ_ID_TO_TXQ_COS(edev, idx) 7 ((idx) / (QEDE_BASE_TSS_COUNT(edev) + 8 (edev)->fwd_dev_queues)) 9 10 11 #define QEDE_NDEV_TXQ_ID_TO_TXQ(edev, idx) 12 (&((edev)->fp_array[QEDE_NDEV_TXQ_ID_TO_FP_ID(edev, idx)].txq 13 [QEDE_NDEV_TXQ_ID_TO_TXQ_COS(edev, idx)]))
1 netdev_tx_t qede_start_xmit(struct sk_buff *skb, struct net_device *ndev) 2 { 3 struct qede_dev *edev = netdev_priv(ndev); 4 struct netdev_queue *netdev_txq; 5 struct qede_tx_queue *txq; 6 ...... 7 txq = QEDE_NDEV_TXQ_ID_TO_TXQ(edev, txq_index); 8 netdev_txq = netdev_get_tx_queue(txq->fp->ndev, txq->ndev_txq_id); 9 ..... 10 }
qlogic网卡队列比较特殊,除了ethtool -l看到的FP队列之外,每个FP队列还有4个cos队列,
可以通过观察网卡队列发包统计看出。
# ethtool -l eth0
Channel parameters for eth0:
Pre-set maximums:
RX: 64
TX: 64
Other: 0
Combined: 64
Current hardware settings:
RX: 0
TX: 0
Other: 0
Combined: 44
# ethtool -S eth0 |grep xmit_pkts ##其中一个FP队列包含4个cos
0_0: xmit_pkts: 29
0_1: xmit_pkts: 20
0_2: xmit_pkts: 26
0_3: xmit_pkts: 4
当前网卡队列配置为combined,没有入向队列,并且没有转发队列,所以QEDE_NDEV_TXQ_ID_TO_TXQ可以简化:
fp_array[idx%queue_numx].txq[idx/queue_nums]
其中queue_nums也就是基本队列数,本例中为44。
Qlogic队列选择表:
APP_bind |
fp index |
cos index |
0-21 |
0-21 |
0 |
22-43 |
22-43 |
0 |
44-65 |
0-21 |
1 |
66-87 |
22-43 |
1 |
由上表可以看到,发包线程绑核在cpu0-cpu21和cpu44-cpu65时,通过FP队列0-21发送数据;
发包线程绑核在cpu22-cpu43和cpu66-cpu87时,通过FP队列22-43发送数据。而网卡中断绑定在
cpu0-cpu21和cpu44-cpu65,这样通过FP队列0-21发送的数据包,在cpu0-cpu21上通过qede_tx_int
函数清除,而通过FP队列22-43发送的数据包,在cpu44-cpu65上通过qede_tx_int函数清除。
这样就出现了跨核清除发送描述符的情况,也就会有qede_tx_int函数调用消耗差别。因此
出现各个cpu核软中断不均衡的问题。
网卡中断绑卡修正
在测试之初,网卡中断按照网卡所在numa节点进行绑核,是为了防止napi_poll跨核访问内存
来清除TX描述符,但是实际测试数据与预期不相符,按numa绑核反而会出现跨核访问问题,导致
qede_tx_int函数在有些核上消耗比较大。
根据qlogic选择队列方式修改网卡中断绑核,网卡中断按cpu顺序依次绑核,网卡0中断绑定
到cpu0-cpu43,网卡1中断绑定到cpu44-cpu87,以此类推。也就是每个网卡中断绑核各占两个物
理cpu的一半核。
根据Qlogic队列选择表,我们可以推出,不同cpu核上发包时,qede_tx_int函数会在对应的
cpu核上清理TX描述符,不会出现跨核清理TX descriptor的情况。
PS:各位读者如果有什么想法或者疑问,欢迎交流!
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。