diff options
-rw-r--r-- | include/linux/netdevice.h | 3 | ||||
-rw-r--r-- | net/core/dev.c | 23 |
2 files changed, 23 insertions, 3 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index cd547d04a8c..f8574e76b74 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -474,6 +474,9 @@ struct netdev_queue { * please use this field instead of dev->trans_start */ unsigned long trans_start; + unsigned long tx_bytes; + unsigned long tx_packets; + unsigned long tx_dropped; } ____cacheline_aligned_in_smp; diff --git a/net/core/dev.c b/net/core/dev.c index 14dd725aaab..6d3630d1627 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -4943,13 +4943,30 @@ void netdev_run_todo(void) * the internal statistics structure is used. */ const struct net_device_stats *dev_get_stats(struct net_device *dev) - { +{ const struct net_device_ops *ops = dev->netdev_ops; if (ops->ndo_get_stats) return ops->ndo_get_stats(dev); - else - return &dev->stats; + else { + unsigned long tx_bytes = 0, tx_packets = 0, tx_dropped = 0; + struct net_device_stats *stats = &dev->stats; + unsigned int i; + struct netdev_queue *txq; + + for (i = 0; i < dev->num_tx_queues; i++) { + txq = netdev_get_tx_queue(dev, i); + tx_bytes += txq->tx_bytes; + tx_packets += txq->tx_packets; + tx_dropped += txq->tx_dropped; + } + if (tx_bytes || tx_packets || tx_dropped) { + stats->tx_bytes = tx_bytes; + stats->tx_packets = tx_packets; + stats->tx_dropped = tx_dropped; + } + return stats; + } } EXPORT_SYMBOL(dev_get_stats); |