[v5,28/28] net/cnxk: support meter action to flow destroy

Message ID 20211012070612.352164-29-skori@marvell.com (mailing list archive)
State Accepted, archived
Delegated to: Jerin Jacob
Headers
Series Support ingress policer |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK
ci/intel-Testing success Testing PASS

Commit Message

Sunil Kumar Kori Oct. 12, 2021, 7:06 a.m. UTC
  From: Sunil Kumar Kori <skori@marvell.com>

Meters are configured per flow using rte_flow_create API.
Patch adds support for destroy operation for meter action
applied on the flow.

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
Signed-off-by: Rakesh Kudurumalla <rkudurumalla@marvell.com>
---
v5:
 - Fix checkpatch errors
 - Fix patch apply errors

v4:
 - Rebase support on dpdk-next-net-mrvl branch
 - Handled meter action during flow destroy
 - Handled meter cleanup during port shutdown
 
v3:
 - Rebase support on latest DPDK
 - Handled multilevel chaining for tree hierarchy
 - Fix naming convention

v2:
 - Rebase support on latest DPDK
 - Handled multilevel chaining for linear hierarchy
 - Review comments incorporated

 drivers/net/cnxk/cn10k_rte_flow.c  | 22 +++++++++++++++-
 drivers/net/cnxk/cnxk_ethdev.c     | 40 ++++++++++++++++++++++++++++++
 drivers/net/cnxk/cnxk_ethdev.h     |  2 ++
 drivers/net/cnxk/cnxk_ethdev_mtr.c |  7 ++++++
 4 files changed, 70 insertions(+), 1 deletion(-)
  

Patch

diff --git a/drivers/net/cnxk/cn10k_rte_flow.c b/drivers/net/cnxk/cn10k_rte_flow.c
index 00c0b172e4..8c87452934 100644
--- a/drivers/net/cnxk/cn10k_rte_flow.c
+++ b/drivers/net/cnxk/cn10k_rte_flow.c
@@ -12,6 +12,14 @@  cn10k_mtr_connect(struct rte_eth_dev *eth_dev, uint32_t mtr_id)
 	return nix_mtr_connect(eth_dev, mtr_id);
 }
 
+static int
+cn10k_mtr_destroy(struct rte_eth_dev *eth_dev, uint32_t mtr_id)
+{
+	struct rte_mtr_error mtr_error;
+
+	return nix_mtr_destroy(eth_dev, mtr_id, &mtr_error);
+}
+
 static int
 cn10k_mtr_configure(struct rte_eth_dev *eth_dev,
 		    const struct rte_flow_action actions[])
@@ -215,6 +223,8 @@  cn10k_flow_destroy(struct rte_eth_dev *eth_dev, struct rte_flow *rte_flow,
 	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
 	int mark_actions = 0, vtag_actions = 0;
 	struct roc_npc *npc = &dev->npc;
+	uint32_t mtr_id;
+	int rc;
 
 	mark_actions = roc_npc_mark_actions_get(npc);
 	if (mark_actions) {
@@ -237,5 +247,15 @@  cn10k_flow_destroy(struct rte_eth_dev *eth_dev, struct rte_flow *rte_flow,
 		}
 	}
 
-	return cnxk_flow_destroy(eth_dev, flow, error);
+	mtr_id = flow->mtr_id;
+	rc = cnxk_flow_destroy(eth_dev, flow, error);
+	if (!rc) {
+		rc = cn10k_mtr_destroy(eth_dev, mtr_id);
+		if (rc) {
+			rte_flow_error_set(error, ENXIO,
+				RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				"Meter attached to this flow does not exist");
+		}
+	}
+	return rc;
 }
diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c
index 2bb33d8f2d..69bd58ae45 100644
--- a/drivers/net/cnxk/cnxk_ethdev.c
+++ b/drivers/net/cnxk/cnxk_ethdev.c
@@ -141,6 +141,38 @@  nix_security_setup(struct cnxk_eth_dev *dev)
 	return rc;
 }
 
