- int i;
-
- /* We potentially have 3 sources of stats that need to be
- * combined: those we have collected (split into err_stats and
- * percpu_stats), offset_stats from set_stats(), and device
- * error stats from netdev->get_stats() (for errors that happen
- * downstream and therefore aren't reported through our
- * vport_record_error() function).
- * Stats from first two sources are merged and reported by ovs over
- * OVS_VPORT_ATTR_STATS.
- * netdev-stats can be directly read over netlink-ioctl.
- */
-
- spin_lock_bh(&vport->stats_lock);
-
- *stats = vport->offset_stats;
-
- stats->rx_errors += vport->err_stats.rx_errors;
- stats->tx_errors += vport->err_stats.tx_errors;
- stats->tx_dropped += vport->err_stats.tx_dropped;
- stats->rx_dropped += vport->err_stats.rx_dropped;
-
- spin_unlock_bh(&vport->stats_lock);
-
- for_each_possible_cpu(i) {
- const struct vport_percpu_stats *percpu_stats;
- struct vport_percpu_stats local_stats;
- unsigned int start;
-
- percpu_stats = per_cpu_ptr(vport->percpu_stats, i);
-
- do {
- start = u64_stats_fetch_begin_bh(&percpu_stats->sync);
- local_stats = *percpu_stats;
- } while (u64_stats_fetch_retry_bh(&percpu_stats->sync, start));
-
- stats->rx_bytes += local_stats.rx_bytes;
- stats->rx_packets += local_stats.rx_packets;
- stats->tx_bytes += local_stats.tx_bytes;
- stats->tx_packets += local_stats.tx_packets;
- }
+ const struct rtnl_link_stats64 *dev_stats;
+ struct rtnl_link_stats64 temp;
+
+ dev_stats = dev_get_stats(vport->dev, &temp);
+ stats->rx_errors = dev_stats->rx_errors;
+ stats->tx_errors = dev_stats->tx_errors;
+ stats->tx_dropped = dev_stats->tx_dropped;
+ stats->rx_dropped = dev_stats->rx_dropped;
+
+ stats->rx_bytes = dev_stats->rx_bytes;
+ stats->rx_packets = dev_stats->rx_packets;
+ stats->tx_bytes = dev_stats->tx_bytes;
+ stats->tx_packets = dev_stats->tx_packets;