net: mscc: ocelot: report ndo_get_stats64 from the wraparound-resistant ocelot->stats
Rather than reading the stats64 counters directly from the 32-bit
hardware, it's better to rely on the output produced by the periodic
ocelot_port_update_stats().
It would be even better to call ocelot_port_update_stats() right from
ocelot_get_stats64() to make sure we report the current values rather
than the ones from 2 seconds ago. But we need to export
ocelot_port_update_stats() from the switch lib towards the switchdev
driver for that, and future work will largely undo that.
There are more ocelot-based drivers waiting to be introduced, an example
of which is the SPI-controlled VSC7512. In that driver's case, it will
be impossible to call ocelot_port_update_stats() from ndo_get_stats64
context, since the latter is atomic, and reading the stats over SPI is
sleepable. So the compromise taken here, which will also hold going
forward, is to report 64-bit counters to stats64, which are not 100% up
to date.
Fixes: a556c76adc
("net: mscc: Add initial Ocelot switch support")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
d4c3676507
commit
e780e3193e
|
@ -725,41 +725,40 @@ static void ocelot_get_stats64(struct net_device *dev,
|
|||
struct ocelot_port_private *priv = netdev_priv(dev);
|
||||
struct ocelot *ocelot = priv->port.ocelot;
|
||||
int port = priv->port.index;
|
||||
u64 *s;
|
||||
|
||||
spin_lock(&ocelot->stats_lock);
|
||||
|
||||
/* Configure the port to read the stats from */
|
||||
ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(port),
|
||||
SYS_STAT_CFG);
|
||||
s = &ocelot->stats[port * OCELOT_NUM_STATS];
|
||||
|
||||
/* Get Rx stats */
|
||||
stats->rx_bytes = ocelot_read(ocelot, SYS_COUNT_RX_OCTETS);
|
||||
stats->rx_packets = ocelot_read(ocelot, SYS_COUNT_RX_SHORTS) +
|
||||
ocelot_read(ocelot, SYS_COUNT_RX_FRAGMENTS) +
|
||||
ocelot_read(ocelot, SYS_COUNT_RX_JABBERS) +
|
||||
ocelot_read(ocelot, SYS_COUNT_RX_LONGS) +
|
||||
ocelot_read(ocelot, SYS_COUNT_RX_64) +
|
||||
ocelot_read(ocelot, SYS_COUNT_RX_65_127) +
|
||||
ocelot_read(ocelot, SYS_COUNT_RX_128_255) +
|
||||
ocelot_read(ocelot, SYS_COUNT_RX_256_511) +
|
||||
ocelot_read(ocelot, SYS_COUNT_RX_512_1023) +
|
||||
ocelot_read(ocelot, SYS_COUNT_RX_1024_1526) +
|
||||
ocelot_read(ocelot, SYS_COUNT_RX_1527_MAX);
|
||||
stats->multicast = ocelot_read(ocelot, SYS_COUNT_RX_MULTICAST);
|
||||
stats->rx_bytes = s[OCELOT_STAT_RX_OCTETS];
|
||||
stats->rx_packets = s[OCELOT_STAT_RX_SHORTS] +
|
||||
s[OCELOT_STAT_RX_FRAGMENTS] +
|
||||
s[OCELOT_STAT_RX_JABBERS] +
|
||||
s[OCELOT_STAT_RX_LONGS] +
|
||||
s[OCELOT_STAT_RX_64] +
|
||||
s[OCELOT_STAT_RX_65_127] +
|
||||
s[OCELOT_STAT_RX_128_255] +
|
||||
s[OCELOT_STAT_RX_256_511] +
|
||||
s[OCELOT_STAT_RX_512_1023] +
|
||||
s[OCELOT_STAT_RX_1024_1526] +
|
||||
s[OCELOT_STAT_RX_1527_MAX];
|
||||
stats->multicast = s[OCELOT_STAT_RX_MULTICAST];
|
||||
stats->rx_dropped = dev->stats.rx_dropped;
|
||||
|
||||
/* Get Tx stats */
|
||||
stats->tx_bytes = ocelot_read(ocelot, SYS_COUNT_TX_OCTETS);
|
||||
stats->tx_packets = ocelot_read(ocelot, SYS_COUNT_TX_64) +
|
||||
ocelot_read(ocelot, SYS_COUNT_TX_65_127) +
|
||||
ocelot_read(ocelot, SYS_COUNT_TX_128_255) +
|
||||
ocelot_read(ocelot, SYS_COUNT_TX_256_511) +
|
||||
ocelot_read(ocelot, SYS_COUNT_TX_512_1023) +
|
||||
ocelot_read(ocelot, SYS_COUNT_TX_1024_1526) +
|
||||
ocelot_read(ocelot, SYS_COUNT_TX_1527_MAX);
|
||||
stats->tx_dropped = ocelot_read(ocelot, SYS_COUNT_TX_DROPS) +
|
||||
ocelot_read(ocelot, SYS_COUNT_TX_AGING);
|
||||
stats->collisions = ocelot_read(ocelot, SYS_COUNT_TX_COLLISION);
|
||||
stats->tx_bytes = s[OCELOT_STAT_TX_OCTETS];
|
||||
stats->tx_packets = s[OCELOT_STAT_TX_64] +
|
||||
s[OCELOT_STAT_TX_65_127] +
|
||||
s[OCELOT_STAT_TX_128_255] +
|
||||
s[OCELOT_STAT_TX_256_511] +
|
||||
s[OCELOT_STAT_TX_512_1023] +
|
||||
s[OCELOT_STAT_TX_1024_1526] +
|
||||
s[OCELOT_STAT_TX_1527_MAX];
|
||||
stats->tx_dropped = s[OCELOT_STAT_TX_DROPS] +
|
||||
s[OCELOT_STAT_TX_AGED];
|
||||
stats->collisions = s[OCELOT_STAT_TX_COLLISION];
|
||||
|
||||
spin_unlock(&ocelot->stats_lock);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue