[v5,38/80] net/ntnic: add flow flush

Message ID 20241030213940.3470062-39-sil-plv@napatech.com (mailing list archive)
State Accepted, archived
Delegated to: Ferruh Yigit
Headers
Series Provide flow filter and statistics support |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Serhii Iliushyk Oct. 30, 2024, 9:38 p.m. UTC
From: Oleksandr Kolomeiets <okl-plv@napatech.com>

Implements flow flush support

Signed-off-by: Oleksandr Kolomeiets <okl-plv@napatech.com>
---
 drivers/net/ntnic/nthw/flow_api/flow_api.c    | 13 ++++++
 .../profile_inline/flow_api_profile_inline.c  | 43 +++++++++++++++++++
 .../profile_inline/flow_api_profile_inline.h  |  4 ++
 drivers/net/ntnic/ntnic_filter/ntnic_filter.c | 38 ++++++++++++++++
 drivers/net/ntnic/ntnic_mod_reg.h             |  7 +++
 5 files changed, 105 insertions(+)
  

Patch

diff --git a/drivers/net/ntnic/nthw/flow_api/flow_api.c b/drivers/net/ntnic/nthw/flow_api/flow_api.c
index ec91d08e27..fc9c68ed1a 100644
--- a/drivers/net/ntnic/nthw/flow_api/flow_api.c
+++ b/drivers/net/ntnic/nthw/flow_api/flow_api.c
@@ -251,6 +251,18 @@  static int flow_destroy(struct flow_eth_dev *dev __rte_unused,
 	return profile_inline_ops->flow_destroy_profile_inline(dev, flow, error);
 }
 
+static int flow_flush(struct flow_eth_dev *dev, uint16_t caller_id, struct rte_flow_error *error)
+{
+	const struct profile_inline_ops *profile_inline_ops = get_profile_inline_ops();
+
+	if (profile_inline_ops == NULL) {
+		NT_LOG_DBGX(ERR, FILTER, "profile_inline module uninitialized");
+		return -1;
+	}
+
+	return profile_inline_ops->flow_flush_profile_inline(dev, caller_id, error);
+}
+
 /*
  * Device Management API
  */
@@ -1013,6 +1025,7 @@  static const struct flow_filter_ops ops = {
 	 */
 	.flow_create = flow_create,
 	.flow_destroy = flow_destroy,
+	.flow_flush = flow_flush,
 	.flow_dev_dump = flow_dev_dump,
 };
 
diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
index 2d3df62cda..0232954bec 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
@@ -3631,6 +3631,48 @@  int flow_destroy_profile_inline(struct flow_eth_dev *dev, struct flow_handle *fl
 	return err;
 }
 
