From patchwork Tue Sep 28 06:50:33 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Dumazet X-Patchwork-Id: 65938 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 631B8B6F06 for ; Tue, 28 Sep 2010 16:50:44 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757137Ab0I1Guk (ORCPT ); Tue, 28 Sep 2010 02:50:40 -0400 Received: from mail-fx0-f46.google.com ([209.85.161.46]:57403 "EHLO mail-fx0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752869Ab0I1Guj (ORCPT ); Tue, 28 Sep 2010 02:50:39 -0400 Received: by fxm3 with SMTP id 3so2400513fxm.19 for ; Mon, 27 Sep 2010 23:50:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:subject:from:to:cc :content-type:date:message-id:mime-version:x-mailer :content-transfer-encoding; bh=QrgB5QDsh1VsMyKZXGuOkv2bzR4ArcNLXJIyHrY3xVw=; b=C4Rv3L63w/rdcSaSdVFIIMSTM9YYJQK3lZAuNo67o+Yrvtn4aITO5N6Bc07VcMbd6H QPRLSjU9ixpB6mWtKC0jVy9YSmkL2jWJICjjpAdiH1AR0k7+wvG3byXM0DqVYiZ00vUP GTZ9++NQeWvV7hfELGQYyb12ZNS9x7/qcNKXI= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=subject:from:to:cc:content-type:date:message-id:mime-version :x-mailer:content-transfer-encoding; b=pnxcxL60Djq+cyA8O/x4+xIstNpQkGlRqT50OIXP2V7VGsbcvyaaBRpSLxnI4eX4RC 3jaVsFVqOjSOntjIWdktU3mQ1pJ0FPsrqLCzFhRTroA+nz3C4AKGD4ry7MsTWqYrhIOP u8JK1207pmCzTaaCfrYllyJQEmxEZADf09sVg= Received: by 10.223.112.193 with SMTP id x1mr3405324fap.72.1285656638274; Mon, 27 Sep 2010 23:50:38 -0700 (PDT) Received: from [10.150.51.210] (gw0.net.jmsp.net [212.23.165.14]) by mx.google.com with ESMTPS id k25sm2903588fac.17.2010.09.27.23.50.36 (version=SSLv3 cipher=RC4-MD5); Mon, 27 Sep 2010 23:50:37 -0700 (PDT) Subject: [PATCH net-next-2.6] dummy: percpu stats and lockless xmit From: Eric Dumazet To: David Miller Cc: netdev Date: Tue, 28 Sep 2010 08:50:33 +0200 Message-ID: <1285656633.10438.35.camel@edumazet-laptop> Mime-Version: 1.0 X-Mailer: Evolution 2.30.3 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Converts dummy network device driver to : - percpu stats - 64bit stats - lockless xmit (NETIF_F_LLTX) - performance features added (NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO | NETIF_F_NO_CSUM | NETIF_F_HIGHDMA) Signed-off-by: Eric Dumazet --- drivers/net/dummy.c | 58 ++++++++++++++++++++++++++++++++++-- include/linux/netdevice.h | 1 2 files changed, 56 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/drivers/net/dummy.c b/drivers/net/dummy.c index 37dcfdc..ff2d29b 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -36,6 +36,7 @@ #include #include #include +#include static int numdummies = 1; @@ -55,21 +56,69 @@ static void set_multicast_list(struct net_device *dev) { } +struct pcpu_dstats { + u64 tx_packets; + u64 tx_bytes; + struct u64_stats_sync syncp; +}; + +static struct rtnl_link_stats64 *dummy_get_stats64(struct net_device *dev, + struct rtnl_link_stats64 *stats) +{ + int i; + + for_each_possible_cpu(i) { + const struct pcpu_dstats *dstats; + u64 tbytes, tpackets; + unsigned int start; + + dstats = per_cpu_ptr(dev->dstats, i); + do { + start = u64_stats_fetch_begin(&dstats->syncp); + tbytes = dstats->tx_bytes; + tpackets = dstats->tx_packets; + } while (u64_stats_fetch_retry(&dstats->syncp, start)); + stats->tx_bytes += tbytes; + stats->tx_packets += tpackets; + } + return stats; +} static netdev_tx_t dummy_xmit(struct sk_buff *skb, struct net_device *dev) { - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; + struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats); + + u64_stats_update_begin(&dstats->syncp); + dstats->tx_packets++; + dstats->tx_bytes += skb->len; + u64_stats_update_end(&dstats->syncp); dev_kfree_skb(skb); return NETDEV_TX_OK; } +static int dummy_dev_init(struct net_device *dev) +{ + dev->dstats = alloc_percpu(struct pcpu_dstats); + if (!dev->dstats) + return -ENOMEM; + + return 0; +} + +static void dummy_dev_free(struct net_device *dev) +{ + free_percpu(dev->dstats); + free_netdev(dev); +} + static const struct net_device_ops dummy_netdev_ops = { + .ndo_init = dummy_dev_init, .ndo_start_xmit = dummy_xmit, .ndo_validate_addr = eth_validate_addr, .ndo_set_multicast_list = set_multicast_list, .ndo_set_mac_address = dummy_set_address, + .ndo_get_stats64 = dummy_get_stats64, }; static void dummy_setup(struct net_device *dev) @@ -78,14 +127,17 @@ static void dummy_setup(struct net_device *dev) /* Initialize the device structure. */ dev->netdev_ops = &dummy_netdev_ops; - dev->destructor = free_netdev; + dev->destructor = dummy_dev_free; /* Fill in device structure with ethernet-generic values. */ dev->tx_queue_len = 0; dev->flags |= IFF_NOARP; dev->flags &= ~IFF_MULTICAST; + dev->features |= NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO; + dev->features |= NETIF_F_NO_CSUM | NETIF_F_HIGHDMA | NETIF_F_LLTX; random_ether_addr(dev->dev_addr); } + static int dummy_validate(struct nlattr *tb[], struct nlattr *data[]) { if (tb[IFLA_ADDRESS]) { diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 83de0eb..6cff445 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1054,6 +1054,7 @@ struct net_device { void *ml_priv; struct pcpu_lstats __percpu *lstats; /* loopback stats */ struct pcpu_tstats __percpu *tstats; /* tunnel stats */ + struct pcpu_dstats __percpu *dstats; /* dummy stats */ }; /* GARP */ struct garp_port *garp_port;