diff options
author | Chris Metcalf <cmetcalf@tilera.com> | 2013-07-25 12:41:15 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-07-30 19:15:18 -0400 |
commit | d68e2d3bd229721ad3ea0f6bec7d3407cf8bf1f9 (patch) | |
tree | 32cc0665bd071b95661ba680732f6d2873846356 /drivers/net/ethernet/tile | |
parent | 60ff779c4abba37a31bd8624ef45026f7fb1b70c (diff) |
tile: handle 64-bit statistics in tilepro network driver
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/tile')
-rw-r--r-- | drivers/net/ethernet/tile/tilepro.c | 77 |
1 files changed, 54 insertions, 23 deletions
diff --git a/drivers/net/ethernet/tile/tilepro.c b/drivers/net/ethernet/tile/tilepro.c index 36435499814b..f66ac2000c00 100644 --- a/drivers/net/ethernet/tile/tilepro.c +++ b/drivers/net/ethernet/tile/tilepro.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/in6.h> | 31 | #include <linux/in6.h> |
32 | #include <linux/timer.h> | 32 | #include <linux/timer.h> |
33 | #include <linux/io.h> | 33 | #include <linux/io.h> |
34 | #include <linux/u64_stats_sync.h> | ||
34 | #include <asm/checksum.h> | 35 | #include <asm/checksum.h> |
35 | #include <asm/homecache.h> | 36 | #include <asm/homecache.h> |
36 | 37 | ||
@@ -156,10 +157,13 @@ struct tile_netio_queue { | |||
156 | * Statistics counters for a specific cpu and device. | 157 | * Statistics counters for a specific cpu and device. |
157 | */ | 158 | */ |
158 | struct tile_net_stats_t { | 159 | struct tile_net_stats_t { |
159 | u32 rx_packets; | 160 | struct u64_stats_sync syncp; |
160 | u32 rx_bytes; | 161 | u64 rx_packets; /* total packets received */ |
161 | u32 tx_packets; | 162 | u64 tx_packets; /* total packets transmitted */ |
162 | u32 tx_bytes; | 163 | u64 rx_bytes; /* total bytes received */ |
164 | u64 tx_bytes; /* total bytes transmitted */ | ||
165 | u64 rx_errors; /* packets truncated or marked bad by hw */ | ||
166 | u64 rx_dropped; /* packets not for us or intf not up */ | ||
163 | }; | 167 | }; |
164 | 168 | ||
165 | 169 | ||
@@ -218,8 +222,6 @@ struct tile_net_priv { | |||
218 | int network_cpus_count; | 222 | int network_cpus_count; |
219 | /* Credits per network cpu. */ | 223 | /* Credits per network cpu. */ |
220 | int network_cpus_credits; | 224 | int network_cpus_credits; |
221 | /* Network stats. */ | ||
222 | struct net_device_stats stats; | ||
223 | /* For NetIO bringup retries. */ | 225 | /* For NetIO bringup retries. */ |
224 | struct delayed_work retry_work; | 226 | struct delayed_work retry_work; |
225 | /* Quick access to per cpu data. */ | 227 | /* Quick access to per cpu data. */ |
@@ -847,6 +849,8 @@ static bool tile_net_poll_aux(struct tile_net_cpu *info, int index) | |||
847 | } | 849 | } |
848 | } | 850 | } |
849 | 851 | ||
852 | u64_stats_update_begin(&stats->syncp); | ||
853 | |||
850 | if (filter) { | 854 | if (filter) { |
851 | 855 | ||
852 | /* ISSUE: Update "drop" statistics? */ | 856 | /* ISSUE: Update "drop" statistics? */ |
@@ -881,6 +885,8 @@ static bool tile_net_poll_aux(struct tile_net_cpu *info, int index) | |||
881 | stats->rx_bytes += len; | 885 | stats->rx_bytes += len; |
882 | } | 886 | } |
883 | 887 | ||
888 | u64_stats_update_end(&stats->syncp); | ||
889 | |||
884 | /* ISSUE: It would be nice to defer this until the packet has */ | 890 | /* ISSUE: It would be nice to defer this until the packet has */ |
885 | /* actually been processed. */ | 891 | /* actually been processed. */ |
886 | tile_net_return_credit(info); | 892 | tile_net_return_credit(info); |
@@ -1907,8 +1913,10 @@ busy: | |||
1907 | kfree_skb(olds[i]); | 1913 | kfree_skb(olds[i]); |
1908 | 1914 | ||
1909 | /* Update stats. */ | 1915 | /* Update stats. */ |
1916 | u64_stats_update_begin(&stats->syncp); | ||
1910 | stats->tx_packets += num_segs; | 1917 | stats->tx_packets += num_segs; |
1911 | stats->tx_bytes += (num_segs * sh_len) + d_len; | 1918 | stats->tx_bytes += (num_segs * sh_len) + d_len; |
1919 | u64_stats_update_end(&stats->syncp); | ||
1912 | 1920 | ||
1913 | /* Make sure the egress timer is scheduled. */ | 1921 | /* Make sure the egress timer is scheduled. */ |
1914 | tile_net_schedule_egress_timer(info); | 1922 | tile_net_schedule_egress_timer(info); |
@@ -2089,8 +2097,10 @@ busy: | |||
2089 | kfree_skb(olds[i]); | 2097 | kfree_skb(olds[i]); |
2090 | 2098 | ||
2091 | /* HACK: Track "expanded" size for short packets (e.g. 42 < 60). */ | 2099 | /* HACK: Track "expanded" size for short packets (e.g. 42 < 60). */ |
2100 | u64_stats_update_begin(&stats->syncp); | ||
2092 | stats->tx_packets++; | 2101 | stats->tx_packets++; |
2093 | stats->tx_bytes += ((len >= ETH_ZLEN) ? len : ETH_ZLEN); | 2102 | stats->tx_bytes += ((len >= ETH_ZLEN) ? len : ETH_ZLEN); |
2103 | u64_stats_update_end(&stats->syncp); | ||
2094 | 2104 | ||
2095 | /* Make sure the egress timer is scheduled. */ | 2105 | /* Make sure the egress timer is scheduled. */ |
2096 | tile_net_schedule_egress_timer(info); | 2106 | tile_net_schedule_egress_timer(info); |
@@ -2127,30 +2137,51 @@ static int tile_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
2127 | * | 2137 | * |
2128 | * Returns the address of the device statistics structure. | 2138 | * Returns the address of the device statistics structure. |
2129 | */ | 2139 | */ |
2130 | static struct net_device_stats *tile_net_get_stats(struct net_device *dev) | 2140 | static struct rtnl_link_stats64 *tile_net_get_stats64(struct net_device *dev, |
2141 | struct rtnl_link_stats64 *stats) | ||
2131 | { | 2142 | { |
2132 | struct tile_net_priv *priv = netdev_priv(dev); | 2143 | struct tile_net_priv *priv = netdev_priv(dev); |
2133 | u32 rx_packets = 0; | 2144 | u64 rx_packets = 0, tx_packets = 0; |
2134 | u32 tx_packets = 0; | 2145 | u64 rx_bytes = 0, tx_bytes = 0; |
2135 | u32 rx_bytes = 0; | 2146 | u64 rx_errors = 0, rx_dropped = 0; |
2136 | u32 tx_bytes = 0; | ||
2137 | int i; | 2147 | int i; |
2138 | 2148 | ||
2139 | for_each_online_cpu(i) { | 2149 | for_each_online_cpu(i) { |
2140 | if (priv->cpu[i]) { | 2150 | struct tile_net_stats_t *cpu_stats; |
2141 | rx_packets += priv->cpu[i]->stats.rx_packets; | 2151 | u64 trx_packets, ttx_packets, trx_bytes, ttx_bytes; |
2142 | rx_bytes += priv->cpu[i]->stats.rx_bytes; | 2152 | u64 trx_errors, trx_dropped; |
2143 | tx_packets += priv->cpu[i]->stats.tx_packets; | 2153 | unsigned int start; |
2144 | tx_bytes += priv->cpu[i]->stats.tx_bytes; | 2154 | |
2145 | } | 2155 | if (priv->cpu[i] == NULL) |
2156 | continue; | ||
2157 | cpu_stats = &priv->cpu[i]->stats; | ||
2158 | |||
2159 | do { | ||
2160 | start = u64_stats_fetch_begin_bh(&cpu_stats->syncp); | ||
2161 | trx_packets = cpu_stats->rx_packets; | ||
2162 | ttx_packets = cpu_stats->tx_packets; | ||
2163 | trx_bytes = cpu_stats->rx_bytes; | ||
2164 | ttx_bytes = cpu_stats->tx_bytes; | ||
2165 | trx_errors = cpu_stats->rx_errors; | ||
2166 | trx_dropped = cpu_stats->rx_dropped; | ||
2167 | } while (u64_stats_fetch_retry_bh(&cpu_stats->syncp, start)); | ||
2168 | |||
2169 | rx_packets += trx_packets; | ||
2170 | tx_packets += ttx_packets; | ||
2171 | rx_bytes += trx_bytes; | ||
2172 | tx_bytes += ttx_bytes; | ||
2173 | rx_errors += trx_errors; | ||
2174 | rx_dropped += trx_dropped; | ||
2146 | } | 2175 | } |
2147 | 2176 | ||
2148 | priv->stats.rx_packets = rx_packets; | 2177 | stats->rx_packets = rx_packets; |
2149 | priv->stats.rx_bytes = rx_bytes; | 2178 | stats->tx_packets = tx_packets; |
2150 | priv->stats.tx_packets = tx_packets; | 2179 | stats->rx_bytes = rx_bytes; |
2151 | priv->stats.tx_bytes = tx_bytes; | 2180 | stats->tx_bytes = tx_bytes; |
2181 | stats->rx_errors = rx_errors; | ||
2182 | stats->rx_dropped = rx_dropped; | ||
2152 | 2183 | ||
2153 | return &priv->stats; | 2184 | return stats; |
2154 | } | 2185 | } |
2155 | 2186 | ||
2156 | 2187 | ||
@@ -2287,7 +2318,7 @@ static const struct net_device_ops tile_net_ops = { | |||
2287 | .ndo_stop = tile_net_stop, | 2318 | .ndo_stop = tile_net_stop, |
2288 | .ndo_start_xmit = tile_net_tx, | 2319 | .ndo_start_xmit = tile_net_tx, |
2289 | .ndo_do_ioctl = tile_net_ioctl, | 2320 | .ndo_do_ioctl = tile_net_ioctl, |
2290 | .ndo_get_stats = tile_net_get_stats, | 2321 | .ndo_get_stats64 = tile_net_get_stats64, |
2291 | .ndo_change_mtu = tile_net_change_mtu, | 2322 | .ndo_change_mtu = tile_net_change_mtu, |
2292 | .ndo_tx_timeout = tile_net_tx_timeout, | 2323 | .ndo_tx_timeout = tile_net_tx_timeout, |
2293 | .ndo_set_mac_address = tile_net_set_mac_address, | 2324 | .ndo_set_mac_address = tile_net_set_mac_address, |