From: Roi Dayan Date: Sun, 24 Jul 2022 11:14:55 +0000 (+0300) Subject: net/mlx5e: TC, Separate get/update/replace meter functions X-Git-Tag: v6.1~860^2~18^2~10 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=f8e9d413a28a36f7451ca3b53306a6a8daa7b997;p=mirror_ubuntu-kernels.git 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 Reviewed-by: Jianbo Liu Reviewed-by: Oz Shlomo Signed-off-by: Saeed Mahameed --- diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.c index 6409e4fa16a1..17529cc07ff4 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.c @@ -344,69 +344,149 @@ __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; - int err; flow_meters = mlx5e_get_flow_meters(mdev); if (!flow_meters) 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_tc_meter_get(flow_meters, params->index); + mutex_unlock(&flow_meters->sync_lock); - meter = __mlx5e_flow_meter_alloc(flow_meters); - if (IS_ERR(meter)) { - err = PTR_ERR(meter); - goto err_alloc; + 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; - -add_ref: 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 err_update; + goto out; meter->params.mode = params->mode; meter->params.rate = params->rate; meter->params.burst = params->burst; } - mutex_unlock(&flow_meters->sync_lock); - return meter; +out: + return err; +} -err_update: - if (--meter->refcnt == 0) { - hash_del(&meter->hlist); - __mlx5e_flow_meter_free(meter); - } -err_alloc: +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_PTR(err); + return err; } -void -mlx5e_tc_meter_put(struct mlx5e_flow_meter_handle *meter) +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 = meter->flow_meters; + struct mlx5e_flow_meters *flow_meters; + struct mlx5e_flow_meter_handle *meter; + int err; + + flow_meters = mlx5e_get_flow_meters(mdev); + if (!flow_meters) + return ERR_PTR(-EOPNOTSUPP); mutex_lock(&flow_meters->sync_lock); - if (--meter->refcnt == 0) { - hash_del(&meter->hlist); - __mlx5e_flow_meter_free(meter); + 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_get; + } } + + err = __mlx5e_tc_meter_update(meter, params); + if (err) + goto err_update; + mutex_unlock(&flow_meters->sync_lock); + return meter; + +err_update: + __mlx5e_tc_meter_put(meter); +err_get: + mutex_unlock(&flow_meters->sync_lock); + return ERR_PTR(err); } enum mlx5_flow_namespace_type diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.h b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.h index a73ebf94ad17..71ffa86e8965 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.h @@ -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); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index a38e1505bace..c3ec23f883cd 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -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);