diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/ip_gre.c | 59 | ||||
-rw-r--r-- | net/ipv4/ipip.c | 53 | ||||
-rw-r--r-- | net/ipv6/sit.c | 52 |
3 files changed, 109 insertions, 55 deletions
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 02d07c6f630f..b9abf265c2f8 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -169,30 +169,49 @@ struct ipgre_net { | |||
169 | 169 | ||
170 | /* often modified stats are per cpu, other are shared (netdev->stats) */ | 170 | /* often modified stats are per cpu, other are shared (netdev->stats) */ |
171 | struct pcpu_tstats { | 171 | struct pcpu_tstats { |
172 | unsigned long rx_packets; | 172 | u64 rx_packets; |
173 | unsigned long rx_bytes; | 173 | u64 rx_bytes; |
174 | unsigned long tx_packets; | 174 | u64 tx_packets; |
175 | unsigned long tx_bytes; | 175 | u64 tx_bytes; |
176 | } __attribute__((aligned(4*sizeof(unsigned long)))); | 176 | struct u64_stats_sync syncp; |
177 | }; | ||
177 | 178 | ||
178 | static struct net_device_stats *ipgre_get_stats(struct net_device *dev) | 179 | static struct rtnl_link_stats64 *ipgre_get_stats64(struct net_device *dev, |
180 | struct rtnl_link_stats64 *tot) | ||
179 | { | 181 | { |
180 | struct pcpu_tstats sum = { 0 }; | ||
181 | int i; | 182 | int i; |
182 | 183 | ||
183 | for_each_possible_cpu(i) { | 184 | for_each_possible_cpu(i) { |
184 | const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i); | 185 | const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i); |
185 | 186 | u64 rx_packets, rx_bytes, tx_packets, tx_bytes; | |
186 | sum.rx_packets += tstats->rx_packets; | 187 | unsigned int start; |
187 | sum.rx_bytes += tstats->rx_bytes; | 188 | |
188 | sum.tx_packets += tstats->tx_packets; | 189 | do { |
189 | sum.tx_bytes += tstats->tx_bytes; | 190 | start = u64_stats_fetch_begin_bh(&tstats->syncp); |
191 | rx_packets = tstats->rx_packets; | ||
192 | tx_packets = tstats->tx_packets; | ||
193 | rx_bytes = tstats->rx_bytes; | ||
194 | tx_bytes = tstats->tx_bytes; | ||
195 | } while (u64_stats_fetch_retry_bh(&tstats->syncp, start)); | ||
196 | |||
197 | tot->rx_packets += rx_packets; | ||
198 | tot->tx_packets += tx_packets; | ||
199 | tot->rx_bytes += rx_bytes; | ||
200 | tot->tx_bytes += tx_bytes; | ||
190 | } | 201 | } |
191 | dev->stats.rx_packets = sum.rx_packets; | 202 | |
192 | dev->stats.rx_bytes = sum.rx_bytes; | 203 | tot->multicast = dev->stats.multicast; |
193 | dev->stats.tx_packets = sum.tx_packets; | 204 | tot->rx_crc_errors = dev->stats.rx_crc_errors; |
194 | dev->stats.tx_bytes = sum.tx_bytes; | 205 | tot->rx_fifo_errors = dev->stats.rx_fifo_errors; |
195 | return &dev->stats; | 206 | tot->rx_length_errors = dev->stats.rx_length_errors; |
207 | tot->rx_errors = dev->stats.rx_errors; | ||
208 | tot->tx_fifo_errors = dev->stats.tx_fifo_errors; | ||
209 | tot->tx_carrier_errors = dev->stats.tx_carrier_errors; | ||
210 | tot->tx_dropped = dev->stats.tx_dropped; | ||
211 | tot->tx_aborted_errors = dev->stats.tx_aborted_errors; | ||
212 | tot->tx_errors = dev->stats.tx_errors; | ||
213 | |||
214 | return tot; | ||
196 | } | 215 | } |
197 | 216 | ||
198 | /* Given src, dst and key, find appropriate for input tunnel. */ | 217 | /* Given src, dst and key, find appropriate for input tunnel. */ |
@@ -672,8 +691,10 @@ static int ipgre_rcv(struct sk_buff *skb) | |||
672 | } | 691 | } |
673 | 692 | ||
674 | tstats = this_cpu_ptr(tunnel->dev->tstats); | 693 | tstats = this_cpu_ptr(tunnel->dev->tstats); |
694 | u64_stats_update_begin(&tstats->syncp); | ||
675 | tstats->rx_packets++; | 695 | tstats->rx_packets++; |
676 | tstats->rx_bytes += skb->len; | 696 | tstats->rx_bytes += skb->len; |
697 | u64_stats_update_end(&tstats->syncp); | ||
677 | 698 | ||
678 | __skb_tunnel_rx(skb, tunnel->dev); | 699 | __skb_tunnel_rx(skb, tunnel->dev); |
679 | 700 | ||
@@ -1253,7 +1274,7 @@ static const struct net_device_ops ipgre_netdev_ops = { | |||
1253 | .ndo_start_xmit = ipgre_tunnel_xmit, | 1274 | .ndo_start_xmit = ipgre_tunnel_xmit, |
1254 | .ndo_do_ioctl = ipgre_tunnel_ioctl, | 1275 | .ndo_do_ioctl = ipgre_tunnel_ioctl, |
1255 | .ndo_change_mtu = ipgre_tunnel_change_mtu, | 1276 | .ndo_change_mtu = ipgre_tunnel_change_mtu, |
1256 | .ndo_get_stats = ipgre_get_stats, | 1277 | .ndo_get_stats64 = ipgre_get_stats64, |
1257 | }; | 1278 | }; |
1258 | 1279 | ||
1259 | static void ipgre_dev_free(struct net_device *dev) | 1280 | static void ipgre_dev_free(struct net_device *dev) |
@@ -1507,7 +1528,7 @@ static const struct net_device_ops ipgre_tap_netdev_ops = { | |||
1507 | .ndo_set_mac_address = eth_mac_addr, | 1528 | .ndo_set_mac_address = eth_mac_addr, |
1508 | .ndo_validate_addr = eth_validate_addr, | 1529 | .ndo_validate_addr = eth_validate_addr, |
1509 | .ndo_change_mtu = ipgre_tunnel_change_mtu, | 1530 | .ndo_change_mtu = ipgre_tunnel_change_mtu, |
1510 | .ndo_get_stats = ipgre_get_stats, | 1531 | .ndo_get_stats64 = ipgre_get_stats64, |
1511 | }; | 1532 | }; |
1512 | 1533 | ||
1513 | static void ipgre_tap_setup(struct net_device *dev) | 1534 | static void ipgre_tap_setup(struct net_device *dev) |
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) |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index f9608db9dcfb..e5fef943e30a 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -87,31 +87,47 @@ struct sit_net { | |||
87 | 87 | ||
88 | /* often modified stats are per cpu, other are shared (netdev->stats) */ | 88 | /* often modified stats are per cpu, other are shared (netdev->stats) */ |
89 | struct pcpu_tstats { | 89 | struct pcpu_tstats { |
90 | unsigned long rx_packets; | 90 | u64 rx_packets; |
91 | unsigned long rx_bytes; | 91 | u64 rx_bytes; |
92 | unsigned long tx_packets; | 92 | u64 tx_packets; |
93 | unsigned long tx_bytes; | 93 | u64 tx_bytes; |
94 | } __attribute__((aligned(4*sizeof(unsigned long)))); | 94 | struct u64_stats_sync syncp; |
95 | }; | ||
95 | 96 | ||
96 | static struct net_device_stats *ipip6_get_stats(struct net_device *dev) | 97 | static struct rtnl_link_stats64 *ipip6_get_stats64(struct net_device *dev, |
98 | struct rtnl_link_stats64 *tot) | ||
97 | { | 99 | { |
98 | struct pcpu_tstats sum = { 0 }; | ||
99 | int i; | 100 | int i; |
100 | 101 | ||
101 | for_each_possible_cpu(i) { | 102 | for_each_possible_cpu(i) { |
102 | const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i); | 103 | const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i); |
103 | 104 | u64 rx_packets, rx_bytes, tx_packets, tx_bytes; | |
104 | sum.rx_packets += tstats->rx_packets; | 105 | unsigned int start; |
105 | sum.rx_bytes += tstats->rx_bytes; | 106 | |
106 | sum.tx_packets += tstats->tx_packets; | 107 | do { |
107 | sum.tx_bytes += tstats->tx_bytes; | 108 | start = u64_stats_fetch_begin_bh(&tstats->syncp); |
109 | rx_packets = tstats->rx_packets; | ||
110 | tx_packets = tstats->tx_packets; | ||
111 | rx_bytes = tstats->rx_bytes; | ||
112 | tx_bytes = tstats->tx_bytes; | ||
113 | } while (u64_stats_fetch_retry_bh(&tstats->syncp, start)); | ||
114 | |||
115 | tot->rx_packets += rx_packets; | ||
116 | tot->tx_packets += tx_packets; | ||
117 | tot->rx_bytes += rx_bytes; | ||
118 | tot->tx_bytes += tx_bytes; | ||
108 | } | 119 | } |
109 | dev->stats.rx_packets = sum.rx_packets; | 120 | |
110 | dev->stats.rx_bytes = sum.rx_bytes; | 121 | tot->rx_errors = dev->stats.rx_errors; |
111 | dev->stats.tx_packets = sum.tx_packets; | 122 | tot->tx_fifo_errors = dev->stats.tx_fifo_errors; |
112 | dev->stats.tx_bytes = sum.tx_bytes; | 123 | tot->tx_carrier_errors = dev->stats.tx_carrier_errors; |
113 | return &dev->stats; | 124 | tot->tx_dropped = dev->stats.tx_dropped; |
125 | tot->tx_aborted_errors = dev->stats.tx_aborted_errors; | ||
126 | tot->tx_errors = dev->stats.tx_errors; | ||
127 | |||
128 | return tot; | ||
114 | } | 129 | } |
130 | |||
115 | /* | 131 | /* |
116 | * Must be invoked with rcu_read_lock | 132 | * Must be invoked with rcu_read_lock |
117 | */ | 133 | */ |
@@ -1126,7 +1142,7 @@ static const struct net_device_ops ipip6_netdev_ops = { | |||
1126 | .ndo_start_xmit = ipip6_tunnel_xmit, | 1142 | .ndo_start_xmit = ipip6_tunnel_xmit, |
1127 | .ndo_do_ioctl = ipip6_tunnel_ioctl, | 1143 | .ndo_do_ioctl = ipip6_tunnel_ioctl, |
1128 | .ndo_change_mtu = ipip6_tunnel_change_mtu, | 1144 | .ndo_change_mtu = ipip6_tunnel_change_mtu, |
1129 | .ndo_get_stats = ipip6_get_stats, | 1145 | .ndo_get_stats64= ipip6_get_stats64, |
1130 | }; | 1146 | }; |
1131 | 1147 | ||
1132 | static void ipip6_dev_free(struct net_device *dev) | 1148 | static void ipip6_dev_free(struct net_device *dev) |