linux tcp重传多会导致软中断在各个核很不均匀么?

时间:2021-04-08 15:51:05

网络不稳定,会导致某些核的软中断很高么?那么,下面我们来分析下这个论断的准确性。

环境描述:

网卡软中断进行了绑核。设备具备80个核,960个网卡中断,没开启bbr,全部是tcp呼叫。

# cat /proc/cpuinfo |grep processor|wc -l
# cat /proc/interrupts |grep   eth |wc -l
# cat /proc/irq//smp_affinity
,,,,,,

每个网卡中断指定在一个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 = ;
}

我们看到,在这个地方设置了重传定时器icsk_retransmit_timer,根据软中断的数组:

enum
{
HI_SOFTIRQ=,
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:                                                                                                                                                                 Local timer interrupts

除了cpu0,其他核都是很均匀了。

事实上,这个问题直接分析/proc/interrupts就能看出来,其实是由于某些核上的NET_TX_SOFTIRQ非常少导致的。

那么问题来了,虽然我们知道了重传的报文对cpu的软中断数不均衡情况影响很小,那为什么呼叫的时候,各个cpu的软中断数相差很大呢。

回到问题的本质,我们的系统其实开启了RPS和RFS,

#  cat /sys/class/net/eth10/queues/rx-/rps_cpus
,,,,,,,,,,,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  -e  irq:softirq_entry

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

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

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

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

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

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

# cpupower -c  frequency-info
analyzing CPU :
driver: intel_pstate
CPUs which run at the same hardware frequency:
CPUs which need to have their frequency coordinated by software:
maximum transition latency: Cannot determine or is not supported.
hardware limits: MHz - 2.70 GHz
available cpufreq governors: performance powersave
current policy: frequency should be within 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