[ovs-dev] [PATCH 3/6] netdev-vport: Use vport stats layer on 32-bit machines.

Ben Pfaff blp at nicira.com
Thu Jun 10 20:24:07 UTC 2010


On Thu, Jun 10, 2010 at 01:14:59PM -0700, Jesse Gross wrote:
> Are you saying to make that definition and then do #if USE_GEN_STATS?  In
> that case the preprocessor will barf on the sizeof operator.  If you really
> want it done statically, it is possible to use a generic test for a 64-bit
> machine but that doesn't really seem all that robust.
> 
> Or just define it and use a normal if statement?  It will still be done at
> runtime but any decent optimizing compiler will recognize that the condition
> is always true or always false.

The latter.  Here's what I had in mind.  I wrote the #define as an enum
to emphasize that it can't be used in #if, but I'll understand if you
think it's weird that way.

--8<--------------------------cut here-------------------------->8--

>From d1050c6dfc68a936d97b6a1dd771d62c68ec113b Mon Sep 17 00:00:00 2001
From: Ben Pfaff <blp at nicira.com>
Date: Thu, 10 Jun 2010 13:20:36 -0700
Subject: [PATCH] netdev-vport: Use vport stats layer on 32-bit machines.

Linux devices store stats in counters the size of a machine word,
which are rapidly overflowed on a 32-bit machine.  In this
situation we now use the vport stats layer, which always uses 64-
bit stats.  On 64-bit machines we continue to use the normal
Linux stats to avoid the extra overhead of counting twice.
---
 datapath/vport-netdev.c |   17 ++++++++++++++++-
 1 files changed, 16 insertions(+), 1 deletions(-)

diff --git a/datapath/vport-netdev.c b/datapath/vport-netdev.c
index 50c51ac..4603a14 100644
--- a/datapath/vport-netdev.c
+++ b/datapath/vport-netdev.c
@@ -22,6 +22,10 @@
 
 #include "compat.h"
 
+/* If the native device stats aren't 64-bit, then we use the vport generic
+ * stats tracking, which are always 64-bit. */
+enum { USE_GEN_STATS = sizeof(((struct net_device_stats *)0)->rx_bytes) < 8 };
+
 struct vport_ops netdev_vport_ops;
 
 static void netdev_port_receive(struct net_bridge_port *, struct sk_buff *);
@@ -99,6 +103,16 @@ netdev_create(const char *name, const void __user *config)
 		goto error_put;
 	}
 
+	/* If we are using the vport stats layer initialize it to the current
+	 * values so we are roughly consistent with the device stats. */
+	if (USE_GEN_STATS) {
+		struct odp_vport_stats stats;
+
+		err = netdev_get_stats(vport, &stats);
+		if (!err)
+			vport_set_stats(vport, &stats);
+	}
+
 	return vport;
 
 error_put:
@@ -293,7 +307,8 @@ netdev_get_vport(struct net_device *dev)
 
 struct vport_ops netdev_vport_ops = {
 	.type		= "netdev",
-	.flags		= VPORT_F_REQUIRED,
+	.flags		= (VPORT_F_REQUIRED |
+			   (USE_GEN_STATS ? VPORT_F_GEN_STATS : 0)),
 	.init		= netdev_init,
 	.exit		= netdev_exit,
 	.create		= netdev_create,
-- 
1.7.1






More information about the dev mailing list