diff options
Diffstat (limited to 'net/ipv6/ip6_tunnel.c')
-rw-r--r-- | net/ipv6/ip6_tunnel.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 02894216a46d..1e5e2404f1af 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -101,17 +101,26 @@ struct ip6_tnl_net { | |||
101 | 101 | ||
102 | static struct net_device_stats *ip6_get_stats(struct net_device *dev) | 102 | static struct net_device_stats *ip6_get_stats(struct net_device *dev) |
103 | { | 103 | { |
104 | struct pcpu_sw_netstats sum = { 0 }; | 104 | struct pcpu_sw_netstats tmp, sum = { 0 }; |
105 | int i; | 105 | int i; |
106 | 106 | ||
107 | for_each_possible_cpu(i) { | 107 | for_each_possible_cpu(i) { |
108 | unsigned int start; | ||
108 | const struct pcpu_sw_netstats *tstats = | 109 | const struct pcpu_sw_netstats *tstats = |
109 | per_cpu_ptr(dev->tstats, i); | 110 | per_cpu_ptr(dev->tstats, i); |
110 | 111 | ||
111 | sum.rx_packets += tstats->rx_packets; | 112 | do { |
112 | sum.rx_bytes += tstats->rx_bytes; | 113 | start = u64_stats_fetch_begin_bh(&tstats->syncp); |
113 | sum.tx_packets += tstats->tx_packets; | 114 | tmp.rx_packets = tstats->rx_packets; |
114 | sum.tx_bytes += tstats->tx_bytes; | 115 | tmp.rx_bytes = tstats->rx_bytes; |
116 | tmp.tx_packets = tstats->tx_packets; | ||
117 | tmp.tx_bytes = tstats->tx_bytes; | ||
118 | } while (u64_stats_fetch_retry_bh(&tstats->syncp, start)); | ||
119 | |||
120 | sum.rx_packets += tmp.rx_packets; | ||
121 | sum.rx_bytes += tmp.rx_bytes; | ||
122 | sum.tx_packets += tmp.tx_packets; | ||
123 | sum.tx_bytes += tmp.tx_bytes; | ||
115 | } | 124 | } |
116 | dev->stats.rx_packets = sum.rx_packets; | 125 | dev->stats.rx_packets = sum.rx_packets; |
117 | dev->stats.rx_bytes = sum.rx_bytes; | 126 | dev->stats.rx_bytes = sum.rx_bytes; |
@@ -823,8 +832,10 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol, | |||
823 | } | 832 | } |
824 | 833 | ||
825 | tstats = this_cpu_ptr(t->dev->tstats); | 834 | tstats = this_cpu_ptr(t->dev->tstats); |
835 | u64_stats_update_begin(&tstats->syncp); | ||
826 | tstats->rx_packets++; | 836 | tstats->rx_packets++; |
827 | tstats->rx_bytes += skb->len; | 837 | tstats->rx_bytes += skb->len; |
838 | u64_stats_update_end(&tstats->syncp); | ||
828 | 839 | ||
829 | netif_rx(skb); | 840 | netif_rx(skb); |
830 | 841 | ||