[dpdk-dev,7/7] net/cxgbe: implement flow flush operation

Message ID 93202e988fd013bb7410ea1226c11c73b86a556a.1528469677.git.rahul.lakkireddy@chelsio.com (mailing list archive)
State Accepted, archived
Delegated to: Ferruh Yigit
Headers
Series cxgbe: add support to offload flows via rte_flow |

Checks

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

Commit Message

Rahul Lakkireddy June 8, 2018, 5:58 p.m. UTC
  From: Shagun Agrawal <shaguna@chelsio.com>

Add API to flush all the filters under specified port.

Signed-off-by: Shagun Agrawal <shaguna@chelsio.com>
Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
 drivers/net/cxgbe/cxgbe_filter.h |  1 +
 drivers/net/cxgbe/cxgbe_flow.c   | 40 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 40 insertions(+), 1 deletion(-)
  

Patch

diff --git a/drivers/net/cxgbe/cxgbe_filter.h b/drivers/net/cxgbe/cxgbe_filter.h
index 3c81c1a64..70443df4c 100644
--- a/drivers/net/cxgbe/cxgbe_filter.h
+++ b/drivers/net/cxgbe/cxgbe_filter.h
@@ -141,6 +141,7 @@  struct filter_entry {
 	u32 pending:1;              /* filter action is pending FW reply */
 	struct filter_ctx *ctx;     /* caller's completion hook */
 	struct rte_eth_dev *dev;    /* Port's rte eth device */
+	void *private;              /* For use by apps using filter_entry */
 
 	/* This will store the actual tid */
 	u32 tid;
diff --git a/drivers/net/cxgbe/cxgbe_flow.c b/drivers/net/cxgbe/cxgbe_flow.c
index 89490ecc2..061947dae 100644
--- a/drivers/net/cxgbe/cxgbe_flow.c
+++ b/drivers/net/cxgbe/cxgbe_flow.c
@@ -468,6 +468,8 @@  cxgbe_flow_create(struct rte_eth_dev *dev,
 		return NULL;
 	}
 
+	flow->f->private = flow; /* Will be used during flush */
+
 	return flow;
 }
 
@@ -632,11 +634,47 @@  cxgbe_flow_validate(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/*
+ * @ret : > 0 filter destroyed succsesfully
+ *        < 0 error destroying filter
+ *        == 1 filter not active / not found
+ */
+static int
+cxgbe_check_n_destroy(struct filter_entry *f, struct rte_eth_dev *dev,
+		      struct rte_flow_error *e)
+{
+	if (f && (f->valid || f->pending) &&
+	    f->dev == dev && /* Only if user has asked for this port */
+	     f->private) /* We (rte_flow) created this filter */
+		return cxgbe_flow_destroy(dev, (struct rte_flow *)f->private,
+					  e);
+	return 1;
+}
+
+static int cxgbe_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *e)
+{
+	struct adapter *adap = ethdev2adap(dev);
+	unsigned int i;
+	int ret = 0;
+
+	if (adap->tids.ftid_tab) {
+		struct filter_entry *f = &adap->tids.ftid_tab[0];
+
+		for (i = 0; i < adap->tids.nftids; i++, f++) {
+			ret = cxgbe_check_n_destroy(f, dev, e);
+			if (ret < 0)
+				goto out;
+		}
+	}
+out:
+	return ret >= 0 ? 0 : ret;
+}
+
 static const struct rte_flow_ops cxgbe_flow_ops = {
 	.validate	= cxgbe_flow_validate,
 	.create		= cxgbe_flow_create,
 	.destroy	= cxgbe_flow_destroy,
-	.flush		= NULL,
+	.flush		= cxgbe_flow_flush,
 	.query		= cxgbe_flow_query,
 	.isolate	= NULL,
 };