Both PSFP stats and the port stats read by ocelot_check_stats_work() are indirectly read through the same mechanism - write to STAT_CFG:STAT_VIEW, read from SYS:STAT:CNT[n]. It's just that for port stats, we write STAT_VIEW with the index of the port, and for PSFP stats, we write STAT_VIEW with the filter index. So if we allow them to run concurrently, ocelot_check_stats_work() may change the view from vsc9959_psfp_counters_get(), and vice versa.
Unified · Split
| @@ -1886,6 +1886,8 @@ static void vsc9959_psfp_sgi_table_del(struct ocelot *ocelot, · 1885 unmodified lines | ||
| 1886 | 1886 | static void vsc9959_psfp_counters_get(struct ocelot *ocelot, u32 index, |
| 1887 | 1887 | struct felix_stream_filter_counters *counters) |
| 1888 | 1888 | { |
| 1889 | + mutex_lock(&ocelot->stats_lock); | |
| 1890 | + | |
| 1889 | 1891 | ocelot_rmw(ocelot, SYS_STAT_CFG_STAT_VIEW(index), |
| 1890 | 1892 | SYS_STAT_CFG_STAT_VIEW_M, |
| 1891 | 1893 | SYS_STAT_CFG); |
| @@ -1900,6 +1902,8 @@ static void vsc9959_psfp_counters_get(struct ocelot *ocelot, u32 index, · 8 unmodified lines | ||
| 1900 | 1902 | SYS_STAT_CFG_STAT_VIEW(index) | |
| 1901 | 1903 | SYS_STAT_CFG_STAT_CLEAR_SHOT(0x10), |
| 1902 | 1904 | SYS_STAT_CFG); |
| 1905 | + | |
| 1906 | + mutex_unlock(&ocelot->stats_lock); | |
| 1903 | 1907 | } |
| 1904 | 1908 | |
| 1905 | 1909 | static int vsc9959_psfp_filter_add(struct ocelot *ocelot, int port, |