From: Eric Dumazet <eric.dumazet(a)gmail.com>
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(a)gmail.com>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
[sven.eckelmann(a)gmx.de: Added compat.h defines for pre-2.6.36 kernels]
Signed-off-by: Sven Eckelmann <sven.eckelmann(a)gmx.de>
---
This patch entered net-next-2.6 today. It is also part of maint and must be
applied in trunk too.
The original commit can be found using its SHA1
28172739f0a276eb8d6ca917b3974c2edb036da3.
batman-adv/compat.h | 8 ++++++++
batman-adv/hard-interface.c | 3 ++-
2 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/batman-adv/compat.h b/batman-adv/compat.h
index 09016c8..103593d 100644
--- a/batman-adv/compat.h
+++ b/batman-adv/compat.h
@@ -249,4 +249,12 @@ static inline struct net_device_stats *dev_get_stats(struct net_device *dev)
#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_ */
diff --git a/batman-adv/hard-interface.c b/batman-adv/hard-interface.c
index 5ff9dcb..6a37c33 100644
--- a/batman-adv/hard-interface.c
+++ b/batman-adv/hard-interface.c
@@ -445,6 +445,7 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
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 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
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;
--
1.7.1