diff options
Diffstat (limited to 'net/8021q/vlan_dev.c')
-rw-r--r-- | net/8021q/vlan_dev.c | 61 |
1 files changed, 35 insertions, 26 deletions
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index f3c9552f6ba8..2fa3f4a3f60f 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -141,7 +141,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, | |||
141 | struct packet_type *ptype, struct net_device *orig_dev) | 141 | struct packet_type *ptype, struct net_device *orig_dev) |
142 | { | 142 | { |
143 | struct vlan_hdr *vhdr; | 143 | struct vlan_hdr *vhdr; |
144 | struct vlan_rx_stats *rx_stats; | 144 | struct vlan_pcpu_stats *rx_stats; |
145 | struct net_device *vlan_dev; | 145 | struct net_device *vlan_dev; |
146 | u16 vlan_id; | 146 | u16 vlan_id; |
147 | u16 vlan_tci; | 147 | u16 vlan_tci; |
@@ -177,7 +177,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, | |||
177 | } else { | 177 | } else { |
178 | skb->dev = vlan_dev; | 178 | skb->dev = vlan_dev; |
179 | 179 | ||
180 | rx_stats = this_cpu_ptr(vlan_dev_info(skb->dev)->vlan_rx_stats); | 180 | rx_stats = this_cpu_ptr(vlan_dev_info(skb->dev)->vlan_pcpu_stats); |
181 | 181 | ||
182 | u64_stats_update_begin(&rx_stats->syncp); | 182 | u64_stats_update_begin(&rx_stats->syncp); |
183 | rx_stats->rx_packets++; | 183 | rx_stats->rx_packets++; |
@@ -310,8 +310,6 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, | |||
310 | static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, | 310 | static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, |
311 | struct net_device *dev) | 311 | struct net_device *dev) |
312 | { | 312 | { |
313 | int i = skb_get_queue_mapping(skb); | ||
314 | struct netdev_queue *txq = netdev_get_tx_queue(dev, i); | ||
315 | struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); | 313 | struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); |
316 | unsigned int len; | 314 | unsigned int len; |
317 | int ret; | 315 | int ret; |
@@ -334,10 +332,16 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, | |||
334 | ret = dev_queue_xmit(skb); | 332 | ret = dev_queue_xmit(skb); |
335 | 333 | ||
336 | if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { | 334 | if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { |
337 | txq->tx_packets++; | 335 | struct vlan_pcpu_stats *stats; |
338 | txq->tx_bytes += len; | 336 | |
339 | } else | 337 | stats = this_cpu_ptr(vlan_dev_info(dev)->vlan_pcpu_stats); |
340 | txq->tx_dropped++; | 338 | u64_stats_update_begin(&stats->syncp); |
339 | stats->tx_packets++; | ||
340 | stats->tx_bytes += len; | ||
341 | u64_stats_update_begin(&stats->syncp); | ||
342 | } else { | ||
343 | this_cpu_inc(vlan_dev_info(dev)->vlan_pcpu_stats->tx_dropped); | ||
344 | } | ||
341 | 345 | ||
342 | return ret; | 346 | return ret; |
343 | } | 347 | } |
@@ -696,6 +700,7 @@ static int vlan_dev_init(struct net_device *dev) | |||
696 | (1<<__LINK_STATE_PRESENT); | 700 | (1<<__LINK_STATE_PRESENT); |
697 | 701 | ||
698 | dev->features |= real_dev->features & real_dev->vlan_features; | 702 | dev->features |= real_dev->features & real_dev->vlan_features; |
703 | dev->features |= NETIF_F_LLTX; | ||
699 | dev->gso_max_size = real_dev->gso_max_size; | 704 | dev->gso_max_size = real_dev->gso_max_size; |
700 | 705 | ||
701 | /* ipv6 shared card related stuff */ | 706 | /* ipv6 shared card related stuff */ |
@@ -728,8 +733,8 @@ static int vlan_dev_init(struct net_device *dev) | |||
728 | 733 | ||
729 | vlan_dev_set_lockdep_class(dev, subclass); | 734 | vlan_dev_set_lockdep_class(dev, subclass); |
730 | 735 | ||
731 | vlan_dev_info(dev)->vlan_rx_stats = alloc_percpu(struct vlan_rx_stats); | 736 | vlan_dev_info(dev)->vlan_pcpu_stats = alloc_percpu(struct vlan_pcpu_stats); |
732 | if (!vlan_dev_info(dev)->vlan_rx_stats) | 737 | if (!vlan_dev_info(dev)->vlan_pcpu_stats) |
733 | return -ENOMEM; | 738 | return -ENOMEM; |
734 | 739 | ||
735 | return 0; | 740 | return 0; |
@@ -741,8 +746,8 @@ static void vlan_dev_uninit(struct net_device *dev) | |||
741 | struct vlan_dev_info *vlan = vlan_dev_info(dev); | 746 | struct vlan_dev_info *vlan = vlan_dev_info(dev); |
742 | int i; | 747 | int i; |
743 | 748 | ||
744 | free_percpu(vlan->vlan_rx_stats); | 749 | free_percpu(vlan->vlan_pcpu_stats); |
745 | vlan->vlan_rx_stats = NULL; | 750 | vlan->vlan_pcpu_stats = NULL; |
746 | for (i = 0; i < ARRAY_SIZE(vlan->egress_priority_map); i++) { | 751 | for (i = 0; i < ARRAY_SIZE(vlan->egress_priority_map); i++) { |
747 | while ((pm = vlan->egress_priority_map[i]) != NULL) { | 752 | while ((pm = vlan->egress_priority_map[i]) != NULL) { |
748 | vlan->egress_priority_map[i] = pm->next; | 753 | vlan->egress_priority_map[i] = pm->next; |
@@ -780,33 +785,37 @@ static u32 vlan_ethtool_get_flags(struct net_device *dev) | |||
780 | 785 | ||
781 | static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) | 786 | static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) |
782 | { | 787 | { |
783 | dev_txq_stats_fold(dev, stats); | ||
784 | 788 | ||
785 | if (vlan_dev_info(dev)->vlan_rx_stats) { | 789 | if (vlan_dev_info(dev)->vlan_pcpu_stats) { |
786 | struct vlan_rx_stats *p, accum = {0}; | 790 | struct vlan_pcpu_stats *p; |
791 | u32 rx_errors = 0, tx_dropped = 0; | ||
787 | int i; | 792 | int i; |
788 | 793 | ||
789 | for_each_possible_cpu(i) { | 794 | for_each_possible_cpu(i) { |
790 | u64 rxpackets, rxbytes, rxmulticast; | 795 | u64 rxpackets, rxbytes, rxmulticast, txpackets, txbytes; |
791 | unsigned int start; | 796 | unsigned int start; |
792 | 797 | ||
793 | p = per_cpu_ptr(vlan_dev_info(dev)->vlan_rx_stats, i); | 798 | p = per_cpu_ptr(vlan_dev_info(dev)->vlan_pcpu_stats, i); |
794 | do { | 799 | do { |
795 | start = u64_stats_fetch_begin_bh(&p->syncp); | 800 | start = u64_stats_fetch_begin_bh(&p->syncp); |
796 | rxpackets = p->rx_packets; | 801 | rxpackets = p->rx_packets; |
797 | rxbytes = p->rx_bytes; | 802 | rxbytes = p->rx_bytes; |
798 | rxmulticast = p->rx_multicast; | 803 | rxmulticast = p->rx_multicast; |
804 | txpackets = p->tx_packets; | ||
805 | txbytes = p->tx_bytes; | ||
799 | } while (u64_stats_fetch_retry_bh(&p->syncp, start)); | 806 | } while (u64_stats_fetch_retry_bh(&p->syncp, start)); |
800 | accum.rx_packets += rxpackets; | 807 | |
801 | accum.rx_bytes += rxbytes; | 808 | stats->rx_packets += rxpackets; |
802 | accum.rx_multicast += rxmulticast; | 809 | stats->rx_bytes += rxbytes; |
803 | /* rx_errors is ulong, not protected by syncp */ | 810 | stats->multicast += rxmulticast; |
804 | accum.rx_errors += p->rx_errors; | 811 | stats->tx_packets += txpackets; |
812 | stats->tx_bytes += txbytes; | ||
813 | /* rx_errors & tx_dropped are u32 */ | ||
814 | rx_errors += p->rx_errors; | ||
815 | tx_dropped += p->tx_dropped; | ||
805 | } | 816 | } |
806 | stats->rx_packets = accum.rx_packets; | 817 | stats->rx_errors = rx_errors; |
807 | stats->rx_bytes = accum.rx_bytes; | 818 | stats->tx_dropped = tx_dropped; |
808 | stats->rx_errors = accum.rx_errors; | ||
809 | stats->multicast = accum.rx_multicast; | ||
810 | } | 819 | } |
811 | return stats; | 820 | return stats; |
812 | } | 821 | } |