summary refs log tree commit diff
path: root/include/soc
diff options
context:
space:
mode:
authorVladimir Oltean <vladimir.oltean@nxp.com>2022-09-08 19:48:05 +0300
committerDavid S. Miller <davem@davemloft.net>2022-09-09 10:59:12 +0100
commit25027c8409b4541611d0060077607d8ca70740df (patch)
treed44a818d9880dac79d364bcf7c518ebcf52d8cf8 /include/soc
parent96980ff7c2caa5baef0c684e719547a53762e82c (diff)
downloadlinux-25027c8409b4541611d0060077607d8ca70740df.tar.gz
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 'include/soc')
-rw-r--r--include/soc/mscc/ocelot.h3
1 files changed, 3 insertions, 0 deletions
diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
index e85fb3b15524..bc6ca1be08f3 100644
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -729,6 +729,7 @@ struct ocelot_ops {
 			      struct flow_stats *stats);
 	void (*cut_through_fwd)(struct ocelot *ocelot);
 	void (*tas_clock_adjust)(struct ocelot *ocelot);
+	void (*update_stats)(struct ocelot *ocelot);
 };
 
 struct ocelot_vcap_policer {
@@ -766,6 +767,8 @@ struct ocelot_psfp_list {
 	struct list_head stream_list;
 	struct list_head sfi_list;
 	struct list_head sgi_list;
+	/* Serialize access to the lists */
+	struct mutex lock;
 };
 
 enum ocelot_sb {