最近的vpp-dev邮件中在讨论使用af-packet插件时,创建host接口之后ping功能出现很高的延迟。
链接:https://lists.fd.io/g/vpp-dev/topic/high_latency_while_pinging/101937209
下面是在本地环境中创建host-ens224接口,分别在内核下ping网关和在vpp中ping网关的延迟情况,对比发现确实存在延迟很高的情况。
代码语言:javascript复制#创建host接口,mac地址设置与内核接口mac地址一致,否则报文无法进入到vpp。
#当前也可以在内核接口设置为混杂模式
create host-interface name ens224 hw-addr 00:50:56:30:9a:1e
#设置接口up,并配置dhcp client
DBGvpp# set interface state host-ens224 up
DBGvpp# set dhcp client intfc host-ens224
set dhcp client: dhcp client already enabled on host-ens224
DBGvpp# show interface addr
host-ens224 (up):
L3 192.168.0.110/24
#内核下ping网关
root@jinsh:~/workspace# ping 192.168.0.1
PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data.
64 bytes from 192.168.0.1: icmp_seq=1 ttl=64 time=1.44 ms
64 bytes from 192.168.0.1: icmp_seq=2 ttl=64 time=1.69 ms
64 bytes from 192.168.0.1: icmp_seq=3 ttl=64 time=2.42 ms
64 bytes from 192.168.0.1: icmp_seq=4 ttl=64 time=1.51 ms
64 bytes from 192.168.0.1: icmp_seq=5 ttl=64 time=1.54 ms
64 bytes from 192.168.0.1: icmp_seq=6 ttl=64 time=1.34 ms
64 bytes from 192.168.0.1: icmp_seq=7 ttl=64 time=1.44 ms
64 bytes from 192.168.0.1: icmp_seq=8 ttl=64 time=1.43 ms
--- 192.168.0.1 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9016ms
rtt min/avg/max/mdev = 1.308/1.601/2.422/0.318 ms
#vppctl ping网关
root@jinsh:~/workspace# vppctl ping 192.168.0.1
116 bytes from 192.168.0.1: icmp_seq=1 ttl=64 time=37.6834 ms
116 bytes from 192.168.0.1: icmp_seq=2 ttl=64 time=14.3439 ms
116 bytes from 192.168.0.1: icmp_seq=3 ttl=64 time=13.5889 ms
116 bytes from 192.168.0.1: icmp_seq=4 ttl=64 time=5.5926 ms
116 bytes from 192.168.0.1: icmp_seq=5 ttl=64 time=14.0425 ms
Statistics: 5 sent, 5 received, 0% packet loss
默认host-interface接口实现 af_packet v3版本。对于 v3 版本的 af_packet (mmap) 缓存数据块,默认的最小延迟超时为1ms。AF_PACKET v3 使用块级通知机制而不是帧级。是根据超时或缓存数据块被填充满来通知应用层。VPP 中的 AF_PACKET v3 默认块大小为 64K 字节,以容纳 GSO 数据包。需要大量 ping 数据包才能填满该块。所以,在发起ping功能时是超时触发应用层。可以通过使用 VPP show error命令查看“超时块”与“总接收块”的计数来确认是超时触发。
代码语言:javascript复制root@jinsh:~/workspace# vppctl show error | grep af-packet
2281 af-packet-input timed out block error
2281 af-packet-input total received block error
在函数af_packet_v3_device_input_fn中通过block块返回状态来判断是否是超时返回。
代码语言:javascript复制 if (TP_STATUS_BLK_TMO & bd->hdr.bh1.block_status)
timedout_blk ;
接下来我们创建af-packet v2版本,来测试一下ping延迟情况。如下所示,ping延迟确实比v3版本确实有所改善,但和内核比较差距还是比较大。将host-interface默认是中断模式,将设置为pool模式之后也没有改善。
代码语言:javascript复制#创建V2模式
create host-interface v2 name ens224 hw-addr 00:50:56:30:9a:1e
root@jinsh:~/workspace# vppctl ping 192.168.0.1
116 bytes from 192.168.0.1: icmp_seq=1 ttl=64 time=9.6021 ms
116 bytes from 192.168.0.1: icmp_seq=2 ttl=64 time=2.5152 ms
116 bytes from 192.168.0.1: icmp_seq=3 ttl=64 time=4.7199 ms
116 bytes from 192.168.0.1: icmp_seq=4 ttl=64 time=8.6667 ms
116 bytes from 192.168.0.1: icmp_seq=5 ttl=64 time=2.3151 ms
下面对比一下v2和v3版本差距,只有RX队列存在差异。
代码语言:javascript复制BGvpp# show hardware-interfaces host-ens224
Name Idx Link Hardware
host-ens224 2 up host-ens224
Link speed: unknown
RX Queues:
queue thread mode
0 vpp_wk_1 (2) interrupt
TX Queues:
TX Hash: [name: hash-eth-l34 priority: 50 description: Hash ethernet L34 headers]
queue shared thread(s)
0 yes 0-2
Ethernet address 00:50:56:30:9a:1e
Linux PACKET socket interface v3
FEATURES:
qdisc-bpass-enabled
cksum-gso-enabled
RX Queue 0:
block size:65536 nr:160 frame size:2048 nr:5120 next block:128
TX Queue 0:
block size:69206016 nr:1 frame size:67584 nr:1024 next frame:84
available:1024 request:0 sending:0 wrong:0 total:1024
DBGvpp# show hardware-interfaces host-ens224
Name Idx Link Hardware
host-ens224 2 up host-ens224
Link speed: unknown
RX Queues:
queue thread mode
0 vpp_wk_1 (2) polling
TX Queues:
TX Hash: [name: hash-eth-l34 priority: 50 description: Hash ethernet L34 headers]
queue shared thread(s)
0 yes 0-2
Ethernet address 00:50:56:30:9a:1e
Linux PACKET socket interface v2
FEATURES:
qdisc-bpass-enabled
cksum-gso-enabled
RX Queue 0:
block size:69206016 nr:1 frame size:67584 nr:1024 next frame:1003
TX Queue 0:
block size:69206016 nr:1 frame size:67584 nr:1024 next frame:667
available:1024 request:0 sending:0 wrong:0 total:1024
block size:块大小,nr 块个数
frame size:数据帧大小,nr:数据帧总数。
通过对比发现v3版本申请多个block块,而v2版本只有1个block块。数据块内存分布可以查看上一篇文章《learning:af_packet plugin (1)》中的说明。