Author: marek Date: 2010-07-11 16:34:09 +0200 (Sun, 11 Jul 2010) New Revision: 1735
Modified: trunk/batman-adv/compat.h trunk/batman-adv/hard-interface.c Log: batman-adv: 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 [sven.eckelmann@gmx.de: Added compat.h defines for pre-2.6.36 kernels] Signed-off-by: Sven Eckelmann sven.eckelmann@gmx.de
Modified: trunk/batman-adv/compat.h =================================================================== --- trunk/batman-adv/compat.h 2010-07-06 23:07:47 UTC (rev 1734) +++ trunk/batman-adv/compat.h 2010-07-11 14:34:09 UTC (rev 1735) @@ -249,4 +249,12 @@
#endif /* < KERNEL_VERSION(2, 6, 29) */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) + +#define dev_get_stats(x, y) dev_get_stats(x) + +#define rtnl_link_stats64 rtnl_link_stats __attribute__((unused)) + +#endif /* < KERNEL_VERSION(2, 6, 36) */ + #endif /* _NET_BATMAN_ADV_COMPAT_H_ */
Modified: trunk/batman-adv/hard-interface.c =================================================================== --- trunk/batman-adv/hard-interface.c 2010-07-06 23:07:47 UTC (rev 1734) +++ trunk/batman-adv/hard-interface.c 2010-07-11 14:34:09 UTC (rev 1735) @@ -445,6 +445,7 @@ struct batman_packet *batman_packet; struct batman_if *batman_if; struct net_device_stats *stats; + struct rtnl_link_stats64 temp; int ret;
skb = skb_share_check(skb, GFP_ATOMIC); @@ -480,7 +481,7 @@ if (batman_if->if_status != IF_ACTIVE) goto err_free;
- stats = (struct net_device_stats *)dev_get_stats(skb->dev); + stats = (struct net_device_stats *)dev_get_stats(skb->dev, &temp); if (stats) { stats->rx_packets++; stats->rx_bytes += skb->len;