aboutsummaryrefslogtreecommitdiffstats
path: root/net/8021q
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2010-07-07 17:58:56 -0400
committerDavid S. Miller <davem@davemloft.net>2010-07-07 17:58:56 -0400
commit28172739f0a276eb8d6ca917b3974c2edb036da3 (patch)
treeb1dc00cfa20c209992e247c6f73601f609f9ca3b /net/8021q
parent217d32dc5f299c483ca0d3c8cc6811c72c0339c4 (diff)
net: fix 64 bit counters on 32 bit arches
There is a small possibility that a reader gets incorrect values on 32 bit arches. SNMP applications could catch incorrect counters when a 32bit high part is changed by another stats consumer/provider. One way to solve this is to add a rtnl_link_stats64 param to all ndo_get_stats64() methods, and also add such a parameter to dev_get_stats(). Rule is that we are not allowed to use dev->stats64 as a temporary storage for 64bit stats, but a caller provided area (usually on stack) Old drivers (only providing get_stats() method) need no changes. Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/8021q')
-rw-r--r--net/8021q/vlan_dev.c6
-rw-r--r--net/8021q/vlanproc.c3
2 files changed, 4 insertions, 5 deletions
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index c6456cb842fa..7865a4ce5250 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -803,11 +803,9 @@ static u32 vlan_ethtool_get_flags(struct net_device *dev)
803 return dev_ethtool_get_flags(vlan->real_dev); 803 return dev_ethtool_get_flags(vlan->real_dev);
804} 804}
805 805
806static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev) 806static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
807{ 807{
808 struct rtnl_link_stats64 *stats = &dev->stats64; 808 dev_txq_stats_fold(dev, (struct net_device_stats *)stats);
809
810 dev_txq_stats_fold(dev, &dev->stats);
811 809
812 if (vlan_dev_info(dev)->vlan_rx_stats) { 810 if (vlan_dev_info(dev)->vlan_rx_stats) {
813 struct vlan_rx_stats *p, accum = {0}; 811 struct vlan_rx_stats *p, accum = {0};
diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c
index df56f5ce887c..80e280f56686 100644
--- a/net/8021q/vlanproc.c
+++ b/net/8021q/vlanproc.c
@@ -278,6 +278,7 @@ static int vlandev_seq_show(struct seq_file *seq, void *offset)
278{ 278{
279 struct net_device *vlandev = (struct net_device *) seq->private; 279 struct net_device *vlandev = (struct net_device *) seq->private;
280 const struct vlan_dev_info *dev_info = vlan_dev_info(vlandev); 280 const struct vlan_dev_info *dev_info = vlan_dev_info(vlandev);
281 struct rtnl_link_stats64 temp;
281 const struct rtnl_link_stats64 *stats; 282 const struct rtnl_link_stats64 *stats;
282 static const char fmt[] = "%30s %12lu\n"; 283 static const char fmt[] = "%30s %12lu\n";
283 static const char fmt64[] = "%30s %12llu\n"; 284 static const char fmt64[] = "%30s %12llu\n";
@@ -286,7 +287,7 @@ static int vlandev_seq_show(struct seq_file *seq, void *offset)
286 if (!is_vlan_dev(vlandev)) 287 if (!is_vlan_dev(vlandev))
287 return 0; 288 return 0;
288 289
289 stats = dev_get_stats(vlandev); 290 stats = dev_get_stats(vlandev, &temp);
290 seq_printf(seq, 291 seq_printf(seq,
291 "%s VID: %d REORDER_HDR: %i dev->priv_flags: %hx\n", 292 "%s VID: %d REORDER_HDR: %i dev->priv_flags: %hx\n",
292 vlandev->name, dev_info->vlan_id, 293 vlandev->name, dev_info->vlan_id,