From patchwork Wed Nov 16 22:15:07 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: david decotigny X-Patchwork-Id: 126054 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 6A3ADB71C6 for ; Thu, 17 Nov 2011 09:18:23 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754564Ab1KPWSD (ORCPT ); Wed, 16 Nov 2011 17:18:03 -0500 Received: from mail-ey0-f202.google.com ([209.85.215.202]:48441 "EHLO mail-ey0-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753969Ab1KPWPg (ORCPT ); Wed, 16 Nov 2011 17:15:36 -0500 Received: by eyg5 with SMTP id 5so23822eyg.1 for ; Wed, 16 Nov 2011 14:15:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=beta; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :in-reply-to:references:organization:x-system-of-record; bh=eUCKSs0Q+YvWKuLIBC2bXVqfucRlAR9FhLNVyBHKZvs=; b=VQHKMfI9Wtitcu9u4/0xSHPtqVOcP5Fu8bfZhDEQ85L0JMdiPTN3EbCPrnuhNI1dqm QIb69kxFRZ+CYWDQ1d1g== Received: by 10.14.9.12 with SMTP id 12mr1259173ees.0.1321481734544; Wed, 16 Nov 2011 14:15:34 -0800 (PST) Received: by 10.14.9.12 with SMTP id 12mr1259139ees.0.1321481734295; Wed, 16 Nov 2011 14:15:34 -0800 (PST) Received: from hpza9.eem.corp.google.com ([74.125.121.33]) by gmr-mx.google.com with ESMTPS id i11si18263794eea.0.2011.11.16.14.15.34 (version=TLSv1/SSLv3 cipher=AES128-SHA); Wed, 16 Nov 2011 14:15:34 -0800 (PST) Received: from wpaz1.hot.corp.google.com (wpaz1.hot.corp.google.com [172.24.198.65]) by hpza9.eem.corp.google.com (Postfix) with ESMTPS id 009FC5C0050; Wed, 16 Nov 2011 14:15:33 -0800 (PST) Received: from decotigny.mtv.corp.google.com (decotigny.mtv.corp.google.com [172.18.64.159]) by wpaz1.hot.corp.google.com with ESMTP id pAGMFU3H009637; Wed, 16 Nov 2011 14:15:30 -0800 Received: by decotigny.mtv.corp.google.com (Postfix, from userid 128857) id 6929B26B30; Wed, 16 Nov 2011 14:15:30 -0800 (PST) From: David Decotigny To: netdev@vger.kernel.org, linux-kernel@vger.kernel.org Cc: "David S. Miller" , Ian Campbell , Eric Dumazet , Jeff Kirsher , Ben Hutchings , Jiri Pirko , Joe Perches , Szymon Janc , Richard Jones , Ayaz Abdulla , david decotigny Subject: [PATCH net-next v6 1/9] forcedeth: fix stats on hardware without extended stats support Date: Wed, 16 Nov 2011 14:15:07 -0800 Message-Id: <8c7efb0e70de49267b0f740ed183e17747861f1d.1321481064.git.david.decotigny@google.com> X-Mailer: git-send-email 1.7.3.1 In-Reply-To: References: In-Reply-To: References: Organization: Google, Inc. X-System-Of-Record: true Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: david decotigny This change makes sure that tx_packets/rx_bytes ifconfig counters are updated even on NICs that don't provide hardware support for these stats: they are now updated in software. For the sake of consistency, we also now have tx_bytes updated in software (hardware counters include ethernet CRC, and software doesn't account for it). This reverts parts of: - "forcedeth: statistics optimization" (21828163b2) - "forcedeth: Improve stats counters" (0bdfea8ba8) - "forcedeth: remove unneeded stats updates" (4687f3f364) Tested: pktgen + loopback (http://patchwork.ozlabs.org/patch/124698/) reports identical tx_packets/rx_packets and tx_bytes/rx_bytes. Signed-off-by: David Decotigny Signed-off-by: David S. Miller (cherry picked from commit 898bdf2cb43eb0a962c397eb4dd1aec2c7211be2) --- drivers/net/ethernet/nvidia/forcedeth.c | 36 +++++++++++++++++++++++------- 1 files changed, 27 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c index e8a5ae3..374625b 100644 --- a/drivers/net/ethernet/nvidia/forcedeth.c +++ b/drivers/net/ethernet/nvidia/forcedeth.c @@ -609,7 +609,7 @@ struct nv_ethtool_str { }; static const struct nv_ethtool_str nv_estats_str[] = { - { "tx_bytes" }, + { "tx_bytes" }, /* includes Ethernet FCS CRC */ { "tx_zero_rexmt" }, { "tx_one_rexmt" }, { "tx_many_rexmt" }, @@ -637,7 +637,7 @@ static const struct nv_ethtool_str nv_estats_str[] = { /* version 2 stats */ { "tx_deferral" }, { "tx_packets" }, - { "rx_bytes" }, + { "rx_bytes" }, /* includes Ethernet FCS CRC */ { "tx_pause" }, { "rx_pause" }, { "rx_drop_frame" }, @@ -649,7 +649,7 @@ static const struct nv_ethtool_str nv_estats_str[] = { }; struct nv_ethtool_stats { - u64 tx_bytes; + u64 tx_bytes; /* should be ifconfig->tx_bytes + 4*tx_packets */ u64 tx_zero_rexmt; u64 tx_one_rexmt; u64 tx_many_rexmt; @@ -670,14 +670,14 @@ struct nv_ethtool_stats { u64 rx_unicast; u64 rx_multicast; u64 rx_broadcast; - u64 rx_packets; + u64 rx_packets; /* should be ifconfig->rx_packets */ u64 rx_errors_total; u64 tx_errors_total; /* version 2 stats */ u64 tx_deferral; - u64 tx_packets; - u64 rx_bytes; + u64 tx_packets; /* should be ifconfig->tx_packets */ + u64 rx_bytes; /* should be ifconfig->rx_bytes + 4*rx_packets */ u64 tx_pause; u64 rx_pause; u64 rx_drop_frame; @@ -1706,10 +1706,17 @@ static struct net_device_stats *nv_get_stats(struct net_device *dev) if (np->driver_data & (DEV_HAS_STATISTICS_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_STATISTICS_V3)) { nv_get_hw_stats(dev); + /* + * Note: because HW stats are not always available and + * for consistency reasons, the following ifconfig + * stats are managed by software: rx_bytes, tx_bytes, + * rx_packets and tx_packets. The related hardware + * stats reported by ethtool should be equivalent to + * these ifconfig stats, with 4 additional bytes per + * packet (Ethernet FCS CRC). + */ + /* copy to net_device stats */ - dev->stats.tx_packets = np->estats.tx_packets; - dev->stats.rx_bytes = np->estats.rx_bytes; - dev->stats.tx_bytes = np->estats.tx_bytes; dev->stats.tx_fifo_errors = np->estats.tx_fifo_errors; dev->stats.tx_carrier_errors = np->estats.tx_carrier_errors; dev->stats.rx_crc_errors = np->estats.rx_crc_errors; @@ -2380,6 +2387,9 @@ static int nv_tx_done(struct net_device *dev, int limit) if (flags & NV_TX_ERROR) { if ((flags & NV_TX_RETRYERROR) && !(flags & NV_TX_RETRYCOUNT_MASK)) nv_legacybackoff_reseed(dev); + } else { + dev->stats.tx_packets++; + dev->stats.tx_bytes += np->get_tx_ctx->skb->len; } dev_kfree_skb_any(np->get_tx_ctx->skb); np->get_tx_ctx->skb = NULL; @@ -2390,6 +2400,9 @@ static int nv_tx_done(struct net_device *dev, int limit) if (flags & NV_TX2_ERROR) { if ((flags & NV_TX2_RETRYERROR) && !(flags & NV_TX2_RETRYCOUNT_MASK)) nv_legacybackoff_reseed(dev); + } else { + dev->stats.tx_packets++; + dev->stats.tx_bytes += np->get_tx_ctx->skb->len; } dev_kfree_skb_any(np->get_tx_ctx->skb); np->get_tx_ctx->skb = NULL; @@ -2429,6 +2442,9 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit) else nv_legacybackoff_reseed(dev); } + } else { + dev->stats.tx_packets++; + dev->stats.tx_bytes += np->get_tx_ctx->skb->len; } dev_kfree_skb_any(np->get_tx_ctx->skb); @@ -2678,6 +2694,7 @@ static int nv_rx_process(struct net_device *dev, int limit) skb->protocol = eth_type_trans(skb, dev); napi_gro_receive(&np->napi, skb); dev->stats.rx_packets++; + dev->stats.rx_bytes += len; next_pkt: if (unlikely(np->get_rx.orig++ == np->last_rx.orig)) np->get_rx.orig = np->first_rx.orig; @@ -2761,6 +2778,7 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit) } napi_gro_receive(&np->napi, skb); dev->stats.rx_packets++; + dev->stats.rx_bytes += len; } else { dev_kfree_skb(skb); }