mlxsw: spectrum: Wipe xstats.backlog of down ports
commitca7609ff36upstream. Per-port counter cache used by Qdiscs is updated periodically, unless the port is down. The fact that the cache is not updated for down ports is no problem for most counters, which are relative in nature. However, backlog is absolute in nature, and if there is a non-zero value in the cache around the time that the port goes down, that value just stays there. This value then leaks to offloaded Qdiscs that report non-zero backlog even if there (obviously) is no traffic. The HW does not keep backlog of a downed port, so do likewise: as the port goes down, wipe the backlog value from xstats. Fixes:075ab8adaf("mlxsw: spectrum: Collect tclass related stats periodically") Signed-off-by: Petr Machata <petrm@mellanox.com> Acked-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
fd0d69bb32
commit
565389fc18
1 changed files with 13 additions and 0 deletions
|
|
@ -1061,6 +1061,9 @@ static void update_stats_cache(struct work_struct *work)
|
|||
periodic_hw_stats.update_dw.work);
|
||||
|
||||
if (!netif_carrier_ok(mlxsw_sp_port->dev))
|
||||
/* Note: mlxsw_sp_port_down_wipe_counters() clears the cache as
|
||||
* necessary when port goes down.
|
||||
*/
|
||||
goto out;
|
||||
|
||||
mlxsw_sp_port_get_hw_stats(mlxsw_sp_port->dev,
|
||||
|
|
@ -3309,6 +3312,15 @@ static int mlxsw_sp_port_unsplit(struct mlxsw_core *mlxsw_core, u8 local_port,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mlxsw_sp_port_down_wipe_counters(struct mlxsw_sp_port *mlxsw_sp_port)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < TC_MAX_QUEUE; i++)
|
||||
mlxsw_sp_port->periodic_hw_stats.xstats.backlog[i] = 0;
|
||||
}
|
||||
|
||||
static void mlxsw_sp_pude_event_func(const struct mlxsw_reg_info *reg,
|
||||
char *pude_pl, void *priv)
|
||||
{
|
||||
|
|
@ -3329,6 +3341,7 @@ static void mlxsw_sp_pude_event_func(const struct mlxsw_reg_info *reg,
|
|||
} else {
|
||||
netdev_info(mlxsw_sp_port->dev, "link down\n");
|
||||
netif_carrier_off(mlxsw_sp_port->dev);
|
||||
mlxsw_sp_port_down_wipe_counters(mlxsw_sp_port);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue