diff options
author | stephen hemminger <shemminger@vyatta.com> | 2012-04-12 02:31:16 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-04-14 14:47:05 -0400 |
commit | 87b6d218f3adb00e6b58c7f96f8b5a74ff91abb4 (patch) | |
tree | 0a8108621afcaf9549a05a33ca08adb4a810b257 /net/ipv4/ipip.c | |
parent | 64d683c5825003ffb3b127057a165e6bfc26691e (diff) |
tunnel: implement 64 bits statistics
Convert the per-cpu statistics kept for GRE, IPIP, and SIT tunnels
to use 64 bit statistics.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/ipip.c')
-rw-r--r-- | net/ipv4/ipip.c | 53 |
1 files changed, 35 insertions, 18 deletions
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index ae1413e3f2f8..b5a1849b83d5 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c | |||
@@ -144,30 +144,45 @@ static void ipip_dev_free(struct net_device *dev); | |||
144 | 144 | ||
145 | /* often modified stats are per cpu, other are shared (netdev->stats) */ | 145 | /* often modified stats are per cpu, other are shared (netdev->stats) */ |
146 | struct pcpu_tstats { | 146 | struct pcpu_tstats { |
147 | unsigned long rx_packets; | 147 | u64 rx_packets; |
148 | unsigned long rx_bytes; | 148 | u64 rx_bytes; |
149 | unsigned long tx_packets; | 149 | u64 tx_packets; |
150 | unsigned long tx_bytes; | 150 | u64 tx_bytes; |
151 | } __attribute__((aligned(4*sizeof(unsigned long)))); | 151 | struct u64_stats_sync syncp; |
152 | }; | ||
152 | 153 | ||
153 | static struct net_device_stats *ipip_get_stats(struct net_device *dev) | 154 | static struct rtnl_link_stats64 *ipip_get_stats64(struct net_device *dev, |
155 | struct rtnl_link_stats64 *tot) | ||
154 | { | 156 | { |
155 | struct pcpu_tstats sum = { 0 }; | ||
156 | int i; | 157 | int i; |
157 | 158 | ||
158 | for_each_possible_cpu(i) { | 159 | for_each_possible_cpu(i) { |
159 | const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i); | 160 | const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i); |
160 | 161 | u64 rx_packets, rx_bytes, tx_packets, tx_bytes; | |
161 | sum.rx_packets += tstats->rx_packets; | 162 | unsigned int start; |
162 | sum.rx_bytes += tstats->rx_bytes; | 163 | |
163 | sum.tx_packets += tstats->tx_packets; | 164 | do { |
164 | sum.tx_bytes += tstats->tx_bytes; | 165 | start = u64_stats_fetch_begin_bh(&tstats->syncp); |
166 | rx_packets = tstats->rx_packets; | ||
167 | tx_packets = tstats->tx_packets; | ||
168 | rx_bytes = tstats->rx_bytes; | ||
169 | tx_bytes = tstats->tx_bytes; | ||
170 | } while (u64_stats_fetch_retry_bh(&tstats->syncp, start)); | ||
171 | |||
172 | tot->rx_packets += rx_packets; | ||
173 | tot->tx_packets += tx_packets; | ||
174 | tot->rx_bytes += rx_bytes; | ||
175 | tot->tx_bytes += tx_bytes; | ||
165 | } | 176 | } |
166 | dev->stats.rx_packets = sum.rx_packets; | 177 | |
167 | dev->stats.rx_bytes = sum.rx_bytes; | 178 | tot->tx_fifo_errors = dev->stats.tx_fifo_errors; |
168 | dev->stats.tx_packets = sum.tx_packets; | 179 | tot->tx_carrier_errors = dev->stats.tx_carrier_errors; |
169 | dev->stats.tx_bytes = sum.tx_bytes; | 180 | tot->tx_dropped = dev->stats.tx_dropped; |
170 | return &dev->stats; | 181 | tot->tx_aborted_errors = dev->stats.tx_aborted_errors; |
182 | tot->tx_errors = dev->stats.tx_errors; | ||
183 | tot->collisions = dev->stats.collisions; | ||
184 | |||
185 | return tot; | ||
171 | } | 186 | } |
172 | 187 | ||
173 | static struct ip_tunnel * ipip_tunnel_lookup(struct net *net, | 188 | static struct ip_tunnel * ipip_tunnel_lookup(struct net *net, |
@@ -404,8 +419,10 @@ static int ipip_rcv(struct sk_buff *skb) | |||
404 | skb->pkt_type = PACKET_HOST; | 419 | skb->pkt_type = PACKET_HOST; |
405 | 420 | ||
406 | tstats = this_cpu_ptr(tunnel->dev->tstats); | 421 | tstats = this_cpu_ptr(tunnel->dev->tstats); |
422 | u64_stats_update_begin(&tstats->syncp); | ||
407 | tstats->rx_packets++; | 423 | tstats->rx_packets++; |
408 | tstats->rx_bytes += skb->len; | 424 | tstats->rx_bytes += skb->len; |
425 | u64_stats_update_end(&tstats->syncp); | ||
409 | 426 | ||
410 | __skb_tunnel_rx(skb, tunnel->dev); | 427 | __skb_tunnel_rx(skb, tunnel->dev); |
411 | 428 | ||
@@ -730,7 +747,7 @@ static const struct net_device_ops ipip_netdev_ops = { | |||
730 | .ndo_start_xmit = ipip_tunnel_xmit, | 747 | .ndo_start_xmit = ipip_tunnel_xmit, |
731 | .ndo_do_ioctl = ipip_tunnel_ioctl, | 748 | .ndo_do_ioctl = ipip_tunnel_ioctl, |
732 | .ndo_change_mtu = ipip_tunnel_change_mtu, | 749 | .ndo_change_mtu = ipip_tunnel_change_mtu, |
733 | .ndo_get_stats = ipip_get_stats, | 750 | .ndo_get_stats64 = ipip_get_stats64, |
734 | }; | 751 | }; |
735 | 752 | ||
736 | static void ipip_dev_free(struct net_device *dev) | 753 | static void ipip_dev_free(struct net_device *dev) |