Patchwork [net-next-2.6] dummy: percpu stats and lockless xmit

login
register
mail settings
Submitter Eric Dumazet
Date Sept. 28, 2010, 6:50 a.m.
Message ID <1285656633.10438.35.camel@edumazet-laptop>
Download mbox | patch
Permalink /patch/65938/
State Accepted
Delegated to: David Miller
Headers show

Comments

Eric Dumazet - Sept. 28, 2010, 6:50 a.m.
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 <eric.dumazet@gmail.com>
---
 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
Stephen Hemminger - Sept. 28, 2010, 7:52 a.m.
> 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 <eric.dumazet@gmail.com>

IFB device could use many of these enhancements.
--
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
Eric Dumazet - Sept. 28, 2010, 8:02 a.m.
Le mardi 28 septembre 2010 à 00:52 -0700, Stephen Hemminger a écrit :
> > 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 <eric.dumazet@gmail.com>
> 
> IFB device could use many of these enhancements.

Yes, probably ;)

I was considering the NETIF_F_NETNS_LOCAL, should we set it for dummy
device ?



--
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
David Miller - Sept. 29, 2010, 8:26 p.m.
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Tue, 28 Sep 2010 08:50:33 +0200

> 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 <eric.dumazet@gmail.com>

Applied.
--
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

Patch

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 <linux/moduleparam.h>
 #include <linux/rtnetlink.h>
 #include <net/rtnetlink.h>
+#include <linux/u64_stats_sync.h>
 
 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;