From: Andrew Gallatin <hidden> Date: 2012-11-14 13:06:38
Unlike LRO, GRO requires that vlan tags be removed before
aggregation can occur. Since the myri10ge NIC does not support
hardware vlan tag offload, we must remove the tag in the driver
to achieve performance comparable to LRO for vlan tagged frames.
Signed-off-by: Andrew Gallatin <redacted>
---
drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 47
++++++++++++++++++++++
1 file changed, 47 insertions(+)
@@ -1264,6 +1264,48 @@ myri10ge_unmap_rx_page(struct pci_dev *pdev,}}+/*+*GROdoesnotsupportaccelerationoftaggedvlanframes,and+*thisNICdoesnotsupportvlantagoffload,sowemustpop+*thetagourselvestobeabletoachieveGROperformancethat+*iscomparabletoLRO.+*/++staticinlinevoid+myri10ge_vlan_rx(structnet_device*dev,void*addr,structsk_buff*skb)+{+u8*va;+structvlan_ethhdr*veh;+structethhdr*eh;+structskb_frag_struct*frag;+u16proto;++va=addr;+va+=MXGEFW_PAD;+veh=(structvlan_ethhdr*)va;+if((dev->features&(NETIF_F_HW_VLAN_RX|NETIF_F_GRO))==+(NETIF_F_HW_VLAN_RX|NETIF_F_GRO)&&+(veh->h_vlan_proto==ntohs(ETH_P_8021Q))){+/* fixup csum if needed */+if(skb->ip_summed==CHECKSUM_COMPLETE)+skb->csum=csum_sub(skb->csum,+csum_partial(va+ETH_HLEN,+VLAN_HLEN,0));+/* pop tag */+__vlan_hwaccel_put_tag(skb,ntohs(veh->h_vlan_TCI));+proto=veh->h_vlan_encapsulated_proto;+memmove(va+VLAN_HLEN,va,ETH_HLEN);+va+=VLAN_HLEN;+eh=(structethhdr*)va;+eh->h_proto=proto;+skb->len-=VLAN_HLEN;+skb->data_len-=VLAN_HLEN;+frag=skb_shinfo(skb)->frags;+frag->page_offset+=VLAN_HLEN;+skb_frag_size_set(frag,skb_frag_size(frag)-VLAN_HLEN);+}+}+staticinlineintmyri10ge_rx_done(structmyri10ge_slice_state*ss,intlen,__wsumcsum){
From: Eric Dumazet <hidden> Date: 2012-11-14 14:46:50
On Wed, 2012-11-14 at 08:06 -0500, Andrew Gallatin wrote:
quoted hunk
Unlike LRO, GRO requires that vlan tags be removed before
aggregation can occur. Since the myri10ge NIC does not support
hardware vlan tag offload, we must remove the tag in the driver
to achieve performance comparable to LRO for vlan tagged frames.
Signed-off-by: Andrew Gallatin <redacted>
---
drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 47
++++++++++++++++++++++
1 file changed, 47 insertions(+)
@@ -1264,6 +1264,48 @@ myri10ge_unmap_rx_page(struct pci_dev *pdev,}}+/*+*GROdoesnotsupportaccelerationoftaggedvlanframes,and+*thisNICdoesnotsupportvlantagoffload,sowemustpop+*thetagourselvestobeabletoachieveGROperformancethat+*iscomparabletoLRO.+*/++staticinlinevoid+myri10ge_vlan_rx(structnet_device*dev,void*addr,structsk_buff*skb)+{+u8*va;+structvlan_ethhdr*veh;+structethhdr*eh;+structskb_frag_struct*frag;+u16proto;++va=addr;+va+=MXGEFW_PAD;+veh=(structvlan_ethhdr*)va;+if((dev->features&(NETIF_F_HW_VLAN_RX|NETIF_F_GRO))==+(NETIF_F_HW_VLAN_RX|NETIF_F_GRO)&&+(veh->h_vlan_proto==ntohs(ETH_P_8021Q))){+/* fixup csum if needed */+if(skb->ip_summed==CHECKSUM_COMPLETE)+skb->csum=csum_sub(skb->csum,+csum_partial(va+ETH_HLEN,+VLAN_HLEN,0));+/* pop tag */+__vlan_hwaccel_put_tag(skb,ntohs(veh->h_vlan_TCI));+proto=veh->h_vlan_encapsulated_proto;
I am not sure you need this @proto ?
+ memmove(va + VLAN_HLEN, va, ETH_HLEN);
You could only memmove the mac addresses (2 * ETH_ALEN)
To not touch the proto (and avoid possible aliasing problems)
From: Andrew Gallatin <hidden> Date: 2012-11-14 15:43:44
On 11/14/12 09:46, Eric Dumazet wrote:
On Wed, 2012-11-14 at 08:06 -0500, Andrew Gallatin wrote:
quoted
Unlike LRO, GRO requires that vlan tags be removed before
aggregation can occur. Since the myri10ge NIC does not support
hardware vlan tag offload, we must remove the tag in the driver
to achieve performance comparable to LRO for vlan tagged frames.
Signed-off-by: Andrew Gallatin <redacted>
---
drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 47
++++++++++++++++++++++
1 file changed, 47 insertions(+)
@@ -1264,6 +1264,48 @@ myri10ge_unmap_rx_page(struct pci_dev *pdev,}}+/*+*GROdoesnotsupportaccelerationoftaggedvlanframes,and+*thisNICdoesnotsupportvlantagoffload,sowemustpop+*thetagourselvestobeabletoachieveGROperformancethat+*iscomparabletoLRO.+*/++staticinlinevoid+myri10ge_vlan_rx(structnet_device*dev,void*addr,structsk_buff*skb)+{+u8*va;+structvlan_ethhdr*veh;+structethhdr*eh;+structskb_frag_struct*frag;+u16proto;++va=addr;+va+=MXGEFW_PAD;+veh=(structvlan_ethhdr*)va;+if((dev->features&(NETIF_F_HW_VLAN_RX|NETIF_F_GRO))==+(NETIF_F_HW_VLAN_RX|NETIF_F_GRO)&&+(veh->h_vlan_proto==ntohs(ETH_P_8021Q))){+/* fixup csum if needed */+if(skb->ip_summed==CHECKSUM_COMPLETE)+skb->csum=csum_sub(skb->csum,+csum_partial(va+ETH_HLEN,+VLAN_HLEN,0));+/* pop tag */+__vlan_hwaccel_put_tag(skb,ntohs(veh->h_vlan_TCI));+proto=veh->h_vlan_encapsulated_proto;
I am not sure you need this @proto ?
quoted
+ memmove(va + VLAN_HLEN, va, ETH_HLEN);
You could only memmove the mac addresses (2 * ETH_ALEN)
To not touch the proto (and avoid possible aliasing problems)
Indeed, your suggestion works and is simpler and less risky.
Thank you for your help.
I also think that I am making a mistake by only popping the tag when
GRO is enabled. My fear is that something will become confused when
skb->dev->features contains NETIF_F_HW_VLAN_RX, but the tag is not
decap'ed. So I will remove the check for NETIF_F_GRO when popping
the vlan tag.
Thanks,
Drew
From: Andrew Gallatin <hidden> Date: 2012-11-14 16:32:32
Unlike LRO, GRO requires that vlan tags be removed before
aggregation can occur. Since the myri10ge NIC does not support
hardware vlan tag offload, we must remove the tag in the driver
to achieve performance comparable to LRO for vlan tagged frames.
Updated with change suggested by Eric Duzamet to simplify the vlan
tag popping & a change by me to always pop tags when
NETIF_F_HW_VLAN_RX is set.
Signed-off-by: Andrew Gallatin <redacted>
---
drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 40
++++++++++++++++++++++
1 file changed, 40 insertions(+)
@@ -1264,6 +1264,41 @@ myri10ge_unmap_rx_page(struct pci_dev *pdev,}}+/*+*GROdoesnotsupportaccelerationoftaggedvlanframes,and+*thisNICdoesnotsupportvlantagoffload,sowemustpop+*thetagourselvestobeabletoachieveGROperformancethat+*iscomparabletoLRO.+*/++staticinlinevoid+myri10ge_vlan_rx(structnet_device*dev,void*addr,structsk_buff*skb)+{+u8*va;+structvlan_ethhdr*veh;+structskb_frag_struct*frag;++va=addr;+va+=MXGEFW_PAD;+veh=(structvlan_ethhdr*)va;+if((dev->features&(NETIF_F_HW_VLAN_RX))==NETIF_F_HW_VLAN_RX&&+(veh->h_vlan_proto==ntohs(ETH_P_8021Q))){+/* fixup csum if needed */+if(skb->ip_summed==CHECKSUM_COMPLETE)+skb->csum=csum_sub(skb->csum,+csum_partial(va+ETH_HLEN,+VLAN_HLEN,0));+/* pop tag */+__vlan_hwaccel_put_tag(skb,ntohs(veh->h_vlan_TCI));+memmove(va+VLAN_HLEN,va,2*ETH_ALEN);+skb->len-=VLAN_HLEN;+skb->data_len-=VLAN_HLEN;+frag=skb_shinfo(skb)->frags;+frag->page_offset+=VLAN_HLEN;+skb_frag_size_set(frag,skb_frag_size(frag)-VLAN_HLEN);+}+}+staticinlineintmyri10ge_rx_done(structmyri10ge_slice_state*ss,intlen,__wsumcsum){