提交 075ab8ad 编写于 作者: N Nogah Frankel 提交者: David S. Miller

mlxsw: spectrum: Collect tclass related stats periodically

Add more statistics to be collected from the HW periodically. These stats
are tclass based (beside ECN marked packet, that exist only port based).
They are needed to expose RED qdisc stats and xstats correctly.
Signed-off-by: NNogah Frankel <nogahf@mellanox.com>
Signed-off-by: NJiri Pirko <jiri@mellanox.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 0afc1221
...@@ -1324,6 +1324,38 @@ static int mlxsw_sp_port_get_hw_stats(struct net_device *dev, ...@@ -1324,6 +1324,38 @@ static int mlxsw_sp_port_get_hw_stats(struct net_device *dev,
return err; return err;
} }
static void
mlxsw_sp_port_get_hw_xstats(struct net_device *dev,
struct mlxsw_sp_port_xstats *xstats)
{
char ppcnt_pl[MLXSW_REG_PPCNT_LEN];
int err, i;
err = mlxsw_sp_port_get_stats_raw(dev, MLXSW_REG_PPCNT_EXT_CNT, 0,
ppcnt_pl);
if (!err)
xstats->ecn = mlxsw_reg_ppcnt_ecn_marked_get(ppcnt_pl);
for (i = 0; i < TC_MAX_QUEUE; i++) {
err = mlxsw_sp_port_get_stats_raw(dev,
MLXSW_REG_PPCNT_TC_CONG_TC,
i, ppcnt_pl);
if (!err)
xstats->wred_drop[i] =
mlxsw_reg_ppcnt_wred_discard_get(ppcnt_pl);
err = mlxsw_sp_port_get_stats_raw(dev, MLXSW_REG_PPCNT_TC_CNT,
i, ppcnt_pl);
if (err)
continue;
xstats->backlog[i] =
mlxsw_reg_ppcnt_tc_transmit_queue_get(ppcnt_pl);
xstats->tail_drop[i] =
mlxsw_reg_ppcnt_tc_no_buffer_discard_uc_get(ppcnt_pl);
}
}
static void update_stats_cache(struct work_struct *work) static void update_stats_cache(struct work_struct *work)
{ {
struct mlxsw_sp_port *mlxsw_sp_port = struct mlxsw_sp_port *mlxsw_sp_port =
...@@ -1335,6 +1367,8 @@ static void update_stats_cache(struct work_struct *work) ...@@ -1335,6 +1367,8 @@ static void update_stats_cache(struct work_struct *work)
mlxsw_sp_port_get_hw_stats(mlxsw_sp_port->dev, mlxsw_sp_port_get_hw_stats(mlxsw_sp_port->dev,
&mlxsw_sp_port->periodic_hw_stats.stats); &mlxsw_sp_port->periodic_hw_stats.stats);
mlxsw_sp_port_get_hw_xstats(mlxsw_sp_port->dev,
&mlxsw_sp_port->periodic_hw_stats.xstats);
out: out:
mlxsw_core_schedule_dw(&mlxsw_sp_port->periodic_hw_stats.update_dw, mlxsw_core_schedule_dw(&mlxsw_sp_port->periodic_hw_stats.update_dw,
......
...@@ -213,6 +213,14 @@ struct mlxsw_sp_qdisc { ...@@ -213,6 +213,14 @@ struct mlxsw_sp_qdisc {
enum mlxsw_sp_qdisc_type type; enum mlxsw_sp_qdisc_type type;
}; };
/* No need an internal lock; At worse - miss a single periodic iteration */
struct mlxsw_sp_port_xstats {
u64 ecn;
u64 wred_drop[TC_MAX_QUEUE];
u64 tail_drop[TC_MAX_QUEUE];
u64 backlog[TC_MAX_QUEUE];
};
struct mlxsw_sp_port { struct mlxsw_sp_port {
struct net_device *dev; struct net_device *dev;
struct mlxsw_sp_port_pcpu_stats __percpu *pcpu_stats; struct mlxsw_sp_port_pcpu_stats __percpu *pcpu_stats;
...@@ -242,6 +250,7 @@ struct mlxsw_sp_port { ...@@ -242,6 +250,7 @@ struct mlxsw_sp_port {
struct { struct {
#define MLXSW_HW_STATS_UPDATE_TIME HZ #define MLXSW_HW_STATS_UPDATE_TIME HZ
struct rtnl_link_stats64 stats; struct rtnl_link_stats64 stats;
struct mlxsw_sp_port_xstats xstats;
struct delayed_work update_dw; struct delayed_work update_dw;
} periodic_hw_stats; } periodic_hw_stats;
struct mlxsw_sp_port_sample *sample; struct mlxsw_sp_port_sample *sample;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册