diff options
-rw-r--r-- | drivers/net/macvlan.c | 2 | ||||
-rw-r--r-- | include/linux/netdevice.h | 70 | ||||
-rw-r--r-- | net/8021q/vlan_dev.c | 2 | ||||
-rw-r--r-- | net/core/dev.c | 31 |
4 files changed, 56 insertions, 49 deletions
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 6112f1498940..1b28aaec0a5a 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
@@ -436,7 +436,7 @@ static struct rtnl_link_stats64 *macvlan_dev_get_stats64(struct net_device *dev, | |||
436 | { | 436 | { |
437 | struct macvlan_dev *vlan = netdev_priv(dev); | 437 | struct macvlan_dev *vlan = netdev_priv(dev); |
438 | 438 | ||
439 | dev_txq_stats_fold(dev, (struct net_device_stats *)stats); | 439 | dev_txq_stats_fold(dev, stats); |
440 | 440 | ||
441 | if (vlan->rx_stats) { | 441 | if (vlan->rx_stats) { |
442 | struct macvlan_rx_stats *p, accum = {0}; | 442 | struct macvlan_rx_stats *p, accum = {0}; |
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; |
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index a1b8171cfa7b..7cb285f96b99 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -805,7 +805,7 @@ static u32 vlan_ethtool_get_flags(struct net_device *dev) | |||
805 | 805 | ||
806 | static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) | 806 | static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) |
807 | { | 807 | { |
808 | dev_txq_stats_fold(dev, (struct net_device_stats *)stats); | 808 | dev_txq_stats_fold(dev, stats); |
809 | 809 | ||
810 | if (vlan_dev_info(dev)->vlan_rx_stats) { | 810 | if (vlan_dev_info(dev)->vlan_rx_stats) { |
811 | struct vlan_rx_stats *p, accum = {0}; | 811 | struct vlan_rx_stats *p, accum = {0}; |
diff --git a/net/core/dev.c b/net/core/dev.c index eb4201cf9c8c..79ee26ef5095 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -5274,10 +5274,10 @@ void netdev_run_todo(void) | |||
5274 | /** | 5274 | /** |
5275 | * dev_txq_stats_fold - fold tx_queues stats | 5275 | * dev_txq_stats_fold - fold tx_queues stats |
5276 | * @dev: device to get statistics from | 5276 | * @dev: device to get statistics from |
5277 | * @stats: struct net_device_stats to hold results | 5277 | * @stats: struct rtnl_link_stats64 to hold results |
5278 | */ | 5278 | */ |
5279 | void dev_txq_stats_fold(const struct net_device *dev, | 5279 | void dev_txq_stats_fold(const struct net_device *dev, |
5280 | struct net_device_stats *stats) | 5280 | struct rtnl_link_stats64 *stats) |
5281 | { | 5281 | { |
5282 | unsigned long tx_bytes = 0, tx_packets = 0, tx_dropped = 0; | 5282 | unsigned long tx_bytes = 0, tx_packets = 0, tx_dropped = 0; |
5283 | unsigned int i; | 5283 | unsigned int i; |
@@ -5297,6 +5297,27 @@ void dev_txq_stats_fold(const struct net_device *dev, | |||
5297 | } | 5297 | } |
5298 | EXPORT_SYMBOL(dev_txq_stats_fold); | 5298 | EXPORT_SYMBOL(dev_txq_stats_fold); |
5299 | 5299 | ||
5300 | /* Convert net_device_stats to rtnl_link_stats64. They have the same | ||
5301 | * fields in the same order, with only the type differing. | ||
5302 | */ | ||
5303 | static void netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64, | ||
5304 | const struct net_device_stats *netdev_stats) | ||
5305 | { | ||
5306 | #if BITS_PER_LONG == 64 | ||
5307 | BUILD_BUG_ON(sizeof(*stats64) != sizeof(*netdev_stats)); | ||
5308 | memcpy(stats64, netdev_stats, sizeof(*stats64)); | ||
5309 | #else | ||
5310 | size_t i, n = sizeof(*stats64) / sizeof(u64); | ||
5311 | const unsigned long *src = (const unsigned long *)netdev_stats; | ||
5312 | u64 *dst = (u64 *)stats64; | ||
5313 | |||
5314 | BUILD_BUG_ON(sizeof(*netdev_stats) / sizeof(unsigned long) != | ||
5315 | sizeof(*stats64) / sizeof(u64)); | ||
5316 | for (i = 0; i < n; i++) | ||
5317 | dst[i] = src[i]; | ||
5318 | #endif | ||
5319 | } | ||
5320 | |||
5300 | /** | 5321 | /** |
5301 | * dev_get_stats - get network device statistics | 5322 | * dev_get_stats - get network device statistics |
5302 | * @dev: device to get statistics from | 5323 | * @dev: device to get statistics from |
@@ -5317,11 +5338,11 @@ const struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev, | |||
5317 | return ops->ndo_get_stats64(dev, storage); | 5338 | return ops->ndo_get_stats64(dev, storage); |
5318 | } | 5339 | } |
5319 | if (ops->ndo_get_stats) { | 5340 | if (ops->ndo_get_stats) { |
5320 | memcpy(storage, ops->ndo_get_stats(dev), sizeof(*storage)); | 5341 | netdev_stats_to_stats64(storage, ops->ndo_get_stats(dev)); |
5321 | return storage; | 5342 | return storage; |
5322 | } | 5343 | } |
5323 | memcpy(storage, &dev->stats, sizeof(*storage)); | 5344 | netdev_stats_to_stats64(storage, &dev->stats); |
5324 | dev_txq_stats_fold(dev, (struct net_device_stats *)storage); | 5345 | dev_txq_stats_fold(dev, storage); |
5325 | return storage; | 5346 | return storage; |
5326 | } | 5347 | } |
5327 | EXPORT_SYMBOL(dev_get_stats); | 5348 | EXPORT_SYMBOL(dev_get_stats); |