be2net: Fix TX stats for TSO packets
authorSriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Sun, 9 Oct 2016 04:28:52 +0000 (09:58 +0530)
committerDavid S. Miller <davem@davemloft.net>
Sun, 9 Oct 2016 13:30:38 +0000 (09:30 -0400)
TX stats update does not take into account headers which get duplicated
when the TSO packet is split into segments by HW. Fix this for both
tunneled (vxlan) and non-tunneled TSO packets.

Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/emulex/benet/be_main.c

index dcb930a..cece8a0 100644 (file)
@@ -724,14 +724,24 @@ void be_link_status_update(struct be_adapter *adapter, u8 link_status)
        netdev_info(netdev, "Link is %s\n", link_status ? "Up" : "Down");
 }
 
+static int be_gso_hdr_len(struct sk_buff *skb)
+{
+       if (skb->encapsulation)
+               return skb_inner_transport_offset(skb) +
+                      inner_tcp_hdrlen(skb);
+       return skb_transport_offset(skb) + tcp_hdrlen(skb);
+}
+
 static void be_tx_stats_update(struct be_tx_obj *txo, struct sk_buff *skb)
 {
        struct be_tx_stats *stats = tx_stats(txo);
-       u64 tx_pkts = skb_shinfo(skb)->gso_segs ? : 1;
+       u32 tx_pkts = skb_shinfo(skb)->gso_segs ? : 1;
+       /* Account for headers which get duplicated in TSO pkt */
+       u32 dup_hdr_len = tx_pkts > 1 ? be_gso_hdr_len(skb) * (tx_pkts - 1) : 0;
 
        u64_stats_update_begin(&stats->sync);
        stats->tx_reqs++;
-       stats->tx_bytes += skb->len;
+       stats->tx_bytes += skb->len + dup_hdr_len;
        stats->tx_pkts += tx_pkts;
        if (skb->encapsulation && skb->ip_summed == CHECKSUM_PARTIAL)
                stats->tx_vxlan_offload_pkts += tx_pkts;