Problem:
---------

We are running centos 7.2 (ovs-kernel module from distribution) with OVS 2.3.1.

Large tcp frames (> 30Kbytes gro'd) are coming into a vxlan-tunnel port and switched by an ovs-bridge onto a veth port

vxlan-tunnel--(gro'd tcp frames sized > 30K)-->OVS-bridge--(frames sized 1448)-->veth port

As the ovs transmits onto the veth port, the frames are getting segmented into 1448 byte sized packets. All the offload settings are at default on the veth port (gso on, gro on, tso on)

We expect that the OVS can transmit the frame without segmentation onto the veth port. But, due to segmentation, the performance suffers.

Root Cause
-----------

The following trace with debugs shows the root cause that the gso_type is not correctly set on the skb as the packet comes in, and as a result, the dev_xmit_skb is segmenting the frame as ovs transmits it.




ksoftirqd/25-231 [025] ..s. 319.964120: vxlan_rcv: gso_size=1448,gso_type=1001

The above is debug in vport-vxlan.c:vxlan_rcv: trace_printk("gso_size=%d,gso_type=%x\n",skb_shinfo(skb)->gso_size,skb_shinfo(skb)->gso_type);
        Here, gso_type seem to have an invalid value.

ksoftirqd/25-231 [025] ..s. 319.964120: ovs_vport_receive <-vxlan_rcv ksoftirqd/25-231 [025] ..s. 319.964121: ovs_flow_key_extract <-ovs_vport_receive ksoftirqd/25-231 [025] ..s. 319.964121: key_extract <-ovs_flow_key_extract ksoftirqd/25-231 [025] ..s. 319.964121: check_header <-key_extract
    ksoftirqd/25-231   [025] ..s.   319.964121: tcphdr_ok <-key_extract
ksoftirqd/25-231 [025] ..s. 319.964121: ovs_dp_process_packet <-ovs_vport_receive ksoftirqd/25-231 [025] ..s. 319.964121: ovs_flow_tbl_lookup_stats <-ovs_dp_process_packet ksoftirqd/25-231 [025] ..s. 319.964121: masked_flow_lookup <-ovs_flow_tbl_lookup_stats ksoftirqd/25-231 [025] ..s. 319.964121: ovs_flow_mask_key <-masked_flow_lookup ksoftirqd/25-231 [025] ..s. 319.964122: find_bucket.isra.2 <-masked_flow_lookup ksoftirqd/25-231 [025] ..s. 319.964122: masked_flow_lookup <-ovs_flow_tbl_lookup_stats ksoftirqd/25-231 [025] ..s. 319.964122: ovs_flow_mask_key <-masked_flow_lookup ksoftirqd/25-231 [025] ..s. 319.964122: find_bucket.isra.2 <-masked_flow_lookup ksoftirqd/25-231 [025] ..s. 319.964122: ovs_flow_stats_update <-ovs_dp_process_packet ksoftirqd/25-231 [025] ..s. 319.964122: _raw_spin_loca <-ovs_flow_stats_update ksoftirqd/25-231 [025] ..s. 319.964122: _raw_spin_unlock <-ovs_flow_stats_update ksoftirqd/25-231 [025] ..s. 319.964122: ovs_execute_actions <-ovs_dp_process_packet ksoftirqd/25-231 [025] ..s. 319.964123: do_execute_actions <-ovs_execute_actions ksoftirqd/25-231 [025] ..s. 319.964123: do_output <-do_execute_actions ksoftirqd/25-231 [025] ..s. 319.964123: ovs_lookup_vport <-do_output ksoftirqd/25-231 [025] ..s. 319.964123: ovs_vport_send <-do_output ksoftirqd/25-231 [025] ..s. 319.964123: netdev_send <-ovs_vport_send



    ksoftirqd/25-231   [025] ..s.   319.964123: netdev_send: devmtu=8950
ksoftirqd/25-231 [025] ..s. 319.964123: netdev_send: devname=ovs-veth0
    ksoftirqd/25-231   [025] ..s.   319.964124: netdev_send: gso_segs=45
ksoftirqd/25-231 [025] ..s. 319.964124: netif_skb_features <-netdev_send ksoftirqd/25-231 [025] ..s. 319.964124: skb_network_protocol <-netif_skb_features
    ksoftirqd/25-231   [025] ..s.   319.964124: netdev_send: ip_summed=3
ksoftirqd/25-231 [025] ..s. 319.964124: netdev_send: gso_segs=45,len=65226,feat=6103db59e9 ksoftirqd/25-231 [025] ..s. 319.964124: netdev_send: net_gso_ok=0,has_frag_list=1,frag_feat=1 ksoftirqd/25-231 [025] ..s. 319.964125: netdev_send: gso_size=1448,gso_type=4097,ok=0

      The above are debugs in vport-netdev.c:netdev_send:
        trace_printk("devmtu=%d\n",mtu);
        trace_printk("devname=%s\n",netdev_vport->dev->name);
        trace_printk("gso_segs=%d\n",skb_shinfo(skb)->gso_segs);
        features = netif_skb_features(skb);
        feature = skb_shinfo(skb)->gso_type << NETIF_F_GSO_SHIFT;
        net_gso_ok = ((features & feature) == feature);
        gso_ok = skb_gso_ok(skb, features);
        has_frag_list = skb_has_frag_list(skb);
        frag_feat = features & NETIF_F_FRAGLIST ? 1 : 0;
        trace_printk("ip_summed=%d\n",skb->ip_summed);
trace_printk("gso_segs=%d,len=%d,feat=%llx\n",skb_shinfo(skb)->gso_segs,len,features); trace_printk("net_gso_ok=%d,has_frag_list=%d,frag_feat=%d\n",net_gso_ok,has_frag_list,frag_feat); trace_printk("gso_size=%d,gso_type=%d,ok=%d\n",skb_shinfo(skb)->gso_size,skb_shinfo(skb)->gso_type,gso_ok);




ksoftirqd/25-231 [025] ..s. 319.964125: dev_queue_xmit <-netdev_send ksoftirqd/25-231 [025] ..s. 319.964125: local_bh_disable <-dev_queue_xmit ksoftirqd/25-231 [025] ..s. 319.964125: netdev_pick_tx <-dev_queue_xmit ksoftirqd/25-231 [025] ..s. 319.964125: _raw_spin_lock <-dev_queue_xmit ksoftirqd/25-231 [025] ..s. 319.964125: validate_xmit_skb.part.86 <-dev_queue_xmit ksoftirqd/25-231 [025] ..s. 319.964125: netif_skb_features <-validate_xmit_skb.part.86 ksoftirqd/25-231 [025] ..s. 319.964125: skb_network_protocol <-netif_skb_features
                 validate_xmit_skb() calls netif_needs_gso()
                 netif_needs_gso() is true because:
skb_gso_ok is FALSE !! because net_gso_ok() is FALSE because
                 skb_shinfo(skb)->gso_type has a bad value of 0x1001 !!


ksoftirqd/25-231 [025] ..s. 319.964125: __skb_gso_segment <-validate_xmit_skb.part.86 ksoftirqd/25-231 [025] ..s. 319.964126: skb_mac_gso_segment <-__skb_gso_segment ksoftirqd/25-231 [025] ..s. 319.964126: skb_network_protocol <-skb_mac_gso_segment ksoftirqd/25-231 [025] ..s. 319.964126: inet_gso_segment <-skb_mac_gso_segment ksoftirqd/25-231 [025] ..s. 319.964126: tcp4_gso_segment <-inet_gso_segment ksoftirqd/25-231 [025] ..s. 319.964126: tcp_gso_segment <-tcp4_gso_segment ksoftirqd/25-231 [025] ..s. 319.964126: skb_segment <-tcp_gso_segment
                  Frame is getting segmented


I tried the following experiment: in vport-vxlan.c:vxlan_rcv() set the value of gso_type as:
  skb_shinfo(skb)->gso_type = skb_shinfo(skb)->gso_type&0xff;
With this change, frames dont segment onto the veth.

Has this sort of problem been fixed already in more recent versions ?

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to