From patchwork Mon May 18 10:34:33 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Dumazet X-Patchwork-Id: 27353 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@bilbo.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from ozlabs.org (ozlabs.org [203.10.76.45]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "mx.ozlabs.org", Issuer "CA Cert Signing Authority" (verified OK)) by bilbo.ozlabs.org (Postfix) with ESMTPS id C9476B6F44 for ; Mon, 18 May 2009 20:35:06 +1000 (EST) Received: by ozlabs.org (Postfix) id BC456DE095; Mon, 18 May 2009 20:35:06 +1000 (EST) Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by ozlabs.org (Postfix) with ESMTP id 25132DE092 for ; Mon, 18 May 2009 20:35:06 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754858AbZERKef (ORCPT ); Mon, 18 May 2009 06:34:35 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753917AbZERKef (ORCPT ); Mon, 18 May 2009 06:34:35 -0400 Received: from gw1.cosmosbay.com ([212.99.114.194]:51286 "EHLO gw1.cosmosbay.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751930AbZERKee (ORCPT ); Mon, 18 May 2009 06:34:34 -0400 Received: from [127.0.0.1] (localhost [127.0.0.1]) by gw1.cosmosbay.com (8.13.7/8.13.7) with ESMTP id n4IAYXgB008487; Mon, 18 May 2009 12:34:33 +0200 Message-ID: <4A1139B9.6040505@cosmosbay.com> Date: Mon, 18 May 2009 12:34:33 +0200 From: Eric Dumazet User-Agent: Thunderbird 2.0.0.21 (Windows/20090302) MIME-Version: 1.0 To: "David S. Miller" CC: Linux Netdev List Subject: [PATCH 1/2] net: add tx_packets/tx_bytes/tx_dropped counters in struct netdev_queue X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-1.6 (gw1.cosmosbay.com [0.0.0.0]); Mon, 18 May 2009 12:34:33 +0200 (CEST) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org offsetof(struct net_device, features)=0x44 offsetof(struct net_device, stats.tx_packets)=0x54 offsetof(struct net_device, stats.tx_bytes)=0x5c offsetof(struct net_device, stats.tx_dropped)=0x6c Network drivers that touch dev->stats.tx_packets/stats.tx_bytes in their tx path can slow down SMP operations, since they dirty a cache line that should stay shared (dev->features is needed in rx and tx paths) We could move away stats field in net_device but it wont help that much. (Two cache lines dirtied in tx path, we can do one only) Better solution is to add tx_packets/tx_bytes/tx_dropped in struct netdev_queue because this structure is already touched in tx path and counters updates will then be free (no increase in size) Signed-off-by: Eric Dumazet --- include/linux/netdevice.h | 3 +++ net/core/dev.c | 23 ++++++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index cd547d0..4623e9f 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -474,6 +474,9 @@ struct netdev_queue { * please use this field instead of dev->trans_start */ unsigned long trans_start; + unsigned long tx_bytes; + unsigned long tx_packets; + unsigned long tx_dropped; } ____cacheline_aligned_in_smp; diff --git a/net/core/dev.c b/net/core/dev.c index 14dd725..a43b510 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -4943,13 +4943,30 @@ void netdev_run_todo(void) * the internal statistics structure is used. */ const struct net_device_stats *dev_get_stats(struct net_device *dev) - { +{ const struct net_device_ops *ops = dev->netdev_ops; if (ops->ndo_get_stats) return ops->ndo_get_stats(dev); - else - return &dev->stats; + else { + unsigned long tx_bytes = 0, tx_packets = 0, tx_dropped = 0; + struct net_device_stats *stats = &dev->stats; + unsigned int i; + struct netdev_queue *txq; + + for (i = 0; i < dev->num_tx_queues; i++) { + txq = netdev_get_tx_queue(dev, i); + tx_bytes += txq->tx_bytes; + tx_packets += txq->tx_packets; + tx_dropped += txq->tx_dropped; + } + if (tx_bytes || tx_packets || tx_dropped) { + stats->tx_bytes = tx_bytes; + stats->tx_packets = tx_packets; + stats->tx_dropped = tx_dropped; + } + return stats; + } } EXPORT_SYMBOL(dev_get_stats);