[ovs][dpdk] ovs-dpdk, dpdk port 大量丢包

gdb了ovs的代码,发现是 dpdk的imiss计数在不断的丢包。

看了ovs-openvswitchd的日志,重启时发现如下行:

3590 2018-05-21T11:57:03.427Z|00033|timeval|WARN|Unreasonably long 22418ms poll interval (474ms user, 21612ms system)
3591 2018-05-21T11:57:03.427Z|00034|timeval|WARN|faults: 141393 minor, 0 major
3592 2018-05-21T11:57:03.427Z|00035|timeval|WARN|disk: 0 reads, 16 writes
3593 2018-05-21T11:57:03.427Z|00036|timeval|WARN|context switches: 14 voluntary, 120 involuntary

开启debug

[root@vrouter1 ~]# ovs-appctl vlog/set file:dbg

重装新版dpdk

[root@vrouter1 ovs-dpdk]# ls
dpdk-17.11.2.tar.xz  dpdk-stable-17.11.2  openvswitch-2.9.1  openvswitch-2.9.1.tar.gz

1. 编译dpdk

[root@vrouter1 dpdk-stable-17.11.2]# make config T=$RTE_TARGET O=$RTE_TARGET
Configuration done using x86_64-native-linuxapp-gcc
[root@vrouter1 dpdk-stable-17.11.2]# cd x86_64-native-linuxapp-gcc/
[root@vrouter1 x86_64-native-linuxapp-gcc]# make

2. 编译ovs

[root@vrouter1 openvswitch-2.9.1]# ./boot.sh 
[root@vrouter1 openvswitch-2.9.1]# ./configure --with-dpdk=$RTE_SDK/$RTE_TARGET
[root@vrouter1 openvswitch-2.9.1]# make
[root@vrouter1 openvswitch-2.9.1]# make install

3. 运行

[root@vrouter1 ovs-dpdk]# cat ovs.sh 
export PATH=$PATH:/usr/local/share/openvswitch/scripts
export DB_SOCK=/usr/local/var/run/openvswitch/db.sock

ovs-ctl --no-ovs-vswitchd start
#ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-init=true
#ovs-ctl --no-ovsdb-server --db-sock="$DB_SOCK" start
ovs-ctl --no-ovsdb-server start
[root@vrouter1 ovs-dpdk]# 

4. 配置

[root@vrouter1 Datapath]# dpdk-devbind -b vfio-pci 0000:01:00.0
[root@vrouter1 ovs-dpdk]# ovs-vsctl add-br br-phy -- set bridge br-phy datapath_type=netdev
[root@vrouter1 ovs-dpdk]# ovs-vsctl add-port br-phy dpdk-p0 -- set Interface dpdk-p0 type=dpdk options:dpdk-devargs=0000:01:00.0
[root@vrouter1 ovs-dpdk]# ovs-vsctl add-br br0 -- set bridge br0 datapath_type=netdev
[root@vrouter1 ovs-dpdk]# ovs-vsctl add-port br0 vxlan0 -- set Interface vxlan0 type=vxlan options:remote_ip=10.0.0.163 options:local_ip=10.0.0.161 options:in_key=flow options:out_key=flow
 #>ovs-appctl ovs/route/add 10.0.0.163/24 br-phy
[root@vrouter1 ~]# ip a add 10.0.0.161/24 dev br-phy

5. 绑定dpdk core

[root@vrouter1 ~]# ovs-vsctl set Interface dpdk-p0 options:n_rxq=4
[root@vrouter1 ~]# ovs-vsctl set Open_vSwitch . other_config:pmd-cpu-mask=0x154

6. 不丢包了。

7. vhost user client

7.1 启动vhost iommu

[root@vrouter1 ~]# ovs-vsctl set Open_vSwitch . other_config:vhost-iommu-support=true

8 添加vhostuserclient网卡

