aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/netdevice.h
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2010-07-09 05:11:52 -0400
committerDavid S. Miller <davem@davemloft.net>2010-07-09 20:41:56 -0400
commit3cfde79c6c7c8002375c4a8e5be7f602fbb9675d (patch)
tree53fe969e9f8bb45531c1e84c82e822ff47ea015c /include/linux/netdevice.h
parentcc7b86c1a8f207c8aa77aad6941475d8294a83c4 (diff)
net: Get rid of rtnl_link_stats64 / net_device_stats union
In commit be1f3c2c027cc5ad735df6a45a542ed1db7ec48b "net: Enable 64-bit net device statistics on 32-bit architectures" I redefined struct net_device_stats so that it could be used in a union with struct rtnl_link_stats64, avoiding the need for explicit copying or conversion between the two. However, this is unsafe because there is no locking required and no lock consistently held around calls to dev_get_stats() and use of the statistics structure it returns. In commit 28172739f0a276eb8d6ca917b3974c2edb036da3 "net: fix 64 bit counters on 32 bit arches" Eric Dumazet dealt with that problem by requiring callers of dev_get_stats() to provide storage for the result. This means that the net_device::stats64 field and the padding in struct net_device_stats are now redundant, so remove them. Update the comment on net_device_ops::ndo_get_stats64 to reflect its new usage. Change dev_txq_stats_fold() to use struct rtnl_link_stats64, since that is what all its callers are really using and it is no longer going to be compatible with struct net_device_stats. Eric Dumazet suggested the separate function for the structure conversion. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Acked-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/netdevice.h')
-rw-r--r--include/linux/netdevice.h70
1 files changed, 28 insertions, 42 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 8018f6bf3051..17e95e37aed9 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -162,42 +162,32 @@ static inline bool dev_xmit_complete(int rc)
162/* 162/*
163 * Old network device statistics. Fields are native words 163 * Old network device statistics. Fields are native words
164 * (unsigned long) so they can be read and written atomically. 164 * (unsigned long) so they can be read and written atomically.
165 * Each field is padded to 64 bits for compatibility with
166 * rtnl_link_stats64.
167 */ 165 */
168 166
169#if BITS_PER_LONG == 64
170#define NET_DEVICE_STATS_DEFINE(name) unsigned long name
171#elif defined(__LITTLE_ENDIAN)
172#define NET_DEVICE_STATS_DEFINE(name) unsigned long name, pad_ ## name
173#else
174#define NET_DEVICE_STATS_DEFINE(name) unsigned long pad_ ## name, name
175#endif
176
177struct net_device_stats { 167struct net_device_stats {
178 NET_DEVICE_STATS_DEFINE(rx_packets); 168 unsigned long rx_packets;
179 NET_DEVICE_STATS_DEFINE(tx_packets); 169 unsigned long tx_packets;
180 NET_DEVICE_STATS_DEFINE(rx_bytes); 170 unsigned long rx_bytes;
181 NET_DEVICE_STATS_DEFINE(tx_bytes); 171 unsigned long tx_bytes;
182 NET_DEVICE_STATS_DEFINE(rx_errors); 172 unsigned long rx_errors;
183 NET_DEVICE_STATS_DEFINE(tx_errors); 173 unsigned long tx_errors;
184 NET_DEVICE_STATS_DEFINE(rx_dropped); 174 unsigned long rx_dropped;
185 NET_DEVICE_STATS_DEFINE(tx_dropped); 175 unsigned long tx_dropped;
186 NET_DEVICE_STATS_DEFINE(multicast); 176 unsigned long multicast;
187 NET_DEVICE_STATS_DEFINE(collisions); 177 unsigned long collisions;
188 NET_DEVICE_STATS_DEFINE(rx_length_errors); 178 unsigned long rx_length_errors;
189 NET_DEVICE_STATS_DEFINE(rx_over_errors); 179 unsigned long rx_over_errors;
190 NET_DEVICE_STATS_DEFINE(rx_crc_errors); 180 unsigned long rx_crc_errors;
191 NET_DEVICE_STATS_DEFINE(rx_frame_errors); 181 unsigned long rx_frame_errors;
192 NET_DEVICE_STATS_DEFINE(rx_fifo_errors); 182 unsigned long rx_fifo_errors;
193 NET_DEVICE_STATS_DEFINE(rx_missed_errors); 183 unsigned long rx_missed_errors;
194 NET_DEVICE_STATS_DEFINE(tx_aborted_errors); 184 unsigned long tx_aborted_errors;
195 NET_DEVICE_STATS_DEFINE(tx_carrier_errors); 185 unsigned long tx_carrier_errors;
196 NET_DEVICE_STATS_DEFINE(tx_fifo_errors); 186 unsigned long tx_fifo_errors;
197 NET_DEVICE_STATS_DEFINE(tx_heartbeat_errors); 187 unsigned long tx_heartbeat_errors;
198 NET_DEVICE_STATS_DEFINE(tx_window_errors); 188 unsigned long tx_window_errors;
199 NET_DEVICE_STATS_DEFINE(rx_compressed); 189 unsigned long rx_compressed;
200 NET_DEVICE_STATS_DEFINE(tx_compressed); 190 unsigned long tx_compressed;
201}; 191};
202 192
203#endif /* __KERNEL__ */ 193#endif /* __KERNEL__ */
@@ -666,14 +656,13 @@ struct netdev_rx_queue {
666 * Callback uses when the transmitter has not made any progress 656 * Callback uses when the transmitter has not made any progress
667 * for dev->watchdog ticks. 657 * for dev->watchdog ticks.
668 * 658 *
669 * struct rtnl_link_stats64* (*ndo_get_stats64)(struct net_device *dev 659 * struct rtnl_link_stats64* (*ndo_get_stats64)(struct net_device *dev,
670 * struct rtnl_link_stats64 *storage); 660 * struct rtnl_link_stats64 *storage);
671 * struct net_device_stats* (*ndo_get_stats)(struct net_device *dev); 661 * struct net_device_stats* (*ndo_get_stats)(struct net_device *dev);
672 * Called when a user wants to get the network device usage 662 * Called when a user wants to get the network device usage
673 * statistics. Drivers must do one of the following: 663 * statistics. Drivers must do one of the following:
674 * 1. Define @ndo_get_stats64 to update a rtnl_link_stats64 structure 664 * 1. Define @ndo_get_stats64 to fill in a zero-initialised
675 * (which should normally be dev->stats64) and return a ponter to 665 * rtnl_link_stats64 structure passed by the caller.
676 * it. The structure must not be changed asynchronously.
677 * 2. Define @ndo_get_stats to update a net_device_stats structure 666 * 2. Define @ndo_get_stats to update a net_device_stats structure
678 * (which should normally be dev->stats) and return a pointer to 667 * (which should normally be dev->stats) and return a pointer to
679 * it. The structure may be changed asynchronously only if each 668 * it. The structure may be changed asynchronously only if each
@@ -888,10 +877,7 @@ struct net_device {
888 int ifindex; 877 int ifindex;
889 int iflink; 878 int iflink;
890 879
891 union { 880 struct net_device_stats stats;
892 struct rtnl_link_stats64 stats64;
893 struct net_device_stats stats;
894 };
895 881
896#ifdef CONFIG_WIRELESS_EXT 882#ifdef CONFIG_WIRELESS_EXT
897 /* List of functions to handle Wireless Extensions (instead of ioctl). 883 /* List of functions to handle Wireless Extensions (instead of ioctl).
@@ -2147,7 +2133,7 @@ extern void dev_mcast_init(void);
2147extern const struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev, 2133extern const struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,
2148 struct rtnl_link_stats64 *storage); 2134 struct rtnl_link_stats64 *storage);
2149extern void dev_txq_stats_fold(const struct net_device *dev, 2135extern void dev_txq_stats_fold(const struct net_device *dev,
2150 struct net_device_stats *stats); 2136 struct rtnl_link_stats64 *stats);
2151 2137
2152extern int netdev_max_backlog; 2138extern int netdev_max_backlog;
2153extern int netdev_tstamp_prequeue; 2139extern int netdev_tstamp_prequeue;