diff options
Diffstat (limited to 'drivers/net/macvlan.c')
-rw-r--r-- | drivers/net/macvlan.c | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index e096875aa055..e6d626e78515 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
@@ -431,29 +431,38 @@ static void macvlan_uninit(struct net_device *dev) | |||
431 | free_percpu(vlan->rx_stats); | 431 | free_percpu(vlan->rx_stats); |
432 | } | 432 | } |
433 | 433 | ||
434 | static struct net_device_stats *macvlan_dev_get_stats(struct net_device *dev) | 434 | static struct rtnl_link_stats64 *macvlan_dev_get_stats64(struct net_device *dev) |
435 | { | 435 | { |
436 | struct net_device_stats *stats = &dev->stats; | 436 | struct rtnl_link_stats64 *stats = &dev->stats64; |
437 | struct macvlan_dev *vlan = netdev_priv(dev); | 437 | struct macvlan_dev *vlan = netdev_priv(dev); |
438 | 438 | ||
439 | dev_txq_stats_fold(dev, stats); | 439 | dev_txq_stats_fold(dev, &dev->stats); |
440 | 440 | ||
441 | if (vlan->rx_stats) { | 441 | if (vlan->rx_stats) { |
442 | struct macvlan_rx_stats *p, rx = {0}; | 442 | struct macvlan_rx_stats *p, accum = {0}; |
443 | u64 rx_packets, rx_bytes, rx_multicast; | ||
444 | unsigned int start; | ||
443 | int i; | 445 | int i; |
444 | 446 | ||
445 | for_each_possible_cpu(i) { | 447 | for_each_possible_cpu(i) { |
446 | p = per_cpu_ptr(vlan->rx_stats, i); | 448 | p = per_cpu_ptr(vlan->rx_stats, i); |
447 | rx.rx_packets += p->rx_packets; | 449 | do { |
448 | rx.rx_bytes += p->rx_bytes; | 450 | start = u64_stats_fetch_begin_bh(&p->syncp); |
449 | rx.rx_errors += p->rx_errors; | 451 | rx_packets = p->rx_packets; |
450 | rx.multicast += p->multicast; | 452 | rx_bytes = p->rx_bytes; |
453 | rx_multicast = p->rx_multicast; | ||
454 | } while (u64_stats_fetch_retry_bh(&p->syncp, start)); | ||
455 | accum.rx_packets += rx_packets; | ||
456 | accum.rx_bytes += rx_bytes; | ||
457 | accum.rx_multicast += rx_multicast; | ||
458 | /* rx_errors is an ulong, updated without syncp protection */ | ||
459 | accum.rx_errors += p->rx_errors; | ||
451 | } | 460 | } |
452 | stats->rx_packets = rx.rx_packets; | 461 | stats->rx_packets = accum.rx_packets; |
453 | stats->rx_bytes = rx.rx_bytes; | 462 | stats->rx_bytes = accum.rx_bytes; |
454 | stats->rx_errors = rx.rx_errors; | 463 | stats->rx_errors = accum.rx_errors; |
455 | stats->rx_dropped = rx.rx_errors; | 464 | stats->rx_dropped = accum.rx_errors; |
456 | stats->multicast = rx.multicast; | 465 | stats->multicast = accum.rx_multicast; |
457 | } | 466 | } |
458 | return stats; | 467 | return stats; |
459 | } | 468 | } |
@@ -502,7 +511,7 @@ static const struct net_device_ops macvlan_netdev_ops = { | |||
502 | .ndo_change_rx_flags = macvlan_change_rx_flags, | 511 | .ndo_change_rx_flags = macvlan_change_rx_flags, |
503 | .ndo_set_mac_address = macvlan_set_mac_address, | 512 | .ndo_set_mac_address = macvlan_set_mac_address, |
504 | .ndo_set_multicast_list = macvlan_set_multicast_list, | 513 | .ndo_set_multicast_list = macvlan_set_multicast_list, |
505 | .ndo_get_stats = macvlan_dev_get_stats, | 514 | .ndo_get_stats64 = macvlan_dev_get_stats64, |
506 | .ndo_validate_addr = eth_validate_addr, | 515 | .ndo_validate_addr = eth_validate_addr, |
507 | }; | 516 | }; |
508 | 517 | ||