From 57dceba38bb9350162850ebbfad699b6cd0cadcc Mon Sep 17 00:00:00 2001 From: Sriharsha Basavapatna Date: Fri, 24 Feb 2017 21:27:53 -0500 Subject: [PATCH] be2net: Fix TX stats for TSO packets 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 Signed-off-by: David S. Miller (cherry picked from commit f3d6ad84807254954fc69bdebb6123e5a2883baf) Signed-off-by: Brian Maly Signed-off-by: Dhaval Giani --- drivers/net/ethernet/emulex/benet/be_main.c | 15 ++++++-- drivers/net/ethernet/emulex/benet/kcompat.h | 40 +++++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 drivers/net/ethernet/emulex/benet/kcompat.h diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index b1481a41976f..f5e9e22a2cf5 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -19,6 +19,7 @@ #include #include "be.h" #include "be_cmds.h" +#include "kcompat.h" #include #include #include @@ -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 index 000000000000..9a34b4d89edb --- /dev/null +++ b/drivers/net/ethernet/emulex/benet/kcompat.h @@ -0,0 +1,40 @@ + +#ifndef _KCOMPAT_H_ +#define _KCOMPAT_H_ + +#ifndef LINUX_VERSION_CODE +#include +#else +#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif + +static inline int skb_inner_transport_offset(const struct sk_buff *skb) +{ + return skb_inner_transport_header(skb) - skb->data; +} -- 2.50.1