From patchwork Fri Aug 30 12:01:15 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Claudiu Manoil X-Patchwork-Id: 271242 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 0057B2C00D0 for ; Fri, 30 Aug 2013 22:03:31 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755633Ab3H3MD2 (ORCPT ); Fri, 30 Aug 2013 08:03:28 -0400 Received: from co1ehsobe005.messaging.microsoft.com ([216.32.180.188]:30655 "EHLO co1outboundpool.messaging.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755569Ab3H3MD1 (ORCPT ); Fri, 30 Aug 2013 08:03:27 -0400 Received: from mail26-co1-R.bigfish.com (10.243.78.230) by CO1EHSOBE041.bigfish.com (10.243.66.106) with Microsoft SMTP Server id 14.1.225.22; Fri, 30 Aug 2013 12:03:26 +0000 Received: from mail26-co1 (localhost [127.0.0.1]) by mail26-co1-R.bigfish.com (Postfix) with ESMTP id 7C56FC80122; Fri, 30 Aug 2013 12:03:26 +0000 (UTC) X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPV:NLI; H:mail.freescale.net; RD:none; EFVD:NLI X-SpamScore: 0 X-BigFish: VS0(zzzz1f42h208ch1ee6h1de0h1fdah2073h1202h1e76h1d1ah1d2ah1fc6hzz1de098h8275bh1de097hz2dh2a8h839hd24he5bhf0ah107ah1288h12a5h12a9h12bdh12e5h137ah139eh13b6h1441h1504h1537h162dh1631h1758h1898h18e1h1946h19b5h1ad9h1b0ah1b2fh1fb3h1d0ch1d2eh1d3fh1dfeh1dffh1e1dh1e23h1fe8h1ff5h1155h) Received: from mail26-co1 (localhost.localdomain [127.0.0.1]) by mail26-co1 (MessageSwitch) id 1377864204488856_32659; Fri, 30 Aug 2013 12:03:24 +0000 (UTC) Received: from CO1EHSMHS021.bigfish.com (unknown [10.243.78.233]) by mail26-co1.bigfish.com (Postfix) with ESMTP id 73B10AC004A; Fri, 30 Aug 2013 12:03:24 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by CO1EHSMHS021.bigfish.com (10.243.66.31) with Microsoft SMTP Server (TLS) id 14.16.227.3; Fri, 30 Aug 2013 12:03:23 +0000 Received: from tx30smr01.am.freescale.net (10.81.153.31) by 039-SN1MMR1-003.039d.mgd.msft.net (10.84.1.16) with Microsoft SMTP Server (TLS) id 14.3.146.2; Fri, 30 Aug 2013 12:03:21 +0000 Received: from fsr-fed1764-016.ea.freescale.net (fsr-fed1764-016.ea.freescale.net [10.171.81.161]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id r7UC3Jia030661; Fri, 30 Aug 2013 05:03:19 -0700 Received: (from b08782@localhost) by fsr-fed1764-016.ea.freescale.net (8.14.5/8.14.5/Submit) id r7UC1GAf019542; Fri, 30 Aug 2013 15:01:16 +0300 From: Claudiu Manoil To: CC: "David S. Miller" , Eric Dumazet Subject: [PATCH][net-next] gianfar: Fix reported number of sent bytes to BQL Date: Fri, 30 Aug 2013 15:01:15 +0300 Message-ID: <1377864075-19491-1-git-send-email-claudiu.manoil@freescale.com> X-Mailer: git-send-email 1.7.11.7 In-Reply-To: <1367251193.8964.326.camel@edumazet-glaptop> References: <1367251193.8964.326.camel@edumazet-glaptop> MIME-Version: 1.0 X-OriginatorOrg: freescale.net X-FOPE-CONNECTOR: Id%0$Dn%*$RO%0$TLS%0$FQDN%$TlsDn% Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Fix the amount of sent bytes reported to BQL by reporting the number of bytes on wire in the xmit routine, and recording that value for each skb in order to be correctly confirmed on Tx confirmation cleanup. Reporting skb->len to BQL just before exiting xmit is not correct due to possible insertions of TOE block and alignment bytes in the skb->data, which are being stripped off by the controller before transmission on wire. This led to mismatch of (incorrectly) reported bytes to BQL b/w xmit and Tx confirmation, resulting in Tx timeout firing, for the h/w tx timestamping acceleration case. There's no easy way to obtain the number of bytes on wire in the Tx confirmation routine, so skb->cb is used to convey that information from xmit to Tx confirmation, for now (as proposed by Eric). Revived the currently unused GFAR_CB() construct for that purpose. Signed-off-by: Claudiu Manoil Cc: Eric Dumazet --- drivers/net/ethernet/freescale/gianfar.c | 18 +++++++++++------- drivers/net/ethernet/freescale/gianfar.h | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index b2c91dc..c4eaade 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -2092,7 +2092,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) int do_tstamp, do_csum, do_vlan; u32 bufaddr; unsigned long flags; - unsigned int nr_frags, nr_txbds, length, fcb_len = 0; + unsigned int nr_frags, nr_txbds, bytes_sent, fcb_len = 0; rq = skb->queue_mapping; tx_queue = priv->tx_queue[rq]; @@ -2147,7 +2147,10 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) } /* Update transmit stats */ - tx_queue->stats.tx_bytes += skb->len; + bytes_sent = skb->len; + tx_queue->stats.tx_bytes += bytes_sent; + /* keep Tx bytes on wire for BQL accounting */ + GFAR_CB(skb)->bytes_sent = bytes_sent; tx_queue->stats.tx_packets++; txbdp = txbdp_start = tx_queue->cur_tx; @@ -2167,12 +2170,13 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) } else { /* Place the fragment addresses and lengths into the TxBDs */ for (i = 0; i < nr_frags; i++) { + unsigned int frag_len; /* Point at the next BD, wrapping as needed */ txbdp = next_txbd(txbdp, base, tx_queue->tx_ring_size); - length = skb_shinfo(skb)->frags[i].size; + frag_len = skb_shinfo(skb)->frags[i].size; - lstatus = txbdp->lstatus | length | + lstatus = txbdp->lstatus | frag_len | BD_LFLAG(TXBD_READY); /* Handle the last BD specially */ @@ -2182,7 +2186,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) bufaddr = skb_frag_dma_map(priv->dev, &skb_shinfo(skb)->frags[i], 0, - length, + frag_len, DMA_TO_DEVICE); /* set the TxBD length and buffer pointer */ @@ -2250,7 +2254,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb); } - netdev_tx_sent_queue(txq, skb->len); + netdev_tx_sent_queue(txq, bytes_sent); /* We can work in parallel with gfar_clean_tx_ring(), except * when modifying num_txbdfree. Note that we didn't grab the lock @@ -2570,7 +2574,7 @@ static void gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) bdp = next_txbd(bdp, base, tx_ring_size); } - bytes_sent += skb->len; + bytes_sent += GFAR_CB(skb)->bytes_sent; dev_kfree_skb_any(skb); diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h index 46f56f3..04112b9 100644 --- a/drivers/net/ethernet/freescale/gianfar.h +++ b/drivers/net/ethernet/freescale/gianfar.h @@ -575,7 +575,7 @@ struct rxfcb { }; struct gianfar_skb_cb { - int alignamount; + unsigned int bytes_sent; /* bytes-on-wire (i.e. no FCB) */ }; #define GFAR_CB(skb) ((struct gianfar_skb_cb *)((skb)->cb))