]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
be2net: Fix TX stats for TSO packets
authorSriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Sat, 25 Feb 2017 02:27:53 +0000 (21:27 -0500)
committerDhaval Giani <dhaval.giani@oracle.com>
Wed, 8 Mar 2017 01:05:38 +0000 (20:05 -0500)
Orabug: 25570957

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>
(cherry picked from commit f3d6ad84807254954fc69bdebb6123e5a2883baf)
Signed-off-by: Brian Maly <brian.maly@oracle.com>
Signed-off-by: Dhaval Giani <dhaval.giani@oracle.com>
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/emulex/benet/kcompat.h [new file with mode: 0644]

index b1481a41976f236bbbc82c9835367fb0992ddc30..f5e9e22a2cf5ffc5bd94919c04b8198dc17cb82f 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include "be.h"
 #include "be_cmds.h"
+#include "kcompat.h"
 #include <asm/div64.h>
 #include <linux/aer.h>
 #include <linux/if_bridge.h>
@@ -684,14 +685,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;
diff --git a/drivers/net/ethernet/emulex/benet/kcompat.h b/drivers/net/ethernet/emulex/benet/kcompat.h
new file mode 100644 (file)
index 0000000..9a34b4d
--- /dev/null
@@ -0,0 +1,40 @@
+
+#ifndef _KCOMPAT_H_
+#define _KCOMPAT_H_
+
+#ifndef LINUX_VERSION_CODE
+#include <linux/version.h>
+#else
+#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+#endif
+#include <linux/kernel.h>
+#include <linux/kmemcheck.h>
+#include <linux/compiler.h>
+#include <linux/time.h>
+#include <linux/bug.h>
+#include <linux/cache.h>
+#include <linux/rbtree.h>
+#include <linux/socket.h>
+
+#include <linux/atomic.h>
+#include <asm/types.h>
+#include <linux/spinlock.h>
+#include <linux/net.h>
+#include <linux/textsearch.h>
+#include <net/checksum.h>
+#include <linux/rcupdate.h>
+#include <linux/hrtimer.h>
+#include <linux/dma-mapping.h>
+#include <linux/netdev_features.h>
+#include <linux/sched.h>
+#include <linux/splice.h>
+#include <linux/in6.h>
+#include <linux/if_packet.h>
+#include <net/flow.h>
+
+#endif
+
+static inline int skb_inner_transport_offset(const struct sk_buff *skb)
+{
+       return skb_inner_transport_header(skb) - skb->data;
+}