+static int
+nix_meter_fini(struct cnxk_eth_dev *dev)
+{
+	struct cnxk_meter_node *next_mtr = NULL;
+	struct roc_nix_bpf_objs profs = {0};
+	struct cnxk_meter_node *mtr = NULL;
+	struct cnxk_mtr *fms = &dev->mtr;
+	struct roc_nix *nix = &dev->nix;
+	struct roc_nix_rq *rq;
+	uint32_t i;
+	int rc;
+
+	RTE_TAILQ_FOREACH_SAFE(mtr, fms, next, next_mtr) {
+		for (i = 0; i < mtr->rq_num; i++) {
+			rq = &dev->rqs[mtr->rq_id[i]];
+			rc |= roc_nix_bpf_ena_dis(nix, mtr->bpf_id, rq, false);
+		}
+
+		profs.level = mtr->level;
+		profs.count = 1;
+		profs.ids[0] = mtr->bpf_id;
+		rc = roc_nix_bpf_free(nix, &profs, 1);
+
+		if (rc)
+			return rc;
+
+		TAILQ_REMOVE(fms, mtr, next);
+		plt_free(mtr);
+	}
+	return 0;
+}
+
 static int
 nix_security_release(struct cnxk_eth_dev *dev)
 {
@@ -1012,6 +1044,11 @@  cnxk_nix_configure(struct rte_eth_dev *eth_dev)
 		if (rc)
 			goto fail_configure;
 
+		/* Disable and free rte_meter entries */
+		rc = nix_meter_fini(dev);
+		if (rc)
+			goto fail_configure;
+
 		/* Cleanup security support */
 		rc = nix_security_release(dev);
 		if (rc)
@@ -1668,6 +1705,9 @@  cnxk_eth_dev_uninit(struct rte_eth_dev *eth_dev, bool reset)
 
 	roc_nix_npc_rx_ena_dis(nix, false);
 
+	/* Disable and free rte_meter entries */
+	nix_meter_fini(dev);
+
 	/* Disable and free rte_flow entries */
 	roc_npc_fini(&dev->npc);
 
diff --git a/drivers/net/cnxk/cnxk_ethdev.h b/drivers/net/cnxk/cnxk_ethdev.h
index 7e13956572..2d4b073985 100644
--- a/drivers/net/cnxk/cnxk_ethdev.h
+++ b/drivers/net/cnxk/cnxk_ethdev.h
@@ -589,6 +589,8 @@  int nix_mtr_level_update(struct rte_eth_dev *eth_dev, uint32_t id,
 			 uint32_t level);
 int nix_mtr_configure(struct rte_eth_dev *eth_dev, uint32_t id);
 int nix_mtr_connect(struct rte_eth_dev *eth_dev, uint32_t id);
+int nix_mtr_destroy(struct rte_eth_dev *eth_dev, uint32_t id,
+		    struct rte_mtr_error *error);
 int nix_mtr_color_action_validate(struct rte_eth_dev *eth_dev, uint32_t id,
 				  uint32_t *prev_id, uint32_t *next_id,
 				  struct cnxk_mtr_policy_node *policy,
diff --git a/drivers/net/cnxk/cnxk_ethdev_mtr.c b/drivers/net/cnxk/cnxk_ethdev_mtr.c
index c29a7ec47b..22c85336d9 100644
--- a/drivers/net/cnxk/cnxk_ethdev_mtr.c
+++ b/drivers/net/cnxk/cnxk_ethdev_mtr.c
@@ -1054,6 +1054,13 @@  nix_dscp_table_map(struct cnxk_meter_node *mtr,
 	}
 }
 
+int
+nix_mtr_destroy(struct rte_eth_dev *eth_dev, uint32_t id,
+		struct rte_mtr_error *error)
+{
+	return cnxk_nix_mtr_destroy(eth_dev, id, error);
+}
+
 int
 nix_mtr_connect(struct rte_eth_dev *eth_dev, uint32_t id)
 {