mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-30 22:26:55 +00:00
net/mlx5e: TC, Separate get/update/replace meter functions
mlx5e_tc_meter_get() to get an existing meter. mlx5e_tc_meter_update() to update an existing meter without refcount. mlx5e_tc_meter_replace() to get/create a meter and update if needed. Signed-off-by: Roi Dayan <roid@nvidia.com> Reviewed-by: Jianbo Liu <jianbol@nvidia.com> Reviewed-by: Oz Shlomo <ozsh@nvidia.com> Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
This commit is contained in:
parent
b50ce4350c
commit
f8e9d413a2
3 changed files with 127 additions and 42 deletions
|
@ -344,8 +344,118 @@ __mlx5e_flow_meter_free(struct mlx5e_flow_meter_handle *meter)
|
|||
kfree(meter);
|
||||
}
|
||||
|
||||
static struct mlx5e_flow_meter_handle *
|
||||
__mlx5e_tc_meter_get(struct mlx5e_flow_meters *flow_meters, u32 index)
|
||||
{
|
||||
struct mlx5e_flow_meter_handle *meter;
|
||||
|
||||
hash_for_each_possible(flow_meters->hashtbl, meter, hlist, index)
|
||||
if (meter->params.index == index)
|
||||
goto add_ref;
|
||||
|
||||
return ERR_PTR(-ENOENT);
|
||||
|
||||
add_ref:
|
||||
meter->refcnt++;
|
||||
|
||||
return meter;
|
||||
}
|
||||
|
||||
struct mlx5e_flow_meter_handle *
|
||||
mlx5e_tc_meter_get(struct mlx5_core_dev *mdev, struct mlx5e_flow_meter_params *params)
|
||||
{
|
||||
struct mlx5e_flow_meters *flow_meters;
|
||||
struct mlx5e_flow_meter_handle *meter;
|
||||
|
||||
flow_meters = mlx5e_get_flow_meters(mdev);
|
||||
if (!flow_meters)
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
mutex_lock(&flow_meters->sync_lock);
|
||||
meter = __mlx5e_tc_meter_get(flow_meters, params->index);
|
||||
mutex_unlock(&flow_meters->sync_lock);
|
||||
|
||||
return meter;
|
||||
}
|
||||
|
||||
static void
|
||||
__mlx5e_tc_meter_put(struct mlx5e_flow_meter_handle *meter)
|
||||
{
|
||||
if (--meter->refcnt == 0) {
|
||||
hash_del(&meter->hlist);
|
||||
__mlx5e_flow_meter_free(meter);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mlx5e_tc_meter_put(struct mlx5e_flow_meter_handle *meter)
|
||||
{
|
||||
struct mlx5e_flow_meters *flow_meters = meter->flow_meters;
|
||||
|
||||
mutex_lock(&flow_meters->sync_lock);
|
||||
__mlx5e_tc_meter_put(meter);
|
||||
mutex_unlock(&flow_meters->sync_lock);
|
||||
}
|
||||
|
||||
static struct mlx5e_flow_meter_handle *
|
||||
mlx5e_tc_meter_alloc(struct mlx5e_flow_meters *flow_meters,
|
||||
struct mlx5e_flow_meter_params *params)
|
||||
{
|
||||
struct mlx5e_flow_meter_handle *meter;
|
||||
|
||||
meter = __mlx5e_flow_meter_alloc(flow_meters);
|
||||
if (IS_ERR(meter))
|
||||
return meter;
|
||||
|
||||
hash_add(flow_meters->hashtbl, &meter->hlist, params->index);
|
||||
meter->params.index = params->index;
|
||||
meter->refcnt++;
|
||||
|
||||
return meter;
|
||||
}
|
||||
|
||||
static int
|
||||
__mlx5e_tc_meter_update(struct mlx5e_flow_meter_handle *meter,
|
||||
struct mlx5e_flow_meter_params *params)
|
||||
{
|
||||
struct mlx5_core_dev *mdev = meter->flow_meters->mdev;
|
||||
int err = 0;
|
||||
|
||||
if (meter->params.mode != params->mode || meter->params.rate != params->rate ||
|
||||
meter->params.burst != params->burst) {
|
||||
err = mlx5e_tc_meter_modify(mdev, meter, params);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
meter->params.mode = params->mode;
|
||||
meter->params.rate = params->rate;
|
||||
meter->params.burst = params->burst;
|
||||
}
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
mlx5e_tc_meter_update(struct mlx5e_flow_meter_handle *meter,
|
||||
struct mlx5e_flow_meter_params *params)
|
||||
{
|
||||
struct mlx5_core_dev *mdev = meter->flow_meters->mdev;
|
||||
struct mlx5e_flow_meters *flow_meters;
|
||||
int err;
|
||||
|
||||
flow_meters = mlx5e_get_flow_meters(mdev);
|
||||
if (!flow_meters)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
mutex_lock(&flow_meters->sync_lock);
|
||||
err = __mlx5e_tc_meter_update(meter, params);
|
||||
mutex_unlock(&flow_meters->sync_lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
struct mlx5e_flow_meter_handle *
|
||||
mlx5e_tc_meter_replace(struct mlx5_core_dev *mdev, struct mlx5e_flow_meter_params *params)
|
||||
{
|
||||
struct mlx5e_flow_meters *flow_meters;
|
||||
struct mlx5e_flow_meter_handle *meter;
|
||||
|
@ -356,59 +466,29 @@ mlx5e_tc_meter_get(struct mlx5_core_dev *mdev, struct mlx5e_flow_meter_params *p
|
|||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
mutex_lock(&flow_meters->sync_lock);
|
||||
hash_for_each_possible(flow_meters->hashtbl, meter, hlist, params->index)
|
||||
if (meter->params.index == params->index)
|
||||
goto add_ref;
|
||||
|
||||
meter = __mlx5e_flow_meter_alloc(flow_meters);
|
||||
meter = __mlx5e_tc_meter_get(flow_meters, params->index);
|
||||
if (IS_ERR(meter)) {
|
||||
meter = mlx5e_tc_meter_alloc(flow_meters, params);
|
||||
if (IS_ERR(meter)) {
|
||||
err = PTR_ERR(meter);
|
||||
goto err_alloc;
|
||||
goto err_get;
|
||||
}
|
||||
}
|
||||
|
||||
hash_add(flow_meters->hashtbl, &meter->hlist, params->index);
|
||||
meter->params.index = params->index;
|
||||
|
||||
add_ref:
|
||||
meter->refcnt++;
|
||||
|
||||
if (meter->params.mode != params->mode || meter->params.rate != params->rate ||
|
||||
meter->params.burst != params->burst) {
|
||||
err = mlx5e_tc_meter_modify(mdev, meter, params);
|
||||
err = __mlx5e_tc_meter_update(meter, params);
|
||||
if (err)
|
||||
goto err_update;
|
||||
|
||||
meter->params.mode = params->mode;
|
||||
meter->params.rate = params->rate;
|
||||
meter->params.burst = params->burst;
|
||||
}
|
||||
|
||||
mutex_unlock(&flow_meters->sync_lock);
|
||||
return meter;
|
||||
|
||||
err_update:
|
||||
if (--meter->refcnt == 0) {
|
||||
hash_del(&meter->hlist);
|
||||
__mlx5e_flow_meter_free(meter);
|
||||
}
|
||||
err_alloc:
|
||||
__mlx5e_tc_meter_put(meter);
|
||||
err_get:
|
||||
mutex_unlock(&flow_meters->sync_lock);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
void
|
||||
mlx5e_tc_meter_put(struct mlx5e_flow_meter_handle *meter)
|
||||
{
|
||||
struct mlx5e_flow_meters *flow_meters = meter->flow_meters;
|
||||
|
||||
mutex_lock(&flow_meters->sync_lock);
|
||||
if (--meter->refcnt == 0) {
|
||||
hash_del(&meter->hlist);
|
||||
__mlx5e_flow_meter_free(meter);
|
||||
}
|
||||
mutex_unlock(&flow_meters->sync_lock);
|
||||
}
|
||||
|
||||
enum mlx5_flow_namespace_type
|
||||
mlx5e_tc_meter_get_namespace(struct mlx5e_flow_meters *flow_meters)
|
||||
{
|
||||
|
|
|
@ -51,6 +51,11 @@ struct mlx5e_flow_meter_handle *
|
|||
mlx5e_tc_meter_get(struct mlx5_core_dev *mdev, struct mlx5e_flow_meter_params *params);
|
||||
void
|
||||
mlx5e_tc_meter_put(struct mlx5e_flow_meter_handle *meter);
|
||||
int
|
||||
mlx5e_tc_meter_update(struct mlx5e_flow_meter_handle *meter,
|
||||
struct mlx5e_flow_meter_params *params);
|
||||
struct mlx5e_flow_meter_handle *
|
||||
mlx5e_tc_meter_replace(struct mlx5_core_dev *mdev, struct mlx5e_flow_meter_params *params);
|
||||
|
||||
enum mlx5_flow_namespace_type
|
||||
mlx5e_tc_meter_get_namespace(struct mlx5e_flow_meters *flow_meters);
|
||||
|
|
|
@ -361,7 +361,7 @@ mlx5e_tc_add_flow_meter(struct mlx5e_priv *priv,
|
|||
enum mlx5_flow_namespace_type ns_type;
|
||||
struct mlx5e_flow_meter_handle *meter;
|
||||
|
||||
meter = mlx5e_tc_meter_get(priv->mdev, &attr->meter_attr.params);
|
||||
meter = mlx5e_tc_meter_replace(priv->mdev, &attr->meter_attr.params);
|
||||
if (IS_ERR(meter)) {
|
||||
mlx5_core_err(priv->mdev, "Failed to get flow meter\n");
|
||||
return PTR_ERR(meter);
|
||||
|
|
Loading…
Reference in a new issue