linux tcp重传多会导致软中断在各个核很不均匀么?
Posted 安庆
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux tcp重传多会导致软中断在各个核很不均匀么?相关的知识,希望对你有一定的参考价值。
有个同事在排查问题的时候,说因为网络不稳定,导致了某些核的软中断很高。那么,下面我们来分析下这个论断的准确性。
环境描述:
网卡软中断进行了绑核。设备具备80个核,960个网卡中断,没开启bbr,全部是tcp呼叫。
# cat /proc/cpuinfo |grep processor|wc -l 80
# cat /proc/interrupts |grep eth |wc -l 960
# cat /proc/irq/848/smp_affinity 00000000,00000000,00000000,00000000,00008000,00000000,00000000
每个网卡中断指定在一个cpu核上。
问题描述:发现有的核上软中断比其他核高很多,因为当时看到有大概2个点的重传率。
分析过程:
首先,重传的报文数量,确实有可能会引起软中断增高,那我们来看下具体怎么影响的。
tcp_v4_init_sock---->tcp_init_sock---->tcp_init_xmit_timers---->inet_csk_init_xmit_timers
void inet_csk_init_xmit_timers(struct sock *sk, void (*retransmit_handler)(unsigned long), void (*delack_handler)(unsigned long), void (*keepalive_handler)(unsigned long)) { struct inet_connection_sock *icsk = inet_csk(sk); setup_timer(&icsk->icsk_retransmit_timer, retransmit_handler, (unsigned long)sk); setup_timer(&icsk->icsk_delack_timer, delack_handler, (unsigned long)sk); setup_timer(&sk->sk_timer, keepalive_handler, (unsigned long)sk); icsk->icsk_pending = icsk->icsk_ack.pending = 0; }
我们看到,在这个地方设置了重传定时器icsk_retransmit_timer,根据软中断的数组:
enum { HI_SOFTIRQ=0, TIMER_SOFTIRQ, NET_TX_SOFTIRQ, NET_RX_SOFTIRQ, BLOCK_SOFTIRQ, BLOCK_IOPOLL_SOFTIRQ, TASKLET_SOFTIRQ, SCHED_SOFTIRQ, HRTIMER_SOFTIRQ, /* Unused, but kept as tools rely on the numbering. Sigh! */ RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */ NR_SOFTIRQS };
我们的timer,是利用TIMER_SOFTIRQ 这个中断号,那么根据中断号在cpu上分布是否均匀,就能看出影响多大。
LOC: 1072490396 678867892 808702249 738663051 694968438 664162833 654867572 651600329 654034656 645216969 627279751 639649619 641258373 639135342 635356673 641374876 637985751 629441830 632710723 631181922 860372920 811835568 721220382 669551672 649964241 632893235 628735585 624749341 622625858 616301049 619922385 612601767 612468721 614664270 616217297 614498541 610157489 607806218 610633457 604827668 1012416149 991506038 804318769 713451371 635498936 622276467 613574278 604650512 596876703 594943840 589362031 598699322 591033519 592127520 590210531 600537489 590585630 585989825 589738219 589555728 801802931 800267559 706742143 638665014 607582520 588593222 582048215 571846551 576418826 574034238 578342405 567753955 576671298 570976007 573807289 573966353 568759967 891048780 570053521 571002170 Local timer interrupts
除了cpu0,其他核都是很均匀了。
事实上,这个问题直接分析/proc/interrupts就能看出来,其实是由于某些核上的NET_TX_SOFTIRQ非常少导致的。
那么问题来了,虽然我们知道了重传的报文对cpu的软中断数不均衡情况影响很小,那为什么呼叫的时候,各个cpu的软中断数相差很大呢。
回到问题的本质,我们的系统其实开启了RPS和RFS,RPS(Receive Packet Steering)主要是把软中断的负载均衡到各个cpu,简单来说,是网卡驱动对每个流生成一个hash标识,这个HASH值得计算可以通过四元组来计算(SIP,SPORT,DIP,DPORT)。看起来好像没问题。
其实问题就在于,我们是多媒体服务器,用于测试的机器的ip并没有篡改,我们的源ip和目的ip都是固定的,目的端口在第一次请求建联的时候也是固定的,后续的发流也就是靠源端口和目的端口来保证hash的散列性,通过抓包发现,其实这个散列性并不好。当我们把源ip配置很多的时候,现象得到了很大的改善,把服务器的目的ip多增加一些的时候,效果也更好。
以上是关于linux tcp重传多会导致软中断在各个核很不均匀么?的主要内容,如果未能解决你的问题,请参考以下文章
Linux性能优化从入门到实战:05 CPU篇:硬中断软中断