diff options
Diffstat (limited to 'net/core')
| -rw-r--r-- | net/core/dev.c | 31 |
1 files changed, 26 insertions, 5 deletions
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); |
