Skip to content

Commit 861fb82

Browse files
Nogah Frankeldavem330
authored andcommitted
mlxsw: spectrum: Support RED xstats
Add support for ndo_setup_tc with enum tc_setup_type value of TC_SETUP_RED_XSTATS. This call returns the RED qdisc xstats from the cache if the handle ID that is asked for matching the root qdisc ID and fails otherwise. Signed-off-by: Nogah Frankel <nogahf@mellanox.com> Signed-off-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 075ab8a commit 861fb82

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

drivers/net/ethernet/mellanox/mlxsw/spectrum.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include <linux/notifier.h>
4949
#include <net/psample.h>
5050
#include <net/pkt_cls.h>
51+
#include <net/red.h>
5152

5253
#include "port.h"
5354
#include "core.h"
@@ -211,6 +212,14 @@ enum mlxsw_sp_qdisc_type {
211212
struct mlxsw_sp_qdisc {
212213
u32 handle;
213214
enum mlxsw_sp_qdisc_type type;
215+
struct red_stats xstats_base;
216+
union {
217+
struct {
218+
u64 tail_drop_base;
219+
u64 ecn_base;
220+
u64 wred_drop_base;
221+
} red;
222+
} xstats;
214223
};
215224

216225
/* No need an internal lock; At worse - miss a single periodic iteration */

drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <linux/errno.h>
3737
#include <linux/netdevice.h>
3838
#include <net/pkt_cls.h>
39+
#include <net/red.h>
3940

4041
#include "spectrum.h"
4142
#include "reg.h"
@@ -77,6 +78,27 @@ mlxsw_sp_tclass_congestion_disable(struct mlxsw_sp_port *mlxsw_sp_port,
7778
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(cwtpm), cwtpm_cmd);
7879
}
7980

81+
static void
82+
mlxsw_sp_setup_tc_qdisc_clean_stats(struct mlxsw_sp_port *mlxsw_sp_port,
83+
struct mlxsw_sp_qdisc *mlxsw_sp_qdisc,
84+
int tclass_num)
85+
{
86+
struct red_stats *xstats_base = &mlxsw_sp_qdisc->xstats_base;
87+
struct mlxsw_sp_port_xstats *xstats;
88+
89+
xstats = &mlxsw_sp_port->periodic_hw_stats.xstats;
90+
91+
switch (mlxsw_sp_qdisc->type) {
92+
case MLXSW_SP_QDISC_RED:
93+
xstats_base->prob_mark = xstats->ecn;
94+
xstats_base->prob_drop = xstats->wred_drop[tclass_num];
95+
xstats_base->pdrop = xstats->tail_drop[tclass_num];
96+
break;
97+
default:
98+
break;
99+
}
100+
}
101+
80102
static int
81103
mlxsw_sp_qdisc_red_destroy(struct mlxsw_sp_port *mlxsw_sp_port, u32 handle,
82104
struct mlxsw_sp_qdisc *mlxsw_sp_qdisc,
@@ -135,6 +157,11 @@ mlxsw_sp_qdisc_red_replace(struct mlxsw_sp_port *mlxsw_sp_port, u32 handle,
135157
goto err_config;
136158

137159
mlxsw_sp_qdisc->type = MLXSW_SP_QDISC_RED;
160+
if (mlxsw_sp_qdisc->handle != handle)
161+
mlxsw_sp_setup_tc_qdisc_clean_stats(mlxsw_sp_port,
162+
mlxsw_sp_qdisc,
163+
tclass_num);
164+
138165
mlxsw_sp_qdisc->handle = handle;
139166
return 0;
140167

@@ -146,6 +173,26 @@ mlxsw_sp_qdisc_red_replace(struct mlxsw_sp_port *mlxsw_sp_port, u32 handle,
146173
return err;
147174
}
148175

176+
static int
177+
mlxsw_sp_qdisc_get_red_xstats(struct mlxsw_sp_port *mlxsw_sp_port, u32 handle,
178+
struct mlxsw_sp_qdisc *mlxsw_sp_qdisc,
179+
int tclass_num, struct red_stats *res)
180+
{
181+
struct red_stats *xstats_base = &mlxsw_sp_qdisc->xstats_base;
182+
struct mlxsw_sp_port_xstats *xstats;
183+
184+
if (mlxsw_sp_qdisc->handle != handle ||
185+
mlxsw_sp_qdisc->type != MLXSW_SP_QDISC_RED)
186+
return -EOPNOTSUPP;
187+
188+
xstats = &mlxsw_sp_port->periodic_hw_stats.xstats;
189+
190+
res->prob_drop = xstats->wred_drop[tclass_num] - xstats_base->prob_drop;
191+
res->prob_mark = xstats->ecn - xstats_base->prob_mark;
192+
res->pdrop = xstats->tail_drop[tclass_num] - xstats_base->pdrop;
193+
return 0;
194+
}
195+
149196
#define MLXSW_SP_PORT_DEFAULT_TCLASS 0
150197

151198
int mlxsw_sp_setup_tc_red(struct mlxsw_sp_port *mlxsw_sp_port,
@@ -168,6 +215,10 @@ int mlxsw_sp_setup_tc_red(struct mlxsw_sp_port *mlxsw_sp_port,
168215
case TC_RED_DESTROY:
169216
return mlxsw_sp_qdisc_red_destroy(mlxsw_sp_port, p->handle,
170217
mlxsw_sp_qdisc, tclass_num);
218+
case TC_RED_XSTATS:
219+
return mlxsw_sp_qdisc_get_red_xstats(mlxsw_sp_port, p->handle,
220+
mlxsw_sp_qdisc, tclass_num,
221+
p->xstats);
171222
default:
172223
return -EOPNOTSUPP;
173224
}

0 commit comments

Comments
 (0)