History

net: dsa: felix: fix race between reading PSFP stats and port stats

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.

Vladimir Oltean committed 4 years ago

Commit 58bf4db1 parent 839b92f1 file · +4 −0Browse files

Unified · Split

drivers/net/dsa/ocelot/felix_vsc9959.c+4−0
@@ -1886,6 +1886,8 @@ static void vsc9959_psfp_sgi_table_del(struct ocelot *ocelot, · 1885 unmodified lines
1886static void vsc9959_psfp_counters_get(struct ocelot *ocelot, u32 index,1886static void vsc9959_psfp_counters_get(struct ocelot *ocelot, u32 index,
1887 struct felix_stream_filter_counters *counters)1887 struct felix_stream_filter_counters *counters)
1888{1888{
1889 mutex_lock(&ocelot->stats_lock);
1890
1889 ocelot_rmw(ocelot, SYS_STAT_CFG_STAT_VIEW(index),1891 ocelot_rmw(ocelot, SYS_STAT_CFG_STAT_VIEW(index),
1890 SYS_STAT_CFG_STAT_VIEW_M,1892 SYS_STAT_CFG_STAT_VIEW_M,
1891 SYS_STAT_CFG);1893 SYS_STAT_CFG);
@@ -1900,6 +1902,8 @@ static void vsc9959_psfp_counters_get(struct ocelot *ocelot, u32 index, · 8 unmodified lines
1900 SYS_STAT_CFG_STAT_VIEW(index) |1902 SYS_STAT_CFG_STAT_VIEW(index) |
1901 SYS_STAT_CFG_STAT_CLEAR_SHOT(0x10),1903 SYS_STAT_CFG_STAT_CLEAR_SHOT(0x10),
1902 SYS_STAT_CFG);1904 SYS_STAT_CFG);
1905
1906 mutex_unlock(&ocelot->stats_lock);
1903}1907}
1904 1908
1905static int vsc9959_psfp_filter_add(struct ocelot *ocelot, int port,1909static int vsc9959_psfp_filter_add(struct ocelot *ocelot, int port,