diff options
author | Vladimir Oltean <vladimir.oltean@nxp.com> | 2022-09-08 19:48:05 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2022-09-09 12:59:12 +0300 |
commit | 25027c8409b4541611d0060077607d8ca70740df (patch) | |
tree | d44a818d9880dac79d364bcf7c518ebcf52d8cf8 /drivers/net/ethernet/mscc/ocelot.c | |
parent | 96980ff7c2caa5baef0c684e719547a53762e82c (diff) | |
download | linux-25027c8409b4541611d0060077607d8ca70740df.tar.xz |
net: dsa: felix: check the 32-bit PSFP stats against overflow
The Felix PSFP counters suffer from the same problem as the ocelot
ndo_get_stats64 ones - they are 32-bit, so they can easily overflow and
this can easily go undetected.
Add a custom hook in ocelot_check_stats_work() through which driver
specific actions can be taken, and update the stats for the existing
PSFP filters from that hook.
Previously, vsc9959_psfp_filter_add() and vsc9959_psfp_filter_del() were
serialized with respect to each other via rtnl_lock(). However, with the
new entry point into &psfp->sfi_list coming from the periodic worker, we
now need an explicit mutex to serialize access to these lists.
We used to keep a struct felix_stream_filter_counters on stack, through
which vsc9959_psfp_stats_get() - a FLOW_CLS_STATS callback - would
retrieve data from vsc9959_psfp_counters_get(). We need to become
smarter about that in 3 ways:
- we need to keep a persistent set of counters for each stream instead
of keeping them on stack
- we need to promote those counters from u32 to u64, and create a
procedure that properly keeps 64-bit counters. Since we clear the
hardware counters anyway, and we poll every 2 seconds, a simple
increment of a u64 counter with a u32 value will perfectly do the job.
- FLOW_CLS_STATS also expect incremental counters, so we also need to
zeroize our u64 counters every time sch_flower calls us
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/mscc/ocelot.c')
-rw-r--r-- | drivers/net/ethernet/mscc/ocelot.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c index a677a18239c5..8e063322625a 100644 --- a/drivers/net/ethernet/mscc/ocelot.c +++ b/drivers/net/ethernet/mscc/ocelot.c @@ -1934,6 +1934,9 @@ static void ocelot_check_stats_work(struct work_struct *work) spin_unlock(&ocelot->stats_lock); } + if (!err && ocelot->ops->update_stats) + ocelot->ops->update_stats(ocelot); + mutex_unlock(&ocelot->stat_view_lock); if (err) |