All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] veth: Fix veth_get_stats()
@ 2009-11-18 17:09 Eric Dumazet
  2009-11-19 20:27 ` David Miller
  0 siblings, 1 reply; 2+ messages in thread
From: Eric Dumazet @ 2009-11-18 17:09 UTC (permalink / raw)
  To: David S. Miller; +Cc: Linux Netdev List

veth_get_stats() can be called in parallel on several cpus.

It's better to not reset dev->stats as it could give wrong result on
one cpu. Use temporary variables, then store the final results.

Also, we should loop on every possible cpus, not only online cpus,
or cpu hotplug can suddenly give wrong veth stats.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
 drivers/net/veth.c |   35 ++++++++++++++++-------------------
 1 files changed, 16 insertions(+), 19 deletions(-)

diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index ade5b34..52af501 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -210,32 +210,29 @@ rx_drop:
 static struct net_device_stats *veth_get_stats(struct net_device *dev)
 {
 	struct veth_priv *priv;
-	struct net_device_stats *dev_stats;
 	int cpu;
-	struct veth_net_stats *stats;
+	struct veth_net_stats *stats, total = {0};
 
 	priv = netdev_priv(dev);
-	dev_stats = &dev->stats;
-
-	dev_stats->rx_packets = 0;
-	dev_stats->tx_packets = 0;
-	dev_stats->rx_bytes = 0;
-	dev_stats->tx_bytes = 0;
-	dev_stats->tx_dropped = 0;
-	dev_stats->rx_dropped = 0;
 
-	for_each_online_cpu(cpu) {
+	for_each_possible_cpu(cpu) {
 		stats = per_cpu_ptr(priv->stats, cpu);
 
-		dev_stats->rx_packets += stats->rx_packets;
-		dev_stats->tx_packets += stats->tx_packets;
-		dev_stats->rx_bytes += stats->rx_bytes;
-		dev_stats->tx_bytes += stats->tx_bytes;
-		dev_stats->tx_dropped += stats->tx_dropped;
-		dev_stats->rx_dropped += stats->rx_dropped;
+		total.rx_packets += stats->rx_packets;
+		total.tx_packets += stats->tx_packets;
+		total.rx_bytes   += stats->rx_bytes;
+		total.tx_bytes   += stats->tx_bytes;
+		total.tx_dropped += stats->tx_dropped;
+		total.rx_dropped += stats->rx_dropped;
 	}
-
-	return dev_stats;
+	dev->stats.rx_packets = total.rx_packets;
+	dev->stats.tx_packets = total.tx_packets;
+	dev->stats.rx_bytes   = total.rx_bytes;
+	dev->stats.tx_bytes   = total.tx_bytes;
+	dev->stats.tx_dropped = total.tx_dropped;
+	dev->stats.rx_dropped = total.rx_dropped;
+
+	return &dev->stats;
 }
 
 static int veth_open(struct net_device *dev)

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] veth: Fix veth_get_stats()
  2009-11-18 17:09 [PATCH] veth: Fix veth_get_stats() Eric Dumazet
@ 2009-11-19 20:27 ` David Miller
  0 siblings, 0 replies; 2+ messages in thread
From: David Miller @ 2009-11-19 20:27 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 18 Nov 2009 18:09:39 +0100

> veth_get_stats() can be called in parallel on several cpus.
> 
> It's better to not reset dev->stats as it could give wrong result on
> one cpu. Use temporary variables, then store the final results.
> 
> Also, we should loop on every possible cpus, not only online cpus,
> or cpu hotplug can suddenly give wrong veth stats.
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

Applied.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2009-11-19 20:27 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-11-18 17:09 [PATCH] veth: Fix veth_get_stats() Eric Dumazet
2009-11-19 20:27 ` David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.