From b4d76c80a078dcf641f36aa3b3b50a5667a27e16 Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Wed, 19 May 2010 15:22:28 -0700 Subject: [PATCH] vport-netdev: 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 | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/datapath/vport-netdev.c b/datapath/vport-netdev.c index 8e7847ef..72d2928d 100644 --- a/datapath/vport-netdev.c +++ b/datapath/vport-netdev.c @@ -22,6 +22,9 @@ #include "compat.h" +/* If the native device stats aren't 64 bit use the vport stats tracking instead. */ +#define USE_VPORT_STATS (sizeof(((struct net_device_stats *)0)->rx_bytes) < sizeof(u64)) + static void netdev_port_receive(struct net_bridge_port *, struct sk_buff *); /* @@ -97,6 +100,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_VPORT_STATS) { + struct odp_vport_stats stats; + + err = netdev_get_stats(vport, &stats); + if (!err) + vport_set_stats(vport, &stats); + } + return vport; error_put: @@ -291,7 +304,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_VPORT_STATS ? VPORT_F_GEN_STATS : 0)), .init = netdev_init, .exit = netdev_exit, .create = netdev_create, -- 2.30.2