All of lore.kernel.org
 help / color / mirror / Atom feed
From: Suanming Mou <suanmingm@mellanox.com>
To: viacheslavo@mellanox.com, matan@mellanox.com
Cc: orika@mellanox.com, rasland@mellanox.com, dev@dpdk.org
Subject: [dpdk-dev] [PATCH v2 10/19] net/mlx5: support meter modification operations
Date: Fri,  8 Nov 2019 05:49:16 +0200	[thread overview]
Message-ID: <1573184965-49691-11-git-send-email-suanmingm@mellanox.com> (raw)
In-Reply-To: <1573184965-49691-1-git-send-email-suanmingm@mellanox.com>

This commit add meter enable and disable supoort.

New internal functions in rte_mtr_ops callback:
1. meter_enable()
2. meter_disable()

The meter_enable() enables the meter action and the meter_disable()
disables the meter action.

Signed-off-by: Suanming Mou <suanmingm@mellanox.com>
---
 drivers/net/mlx5/mlx5_flow.h       |  10 ++
 drivers/net/mlx5/mlx5_flow_meter.c | 233 ++++++++++++++++++++++++++++++++++++-
 drivers/net/mlx5/mlx5_prm.h        |  32 +++++
 3 files changed, 273 insertions(+), 2 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index aaeb5b3..672552b 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -523,6 +523,10 @@ struct mlx5_flow {
 	bool external; /**< true if the flow is created external to PMD. */
 };
 
+/* Flow meter state. */
+#define MLX5_FLOW_METER_DISABLE 0
+#define MLX5_FLOW_METER_ENABLE 1
+
 #define MLX5_MAN_WIDTH 8
 /* Modify this value if enum rte_mtr_color changes. */
 #define RTE_MTR_DROPPED RTE_COLORS
@@ -553,6 +557,12 @@ struct mlx5_meter_domains_infos {
 	/**< FDB meter table. */
 	void *drop_actn;
 	/**< Drop action as not matched. */
+	uint32_t fmp[MLX5_ST_SZ_DW(flow_meter_parameters)];
+	/**< Flow meter parameter. */
+	size_t fmp_size;
+	/**< Flow meter parameter size. */
+	void *meter_action;
+	/**< Flow meter action. */
 };
 
 /* Meter parameter structure. */
