aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/macvlan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/macvlan.c')
-rw-r--r--drivers/net/macvlan.c80
1 files changed, 35 insertions, 45 deletions
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 0fc9dc7f20db..93f0ba25c808 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -243,18 +243,22 @@ xmit_world:
243netdev_tx_t macvlan_start_xmit(struct sk_buff *skb, 243netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
244 struct net_device *dev) 244 struct net_device *dev)
245{ 245{
246 int i = skb_get_queue_mapping(skb);
247 struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
248 unsigned int len = skb->len; 246 unsigned int len = skb->len;
249 int ret; 247 int ret;
248 const struct macvlan_dev *vlan = netdev_priv(dev);
250 249
251 ret = macvlan_queue_xmit(skb, dev); 250 ret = macvlan_queue_xmit(skb, dev);
252 if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { 251 if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) {
253 txq->tx_packets++; 252 struct macvlan_pcpu_stats *pcpu_stats;
254 txq->tx_bytes += len;
255 } else
256 txq->tx_dropped++;
257 253
254 pcpu_stats = this_cpu_ptr(vlan->pcpu_stats);
255 u64_stats_update_begin(&pcpu_stats->syncp);
256 pcpu_stats->tx_packets++;
257 pcpu_stats->tx_bytes += len;
258 u64_stats_update_end(&pcpu_stats->syncp);
259 } else {
260 this_cpu_inc(vlan->pcpu_stats->tx_dropped);
261 }
258 return ret; 262 return ret;
259} 263}
260EXPORT_SYMBOL_GPL(macvlan_start_xmit); 264EXPORT_SYMBOL_GPL(macvlan_start_xmit);
@@ -414,14 +418,15 @@ static int macvlan_init(struct net_device *dev)
414 dev->state = (dev->state & ~MACVLAN_STATE_MASK) | 418 dev->state = (dev->state & ~MACVLAN_STATE_MASK) |
415 (lowerdev->state & MACVLAN_STATE_MASK); 419 (lowerdev->state & MACVLAN_STATE_MASK);
416 dev->features = lowerdev->features & MACVLAN_FEATURES; 420 dev->features = lowerdev->features & MACVLAN_FEATURES;
421 dev->features |= NETIF_F_LLTX;
417 dev->gso_max_size = lowerdev->gso_max_size; 422 dev->gso_max_size = lowerdev->gso_max_size;
418 dev->iflink = lowerdev->ifindex; 423 dev->iflink = lowerdev->ifindex;
419 dev->hard_header_len = lowerdev->hard_header_len; 424 dev->hard_header_len = lowerdev->hard_header_len;
420 425
421 macvlan_set_lockdep_class(dev); 426 macvlan_set_lockdep_class(dev);
422 427
423 vlan->rx_stats = alloc_percpu(struct macvlan_rx_stats); 428 vlan->pcpu_stats = alloc_percpu(struct macvlan_pcpu_stats);
424 if (!vlan->rx_stats) 429 if (!vlan->pcpu_stats)
425 return -ENOMEM; 430 return -ENOMEM;
426 431
427 return 0; 432 return 0;
@@ -431,7 +436,7 @@ static void macvlan_uninit(struct net_device *dev)
431{ 436{
432 struct macvlan_dev *vlan = netdev_priv(dev); 437 struct macvlan_dev *vlan = netdev_priv(dev);
433 438
434 free_percpu(vlan->rx_stats); 439 free_percpu(vlan->pcpu_stats);
435} 440}
436 441
437static struct rtnl_link_stats64 *macvlan_dev_get_stats64(struct net_device *dev, 442static struct rtnl_link_stats64 *macvlan_dev_get_stats64(struct net_device *dev,
@@ -439,33 +444,38 @@ static struct rtnl_link_stats64 *macvlan_dev_get_stats64(struct net_device *dev,
439{ 444{
440 struct macvlan_dev *vlan = netdev_priv(dev); 445 struct macvlan_dev *vlan = netdev_priv(dev);
441 446
442 dev_txq_stats_fold(dev, stats); 447 if (vlan->pcpu_stats) {
443 448 struct macvlan_pcpu_stats *p;
444 if (vlan->rx_stats) { 449 u64 rx_packets, rx_bytes, rx_multicast, tx_packets, tx_bytes;
445 struct macvlan_rx_stats *p, accum = {0}; 450 u32 rx_errors = 0, tx_dropped = 0;
446 u64 rx_packets, rx_bytes, rx_multicast;
447 unsigned int start; 451 unsigned int start;
448 int i; 452 int i;
449 453
450 for_each_possible_cpu(i) { 454 for_each_possible_cpu(i) {
451 p = per_cpu_ptr(vlan->rx_stats, i); 455 p = per_cpu_ptr(vlan->pcpu_stats, i);
452 do { 456 do {
453 start = u64_stats_fetch_begin_bh(&p->syncp); 457 start = u64_stats_fetch_begin_bh(&p->syncp);
454 rx_packets = p->rx_packets; 458 rx_packets = p->rx_packets;
455 rx_bytes = p->rx_bytes; 459 rx_bytes = p->rx_bytes;
456 rx_multicast = p->rx_multicast; 460 rx_multicast = p->rx_multicast;
461 tx_packets = p->tx_packets;
462 tx_bytes = p->tx_bytes;
457 } while (u64_stats_fetch_retry_bh(&p->syncp, start)); 463 } while (u64_stats_fetch_retry_bh(&p->syncp, start));
458 accum.rx_packets += rx_packets; 464
459 accum.rx_bytes += rx_bytes; 465 stats->rx_packets += rx_packets;
460 accum.rx_multicast += rx_multicast; 466 stats->rx_bytes += rx_bytes;
461 /* rx_errors is an ulong, updated without syncp protection */ 467 stats->multicast += rx_multicast;
462 accum.rx_errors += p->rx_errors; 468 stats->tx_packets += tx_packets;
469 stats->tx_bytes += tx_bytes;
470 /* rx_errors & tx_dropped are u32, updated
471 * without syncp protection.
472 */
473 rx_errors += p->rx_errors;
474 tx_dropped += p->tx_dropped;
463 } 475 }
464 stats->rx_packets = accum.rx_packets; 476 stats->rx_errors = rx_errors;
465 stats->rx_bytes = accum.rx_bytes; 477 stats->rx_dropped = rx_errors;
466 stats->rx_errors = accum.rx_errors; 478 stats->tx_dropped = tx_dropped;
467 stats->rx_dropped = accum.rx_errors;
468 stats->multicast = accum.rx_multicast;
469 } 479 }
470 return stats; 480 return stats;
471} 481}
@@ -601,25 +611,6 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
601 return 0; 611 return 0;
602} 612}
603 613
604static int macvlan_get_tx_queues(struct net *net,
605 struct nlattr *tb[],
606 unsigned int *num_tx_queues,
607 unsigned int *real_num_tx_queues)
608{
609 struct net_device *real_dev;
610
611 if (!tb[IFLA_LINK])
612 return -EINVAL;
613
614 real_dev = __dev_get_by_index(net, nla_get_u32(tb[IFLA_LINK]));
615 if (!real_dev)
616 return -ENODEV;
617
618 *num_tx_queues = real_dev->num_tx_queues;
619 *real_num_tx_queues = real_dev->real_num_tx_queues;
620 return 0;
621}
622
623int macvlan_common_newlink(struct net *src_net, struct net_device *dev, 614int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
624 struct nlattr *tb[], struct nlattr *data[], 615 struct nlattr *tb[], struct nlattr *data[],
625 int (*receive)(struct sk_buff *skb), 616 int (*receive)(struct sk_buff *skb),
@@ -743,7 +734,6 @@ int macvlan_link_register(struct rtnl_link_ops *ops)
743{ 734{
744 /* common fields */ 735 /* common fields */
745 ops->priv_size = sizeof(struct macvlan_dev); 736 ops->priv_size = sizeof(struct macvlan_dev);
746 ops->get_tx_queues = macvlan_get_tx_queues;
747 ops->validate = macvlan_validate; 737 ops->validate = macvlan_validate;
748 ops->maxtype = IFLA_MACVLAN_MAX; 738 ops->maxtype = IFLA_MACVLAN_MAX;
749 ops->policy = macvlan_policy; 739 ops->policy = macvlan_policy;