mlxsw: spectrum_qdisc: Introduce struct mlxsw_sp_qdisc_state
In order to have a tidy structure where to put information related to Qdisc offloads, introduce a new structure. Move there the two existing pieces of data: root_qdisc and tclass_qdiscs. Embed them directly, because there's no reason to go through pointer anymore. Convert users, update init/fini functions. Signed-off-by: Petr Machata <petrm@mellanox.com> Signed-off-by: Ido Schimmel <idosch@mellanox.com> Acked-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
aaca940807
Коммит
ee88450d25
|
@ -139,6 +139,7 @@ struct mlxsw_sp_port_type_speed_ops;
|
||||||
struct mlxsw_sp_ptp_state;
|
struct mlxsw_sp_ptp_state;
|
||||||
struct mlxsw_sp_ptp_ops;
|
struct mlxsw_sp_ptp_ops;
|
||||||
struct mlxsw_sp_span_ops;
|
struct mlxsw_sp_span_ops;
|
||||||
|
struct mlxsw_sp_qdisc_state;
|
||||||
|
|
||||||
struct mlxsw_sp_port_mapping {
|
struct mlxsw_sp_port_mapping {
|
||||||
u8 module;
|
u8 module;
|
||||||
|
@ -276,8 +277,7 @@ struct mlxsw_sp_port {
|
||||||
struct mlxsw_sp_port_sample *sample;
|
struct mlxsw_sp_port_sample *sample;
|
||||||
struct list_head vlans_list;
|
struct list_head vlans_list;
|
||||||
struct mlxsw_sp_port_vlan *default_vlan;
|
struct mlxsw_sp_port_vlan *default_vlan;
|
||||||
struct mlxsw_sp_qdisc *root_qdisc;
|
struct mlxsw_sp_qdisc_state *qdisc;
|
||||||
struct mlxsw_sp_qdisc *tclass_qdiscs;
|
|
||||||
unsigned acl_rule_count;
|
unsigned acl_rule_count;
|
||||||
struct mlxsw_sp_acl_block *ing_acl_block;
|
struct mlxsw_sp_acl_block *ing_acl_block;
|
||||||
struct mlxsw_sp_acl_block *eg_acl_block;
|
struct mlxsw_sp_acl_block *eg_acl_block;
|
||||||
|
|
|
@ -22,6 +22,8 @@ enum mlxsw_sp_qdisc_type {
|
||||||
MLXSW_SP_QDISC_TBF,
|
MLXSW_SP_QDISC_TBF,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mlxsw_sp_qdisc;
|
||||||
|
|
||||||
struct mlxsw_sp_qdisc_ops {
|
struct mlxsw_sp_qdisc_ops {
|
||||||
enum mlxsw_sp_qdisc_type type;
|
enum mlxsw_sp_qdisc_type type;
|
||||||
int (*check_params)(struct mlxsw_sp_port *mlxsw_sp_port,
|
int (*check_params)(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||||
|
@ -64,6 +66,11 @@ struct mlxsw_sp_qdisc {
|
||||||
struct mlxsw_sp_qdisc_ops *ops;
|
struct mlxsw_sp_qdisc_ops *ops;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mlxsw_sp_qdisc_state {
|
||||||
|
struct mlxsw_sp_qdisc root_qdisc;
|
||||||
|
struct mlxsw_sp_qdisc tclass_qdiscs[IEEE_8021QAZ_MAX_TCS];
|
||||||
|
};
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
mlxsw_sp_qdisc_compare(struct mlxsw_sp_qdisc *mlxsw_sp_qdisc, u32 handle,
|
mlxsw_sp_qdisc_compare(struct mlxsw_sp_qdisc *mlxsw_sp_qdisc, u32 handle,
|
||||||
enum mlxsw_sp_qdisc_type type)
|
enum mlxsw_sp_qdisc_type type)
|
||||||
|
@ -77,36 +84,38 @@ static struct mlxsw_sp_qdisc *
|
||||||
mlxsw_sp_qdisc_find(struct mlxsw_sp_port *mlxsw_sp_port, u32 parent,
|
mlxsw_sp_qdisc_find(struct mlxsw_sp_port *mlxsw_sp_port, u32 parent,
|
||||||
bool root_only)
|
bool root_only)
|
||||||
{
|
{
|
||||||
|
struct mlxsw_sp_qdisc_state *qdisc_state = mlxsw_sp_port->qdisc;
|
||||||
int tclass, child_index;
|
int tclass, child_index;
|
||||||
|
|
||||||
if (parent == TC_H_ROOT)
|
if (parent == TC_H_ROOT)
|
||||||
return mlxsw_sp_port->root_qdisc;
|
return &qdisc_state->root_qdisc;
|
||||||
|
|
||||||
if (root_only || !mlxsw_sp_port->root_qdisc ||
|
if (root_only || !qdisc_state ||
|
||||||
!mlxsw_sp_port->root_qdisc->ops ||
|
!qdisc_state->root_qdisc.ops ||
|
||||||
TC_H_MAJ(parent) != mlxsw_sp_port->root_qdisc->handle ||
|
TC_H_MAJ(parent) != qdisc_state->root_qdisc.handle ||
|
||||||
TC_H_MIN(parent) > IEEE_8021QAZ_MAX_TCS)
|
TC_H_MIN(parent) > IEEE_8021QAZ_MAX_TCS)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
child_index = TC_H_MIN(parent);
|
child_index = TC_H_MIN(parent);
|
||||||
tclass = MLXSW_SP_PRIO_CHILD_TO_TCLASS(child_index);
|
tclass = MLXSW_SP_PRIO_CHILD_TO_TCLASS(child_index);
|
||||||
return &mlxsw_sp_port->tclass_qdiscs[tclass];
|
return &qdisc_state->tclass_qdiscs[tclass];
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct mlxsw_sp_qdisc *
|
static struct mlxsw_sp_qdisc *
|
||||||
mlxsw_sp_qdisc_find_by_handle(struct mlxsw_sp_port *mlxsw_sp_port, u32 handle)
|
mlxsw_sp_qdisc_find_by_handle(struct mlxsw_sp_port *mlxsw_sp_port, u32 handle)
|
||||||
{
|
{
|
||||||
|
struct mlxsw_sp_qdisc_state *qdisc_state = mlxsw_sp_port->qdisc;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (mlxsw_sp_port->root_qdisc->handle == handle)
|
if (qdisc_state->root_qdisc.handle == handle)
|
||||||
return mlxsw_sp_port->root_qdisc;
|
return &qdisc_state->root_qdisc;
|
||||||
|
|
||||||
if (mlxsw_sp_port->root_qdisc->handle == TC_H_UNSPEC)
|
if (qdisc_state->root_qdisc.handle == TC_H_UNSPEC)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
|
for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
|
||||||
if (mlxsw_sp_port->tclass_qdiscs[i].handle == handle)
|
if (qdisc_state->tclass_qdiscs[i].handle == handle)
|
||||||
return &mlxsw_sp_port->tclass_qdiscs[i];
|
return &qdisc_state->tclass_qdiscs[i];
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -360,7 +369,8 @@ static int
|
||||||
mlxsw_sp_qdisc_red_destroy(struct mlxsw_sp_port *mlxsw_sp_port,
|
mlxsw_sp_qdisc_red_destroy(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||||
struct mlxsw_sp_qdisc *mlxsw_sp_qdisc)
|
struct mlxsw_sp_qdisc *mlxsw_sp_qdisc)
|
||||||
{
|
{
|
||||||
struct mlxsw_sp_qdisc *root_qdisc = mlxsw_sp_port->root_qdisc;
|
struct mlxsw_sp_qdisc_state *qdisc_state = mlxsw_sp_port->qdisc;
|
||||||
|
struct mlxsw_sp_qdisc *root_qdisc = &qdisc_state->root_qdisc;
|
||||||
|
|
||||||
if (root_qdisc != mlxsw_sp_qdisc)
|
if (root_qdisc != mlxsw_sp_qdisc)
|
||||||
root_qdisc->stats_base.backlog -=
|
root_qdisc->stats_base.backlog -=
|
||||||
|
@ -559,7 +569,8 @@ static int
|
||||||
mlxsw_sp_qdisc_tbf_destroy(struct mlxsw_sp_port *mlxsw_sp_port,
|
mlxsw_sp_qdisc_tbf_destroy(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||||
struct mlxsw_sp_qdisc *mlxsw_sp_qdisc)
|
struct mlxsw_sp_qdisc *mlxsw_sp_qdisc)
|
||||||
{
|
{
|
||||||
struct mlxsw_sp_qdisc *root_qdisc = mlxsw_sp_port->root_qdisc;
|
struct mlxsw_sp_qdisc_state *qdisc_state = mlxsw_sp_port->qdisc;
|
||||||
|
struct mlxsw_sp_qdisc *root_qdisc = &qdisc_state->root_qdisc;
|
||||||
|
|
||||||
if (root_qdisc != mlxsw_sp_qdisc)
|
if (root_qdisc != mlxsw_sp_qdisc)
|
||||||
root_qdisc->stats_base.backlog -=
|
root_qdisc->stats_base.backlog -=
|
||||||
|
@ -737,6 +748,7 @@ int mlxsw_sp_setup_tc_tbf(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||||
static int
|
static int
|
||||||
__mlxsw_sp_qdisc_ets_destroy(struct mlxsw_sp_port *mlxsw_sp_port)
|
__mlxsw_sp_qdisc_ets_destroy(struct mlxsw_sp_port *mlxsw_sp_port)
|
||||||
{
|
{
|
||||||
|
struct mlxsw_sp_qdisc_state *qdisc_state = mlxsw_sp_port->qdisc;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
|
for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
|
||||||
|
@ -746,8 +758,8 @@ __mlxsw_sp_qdisc_ets_destroy(struct mlxsw_sp_port *mlxsw_sp_port)
|
||||||
MLXSW_REG_QEEC_HR_SUBGROUP,
|
MLXSW_REG_QEEC_HR_SUBGROUP,
|
||||||
i, 0, false, 0);
|
i, 0, false, 0);
|
||||||
mlxsw_sp_qdisc_destroy(mlxsw_sp_port,
|
mlxsw_sp_qdisc_destroy(mlxsw_sp_port,
|
||||||
&mlxsw_sp_port->tclass_qdiscs[i]);
|
&qdisc_state->tclass_qdiscs[i]);
|
||||||
mlxsw_sp_port->tclass_qdiscs[i].prio_bitmap = 0;
|
qdisc_state->tclass_qdiscs[i].prio_bitmap = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -786,6 +798,7 @@ __mlxsw_sp_qdisc_ets_replace(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||||
const unsigned int *weights,
|
const unsigned int *weights,
|
||||||
const u8 *priomap)
|
const u8 *priomap)
|
||||||
{
|
{
|
||||||
|
struct mlxsw_sp_qdisc_state *qdisc_state = mlxsw_sp_port->qdisc;
|
||||||
struct mlxsw_sp_qdisc *child_qdisc;
|
struct mlxsw_sp_qdisc *child_qdisc;
|
||||||
int tclass, i, band, backlog;
|
int tclass, i, band, backlog;
|
||||||
u8 old_priomap;
|
u8 old_priomap;
|
||||||
|
@ -793,7 +806,7 @@ __mlxsw_sp_qdisc_ets_replace(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||||
|
|
||||||
for (band = 0; band < nbands; band++) {
|
for (band = 0; band < nbands; band++) {
|
||||||
tclass = MLXSW_SP_PRIO_BAND_TO_TCLASS(band);
|
tclass = MLXSW_SP_PRIO_BAND_TO_TCLASS(band);
|
||||||
child_qdisc = &mlxsw_sp_port->tclass_qdiscs[tclass];
|
child_qdisc = &qdisc_state->tclass_qdiscs[tclass];
|
||||||
old_priomap = child_qdisc->prio_bitmap;
|
old_priomap = child_qdisc->prio_bitmap;
|
||||||
child_qdisc->prio_bitmap = 0;
|
child_qdisc->prio_bitmap = 0;
|
||||||
|
|
||||||
|
@ -825,7 +838,7 @@ __mlxsw_sp_qdisc_ets_replace(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||||
}
|
}
|
||||||
for (; band < IEEE_8021QAZ_MAX_TCS; band++) {
|
for (; band < IEEE_8021QAZ_MAX_TCS; band++) {
|
||||||
tclass = MLXSW_SP_PRIO_BAND_TO_TCLASS(band);
|
tclass = MLXSW_SP_PRIO_BAND_TO_TCLASS(band);
|
||||||
child_qdisc = &mlxsw_sp_port->tclass_qdiscs[tclass];
|
child_qdisc = &qdisc_state->tclass_qdiscs[tclass];
|
||||||
child_qdisc->prio_bitmap = 0;
|
child_qdisc->prio_bitmap = 0;
|
||||||
mlxsw_sp_qdisc_destroy(mlxsw_sp_port, child_qdisc);
|
mlxsw_sp_qdisc_destroy(mlxsw_sp_port, child_qdisc);
|
||||||
mlxsw_sp_port_ets_set(mlxsw_sp_port,
|
mlxsw_sp_port_ets_set(mlxsw_sp_port,
|
||||||
|
@ -875,6 +888,7 @@ mlxsw_sp_qdisc_get_prio_stats(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||||
struct mlxsw_sp_qdisc *mlxsw_sp_qdisc,
|
struct mlxsw_sp_qdisc *mlxsw_sp_qdisc,
|
||||||
struct tc_qopt_offload_stats *stats_ptr)
|
struct tc_qopt_offload_stats *stats_ptr)
|
||||||
{
|
{
|
||||||
|
struct mlxsw_sp_qdisc_state *qdisc_state = mlxsw_sp_port->qdisc;
|
||||||
struct mlxsw_sp_qdisc *tc_qdisc;
|
struct mlxsw_sp_qdisc *tc_qdisc;
|
||||||
u64 tx_packets = 0;
|
u64 tx_packets = 0;
|
||||||
u64 tx_bytes = 0;
|
u64 tx_bytes = 0;
|
||||||
|
@ -883,7 +897,7 @@ mlxsw_sp_qdisc_get_prio_stats(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
|
for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
|
||||||
tc_qdisc = &mlxsw_sp_port->tclass_qdiscs[i];
|
tc_qdisc = &qdisc_state->tclass_qdiscs[i];
|
||||||
mlxsw_sp_qdisc_collect_tc_stats(mlxsw_sp_port, tc_qdisc,
|
mlxsw_sp_qdisc_collect_tc_stats(mlxsw_sp_port, tc_qdisc,
|
||||||
&tx_bytes, &tx_packets,
|
&tx_bytes, &tx_packets,
|
||||||
&drops, &backlog);
|
&drops, &backlog);
|
||||||
|
@ -1009,11 +1023,12 @@ __mlxsw_sp_qdisc_ets_graft(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||||
struct mlxsw_sp_qdisc *mlxsw_sp_qdisc,
|
struct mlxsw_sp_qdisc *mlxsw_sp_qdisc,
|
||||||
u8 band, u32 child_handle)
|
u8 band, u32 child_handle)
|
||||||
{
|
{
|
||||||
|
struct mlxsw_sp_qdisc_state *qdisc_state = mlxsw_sp_port->qdisc;
|
||||||
int tclass_num = MLXSW_SP_PRIO_BAND_TO_TCLASS(band);
|
int tclass_num = MLXSW_SP_PRIO_BAND_TO_TCLASS(band);
|
||||||
struct mlxsw_sp_qdisc *old_qdisc;
|
struct mlxsw_sp_qdisc *old_qdisc;
|
||||||
|
|
||||||
if (band < IEEE_8021QAZ_MAX_TCS &&
|
if (band < IEEE_8021QAZ_MAX_TCS &&
|
||||||
mlxsw_sp_port->tclass_qdiscs[tclass_num].handle == child_handle)
|
qdisc_state->tclass_qdiscs[tclass_num].handle == child_handle)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!child_handle) {
|
if (!child_handle) {
|
||||||
|
@ -1032,7 +1047,7 @@ __mlxsw_sp_qdisc_ets_graft(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||||
mlxsw_sp_qdisc_destroy(mlxsw_sp_port, old_qdisc);
|
mlxsw_sp_qdisc_destroy(mlxsw_sp_port, old_qdisc);
|
||||||
|
|
||||||
mlxsw_sp_qdisc_destroy(mlxsw_sp_port,
|
mlxsw_sp_qdisc_destroy(mlxsw_sp_port,
|
||||||
&mlxsw_sp_port->tclass_qdiscs[tclass_num]);
|
&qdisc_state->tclass_qdiscs[tclass_num]);
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1114,37 +1129,23 @@ int mlxsw_sp_setup_tc_ets(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||||
|
|
||||||
int mlxsw_sp_tc_qdisc_init(struct mlxsw_sp_port *mlxsw_sp_port)
|
int mlxsw_sp_tc_qdisc_init(struct mlxsw_sp_port *mlxsw_sp_port)
|
||||||
{
|
{
|
||||||
struct mlxsw_sp_qdisc *mlxsw_sp_qdisc;
|
struct mlxsw_sp_qdisc_state *qdisc_state;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
mlxsw_sp_qdisc = kzalloc(sizeof(*mlxsw_sp_qdisc), GFP_KERNEL);
|
qdisc_state = kzalloc(sizeof(*qdisc_state), GFP_KERNEL);
|
||||||
if (!mlxsw_sp_qdisc)
|
if (!qdisc_state)
|
||||||
goto err_root_qdisc_init;
|
|
||||||
|
|
||||||
mlxsw_sp_port->root_qdisc = mlxsw_sp_qdisc;
|
|
||||||
mlxsw_sp_port->root_qdisc->prio_bitmap = 0xff;
|
|
||||||
mlxsw_sp_port->root_qdisc->tclass_num = MLXSW_SP_PORT_DEFAULT_TCLASS;
|
|
||||||
|
|
||||||
mlxsw_sp_qdisc = kcalloc(IEEE_8021QAZ_MAX_TCS,
|
|
||||||
sizeof(*mlxsw_sp_qdisc),
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!mlxsw_sp_qdisc)
|
|
||||||
goto err_tclass_qdiscs_init;
|
|
||||||
|
|
||||||
mlxsw_sp_port->tclass_qdiscs = mlxsw_sp_qdisc;
|
|
||||||
for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
|
|
||||||
mlxsw_sp_port->tclass_qdiscs[i].tclass_num = i;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err_tclass_qdiscs_init:
|
|
||||||
kfree(mlxsw_sp_port->root_qdisc);
|
|
||||||
err_root_qdisc_init:
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
qdisc_state->root_qdisc.prio_bitmap = 0xff;
|
||||||
|
qdisc_state->root_qdisc.tclass_num = MLXSW_SP_PORT_DEFAULT_TCLASS;
|
||||||
|
for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
|
||||||
|
qdisc_state->tclass_qdiscs[i].tclass_num = i;
|
||||||
|
|
||||||
|
mlxsw_sp_port->qdisc = qdisc_state;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mlxsw_sp_tc_qdisc_fini(struct mlxsw_sp_port *mlxsw_sp_port)
|
void mlxsw_sp_tc_qdisc_fini(struct mlxsw_sp_port *mlxsw_sp_port)
|
||||||
{
|
{
|
||||||
kfree(mlxsw_sp_port->tclass_qdiscs);
|
kfree(mlxsw_sp_port->qdisc);
|
||||||
kfree(mlxsw_sp_port->root_qdisc);
|
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче