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,

#  cat /sys/class/net/eth10/queues/rx-0/rps_cpus
00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000ffff,ffffffff,ffffffff

# cat /sys/class/net/eth10/queues/rx-0/rps_flow_cnt
4096

RPS(Receive Packet Steering)主要是把软中断的负载均衡到各个cpu,简单来说,是网卡驱动对每个流生成一个hash标识,这个HASH值得计算可以通过四元组来计算(SIP,SPORT,DIP,DPORT)。看起来好像没问题,

其实问题就在于,我们是多媒体服务器,用于测试的机器的ip并没有篡改,我们的源ip和目的ip都是固定的,目的端口在第一次请求建联的时候也是固定的,后续的发流也就是靠源端口和目的端口来保证hash的散列性,通过抓包发现,其实这个散列性并不好。当我们把源ip配置很多的时候,现象得到了很大的改善,把服务器的目的ip多增加一些的时候,效果也更好。

进一步地,除了用肉眼观察,我怎么确定我们的软中断处理情况呢?答案是perf。

比如我要查看cpu14的软中断处理情况,

[root@host]# perf top -C 14 -e  irq:softirq_entry

Samples: 290K of event 'irq:softirq_entry', Event count (approx.): 238847                                                                                                                                 
Overhead  Trace output                                                                                                                                                                                    
  92.30%  vec=3 [action=NET_RX]
   3.24%  vec=0 [action=HI]
   2.83%  vec=1 [action=TIMER]
   1.09%  vec=9 [action=RCU]
   0.49%  vec=7 [action=SCHED]
   0.05%  vec=2 [action=NET_TX]

可以明显看出,收包是中断的大头,然后看哪个中断号占其中的大头呢?可以很明显看到irq为1355的就占了绝大多数。

perf top -C 14 -e  irq:irq_handler_entry
 90.10%  irq=1355 name=i40e-eth7-TxRx-35
   9.06%  irq=1626 name=i40e-eth2-TxRx-35
   

所以说,虽然中断绑核了,但不一定就中断均匀,因为某个中断号触发次数可能就别的中断号高很多。

这么说,如果中断数量差不多,是不是si%就应该差不多呢,理论上是如此,理论上的意思就是:cpu处理该中断的时间消耗差不多,因为top里面看的是时间占比,

比如同样处理一个中断,不同的cpu核的频率不一样的话,也会造成处理软中断最终的时间占比不一样。这种情况比较罕见,需要使用如下命令进行确认:

# cpupower -c 0 frequency-info
analyzing CPU 0:
  driver: intel_pstate
  CPUs which run at the same hardware frequency: 0
  CPUs which need to have their frequency coordinated by software: 0
  maximum transition latency:  Cannot determine or is not supported.
  hardware limits: 1000 MHz - 2.70 GHz
  available cpufreq governors: performance powersave
  current policy: frequency should be within 1000 MHz and 2.70 GHz.
                  The governor "performance" may decide which speed to use
                  within this range.
  current CPU frequency: 2.70 GHz (asserted by call to hardware)
  boost state support:
    Supported: yes
    Active: yes
水平有限,如果有错误,请帮忙提醒我。如果您觉得本文对您有帮助,可以点击下面的 推荐 支持一下我。版权所有,需要转发请带上本文源地址,博客一直在更新,欢迎 关注 。
原文地址:https://www.cnblogs.com/10087622blog/p/7808288.html