diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2010-07-09 05:11:52 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-07-09 20:41:56 -0400 |
commit | 3cfde79c6c7c8002375c4a8e5be7f602fbb9675d (patch) | |
tree | 53fe969e9f8bb45531c1e84c82e822ff47ea015c /include/linux/netdevice.h | |
parent | cc7b86c1a8f207c8aa77aad6941475d8294a83c4 (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.h | 70 |
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 | |||
177 | struct net_device_stats { | 167 | struct 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); | |||
2147 | extern const struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev, | 2133 | extern const struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev, |
2148 | struct rtnl_link_stats64 *storage); | 2134 | struct rtnl_link_stats64 *storage); |
2149 | extern void dev_txq_stats_fold(const struct net_device *dev, | 2135 | extern void dev_txq_stats_fold(const struct net_device *dev, |
2150 | struct net_device_stats *stats); | 2136 | struct rtnl_link_stats64 *stats); |
2151 | 2137 | ||
2152 | extern int netdev_max_backlog; | 2138 | extern int netdev_max_backlog; |
2153 | extern int netdev_tstamp_prequeue; | 2139 | extern int netdev_tstamp_prequeue; |