[root@vrouter1 ~]# ovs-vsctl add-port br0 vhost0 -- set Interface vhost0 type=dpdkvhostuserclient options:vhost-server-path=/tmp/nlb_vm0.sock
[root@vrouter1 ~]# ovs-vsctl add-port br0 vhost1 -- set Interface vhost1 type=dpdkvhostuserclient options:vhost-server-path=/tmp/nlb_vm1.sock

9 加流表

[root@vrouter1 ~]# ovs-appctl dpif/show
netdev@ovs-netdev: hit:31940814928 missed:234
    br-phy:
        br-phy 65534/1: (tap)
        dpdk-p0 1/2: (dpdk: configured_rx_queues=4, configured_rxq_descriptors=2048, configured_tx_queues=7, configured_txq_descriptors=2048, lsc_interrupt_mode=false, mtu=1500, requested_rx_queues=4, requested_rxq_descriptors=2048, requested_tx_queues=7, requested_txq_descriptors=2048, rx_csum_offload=true)
    br0:
        br0 65534/3: (tap)
        vhost0 2/5: (dpdkvhostuserclient: configured_rx_queues=1, configured_tx_queues=1, mtu=1500, requested_rx_queues=1, requested_tx_queues=1)
        vhost1 3/6: (dpdkvhostuserclient: configured_rx_queues=1, configured_tx_queues=1, mtu=1500, requested_rx_queues=1, requested_tx_queues=1)
        vxlan0 1/4: (vxlan: key=flow, local_ip=10.0.0.161, remote_ip=10.0.0.163)
[root@vrouter1 ~]# ovs-ofctl add-flow br0 "cookie=0x1111,table=0, priority=100, tun_id=200,dl_dst=00:00:00:11:22:41,nw_dst=192.168.77.161,actions=move:NXM_NX_TUN_ID[0..23]->NXM_NX_REG0[0..23],resubmit(,1)"
[root@vrouter1 ~]# ovs-ofctl add-flow br0 "cookie=0x1111,table=0, priority=100, tun_id=200,dl_dst=00:00:00:11:22:41,nw_dst=192.168.77.161,actions=move:NXM_NX_TUN_ID[0..23]->NXM_NX_REG0[0..23],resubmit(,1)"

10, 查看队列与core的mapping关系

[root@vrouter1 ~]# ovs-appctl dpif-netdev/pmd-rxq-show 
pmd thread numa_id 0 core_id 2:
    isolated : false
    port: dpdk-p0             queue-id:  0    pmd usage: 77 %
    port: vhost1              queue-id:  2    pmd usage:  0 %
    port: vhost1              queue-id:  3    pmd usage:  0 %
pmd thread numa_id 0 core_id 4:
    isolated : false
    port: dpdk-p0             queue-id:  3    pmd usage: 77 %
    port: vhost1              queue-id:  0    pmd usage:  0 %
pmd thread numa_id 0 core_id 6:
    isolated : false
    port: dpdk-p0             queue-id:  1    pmd usage: 78 %
    port: vhost0              queue-id:  4    pmd usage:  0 %
pmd thread numa_id 0 core_id 8:
    isolated : false
    port: vhost0              queue-id:  0    pmd usage:  0 %
    port: vhost0              queue-id:  3    pmd usage:  0 %
pmd thread numa_id 0 core_id 10:
    isolated : false
    port: dpdk-p0             queue-id:  2    pmd usage: 77 %
    port: vhost1              queue-id:  1    pmd usage:  0 %
    port: vhost1              queue-id:  4    pmd usage:  0 %
pmd thread numa_id 0 core_id 12:
    isolated : false
    port: vhost0              queue-id:  1    pmd usage:  0 %
    port: vhost0              queue-id:  2    pmd usage:  0 %

总结:

丢包只要是丢在了内核,因为top的时候看绑定core的cpu占用,可以看见大约80%的占用是sys,20%是user

正常的情况是包都在dpdk用户态走,所有应该100%是user。

理解了路由,流表,vxlan的原理之后,可以逐个梳理,保证包不会被流转进内核,便可以消除丢包。

总之,原因就是由于流表路由的设置问题使数据包被转发入了内核。

原文地址:https://www.cnblogs.com/hugetong/p/9071564.html