diff --git a/drivers/net/mlx5/mlx5_flow_meter.c b/drivers/net/mlx5/mlx5_flow_meter.c
index 76a3180..6966ffc 100644
--- a/drivers/net/mlx5/mlx5_flow_meter.c
+++ b/drivers/net/mlx5/mlx5_flow_meter.c
@@ -443,6 +443,103 @@
 }
 
 /**
+ * Modify the flow meter action.
+ *
+ * @param[in] priv
+ *   Pointer to mlx5 private data structure.
+ * @param[in] fm
+ *   Pointer to flow meter to be modified.
+ * @param[in] srtcm
+ *   Pointer to meter srtcm description parameter.
+ * @param[in] modify_bits
+ *   The bit in srtcm to be updated.
+ * @param[in] active_state
+ *   The state to be updated.
+ * @return
+ *   0 on success, o negative value otherwise.
+ */
+static int
+mlx5_flow_meter_action_modify(struct mlx5_priv *priv,
+		struct mlx5_flow_meter *fm,
+		const struct mlx5_flow_meter_srtcm_rfc2697_prm *srtcm,
+		uint64_t modify_bits, uint32_t active_state)
+{
+#ifdef HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER
+	uint32_t in[MLX5_ST_SZ_DW(flow_meter_parameters)] = { 0 };
+	uint32_t *attr;
+	struct mlx5dv_dr_flow_meter_attr mod_attr = { 0 };
+	int ret;
+
+	/* Fill command parameters. */
+	mod_attr.reg_c_index = priv->mtr_color_reg - REG_C_0;
+	mod_attr.flow_meter_parameter = in;
+	mod_attr.flow_meter_parameter_sz = fm->mfts->fmp_size;
+	if (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_ACTIVE)
+		mod_attr.active = !!active_state;
+	else
+		mod_attr.active = 0;
+	attr = in;
+	if (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CBS) {
+		MLX5_SET(flow_meter_parameters,
+			 attr, cbs_exponent, srtcm->cbs_exponent);
+		MLX5_SET(flow_meter_parameters,
+			 attr, cbs_mantissa, srtcm->cbs_mantissa);
+	}
+	if (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CIR) {
+		MLX5_SET(flow_meter_parameters,
+			 attr, cir_exponent, srtcm->cir_exponent);
+		MLX5_SET(flow_meter_parameters,
+			 attr, cir_mantissa, srtcm->cir_mantissa);
+	}
+	if (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_EBS) {
+		MLX5_SET(flow_meter_parameters,
+			 attr, ebs_exponent, srtcm->ebs_exponent);
+		MLX5_SET(flow_meter_parameters,
+			 attr, ebs_mantissa, srtcm->ebs_mantissa);
+	}
+	/* Apply modifications to meter only if it was created. */
+	if (fm->mfts->meter_action) {
+		ret = mlx5_glue->dv_modify_flow_action_meter
+					(fm->mfts->meter_action, &mod_attr,
+					rte_cpu_to_be_64(modify_bits));
+		if (ret)
+			return ret;
+	}
+	/* Update succeedded modify meter parameters. */
+	if (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_ACTIVE)
+		fm->active_state = !!active_state;
+	attr = fm->mfts->fmp;
+	if (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CBS) {
+		MLX5_SET(flow_meter_parameters,
+			 attr, cbs_exponent, srtcm->cbs_exponent);
+		MLX5_SET(flow_meter_parameters,
+			 attr, cbs_mantissa, srtcm->cbs_mantissa);
+	}
+	if (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CIR) {
+		MLX5_SET(flow_meter_parameters,
+			 attr, cir_exponent, srtcm->cir_exponent);
+		MLX5_SET(flow_meter_parameters,
+			 attr, cir_mantissa, srtcm->cir_mantissa);
+	}
+	if (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_EBS) {
+		MLX5_SET(flow_meter_parameters,
+			 attr, ebs_exponent, srtcm->ebs_exponent);
+		MLX5_SET(flow_meter_parameters,
+			 attr, ebs_mantissa, srtcm->ebs_mantissa);
+	}
+
+	return 0;
+#else
+	(void)priv;
+	(void)fm;
+	(void)srtcm;
+	(void)modify_bits;
+	(void)active_state;
+	return -ENOTSUP;
+#endif
+}
+
+/**
  * Create meter rules.
  *
  * @param[in] dev
@@ -577,14 +674,146 @@
 	return 0;
 }
 
+/**
+ * Modify meter state.
+ *
+ * @param[in] priv
+ *   Pointer to mlx5 private data structure.
+ * @param[in] fm
+ *   Pointer to flow meter.
+ * @param[in] new_state
+ *   New state to update.
+ * @param[out] error
+ *   Pointer to rte meter error structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+mlx5_flow_meter_modify_state(struct mlx5_priv *priv,
+			     struct mlx5_flow_meter *fm,
+			     uint32_t new_state,
+			     struct rte_mtr_error *error)
+{
+	static const struct mlx5_flow_meter_srtcm_rfc2697_prm srtcm = {
+		.cbs_exponent = 20,
+		.cbs_mantissa = 191,
+		.cir_exponent = 0,
+		.cir_mantissa = 200,
+		.ebs_exponent = 0,
+		.ebs_mantissa = 0,
+	};
+	uint64_t modify_bits = MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CBS |
+			       MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CIR;
+	int ret;
+
+	if (new_state == MLX5_FLOW_METER_DISABLE)
+		ret = mlx5_flow_meter_action_modify(priv, fm, &srtcm,
+						    modify_bits, 0);
+	else
+		ret = mlx5_flow_meter_action_modify(priv, fm,
+						   &fm->profile->srtcm_prm,
+						    modify_bits, 0);
+	if (ret)
+		return -rte_mtr_error_set(error, -ret,
+					  RTE_MTR_ERROR_TYPE_MTR_PARAMS,
+					  NULL,
+					  new_state ?
+					  "Failed to enable meter." :
+					  "Failed to disable meter.");
+	return 0;
+}
+
+/**
+ * Callback to enable flow meter.
+ *
+ * @param[in] dev
+ *   Pointer to Ethernet device.
+ * @param[in] meter_id
+ *   Meter id.
+ * @param[out] error
+ *   Pointer to rte meter error structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+mlx5_flow_meter_enable(struct rte_eth_dev *dev,
+		       uint32_t meter_id,
+		       struct rte_mtr_error *error)
+{
+	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_flow_meter *fm;
+	int ret;
+
+	if (!priv->mtr_en)
+		return -rte_mtr_error_set(error, ENOTSUP,
+					  RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
+					  "Meter is not support");
+	/* Meter object must exist. */
+	fm = mlx5_flow_meter_find(priv, meter_id);
+	if (fm == NULL)
+		return -rte_mtr_error_set(error, ENOENT,
+					  RTE_MTR_ERROR_TYPE_MTR_ID,
+					  NULL, "Meter not found.");
+	if (fm->active_state == MLX5_FLOW_METER_ENABLE)
+		return 0;
+	ret = mlx5_flow_meter_modify_state(priv, fm, MLX5_FLOW_METER_ENABLE,
+					   error);
+	if (!ret)
+		fm->active_state = MLX5_FLOW_METER_ENABLE;
+	return ret;
+}
+
+/**
+ * Callback to disable flow meter.
+ *
+ * @param[in] dev
+ *   Pointer to Ethernet device.
+ * @param[in] meter_id
+ *   Meter id.
+ * @param[out] error
+ *   Pointer to rte meter error structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+mlx5_flow_meter_disable(struct rte_eth_dev *dev,
+			uint32_t meter_id,
+			struct rte_mtr_error *error)
+{
+	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_flow_meter *fm;
+	int ret;
+
+	if (!priv->mtr_en)
+		return -rte_mtr_error_set(error, ENOTSUP,
+					  RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
+					  "Meter is not support");
+	/* Meter object must exist. */
+	fm = mlx5_flow_meter_find(priv, meter_id);
+	if (fm == NULL)
+		return -rte_mtr_error_set(error, ENOENT,
+					  RTE_MTR_ERROR_TYPE_MTR_ID,
+					  NULL, "Meter not found.");
+	if (fm->active_state == MLX5_FLOW_METER_DISABLE)
+		return 0;
+	ret = mlx5_flow_meter_modify_state(priv, fm, MLX5_FLOW_METER_DISABLE,
+					   error);
+	if (!ret)
+		fm->active_state = MLX5_FLOW_METER_DISABLE;
+	return ret;
+}
+
 static const struct rte_mtr_ops mlx5_flow_mtr_ops = {
 	.capabilities_get = mlx5_flow_mtr_cap_get,
 	.meter_profile_add = mlx5_flow_meter_profile_add,
 	.meter_profile_delete = mlx5_flow_meter_profile_delete,
 	.create = mlx5_flow_meter_create,
 	.destroy = mlx5_flow_meter_destroy,
-	.meter_enable = NULL,
-	.meter_disable = NULL,
+	.meter_enable = mlx5_flow_meter_enable,
+	.meter_disable = mlx5_flow_meter_disable,
 	.meter_profile_update = NULL,
 	.meter_dscp_table_update = NULL,
 	.policer_actions_update = NULL,
diff --git a/drivers/net/mlx5/mlx5_prm.h b/drivers/net/mlx5/mlx5_prm.h
index ebedc90..651006b 100644
--- a/drivers/net/mlx5/mlx5_prm.h
+++ b/drivers/net/mlx5/mlx5_prm.h
@@ -1745,6 +1745,38 @@ struct mlx5_ifc_create_sq_in_bits {
 	struct mlx5_ifc_sqc_bits ctx;
 };
 
+enum {
+	MLX5_FLOW_METER_OBJ_MODIFY_FIELD_ACTIVE = (1ULL << 0),
+	MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CBS = (1ULL << 1),
+	MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CIR = (1ULL << 2),
+	MLX5_FLOW_METER_OBJ_MODIFY_FIELD_EBS = (1ULL << 3),
+	MLX5_FLOW_METER_OBJ_MODIFY_FIELD_EIR = (1ULL << 4),
+};
+
+struct mlx5_ifc_flow_meter_parameters_bits {
+	u8         valid[0x1];			// 00h
+	u8         bucket_overflow[0x1];
+	u8         start_color[0x2];
+	u8         both_buckets_on_green[0x1];
+	u8         meter_mode[0x2];
+	u8         reserved_at_1[0x19];
+	u8         reserved_at_2[0x20]; //04h
+	u8         reserved_at_3[0x3];
+	u8         cbs_exponent[0x5];		// 08h
+	u8         cbs_mantissa[0x8];
+	u8         reserved_at_4[0x3];
+	u8         cir_exponent[0x5];
+	u8         cir_mantissa[0x8];
+	u8         reserved_at_5[0x20];		// 0Ch
+	u8         reserved_at_6[0x3];
+	u8         ebs_exponent[0x5];		// 10h
+	u8         ebs_mantissa[0x8];
+	u8         reserved_at_7[0x3];
+	u8         eir_exponent[0x5];
+	u8         eir_mantissa[0x8];
+	u8         reserved_at_8[0x60];		// 14h-1Ch
+};
+
 /* CQE format mask. */
 #define MLX5E_CQE_FORMAT_MASK 0xc
 
-- 
1.8.3.1


  parent reply	other threads:[~2019-11-08  3:50 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-06 15:11 [dpdk-dev] [PATCH 00/19] net/mlx5: support meter Suanming Mou
2019-11-06 15:11 ` [dpdk-dev] [PATCH 01/19] net/mlx5: add meter operation callback Suanming Mou
2019-11-06 15:11 ` [dpdk-dev] [PATCH 02/19] net/mlx5: fill meter capabilities using DevX Suanming Mou
2019-11-06 15:11 ` [dpdk-dev] [PATCH 03/19] net/mlx5: allocate flow meter registers Suanming Mou
2019-11-06 15:11 ` [dpdk-dev] [PATCH 04/19] net/mlx5: support meter profile operations Suanming Mou
2019-11-06 15:11 ` [dpdk-dev] [PATCH 05/19] net/mlx5: validate meter profile Suanming Mou
2019-11-06 15:11 ` [dpdk-dev] [PATCH 06/19] net/mlx5: prepare meter flow tables Suanming Mou
2019-11-06 15:11 ` [dpdk-dev] [PATCH 07/19] net/mlx5: add policer rules operations Suanming Mou
2019-11-06 15:11 ` [dpdk-dev] [PATCH 08/19] net/mlx5: support basic meter operations Suanming Mou
2019-11-06 15:11 ` [dpdk-dev] [PATCH 09/19] net/mlx5: add meter action creation to the glue Suanming Mou
2019-11-06 15:11 ` [dpdk-dev] [PATCH 10/19] net/mlx5: support meter modification operations Suanming Mou
2019-11-06 15:11 ` [dpdk-dev] [PATCH 11/19] net/mlx5: support meter profile update Suanming Mou
2019-11-06 15:11 ` [dpdk-dev] [PATCH 12/19] net/mlx5: expose flow counters management Suanming Mou
2019-11-06 15:11 ` [dpdk-dev] [PATCH 13/19] net/mlx5: add count action to meter Suanming Mou
2019-11-06 15:11 ` [dpdk-dev] [PATCH 14/19] net/mlx5: add meter statistics read and update Suanming Mou
2019-11-06 15:11 ` [dpdk-dev] [PATCH 15/19] net/mlx5: add meter attach and detach Suanming Mou
2019-11-06 15:11 ` [dpdk-dev] [PATCH 16/19] net/mlx5: support meter flow action Suanming Mou
2019-11-06 15:11 ` [dpdk-dev] [PATCH 17/19] net/mlx5: split meter flow Suanming Mou
2019-11-06 15:11 ` [dpdk-dev] [PATCH 18/19] net/mlx5: share tag between meter and metadata Suanming Mou
2019-11-06 15:11 ` [dpdk-dev] [PATCH 19/19] net/mlx5: clean meter resources Suanming Mou
2019-11-08  3:49 ` [dpdk-dev] [PATCH v2 00/19] net/mlx5: support meter Suanming Mou
2019-11-08  3:49   ` [dpdk-dev] [PATCH v2 01/19] net/mlx5: add meter operation callback Suanming Mou
2019-11-08  3:49   ` [dpdk-dev] [PATCH v2 02/19] net/mlx5: fill meter capabilities using DevX Suanming Mou
2019-11-08  3:49   ` [dpdk-dev] [PATCH v2 03/19] net/mlx5: allocate flow meter registers Suanming Mou
2019-11-08  3:49   ` [dpdk-dev] [PATCH v2 04/19] net/mlx5: support meter profile operations Suanming Mou
2019-11-08  3:49   ` [dpdk-dev] [PATCH v2 05/19] net/mlx5: validate meter profile Suanming Mou
2019-11-08  3:49   ` [dpdk-dev] [PATCH v2 06/19] net/mlx5: prepare meter flow tables Suanming Mou
2019-11-08  3:49   ` [dpdk-dev] [PATCH v2 07/19] net/mlx5: add policer rules operations Suanming Mou
2019-11-08  3:49   ` [dpdk-dev] [PATCH v2 08/19] net/mlx5: support basic meter operations Suanming Mou
2019-11-08  3:49   ` [dpdk-dev] [PATCH v2 09/19] net/mlx5: add meter action creation to the glue Suanming Mou
2019-11-08  3:49   ` Suanming Mou [this message]
2019-11-08  3:49   ` [dpdk-dev] [PATCH v2 11/19] net/mlx5: support meter profile update Suanming Mou
2019-11-08  3:49   ` [dpdk-dev] [PATCH v2 12/19] net/mlx5: expose flow counters management Suanming Mou
2019-11-08  3:49   ` [dpdk-dev] [PATCH v2 13/19] net/mlx5: add count action to meter Suanming Mou
2019-11-08  3:49   ` [dpdk-dev] [PATCH v2 14/19] net/mlx5: add meter statistics read and update Suanming Mou
2019-11-08  3:49   ` [dpdk-dev] [PATCH v2 15/19] net/mlx5: add meter attach and detach Suanming Mou
2019-11-08  3:49   ` [dpdk-dev] [PATCH v2 16/19] net/mlx5: support meter flow action Suanming Mou
2019-11-08  3:49   ` [dpdk-dev] [PATCH v2 17/19] net/mlx5: split meter flow Suanming Mou
2019-11-08  3:49   ` [dpdk-dev] [PATCH v2 18/19] net/mlx5: share tag between meter and metadata Suanming Mou
2019-11-08  3:49   ` [dpdk-dev] [PATCH v2 19/19] net/mlx5: clean meter resources Suanming Mou
2019-11-08  6:20   ` [dpdk-dev] [PATCH v2 00/19] net/mlx5: support meter Matan Azrad
2019-11-08 14:22   ` Raslan Darawsheh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1573184965-49691-11-git-send-email-suanmingm@mellanox.com \
    --to=suanmingm@mellanox.com \
    --cc=dev@dpdk.org \
    --cc=matan@mellanox.com \
    --cc=orika@mellanox.com \
    --cc=rasland@mellanox.com \
    --cc=viacheslavo@mellanox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.