aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/macvlan.c2
-rw-r--r--include/linux/netdevice.h70
-rw-r--r--net/8021q/vlan_dev.c2
-rw-r--r--net/core/dev.c31
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
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;
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
806static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) 806static 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 */
5279void dev_txq_stats_fold(const struct net_device *dev, 5279void 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}
5298EXPORT_SYMBOL(dev_txq_stats_fold); 5298EXPORT_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 */
5303static 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}
5327EXPORT_SYMBOL(dev_get_stats); 5348EXPORT_SYMBOL(dev_get_stats);