+int flow_flush_profile_inline(struct flow_eth_dev *dev,
+	uint16_t caller_id,
+	struct rte_flow_error *error)
+{
+	int err = 0;
+
+	flow_nic_set_error(ERR_SUCCESS, error);
+
+	/*
+	 * Delete all created FLM flows from this eth device.
+	 * FLM flows must be deleted first because normal flows are their parents.
+	 */
+	struct flow_handle *flow = dev->ndev->flow_base_flm;
+
+	while (flow && !err) {
+		if (flow->dev == dev && flow->caller_id == caller_id) {
+			struct flow_handle *flow_next = flow->next;
+			err = flow_destroy_profile_inline(dev, flow, error);
+			flow = flow_next;
+
+		} else {
+			flow = flow->next;
+		}
+	}
+
+	/* Delete all created flows from this eth device */
+	flow = dev->ndev->flow_base;
+
+	while (flow && !err) {
+		if (flow->dev == dev && flow->caller_id == caller_id) {
+			struct flow_handle *flow_next = flow->next;
+			err = flow_destroy_profile_inline(dev, flow, error);
+			flow = flow_next;
+
+		} else {
+			flow = flow->next;
+		}
+	}
+
+	return err;
+}
+
 static __rte_always_inline bool all_bits_enabled(uint64_t hash_mask, uint64_t hash_bits)
 {
 	return (hash_mask & hash_bits) == hash_bits;
@@ -4391,6 +4433,7 @@  static const struct profile_inline_ops ops = {
 	.flow_destroy_locked_profile_inline = flow_destroy_locked_profile_inline,
 	.flow_create_profile_inline = flow_create_profile_inline,
 	.flow_destroy_profile_inline = flow_destroy_profile_inline,
+	.flow_flush_profile_inline = flow_flush_profile_inline,
 	.flow_nic_set_hasher_fields_inline = flow_nic_set_hasher_fields_inline,
 	/*
 	 * NT Flow FLM Meter API
diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
index 2c76a2c023..c695842077 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h
@@ -38,6 +38,10 @@  int flow_destroy_profile_inline(struct flow_eth_dev *dev,
 	struct flow_handle *flow,
 	struct rte_flow_error *error);
 
+int flow_flush_profile_inline(struct flow_eth_dev *dev,
+	uint16_t caller_id,
+	struct rte_flow_error *error);
+
 int flow_dev_dump_profile_inline(struct flow_eth_dev *dev,
 	struct flow_handle *flow,
 	uint16_t caller_id,
diff --git a/drivers/net/ntnic/ntnic_filter/ntnic_filter.c b/drivers/net/ntnic/ntnic_filter/ntnic_filter.c
index 67a24a00f1..93d89d59f3 100644
--- a/drivers/net/ntnic/ntnic_filter/ntnic_filter.c
+++ b/drivers/net/ntnic/ntnic_filter/ntnic_filter.c
@@ -582,6 +582,43 @@  static struct rte_flow *eth_flow_create(struct rte_eth_dev *eth_dev,
 	return flow;
 }
 
+static int eth_flow_flush(struct rte_eth_dev *eth_dev, struct rte_flow_error *error)
+{
+	const struct flow_filter_ops *flow_filter_ops = get_flow_filter_ops();
+
+	if (flow_filter_ops == NULL) {
+		NT_LOG_DBGX(ERR, FILTER, "flow_filter module uninitialized");
+		return -1;
+	}
+
+	struct pmd_internals *internals = (struct pmd_internals *)eth_dev->data->dev_private;
+
+	static struct rte_flow_error flow_error = {
+		.type = RTE_FLOW_ERROR_TYPE_NONE, .message = "none" };
+	int res = 0;
+	/* Main application caller_id is port_id shifted above VDPA ports */
+	uint16_t caller_id = get_caller_id(eth_dev->data->port_id);
+
+	if (internals->flw_dev) {
+		res = flow_filter_ops->flow_flush(internals->flw_dev, caller_id, &flow_error);
+		rte_spinlock_lock(&flow_lock);
+
+		for (int flow = 0; flow < MAX_RTE_FLOWS; flow++) {
+			if (nt_flows[flow].used && nt_flows[flow].caller_id == caller_id) {
+				/* Cleanup recorded flows */
+				nt_flows[flow].used = 0;
+				nt_flows[flow].caller_id = 0;
+			}
+		}
+
+		rte_spinlock_unlock(&flow_lock);
+	}
+
+	convert_error(error, &flow_error);
+
+	return res;
+}
+
 static int eth_flow_dev_dump(struct rte_eth_dev *eth_dev,
 	struct rte_flow *flow,
 	FILE *file,
@@ -613,6 +650,7 @@  static int eth_flow_dev_dump(struct rte_eth_dev *eth_dev,
 static const struct rte_flow_ops dev_flow_ops = {
 	.create = eth_flow_create,
 	.destroy = eth_flow_destroy,
+	.flush = eth_flow_flush,
 	.dev_dump = eth_flow_dev_dump,
 };
 
diff --git a/drivers/net/ntnic/ntnic_mod_reg.h b/drivers/net/ntnic/ntnic_mod_reg.h
index cef655c5e0..12baa13800 100644
--- a/drivers/net/ntnic/ntnic_mod_reg.h
+++ b/drivers/net/ntnic/ntnic_mod_reg.h
@@ -253,6 +253,10 @@  struct profile_inline_ops {
 		struct flow_handle *flow,
 		struct rte_flow_error *error);
 
+	int (*flow_flush_profile_inline)(struct flow_eth_dev *dev,
+		uint16_t caller_id,
+		struct rte_flow_error *error);
+
 	int (*flow_dev_dump_profile_inline)(struct flow_eth_dev *dev,
 		struct flow_handle *flow,
 		uint16_t caller_id,
@@ -309,6 +313,9 @@  struct flow_filter_ops {
 	int (*flow_destroy)(struct flow_eth_dev *dev,
 		struct flow_handle *flow,
 		struct rte_flow_error *error);
+
+	int (*flow_flush)(struct flow_eth_dev *dev, uint16_t caller_id,
+		struct rte_flow_error *error);
 };
 
 void register_dev_flow_ops(const struct rte_flow_ops *ops);