Commit 10bf92fd authored by Petr Machata's avatar Petr Machata Committed by Jakub Kicinski

mlxsw: spectrum_router: Add helpers for nexthop counters

The next patch will add the ability to share nexthop counters among
mlxsw nexthops backed by the same core nexthop. To have a place to store
reference count, the counter should be kept in a dedicated structure. In
this patch, introduce the structure together with the related helpers, sans
the refcount, which comes in the next patch.
Signed-off-by: default avatarPetr Machata <petrm@nvidia.com>
Reviewed-by: default avatarIdo Schimmel <idosch@nvidia.com>
Link: https://lore.kernel.org/r/61f23fa4f8c5d7879f68dacd793d8ab7425f33c0.1709901020.git.petrm@nvidia.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 79fa5214
...@@ -3049,6 +3049,8 @@ struct mlxsw_sp_nexthop_key { ...@@ -3049,6 +3049,8 @@ struct mlxsw_sp_nexthop_key {
struct fib_nh *fib_nh; struct fib_nh *fib_nh;
}; };
struct mlxsw_sp_nexthop_counter;
struct mlxsw_sp_nexthop { struct mlxsw_sp_nexthop {
struct list_head neigh_list_node; /* member of neigh entry list */ struct list_head neigh_list_node; /* member of neigh entry list */
struct list_head crif_list_node; struct list_head crif_list_node;
...@@ -3080,8 +3082,7 @@ struct mlxsw_sp_nexthop { ...@@ -3080,8 +3082,7 @@ struct mlxsw_sp_nexthop {
struct mlxsw_sp_neigh_entry *neigh_entry; struct mlxsw_sp_neigh_entry *neigh_entry;
struct mlxsw_sp_ipip_entry *ipip_entry; struct mlxsw_sp_ipip_entry *ipip_entry;
}; };
unsigned int counter_index; struct mlxsw_sp_nexthop_counter *counter;
bool counter_valid;
}; };
static struct net_device * static struct net_device *
...@@ -3151,13 +3152,46 @@ struct mlxsw_sp_nexthop_group { ...@@ -3151,13 +3152,46 @@ struct mlxsw_sp_nexthop_group {
bool can_destroy; bool can_destroy;
}; };
struct mlxsw_sp_nexthop_counter {
unsigned int counter_index;
};
static struct mlxsw_sp_nexthop_counter *
mlxsw_sp_nexthop_counter_alloc(struct mlxsw_sp *mlxsw_sp)
{
struct mlxsw_sp_nexthop_counter *nhct;
int err;
nhct = kzalloc(sizeof(*nhct), GFP_KERNEL);
if (!nhct)
return ERR_PTR(-ENOMEM);
err = mlxsw_sp_flow_counter_alloc(mlxsw_sp, &nhct->counter_index);
if (err)
goto err_counter_alloc;
return nhct;
err_counter_alloc:
kfree(nhct);
return ERR_PTR(err);
}
static void
mlxsw_sp_nexthop_counter_free(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_counter *nhct)
{
mlxsw_sp_flow_counter_free(mlxsw_sp, nhct->counter_index);
kfree(nhct);
}
int mlxsw_sp_nexthop_counter_enable(struct mlxsw_sp *mlxsw_sp, int mlxsw_sp_nexthop_counter_enable(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh) struct mlxsw_sp_nexthop *nh)
{ {
struct mlxsw_sp_nexthop_counter *nhct;
struct devlink *devlink; struct devlink *devlink;
int err;
if (nh->counter_valid) if (nh->counter)
return 0; return 0;
devlink = priv_to_devlink(mlxsw_sp->core); devlink = priv_to_devlink(mlxsw_sp->core);
...@@ -3165,30 +3199,30 @@ int mlxsw_sp_nexthop_counter_enable(struct mlxsw_sp *mlxsw_sp, ...@@ -3165,30 +3199,30 @@ int mlxsw_sp_nexthop_counter_enable(struct mlxsw_sp *mlxsw_sp,
MLXSW_SP_DPIPE_TABLE_NAME_ADJ)) MLXSW_SP_DPIPE_TABLE_NAME_ADJ))
return 0; return 0;
err = mlxsw_sp_flow_counter_alloc(mlxsw_sp, &nh->counter_index); nhct = mlxsw_sp_nexthop_counter_alloc(mlxsw_sp);
if (err) if (IS_ERR(nhct))
return err; return PTR_ERR(nhct);
nh->counter_valid = true; nh->counter = nhct;
return 0; return 0;
} }
void mlxsw_sp_nexthop_counter_disable(struct mlxsw_sp *mlxsw_sp, void mlxsw_sp_nexthop_counter_disable(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh) struct mlxsw_sp_nexthop *nh)
{ {
if (!nh->counter_valid) if (!nh->counter)
return; return;
mlxsw_sp_flow_counter_free(mlxsw_sp, nh->counter_index); mlxsw_sp_nexthop_counter_free(mlxsw_sp, nh->counter);
nh->counter_valid = false; nh->counter = NULL;
} }
int mlxsw_sp_nexthop_counter_get(struct mlxsw_sp *mlxsw_sp, int mlxsw_sp_nexthop_counter_get(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh, u64 *p_counter) struct mlxsw_sp_nexthop *nh, u64 *p_counter)
{ {
if (!nh->counter_valid) if (!nh->counter)
return -EINVAL; return -EINVAL;
return mlxsw_sp_flow_counter_get(mlxsw_sp, nh->counter_index, return mlxsw_sp_flow_counter_get(mlxsw_sp, nh->counter->counter_index,
false, p_counter, NULL); false, p_counter, NULL);
} }
...@@ -3662,8 +3696,9 @@ static int __mlxsw_sp_nexthop_eth_update(struct mlxsw_sp *mlxsw_sp, ...@@ -3662,8 +3696,9 @@ static int __mlxsw_sp_nexthop_eth_update(struct mlxsw_sp *mlxsw_sp,
WARN_ON_ONCE(1); WARN_ON_ONCE(1);
return -EINVAL; return -EINVAL;
} }
if (nh->counter_valid) if (nh->counter)
mlxsw_reg_ratr_counter_pack(ratr_pl, nh->counter_index, true); mlxsw_reg_ratr_counter_pack(ratr_pl, nh->counter->counter_index,
true);
else else
mlxsw_reg_ratr_counter_pack(ratr_pl, 0, false); mlxsw_reg_ratr_counter_pack(ratr_pl, 0, false);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment