summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/mellanox/mlx5/core/en/tc
diff options
context:
space:
mode:
authorRoi Dayan <roid@nvidia.com>2022-07-24 14:14:55 +0300
committerSaeed Mahameed <saeedm@nvidia.com>2022-07-28 13:55:26 -0700
commitf8e9d413a28a36f7451ca3b53306a6a8daa7b997 (patch)
tree329bf56b50fe5478e9369e0e1b56f6674497c98a /drivers/net/ethernet/mellanox/mlx5/core/en/tc
parentb50ce4350c107c96a6a3e481b5e07208f0d058bb (diff)
downloadlinux-stable-f8e9d413a28a36f7451ca3b53306a6a8daa7b997.tar.gz
linux-stable-f8e9d413a28a36f7451ca3b53306a6a8daa7b997.tar.bz2
linux-stable-f8e9d413a28a36f7451ca3b53306a6a8daa7b997.zip
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>
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx5/core/en/tc')
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.c132
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.h5
2 files changed, 111 insertions, 26 deletions
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);