DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 00/10] net/softnic: implement metering and policing API
@ 2018-09-07 18:13 Jasvinder Singh
  2018-09-07 18:13 ` [dpdk-dev] [PATCH 01/10] net/softnic: add metering and policing support Jasvinder Singh
                   ` (9 more replies)
  0 siblings, 10 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-07 18:13 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

This patchset adds the metering and policing API support for the
softnic. The metering and policing action can be enabled through the
flow rules.

This series is prepared on top of following patchset;
https://mails.dpdk.org/archives/dev/2018-September/110998.html

Jasvinder Singh (10):
  net/softnic: add metering and policing support
  net/softnic: add meter profile
  net/softnic: delete meter profile
  net/softnic: create meter object
  net/softnic: destroy meter object
  net/softnic: update meter profile
  net/softnic: update dscp table
  net/softnic: update policer actions
  net/softnic: meter stats read
  net/softnic: enable meter action using flow rule

 drivers/net/softnic/Makefile                    |   1 +
 drivers/net/softnic/meson.build                 |   1 +
 drivers/net/softnic/rte_eth_softnic.c           |  13 +
 drivers/net/softnic/rte_eth_softnic_flow.c      | 170 ++++++
 drivers/net/softnic/rte_eth_softnic_internals.h |  57 ++
 drivers/net/softnic/rte_eth_softnic_meter.c     | 746 ++++++++++++++++++++++++
 drivers/net/softnic/rte_eth_softnic_pipeline.c  |  13 +
 7 files changed, 1001 insertions(+)
 create mode 100644 drivers/net/softnic/rte_eth_softnic_meter.c

-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH 01/10] net/softnic: add metering and policing support
  2018-09-07 18:13 [dpdk-dev] [PATCH 00/10] net/softnic: implement metering and policing API Jasvinder Singh
@ 2018-09-07 18:13 ` Jasvinder Singh
  2018-09-12 16:41   ` [dpdk-dev] [PATCH v2 00/10] net/softnic: implement metering and policing API Jasvinder Singh
  2018-09-07 18:13 ` [dpdk-dev] [PATCH 02/10] net/softnic: add meter profile Jasvinder Singh
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-07 18:13 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Enable metering and policing support for softnic.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/Makefile                    |  1 +
 drivers/net/softnic/meson.build                 |  1 +
 drivers/net/softnic/rte_eth_softnic.c           | 10 ++++++++
 drivers/net/softnic/rte_eth_softnic_internals.h |  5 ++++
 drivers/net/softnic/rte_eth_softnic_meter.c     | 31 +++++++++++++++++++++++++
 5 files changed, 48 insertions(+)
 create mode 100644 drivers/net/softnic/rte_eth_softnic_meter.c

diff --git a/drivers/net/softnic/Makefile b/drivers/net/softnic/Makefile
index 12515b1..720f067b 100644
--- a/drivers/net/softnic/Makefile
+++ b/drivers/net/softnic/Makefile
@@ -34,6 +34,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_pipeline.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_thread.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_cli.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_flow.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_meter.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += parser.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += conn.c
 
diff --git a/drivers/net/softnic/meson.build b/drivers/net/softnic/meson.build
index 56e5e2b..6b7a6cc 100644
--- a/drivers/net/softnic/meson.build
+++ b/drivers/net/softnic/meson.build
@@ -14,6 +14,7 @@ sources = files('rte_eth_softnic_tm.c',
 	'rte_eth_softnic_thread.c',
 	'rte_eth_softnic_cli.c',
 	'rte_eth_softnic_flow.c',
+	'rte_eth_softnic_meter.c',
 	'parser.c',
 	'conn.c')
 deps += ['pipeline', 'port', 'table', 'sched']
diff --git a/drivers/net/softnic/rte_eth_softnic.c b/drivers/net/softnic/rte_eth_softnic.c
index ae2a438..659a1b4 100644
--- a/drivers/net/softnic/rte_eth_softnic.c
+++ b/drivers/net/softnic/rte_eth_softnic.c
@@ -14,6 +14,7 @@
 #include <rte_errno.h>
 #include <rte_ring.h>
 #include <rte_tm_driver.h>
+#include <rte_mtr_driver.h>
 
 #include "rte_eth_softnic.h"
 #include "rte_eth_softnic_internals.h"
@@ -228,6 +229,14 @@ pmd_tm_ops_get(struct rte_eth_dev *dev __rte_unused, void *arg)
 	return 0;
 }
 
+static int
+pmd_mtr_ops_get(struct rte_eth_dev *dev __rte_unused, void *arg)
+{
+	*(const struct rte_mtr_ops **)arg = &pmd_mtr_ops;
+
+	return 0;
+}
+
 static const struct eth_dev_ops pmd_ops = {
 	.dev_configure = pmd_dev_configure,
 	.dev_start = pmd_dev_start,
@@ -239,6 +248,7 @@ static const struct eth_dev_ops pmd_ops = {
 	.tx_queue_setup = pmd_tx_queue_setup,
 	.filter_ctrl = pmd_filter_ctrl,
 	.tm_ops_get = pmd_tm_ops_get,
+	.mtr_ops_get = pmd_mtr_ops_get,
 };
 
 static uint16_t
diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index a1a2e15..92be4e8 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -572,6 +572,11 @@ flow_attr_map_get(struct pmd_internals *softnic,
 extern const struct rte_flow_ops pmd_flow_ops;
 
 /**
+ * Meter
+ */
+extern const struct rte_mtr_ops pmd_mtr_ops;
+
+/**
  * MEMPOOL
  */
 int
diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
new file mode 100644
index 0000000..572288d
--- /dev/null
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017 Intel Corporation
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <rte_mtr.h>
+#include <rte_mtr_driver.h>
+
+#include "rte_eth_softnic_internals.h"
+
+const struct rte_mtr_ops pmd_mtr_ops = {
+	.capabilities_get = NULL,
+
+	.meter_profile_add = NULL,
+	.meter_profile_delete = NULL,
+
+	.create = NULL,
+	.destroy = NULL,
+	.meter_enable = NULL,
+	.meter_disable = NULL,
+
+	.meter_profile_update = NULL,
+	.meter_dscp_table_update = NULL,
+	.policer_actions_update = NULL,
+	.stats_update = NULL,
+
+	.stats_read = NULL,
+};
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH 02/10] net/softnic: add meter profile
  2018-09-07 18:13 [dpdk-dev] [PATCH 00/10] net/softnic: implement metering and policing API Jasvinder Singh
  2018-09-07 18:13 ` [dpdk-dev] [PATCH 01/10] net/softnic: add metering and policing support Jasvinder Singh
@ 2018-09-07 18:13 ` Jasvinder Singh
  2018-09-07 18:13 ` [dpdk-dev] [PATCH 03/10] net/softnic: delete " Jasvinder Singh
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-07 18:13 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter profile add function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic.c           |   3 +
 drivers/net/softnic/rte_eth_softnic_internals.h |  42 ++++++++
 drivers/net/softnic/rte_eth_softnic_meter.c     | 137 +++++++++++++++++++++++-
 3 files changed, 181 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic.c b/drivers/net/softnic/rte_eth_softnic.c
index 659a1b4..d265d1a 100644
--- a/drivers/net/softnic/rte_eth_softnic.c
+++ b/drivers/net/softnic/rte_eth_softnic.c
@@ -186,6 +186,7 @@ pmd_dev_stop(struct rte_eth_dev *dev)
 	softnic_port_in_action_profile_free(p);
 	softnic_tap_free(p);
 	softnic_tmgr_free(p);
+	softnic_mtr_free(p);
 	softnic_link_free(p);
 	softnic_softnic_swq_free_keep_rxq_txq(p);
 	softnic_mempool_free(p);
@@ -296,6 +297,7 @@ pmd_init(struct pmd_params *params)
 	softnic_swq_init(p);
 	softnic_link_init(p);
 	softnic_tmgr_init(p);
+	softnic_mtr_init(p);
 	softnic_tap_init(p);
 	softnic_port_in_action_profile_init(p);
 	softnic_table_action_profile_init(p);
@@ -340,6 +342,7 @@ pmd_free(struct pmd_internals *p)
 	softnic_port_in_action_profile_free(p);
 	softnic_tap_free(p);
 	softnic_tmgr_free(p);
+	softnic_mtr_free(p);
 	softnic_link_free(p);
 	softnic_swq_free(p);
 	softnic_mempool_free(p);
diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index 92be4e8..14ea57d 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -22,6 +22,7 @@
 #include <rte_ethdev_driver.h>
 #include <rte_tm_driver.h>
 #include <rte_flow_driver.h>
+#include <rte_mtr_driver.h>
 
 #include "rte_eth_softnic.h"
 #include "conn.h"
@@ -68,6 +69,35 @@ struct flow_internals {
 };
 
 /**
+ * Meter
+ */
+
+/* MTR meter profile */
+struct softnic_mtr_meter_profile {
+	TAILQ_ENTRY(softnic_mtr_meter_profile) node;
+	uint32_t meter_profile_id;
+	struct rte_mtr_meter_profile params;
+	uint32_t n_users;
+};
+
+TAILQ_HEAD(softnic_mtr_meter_profile_list, softnic_mtr_meter_profile);
+
+/* MTR object */
+struct softnic_mtr {
+	TAILQ_ENTRY(softnic_mtr) node;
+	uint32_t mtr_id;
+	struct rte_mtr_params params;
+	struct rte_flow *flow;
+};
+
+TAILQ_HEAD(softnic_mtr_list, softnic_mtr);
+
+struct mtr_internals {
+	struct softnic_mtr_meter_profile_list meter_profiles;
+	struct softnic_mtr_list mtrs;
+};
+
+/**
  * MEMPOOL
  */
 struct softnic_mempool_params {
@@ -525,6 +555,8 @@ struct pmd_internals {
 	} soft;
 
 	struct flow_internals flow;
+	struct mtr_internals mtr;
+
 	struct softnic_conn *conn;
 	struct softnic_mempool_list mempool_list;
 	struct softnic_swq_list swq_list;
@@ -574,6 +606,16 @@ extern const struct rte_flow_ops pmd_flow_ops;
 /**
  * Meter
  */
+int
+softnic_mtr_init(struct pmd_internals *p);
+
+void
+softnic_mtr_free(struct pmd_internals *p);
+
+struct softnic_mtr_meter_profile *
+softnic_mtr_meter_profile_find(struct pmd_internals *p,
+	uint32_t meter_profile_id);
+
 extern const struct rte_mtr_ops pmd_mtr_ops;
 
 /**
diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 572288d..a80ebf7 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -11,10 +11,145 @@
 
 #include "rte_eth_softnic_internals.h"
 
+int
+softnic_mtr_init(struct pmd_internals *p)
+{
+	/* Initialize meter profiles list */
+	TAILQ_INIT(&p->mtr.meter_profiles);
+
+	/* Initialize MTR objects list */
+	TAILQ_INIT(&p->mtr.mtrs);
+
+	return 0;
+}
+
+void
+softnic_mtr_free(struct pmd_internals *p)
+{
+	/* Remove meter profiles */
+	for ( ; ; ) {
+		struct softnic_mtr_meter_profile *mp;
+
+		mp = TAILQ_FIRST(&p->mtr.meter_profiles);
+		if (mp == NULL)
+			break;
+
+		TAILQ_REMOVE(&p->mtr.meter_profiles, mp, node);
+		free(mp);
+	}
+
+	/* Remove MTR objects */
+	for ( ; ; ) {
+		struct softnic_mtr *m;
+
+		m = TAILQ_FIRST(&p->mtr.mtrs);
+		if (m == NULL)
+			break;
+
+		TAILQ_REMOVE(&p->mtr.mtrs, m, node);
+		free(m);
+	}
+}
+
+struct softnic_mtr_meter_profile *
+softnic_mtr_meter_profile_find(struct pmd_internals *p,
+	uint32_t meter_profile_id)
+{
+	struct softnic_mtr_meter_profile_list *mpl = &p->mtr.meter_profiles;
+	struct softnic_mtr_meter_profile *mp;
+
+	TAILQ_FOREACH(mp, mpl, node)
+		if (meter_profile_id == mp->meter_profile_id)
+			return mp;
+
+	return NULL;
+}
+
+static int
+meter_profile_check(struct rte_eth_dev *dev,
+	uint32_t meter_profile_id,
+	struct rte_mtr_meter_profile *profile,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_meter_profile *mp;
+
+	/* Meter profile ID must be valid. */
+	if (meter_profile_id == UINT32_MAX)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			rte_strerror(EINVAL));
+
+	/* Meter profile must not exist. */
+	mp = softnic_mtr_meter_profile_find(p, meter_profile_id);
+	if (mp)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			rte_strerror(EEXIST));
+
+	/* Profile must not be NULL. */
+	if (profile == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE,
+			NULL,
+			rte_strerror(EINVAL));
+
+	/* Traffic metering algorithm : TRTCM_RFC2698 */
+	if (profile->alg != RTE_MTR_TRTCM_RFC2698)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE,
+			NULL,
+			rte_strerror(EINVAL));
+
+	return 0;
+}
+
+/* MTR meter profile add */
+static int
+pmd_mtr_meter_profile_add(struct rte_eth_dev *dev,
+	uint32_t meter_profile_id,
+	struct rte_mtr_meter_profile *profile,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_meter_profile_list *mpl = &p->mtr.meter_profiles;
+	struct softnic_mtr_meter_profile *mp;
+	int status;
+
+	/* Check input params */
+	status = meter_profile_check(dev, meter_profile_id, profile, error);
+	if (status)
+		return status;
+
+	/* Memory allocation */
+	mp = calloc(1, sizeof(struct softnic_mtr_meter_profile));
+	if (mp == NULL)
+		return -rte_mtr_error_set(error,
+			ENOMEM,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			rte_strerror(ENOMEM));
+
+	/* Fill in */
+	mp->meter_profile_id = meter_profile_id;
+	memcpy(&mp->params, profile, sizeof(mp->params));
+
+	/* Add to list */
+	TAILQ_INSERT_TAIL(mpl, mp, node);
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
-	.meter_profile_add = NULL,
+	.meter_profile_add = pmd_mtr_meter_profile_add,
 	.meter_profile_delete = NULL,
 
 	.create = NULL,
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH 03/10] net/softnic: delete meter profile
  2018-09-07 18:13 [dpdk-dev] [PATCH 00/10] net/softnic: implement metering and policing API Jasvinder Singh
  2018-09-07 18:13 ` [dpdk-dev] [PATCH 01/10] net/softnic: add metering and policing support Jasvinder Singh
  2018-09-07 18:13 ` [dpdk-dev] [PATCH 02/10] net/softnic: add meter profile Jasvinder Singh
@ 2018-09-07 18:13 ` Jasvinder Singh
  2018-09-07 18:13 ` [dpdk-dev] [PATCH 04/10] net/softnic: create meter object Jasvinder Singh
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-07 18:13 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter profile delete function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_meter.c | 35 ++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index a80ebf7..1d6af0c 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -146,11 +146,44 @@ pmd_mtr_meter_profile_add(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* MTR meter profile delete */
+static int
+pmd_mtr_meter_profile_delete(struct rte_eth_dev *dev,
+	uint32_t meter_profile_id,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_meter_profile *mp;
+
+	/* Meter profile must exist */
+	mp = softnic_mtr_meter_profile_find(p, meter_profile_id);
+	if (mp == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			rte_strerror(EINVAL));
+
+	/* Check unused */
+	if (mp->n_users)
+		return -rte_mtr_error_set(error,
+			EBUSY,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			rte_strerror(EBUSY));
+
+	/* Remove from list */
+	TAILQ_REMOVE(&p->mtr.meter_profiles, mp, node);
+	free(mp);
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
 	.meter_profile_add = pmd_mtr_meter_profile_add,
-	.meter_profile_delete = NULL,
+	.meter_profile_delete = pmd_mtr_meter_profile_delete,
 
 	.create = NULL,
 	.destroy = NULL,
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH 04/10] net/softnic: create meter object
  2018-09-07 18:13 [dpdk-dev] [PATCH 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                   ` (2 preceding siblings ...)
  2018-09-07 18:13 ` [dpdk-dev] [PATCH 03/10] net/softnic: delete " Jasvinder Singh
@ 2018-09-07 18:13 ` Jasvinder Singh
  2018-09-07 18:13 ` [dpdk-dev] [PATCH 05/10] net/softnic: destroy " Jasvinder Singh
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-07 18:13 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

implement meter object create function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_internals.h |  4 ++
 drivers/net/softnic/rte_eth_softnic_meter.c     | 92 ++++++++++++++++++++++++-
 2 files changed, 95 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index 14ea57d..4e2ad56 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -612,6 +612,10 @@ softnic_mtr_init(struct pmd_internals *p);
 void
 softnic_mtr_free(struct pmd_internals *p);
 
+struct softnic_mtr *
+softnic_mtr_find(struct pmd_internals *p,
+	uint32_t mtr_id);
+
 struct softnic_mtr_meter_profile *
 softnic_mtr_meter_profile_find(struct pmd_internals *p,
 	uint32_t meter_profile_id);
diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 1d6af0c..261a6a3 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -179,13 +179,103 @@ pmd_mtr_meter_profile_delete(struct rte_eth_dev *dev,
 	return 0;
 }
 
+struct softnic_mtr *
+softnic_mtr_find(struct pmd_internals *p, uint32_t mtr_id)
+{
+	struct softnic_mtr_list *ml = &p->mtr.mtrs;
+	struct softnic_mtr *m;
+
+	TAILQ_FOREACH(m, ml, node)
+		if (m->mtr_id == mtr_id)
+			return m;
+
+	return NULL;
+}
+
+
+/* MTR object create */
+static int
+pmd_mtr_create(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	struct rte_mtr_params *params,
+	int shared,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_list *ml = &p->mtr.mtrs;
+	struct softnic_mtr_meter_profile *mp;
+	struct softnic_mtr *m;
+
+	/* MTR id valid  */
+	if (softnic_mtr_find(p, mtr_id))
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			rte_strerror(EEXIST));
+
+	/* MTR params must not be NULL */
+	if (params == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_MTR_PARAMS,
+			NULL,
+			rte_strerror(EINVAL));
+
+	/* Meter profile must exist */
+	mp = softnic_mtr_meter_profile_find(p, params->meter_profile_id);
+	if (mp == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			rte_strerror(EINVAL));
+
+	/* Previous meter color not supported */
+	if (params->use_prev_mtr_color)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_MTR_PARAMS,
+			NULL,
+			rte_strerror(EINVAL));
+
+	/* Shared MTR object not supported */
+	if (shared)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_SHARED,
+			NULL,
+			rte_strerror(EINVAL));
+
+	/* Memory allocation */
+	m = calloc(1, sizeof(struct softnic_mtr));
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			ENOMEM,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			rte_strerror(ENOMEM));
+
+	/* Fill in */
+	m->mtr_id = mtr_id;
+	memcpy(&m->params, params, sizeof(m->params));
+
+	/* Add to list */
+	TAILQ_INSERT_TAIL(ml, m, node);
+
+	/* Update dependencies */
+	mp->n_users++;
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
 	.meter_profile_add = pmd_mtr_meter_profile_add,
 	.meter_profile_delete = pmd_mtr_meter_profile_delete,
 
-	.create = NULL,
+	.create = pmd_mtr_create,
 	.destroy = NULL,
 	.meter_enable = NULL,
 	.meter_disable = NULL,
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH 05/10] net/softnic: destroy meter object
  2018-09-07 18:13 [dpdk-dev] [PATCH 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                   ` (3 preceding siblings ...)
  2018-09-07 18:13 ` [dpdk-dev] [PATCH 04/10] net/softnic: create meter object Jasvinder Singh
@ 2018-09-07 18:13 ` Jasvinder Singh
  2018-09-07 18:13 ` [dpdk-dev] [PATCH 06/10] net/softnic: update meter profile Jasvinder Singh
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-07 18:13 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter object destroy function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_meter.c | 49 ++++++++++++++++++++++++++++-
 1 file changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 261a6a3..48ec446 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -269,6 +269,53 @@ pmd_mtr_create(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* MTR object destroy */
+static int
+pmd_mtr_destroy(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_list *ml = &p->mtr.mtrs;
+	struct softnic_mtr_meter_profile *mp;
+	struct softnic_mtr *m;
+
+	/* MTR object must exist */
+	m = softnic_mtr_find(p, mtr_id);
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			rte_strerror(EEXIST));
+
+	/* MTR object must not have any owner */
+	if (m->flow != NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			rte_strerror(EINVAL));
+
+	/* Get meter profile */
+	mp = softnic_mtr_meter_profile_find(p, m->params.meter_profile_id);
+	if (mp == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			rte_strerror(EINVAL));
+
+	/* Update dependencies */
+	mp->n_users--;
+
+	/* Remove from list */
+	TAILQ_REMOVE(ml, m, node);
+	free(m);
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
@@ -276,7 +323,7 @@ const struct rte_mtr_ops pmd_mtr_ops = {
 	.meter_profile_delete = pmd_mtr_meter_profile_delete,
 
 	.create = pmd_mtr_create,
-	.destroy = NULL,
+	.destroy = pmd_mtr_destroy,
 	.meter_enable = NULL,
 	.meter_disable = NULL,
 
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH 06/10] net/softnic: update meter profile
  2018-09-07 18:13 [dpdk-dev] [PATCH 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                   ` (4 preceding siblings ...)
  2018-09-07 18:13 ` [dpdk-dev] [PATCH 05/10] net/softnic: destroy " Jasvinder Singh
@ 2018-09-07 18:13 ` Jasvinder Singh
  2018-09-07 18:13 ` [dpdk-dev] [PATCH 07/10] net/softnic: update dscp table Jasvinder Singh
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-07 18:13 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter profile update function

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_internals.h |   5 +
 drivers/net/softnic/rte_eth_softnic_meter.c     | 139 +++++++++++++++++++++++-
 drivers/net/softnic/rte_eth_softnic_pipeline.c  |  12 ++
 3 files changed, 155 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index 4e2ad56..5995e61 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -455,6 +455,7 @@ struct softnic_table {
 	struct softnic_table_action_profile *ap;
 	struct rte_table_action *a;
 	struct flow_list flows;
+	struct softnic_mtr_meter_profile_list meter_profiles;
 };
 
 struct pipeline {
@@ -620,6 +621,10 @@ struct softnic_mtr_meter_profile *
 softnic_mtr_meter_profile_find(struct pmd_internals *p,
 	uint32_t meter_profile_id);
 
+struct softnic_mtr_meter_profile *
+softnic_table_meter_profile_find(struct softnic_table *table,
+	uint32_t meter_profile_id);
+
 extern const struct rte_mtr_ops pmd_mtr_ops;
 
 /**
diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 48ec446..3b05ad6 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -316,6 +316,143 @@ pmd_mtr_destroy(struct rte_eth_dev *dev,
 	return 0;
 }
 
+struct softnic_mtr_meter_profile *
+softnic_table_meter_profile_find(struct softnic_table *table,
+	uint32_t meter_profile_id)
+{
+	struct softnic_mtr_meter_profile *mp;
+
+	TAILQ_FOREACH(mp, &table->meter_profiles, node)
+		if (mp->meter_profile_id == meter_profile_id)
+			return mp;
+
+	return NULL;
+}
+
+static int
+softnic_table_meter_profile_update(struct pmd_internals *p,
+	struct softnic_mtr *mtr,
+	uint32_t meter_profile_id,
+	struct rte_mtr_meter_profile *params,
+	struct rte_mtr_error *error)
+{
+	struct rte_flow *mflow = mtr->flow;
+	struct softnic_table *table = &mflow->pipeline->table[mflow->table_id];
+	struct softnic_mtr_meter_profile *mp;
+	int status, mp_mem_alloc = 0;
+
+	/* Find/allocate meter profile for table */
+	if (!softnic_table_meter_profile_find(table, meter_profile_id)) {
+		mp = calloc(1, sizeof(struct softnic_mtr_meter_profile));
+		if (mp == NULL) {
+			rte_mtr_error_set(error,
+				ENOMEM,
+				RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+				NULL,
+				"Not enough table memory for meter profile");
+			return -1;
+		}
+		mp_mem_alloc = 1;
+
+		/* Fill in */
+		mp->meter_profile_id = meter_profile_id;
+		memcpy(&mp->params, params, sizeof(mp->params));
+
+		/* Add to list */
+		TAILQ_INSERT_TAIL(&table->meter_profiles, mp, node);
+	}
+
+	/* Update meter action */
+	mflow->action.mtr.mtr[0].meter_profile_id = meter_profile_id;
+
+	/* Re-add new rule */
+	status = softnic_pipeline_table_rule_add(p,
+		mflow->pipeline->name,
+		mflow->table_id,
+		&mflow->match,
+		&mflow->action,
+		&mflow->data);
+	if (status) {
+		if (mp_mem_alloc)
+			free(mp);
+
+		rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"Pipeline table rule add failed");
+		return -1;
+	}
+
+	return 0;
+}
+
+/* MTR object meter profile update */
+static int
+pmd_mtr_meter_profile_update(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	uint32_t meter_profile_id,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_meter_profile *mp, *mp_old;
+	struct softnic_mtr *m;
+	int status;
+
+	/* MTR object id must be valid */
+	m = softnic_mtr_find(p, mtr_id);
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			rte_strerror(EEXIST));
+
+	/* Meter profile id must be valid */
+	mp = softnic_mtr_meter_profile_find(p, meter_profile_id);
+	if (mp == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			rte_strerror(EINVAL));
+
+	/* MTR object already set to meter profile id */
+	if (m->params.meter_profile_id == meter_profile_id)
+		return 0;
+
+	m->params.meter_profile_id = meter_profile_id;
+
+	/* Update dependencies */
+	mp_old = softnic_mtr_meter_profile_find(p, m->params.meter_profile_id);
+	if (mp_old == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			rte_strerror(EINVAL));
+
+	mp_old->n_users--;
+	mp->n_users++;
+
+	/*  MTR object owner table update */
+	if (m->flow) {
+		status = softnic_table_meter_profile_update(p,
+				m,
+				meter_profile_id,
+				&mp->params,
+				error);
+		if (status)
+			return -rte_mtr_error_set(error,
+				EINVAL,
+				RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+				NULL,
+				rte_strerror(EINVAL));
+	}
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
@@ -327,7 +464,7 @@ const struct rte_mtr_ops pmd_mtr_ops = {
 	.meter_enable = NULL,
 	.meter_disable = NULL,
 
-	.meter_profile_update = NULL,
+	.meter_profile_update = pmd_mtr_meter_profile_update,
 	.meter_dscp_table_update = NULL,
 	.policer_actions_update = NULL,
 	.stats_update = NULL,
diff --git a/drivers/net/softnic/rte_eth_softnic_pipeline.c b/drivers/net/softnic/rte_eth_softnic_pipeline.c
index d1084ea..77911bb 100644
--- a/drivers/net/softnic/rte_eth_softnic_pipeline.c
+++ b/drivers/net/softnic/rte_eth_softnic_pipeline.c
@@ -56,6 +56,17 @@ softnic_pipeline_table_free(struct softnic_table *table)
 		TAILQ_REMOVE(&table->flows, flow, node);
 		free(flow);
 	}
+
+	for ( ; ; ) {
+		struct softnic_mtr_meter_profile *mp;
+
+		mp = TAILQ_FIRST(&table->meter_profiles);
+		if (mp == NULL)
+			break;
+
+		TAILQ_REMOVE(&table->meter_profiles, mp, node);
+		free(mp);
+	}
 }
 
 void
@@ -989,6 +1000,7 @@ softnic_pipeline_table_create(struct pmd_internals *softnic,
 	table->ap = ap;
 	table->a = action;
 	TAILQ_INIT(&table->flows);
+	TAILQ_INIT(&table->meter_profiles);
 	pipeline->n_tables++;
 
 	return 0;
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH 07/10] net/softnic: update dscp table
  2018-09-07 18:13 [dpdk-dev] [PATCH 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                   ` (5 preceding siblings ...)
  2018-09-07 18:13 ` [dpdk-dev] [PATCH 06/10] net/softnic: update meter profile Jasvinder Singh
@ 2018-09-07 18:13 ` Jasvinder Singh
  2018-09-07 18:13 ` [dpdk-dev] [PATCH 08/10] net/softnic: update policer actions Jasvinder Singh
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-07 18:13 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter object dscp table update.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_internals.h |  1 +
 drivers/net/softnic/rte_eth_softnic_meter.c     | 53 ++++++++++++++++++++++++-
 drivers/net/softnic/rte_eth_softnic_pipeline.c  |  1 +
 3 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index 5995e61..037088b 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -455,6 +455,7 @@ struct softnic_table {
 	struct softnic_table_action_profile *ap;
 	struct rte_table_action *a;
 	struct flow_list flows;
+	struct rte_table_action_dscp_table dscp_table;
 	struct softnic_mtr_meter_profile_list meter_profiles;
 };
 
diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 3b05ad6..9344f37 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -453,6 +453,57 @@ pmd_mtr_meter_profile_update(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* MTR object meter DSCP table update */
+static int
+pmd_mtr_meter_dscp_table_update(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	enum rte_mtr_color *dscp_table,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr *m;
+
+	/* MTR object id must be valid */
+	m = softnic_mtr_find(p, mtr_id);
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			rte_strerror(EEXIST));
+
+	/* MTR object owner valid? */
+	if (m->flow == NULL)
+		return 0;
+
+	/* Update the data plane table */
+	struct pipeline *pipeline = m->flow->pipeline;
+	struct softnic_table *table = &pipeline->table[m->flow->table_id];
+	struct rte_table_action_dscp_table dt;
+	uint32_t i;
+	int status;
+
+	memcpy(&dt, &table->dscp_table, sizeof(dt));
+
+	for (i = 0; i < RTE_DIM(dt.entry); i++)
+		dt.entry[i].color = (enum rte_meter_color)dscp_table[i];
+
+	status = rte_table_action_dscp_table_update(table->a,
+			UINT64_MAX,
+			&dt);
+	if (status)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			rte_strerror(EINVAL));
+
+	/* Update the current table */
+	memcpy(&table->dscp_table, &dt, sizeof(table->dscp_table));
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
@@ -465,7 +516,7 @@ const struct rte_mtr_ops pmd_mtr_ops = {
 	.meter_disable = NULL,
 
 	.meter_profile_update = pmd_mtr_meter_profile_update,
-	.meter_dscp_table_update = NULL,
+	.meter_dscp_table_update = pmd_mtr_meter_dscp_table_update,
 	.policer_actions_update = NULL,
 	.stats_update = NULL,
 
diff --git a/drivers/net/softnic/rte_eth_softnic_pipeline.c b/drivers/net/softnic/rte_eth_softnic_pipeline.c
index 77911bb..7c54ca8 100644
--- a/drivers/net/softnic/rte_eth_softnic_pipeline.c
+++ b/drivers/net/softnic/rte_eth_softnic_pipeline.c
@@ -1001,6 +1001,7 @@ softnic_pipeline_table_create(struct pmd_internals *softnic,
 	table->a = action;
 	TAILQ_INIT(&table->flows);
 	TAILQ_INIT(&table->meter_profiles);
+	memset(&table->dscp_table, 0, sizeof(table->dscp_table));
 	pipeline->n_tables++;
 
 	return 0;
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH 08/10] net/softnic: update policer actions
  2018-09-07 18:13 [dpdk-dev] [PATCH 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                   ` (6 preceding siblings ...)
  2018-09-07 18:13 ` [dpdk-dev] [PATCH 07/10] net/softnic: update dscp table Jasvinder Singh
@ 2018-09-07 18:13 ` Jasvinder Singh
  2018-09-07 18:13 ` [dpdk-dev] [PATCH 09/10] net/softnic: meter stats read Jasvinder Singh
  2018-09-07 18:13 ` [dpdk-dev] [PATCH 10/10] net/softnic: enable meter action using flow rule Jasvinder Singh
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-07 18:13 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter object policer actions function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_meter.c | 127 +++++++++++++++++++++++++++-
 1 file changed, 126 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 9344f37..41af9c7 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -504,6 +504,131 @@ pmd_mtr_meter_dscp_table_update(struct rte_eth_dev *dev,
 	return 0;
 }
 
+static int
+softnic_table_policer_actions_update(struct pmd_internals *p,
+	struct softnic_mtr *m,
+	uint32_t action_mask,
+	enum rte_mtr_policer_action *actions,
+	struct rte_mtr_error *error)
+{
+	struct rte_flow *mflow = m->flow;
+	uint32_t i;
+	int status;
+
+	/* Update meter policer actions */
+	for (i = 0; i < RTE_MTR_COLORS; i++) {
+		if ((action_mask >> i) & 1)
+			mflow->action.mtr.mtr[0].policer[i] =
+				(enum rte_table_action_policer)actions[i];
+	}
+
+	/* Re-add new rule */
+	status = softnic_pipeline_table_rule_add(p,
+		mflow->pipeline->name,
+		mflow->table_id,
+		&mflow->match,
+		&mflow->action,
+		&mflow->data);
+	if (status) {
+		rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"Pipeline table rule re-add failed");
+		return -1;
+	}
+
+	/* Reset the meter stats */
+	struct pipeline *pipeline = mflow->pipeline;
+	struct softnic_table *table = &pipeline->table[mflow->table_id];
+	uint32_t tc_mask = 1 << 0;
+
+	status = rte_table_action_meter_read(table->a,
+		mflow->data,
+		tc_mask,
+		NULL,
+		1);
+	if (status) {
+		rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"Meter stats reset failed");
+		return -1;
+	}
+
+	return 0;
+}
+
+/* MTR object policer action update */
+static int
+pmd_mtr_policer_actions_update(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	uint32_t action_mask,
+	enum rte_mtr_policer_action *actions,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr *m;
+	uint32_t i;
+	int status;
+
+	/* MTR object id must be valid */
+	m = softnic_mtr_find(p, mtr_id);
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			rte_strerror(EEXIST));
+
+	/* Policer actions */
+	if (actions == NULL)
+		return -rte_mtr_error_set(error,
+				EINVAL,
+				RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+				NULL,
+				rte_strerror(EINVAL));
+
+	/* Valid Policer actions */
+	for (i = 0; i < RTE_MTR_COLORS; i++) {
+		if ((action_mask >> i) & 1) {
+			if (actions[i] != MTR_POLICER_ACTION_COLOR_GREEN  &&
+				actions[i] != MTR_POLICER_ACTION_COLOR_YELLOW &&
+				actions[i] != MTR_POLICER_ACTION_COLOR_RED &&
+				actions[i] != MTR_POLICER_ACTION_DROP)
+				return -rte_mtr_error_set(error,
+					EINVAL,
+					RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+					NULL,
+					rte_strerror(EINVAL));
+		}
+	}
+
+	/* MTR object owner valid? */
+	if (m->flow) {
+		status = softnic_table_policer_actions_update(p,
+				m,
+				action_mask,
+				actions,
+				error);
+		if (status)
+			return -rte_mtr_error_set(error,
+				EINVAL,
+				RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+				NULL,
+				rte_strerror(EINVAL));
+	}
+
+	/* Update MTR object policer actions */
+	for (i = 0; i < RTE_MTR_COLORS; i++) {
+		if ((action_mask >> i) & 1)
+			m->params.action[i] = actions[i];
+	}
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
@@ -517,7 +642,7 @@ const struct rte_mtr_ops pmd_mtr_ops = {
 
 	.meter_profile_update = pmd_mtr_meter_profile_update,
 	.meter_dscp_table_update = pmd_mtr_meter_dscp_table_update,
-	.policer_actions_update = NULL,
+	.policer_actions_update = pmd_mtr_policer_actions_update,
 	.stats_update = NULL,
 
 	.stats_read = NULL,
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH 09/10] net/softnic: meter stats read
  2018-09-07 18:13 [dpdk-dev] [PATCH 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                   ` (7 preceding siblings ...)
  2018-09-07 18:13 ` [dpdk-dev] [PATCH 08/10] net/softnic: update policer actions Jasvinder Singh
@ 2018-09-07 18:13 ` Jasvinder Singh
  2018-09-07 18:13 ` [dpdk-dev] [PATCH 10/10] net/softnic: enable meter action using flow rule Jasvinder Singh
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-07 18:13 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter object stats read function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_meter.c | 99 ++++++++++++++++++++++++++++-
 1 file changed, 98 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 41af9c7..2cea19f 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -629,6 +629,103 @@ pmd_mtr_policer_actions_update(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* MTR object stats read */
+static int
+pmd_mtr_stats_read(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	struct rte_mtr_stats *stats,
+	uint64_t *stats_mask,
+	int clear,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr *m;
+	uint32_t i;
+	int status;
+
+	/* MTR object id must be valid */
+	m = softnic_mtr_find(p, mtr_id);
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			rte_strerror(EEXIST));
+
+	/* MTR meter object owner valid? */
+	if (m->flow == NULL)
+		return 0;
+
+	/* Meter stats */
+	struct pipeline *pipeline = m->flow->pipeline;
+	struct softnic_table *table = &pipeline->table[m->flow->table_id];
+	struct rte_table_action_mtr_counters counters;
+	uint32_t tc_mask = 1 << 0;
+
+	status = rte_table_action_meter_read(table->a,
+		m->flow->data,
+		tc_mask,
+		&counters,
+		clear);
+	if (status) {
+		rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"Meter stats read failed");
+		return -1;
+	}
+
+	if (stats) {
+		struct rte_table_action_mtr_counters_tc tc_stats;
+
+		memcpy(&tc_stats, &counters.stats[tc_mask], sizeof(tc_stats));
+
+		for (i = 0; i < RTE_MTR_COLORS; i++) {
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_GREEN) {
+				stats->n_pkts[RTE_MTR_GREEN] += tc_stats.n_packets[i];
+				stats->n_bytes[RTE_MTR_GREEN] += tc_stats.n_bytes[i];
+			}
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_YELLOW) {
+				stats->n_pkts[RTE_MTR_YELLOW] += tc_stats.n_packets[i];
+				stats->n_bytes[RTE_MTR_YELLOW] += tc_stats.n_bytes[i];
+			}
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_RED) {
+				stats->n_pkts[RTE_MTR_RED] += tc_stats.n_packets[i];
+				stats->n_bytes[RTE_MTR_RED] += tc_stats.n_bytes[i];
+			}
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_DROP) {
+				stats->n_pkts_dropped += tc_stats.n_packets[i];
+				stats->n_bytes_dropped += tc_stats.n_bytes[i];
+			}
+		}
+	}
+
+	if (stats_mask) {
+		if (stats->n_pkts[RTE_MTR_GREEN])
+			*stats_mask |= RTE_MTR_STATS_N_PKTS_GREEN;
+		if (stats->n_pkts[RTE_MTR_YELLOW])
+			*stats_mask |= RTE_MTR_STATS_N_PKTS_YELLOW;
+		if (stats->n_pkts[RTE_MTR_RED])
+			*stats_mask |= RTE_MTR_STATS_N_PKTS_RED;
+		if (stats->n_bytes[RTE_MTR_GREEN])
+			*stats_mask |= RTE_MTR_STATS_N_BYTES_GREEN;
+		if (stats->n_bytes[RTE_MTR_YELLOW])
+			*stats_mask |= RTE_MTR_STATS_N_BYTES_YELLOW;
+		if (stats->n_bytes[RTE_MTR_RED])
+			*stats_mask |= RTE_MTR_STATS_N_BYTES_RED;
+		if (stats->n_pkts_dropped)
+			*stats_mask |= RTE_MTR_STATS_N_PKTS_DROPPED;
+		if (stats->n_bytes_dropped)
+			*stats_mask |= RTE_MTR_STATS_N_BYTES_DROPPED;
+	}
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
@@ -645,5 +742,5 @@ const struct rte_mtr_ops pmd_mtr_ops = {
 	.policer_actions_update = pmd_mtr_policer_actions_update,
 	.stats_update = NULL,
 
-	.stats_read = NULL,
+	.stats_read = pmd_mtr_stats_read,
 };
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH 10/10] net/softnic: enable meter action using flow rule
  2018-09-07 18:13 [dpdk-dev] [PATCH 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                   ` (8 preceding siblings ...)
  2018-09-07 18:13 ` [dpdk-dev] [PATCH 09/10] net/softnic: meter stats read Jasvinder Singh
@ 2018-09-07 18:13 ` Jasvinder Singh
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-07 18:13 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter enablement through flow rules.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_flow.c | 170 +++++++++++++++++++++++++++++
 1 file changed, 170 insertions(+)

diff --git a/drivers/net/softnic/rte_eth_softnic_flow.c b/drivers/net/softnic/rte_eth_softnic_flow.c
index 6562004..0f33381 100644
--- a/drivers/net/softnic/rte_eth_softnic_flow.c
+++ b/drivers/net/softnic/rte_eth_softnic_flow.c
@@ -1459,6 +1459,117 @@ flow_rule_action_get(struct pmd_internals *softnic,
 			break;
 		} /* RTE_FLOW_ACTION_TYPE_COUNT */
 
+		case RTE_FLOW_ACTION_TYPE_METER:
+		{
+			struct rte_table_action_mtr_tc_params mtr_tc_params;
+			const struct rte_flow_action_meter *conf = action->conf;
+			struct softnic_mtr *m;
+			struct softnic_mtr_meter_profile *mp;
+			uint32_t meter_profile_id;
+
+			if (conf == NULL)
+				return rte_flow_error_set(error,
+					EINVAL,
+					RTE_FLOW_ERROR_TYPE_ACTION,
+					action,
+					"COUNT: Null configuration");
+
+			if ((params->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) == 0)
+				return rte_flow_error_set(error,
+					EINVAL,
+					RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+					NULL,
+					"METER action not supported by this table");
+
+			m = softnic_mtr_find(softnic, conf->mtr_id);
+			if (m == NULL)
+				return -rte_flow_error_set(error,
+					EINVAL,
+					RTE_FLOW_ERROR_TYPE_ACTION_CONF,
+					NULL,
+					rte_strerror(EINVAL));
+
+			if (params->mtr.n_tc != 1)
+				return -rte_flow_error_set(error,
+					EINVAL,
+					RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+					NULL,
+					rte_strerror(EINVAL));
+
+			meter_profile_id = m->params.meter_profile_id;
+
+			mp = softnic_table_meter_profile_find(table, meter_profile_id);
+			if (mp == NULL) {
+				struct softnic_mtr_meter_profile *mtr_meter_profile;
+				struct rte_table_action_meter_profile profile;
+				int status;
+
+				mp = calloc(1, sizeof(struct softnic_mtr_meter_profile));
+				if (mp == NULL) {
+					rte_flow_error_set(error,
+						ENOMEM,
+						RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+						NULL,
+						"Not enough table memory for meter profile");
+					return -1;
+				}
+
+				mtr_meter_profile = softnic_mtr_meter_profile_find(softnic,
+					meter_profile_id);
+				if (mtr_meter_profile == NULL) {
+					free(mp);
+
+					rte_flow_error_set(error,
+						EINVAL,
+						RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+						NULL,
+						rte_strerror(EINVAL));
+					return -1;
+				}
+
+				mp->meter_profile_id = meter_profile_id;
+				mp->n_users = mtr_meter_profile->n_users;
+				memcpy(&mp->params, &mtr_meter_profile->params,
+					sizeof(mp->params));
+
+				profile.alg = RTE_TABLE_ACTION_METER_TRTCM;
+				memcpy(&profile.trtcm, &mp->params.trtcm_rfc2698,
+					sizeof(profile.trtcm));
+
+				status = rte_table_action_meter_profile_add(table->a,
+					meter_profile_id,
+					&profile);
+				if (status) {
+						free(mp);
+
+					rte_flow_error_set(error,
+						EINVAL,
+						RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+						NULL,
+						rte_strerror(EINVAL));
+					return -1;
+				}
+
+				/* Add to table meter profile list */
+				TAILQ_INSERT_TAIL(&table->meter_profiles, mp, node);
+			}
+
+			mtr_tc_params.meter_profile_id = meter_profile_id;
+			mtr_tc_params.policer[e_RTE_METER_GREEN] =
+				(enum rte_table_action_policer)m->params.action[RTE_MTR_GREEN];
+			mtr_tc_params.policer[e_RTE_METER_YELLOW] =
+				(enum rte_table_action_policer)m->params.action[RTE_MTR_YELLOW];
+			mtr_tc_params.policer[e_RTE_METER_RED] =
+				(enum rte_table_action_policer)m->params.action[RTE_MTR_RED];
+
+			/* RTE_TABLE_ACTION_METER */
+			memcpy(&rule_action->mtr.mtr[0], &mtr_tc_params,
+				sizeof(rule_action->mtr.mtr[0]));
+			rule_action->mtr.tc_mask = 1 << 0;
+			rule_action->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
+			break;
+		} /* RTE_FLOW_ACTION_TYPE_METER */
+
 		default:
 			return -ENOTSUP;
 		}
@@ -1562,6 +1673,35 @@ pmd_flow_validate(struct rte_eth_dev *dev,
 	return 0;
 }
 
+static void set_meter_owner_to_flow(struct pmd_internals *softnic,
+	struct rte_flow *flow,
+	const struct rte_flow_action *action)
+{
+	for ( ; action->type != RTE_FLOW_ACTION_TYPE_END; action++) {
+
+		if (action->type == RTE_FLOW_ACTION_TYPE_VOID)
+			continue;
+
+		if (action->type == RTE_FLOW_ACTION_TYPE_METER) {
+			const struct rte_flow_action_meter *conf = action->conf;
+			struct softnic_mtr_list *ml = &softnic->mtr.mtrs;
+			struct softnic_mtr *m;
+
+			TAILQ_FOREACH(m, ml, node) {
+				if (m->flow == flow) {
+					m->flow = NULL;
+					break;
+				}
+			}
+
+			m = softnic_mtr_find(softnic, conf->mtr_id);
+			m->flow = flow;
+
+			break;
+		}
+	}
+}
+
 static struct rte_flow *
 pmd_flow_create(struct rte_eth_dev *dev,
 	const struct rte_flow_attr *attr,
@@ -1702,6 +1842,8 @@ pmd_flow_create(struct rte_eth_dev *dev,
 	flow->pipeline = pipeline;
 	flow->table_id = table_id;
 
+	set_meter_owner_to_flow(softnic, flow, action);
+
 	/* Flow add to list. */
 	if (new_flow)
 		TAILQ_INSERT_TAIL(&table->flows, flow, node);
@@ -1709,6 +1851,31 @@ pmd_flow_create(struct rte_eth_dev *dev,
 	return flow;
 }
 
+static void reset_meter_owner(struct pmd_internals *softnic,
+	struct softnic_table *table,
+	struct rte_flow *flow)
+{
+	struct softnic_table_action_profile *profile;
+	struct softnic_table_action_profile_params *params;
+
+	profile = softnic_table_action_profile_find(softnic,
+		table->params.action_profile_name);
+
+	params = &profile->params;
+
+	if ((params->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) == 0) {
+		struct softnic_mtr_list *ml = &softnic->mtr.mtrs;
+		struct softnic_mtr *m;
+
+		TAILQ_FOREACH(m, ml, node) {
+			if (m->flow == flow) {
+				m->flow = NULL;
+				break;
+			}
+		}
+	}
+}
+
 static int
 pmd_flow_destroy(struct rte_eth_dev *dev,
 	struct rte_flow *flow,
@@ -1744,6 +1911,9 @@ pmd_flow_destroy(struct rte_eth_dev *dev,
 	TAILQ_REMOVE(&table->flows, flow, node);
 	free(flow);
 
+	/* Update dependencies */
+	reset_meter_owner(softnic, table, flow);
+
 	return 0;
 }
 
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v2 00/10] net/softnic: implement metering and policing API
  2018-09-07 18:13 ` [dpdk-dev] [PATCH 01/10] net/softnic: add metering and policing support Jasvinder Singh
@ 2018-09-12 16:41   ` Jasvinder Singh
  2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 01/10] net/softnic: add metering and policing support Jasvinder Singh
                       ` (9 more replies)
  0 siblings, 10 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-12 16:41 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

This patchset adds the metering and policing API support for the
softnic. The metering and policing action can be enabled through the
flow rules.

This series is prepared on top of following patchset;
https://mails.dpdk.org/archives/dev/2018-September/111379.html

v2 changes:
- fix copyright year for rte_eth_softnic_meter.c
- Place all checks in a separate functions while creating meter object
- Use softnic_pipeline_table_mtr_profile_add() api to add meter profile
  instead of implementing new function
- Use stats type indicator to determine the stats_mask for meter stats read 
 
Jasvinder Singh (10):
  net/softnic: add metering and policing support
  net/softnic: add meter profile
  net/softnic: delete meter profile
  net/softnic: create meter object
  net/softnic: destroy meter object
  net/softnic: update meter profile
  net/softnic: update dscp table
  net/softnic: update policer actions
  net/softnic: meter stats read
  net/softnic: enable flow rule with meter action

 drivers/net/softnic/Makefile                    |   1 +
 drivers/net/softnic/meson.build                 |   1 +
 drivers/net/softnic/rte_eth_softnic.c           |  13 +
 drivers/net/softnic/rte_eth_softnic_flow.c      | 153 +++++
 drivers/net/softnic/rte_eth_softnic_internals.h |  66 +++
 drivers/net/softnic/rte_eth_softnic_meter.c     | 713 ++++++++++++++++++++++++
 drivers/net/softnic/rte_eth_softnic_pipeline.c  |  13 +
 7 files changed, 960 insertions(+)
 create mode 100644 drivers/net/softnic/rte_eth_softnic_meter.c

-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v2 01/10] net/softnic: add metering and policing support
  2018-09-12 16:41   ` [dpdk-dev] [PATCH v2 00/10] net/softnic: implement metering and policing API Jasvinder Singh
@ 2018-09-12 16:41     ` Jasvinder Singh
  2018-09-14 17:45       ` [dpdk-dev] [PATCH v3 00/10] net/softnic: implement metering and policing API Jasvinder Singh
  2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 02/10] net/softnic: add meter profile Jasvinder Singh
                       ` (8 subsequent siblings)
  9 siblings, 1 reply; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-12 16:41 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Enable metering and policing support for softnic.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/Makefile                    |  1 +
 drivers/net/softnic/meson.build                 |  1 +
 drivers/net/softnic/rte_eth_softnic.c           | 10 ++++++++
 drivers/net/softnic/rte_eth_softnic_internals.h |  5 ++++
 drivers/net/softnic/rte_eth_softnic_meter.c     | 31 +++++++++++++++++++++++++
 5 files changed, 48 insertions(+)
 create mode 100644 drivers/net/softnic/rte_eth_softnic_meter.c

diff --git a/drivers/net/softnic/Makefile b/drivers/net/softnic/Makefile
index 12515b1..720f067b 100644
--- a/drivers/net/softnic/Makefile
+++ b/drivers/net/softnic/Makefile
@@ -34,6 +34,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_pipeline.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_thread.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_cli.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_flow.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_meter.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += parser.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += conn.c
 
diff --git a/drivers/net/softnic/meson.build b/drivers/net/softnic/meson.build
index 56e5e2b..6b7a6cc 100644
--- a/drivers/net/softnic/meson.build
+++ b/drivers/net/softnic/meson.build
@@ -14,6 +14,7 @@ sources = files('rte_eth_softnic_tm.c',
 	'rte_eth_softnic_thread.c',
 	'rte_eth_softnic_cli.c',
 	'rte_eth_softnic_flow.c',
+	'rte_eth_softnic_meter.c',
 	'parser.c',
 	'conn.c')
 deps += ['pipeline', 'port', 'table', 'sched']
diff --git a/drivers/net/softnic/rte_eth_softnic.c b/drivers/net/softnic/rte_eth_softnic.c
index ae2a438..659a1b4 100644
--- a/drivers/net/softnic/rte_eth_softnic.c
+++ b/drivers/net/softnic/rte_eth_softnic.c
@@ -14,6 +14,7 @@
 #include <rte_errno.h>
 #include <rte_ring.h>
 #include <rte_tm_driver.h>
+#include <rte_mtr_driver.h>
 
 #include "rte_eth_softnic.h"
 #include "rte_eth_softnic_internals.h"
@@ -228,6 +229,14 @@ pmd_tm_ops_get(struct rte_eth_dev *dev __rte_unused, void *arg)
 	return 0;
 }
 
+static int
+pmd_mtr_ops_get(struct rte_eth_dev *dev __rte_unused, void *arg)
+{
+	*(const struct rte_mtr_ops **)arg = &pmd_mtr_ops;
+
+	return 0;
+}
+
 static const struct eth_dev_ops pmd_ops = {
 	.dev_configure = pmd_dev_configure,
 	.dev_start = pmd_dev_start,
@@ -239,6 +248,7 @@ static const struct eth_dev_ops pmd_ops = {
 	.tx_queue_setup = pmd_tx_queue_setup,
 	.filter_ctrl = pmd_filter_ctrl,
 	.tm_ops_get = pmd_tm_ops_get,
+	.mtr_ops_get = pmd_mtr_ops_get,
 };
 
 static uint16_t
diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index a1a2e15..92be4e8 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -572,6 +572,11 @@ flow_attr_map_get(struct pmd_internals *softnic,
 extern const struct rte_flow_ops pmd_flow_ops;
 
 /**
+ * Meter
+ */
+extern const struct rte_mtr_ops pmd_mtr_ops;
+
+/**
  * MEMPOOL
  */
 int
diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
new file mode 100644
index 0000000..0a5409b
--- /dev/null
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <rte_mtr.h>
+#include <rte_mtr_driver.h>
+
+#include "rte_eth_softnic_internals.h"
+
+const struct rte_mtr_ops pmd_mtr_ops = {
+	.capabilities_get = NULL,
+
+	.meter_profile_add = NULL,
+	.meter_profile_delete = NULL,
+
+	.create = NULL,
+	.destroy = NULL,
+	.meter_enable = NULL,
+	.meter_disable = NULL,
+
+	.meter_profile_update = NULL,
+	.meter_dscp_table_update = NULL,
+	.policer_actions_update = NULL,
+	.stats_update = NULL,
+
+	.stats_read = NULL,
+};
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v2 02/10] net/softnic: add meter profile
  2018-09-12 16:41   ` [dpdk-dev] [PATCH v2 00/10] net/softnic: implement metering and policing API Jasvinder Singh
  2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 01/10] net/softnic: add metering and policing support Jasvinder Singh
@ 2018-09-12 16:41     ` Jasvinder Singh
  2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 03/10] net/softnic: delete " Jasvinder Singh
                       ` (7 subsequent siblings)
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-12 16:41 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter profile add function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic.c           |   3 +
 drivers/net/softnic/rte_eth_softnic_internals.h |  31 ++++++
 drivers/net/softnic/rte_eth_softnic_meter.c     | 122 +++++++++++++++++++++++-
 3 files changed, 155 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic.c b/drivers/net/softnic/rte_eth_softnic.c
index 659a1b4..b7b2383 100644
--- a/drivers/net/softnic/rte_eth_softnic.c
+++ b/drivers/net/softnic/rte_eth_softnic.c
@@ -191,6 +191,7 @@ pmd_dev_stop(struct rte_eth_dev *dev)
 	softnic_mempool_free(p);
 
 	tm_hierarchy_free(p);
+	softnic_mtr_free(p);
 }
 
 static void
@@ -291,6 +292,7 @@ pmd_init(struct pmd_params *params)
 
 	/* Resources */
 	tm_hierarchy_init(p);
+	softnic_mtr_init(p);
 
 	softnic_mempool_init(p);
 	softnic_swq_init(p);
@@ -345,6 +347,7 @@ pmd_free(struct pmd_internals *p)
 	softnic_mempool_free(p);
 
 	tm_hierarchy_free(p);
+	softnic_mtr_free(p);
 
 	rte_free(p);
 }
diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index 92be4e8..1db9310 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -22,6 +22,7 @@
 #include <rte_ethdev_driver.h>
 #include <rte_tm_driver.h>
 #include <rte_flow_driver.h>
+#include <rte_mtr_driver.h>
 
 #include "rte_eth_softnic.h"
 #include "conn.h"
@@ -68,6 +69,24 @@ struct flow_internals {
 };
 
 /**
+ * Meter
+ */
+
+/* MTR meter profile */
+struct softnic_mtr_meter_profile {
+	TAILQ_ENTRY(softnic_mtr_meter_profile) node;
+	uint32_t meter_profile_id;
+	struct rte_mtr_meter_profile params;
+	uint32_t n_users;
+};
+
+TAILQ_HEAD(softnic_mtr_meter_profile_list, softnic_mtr_meter_profile);
+
+struct mtr_internals {
+	struct softnic_mtr_meter_profile_list meter_profiles;
+};
+
+/**
  * MEMPOOL
  */
 struct softnic_mempool_params {
@@ -525,6 +544,8 @@ struct pmd_internals {
 	} soft;
 
 	struct flow_internals flow;
+	struct mtr_internals mtr;
+
 	struct softnic_conn *conn;
 	struct softnic_mempool_list mempool_list;
 	struct softnic_swq_list swq_list;
@@ -574,6 +595,16 @@ extern const struct rte_flow_ops pmd_flow_ops;
 /**
  * Meter
  */
+int
+softnic_mtr_init(struct pmd_internals *p);
+
+void
+softnic_mtr_free(struct pmd_internals *p);
+
+struct softnic_mtr_meter_profile *
+softnic_mtr_meter_profile_find(struct pmd_internals *p,
+	uint32_t meter_profile_id);
+
 extern const struct rte_mtr_ops pmd_mtr_ops;
 
 /**
diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 0a5409b..1222866 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -11,10 +11,130 @@
 
 #include "rte_eth_softnic_internals.h"
 
+int
+softnic_mtr_init(struct pmd_internals *p)
+{
+	/* Initialize meter profiles list */
+	TAILQ_INIT(&p->mtr.meter_profiles);
+
+	return 0;
+}
+
+void
+softnic_mtr_free(struct pmd_internals *p)
+{
+	/* Remove meter profiles */
+	for ( ; ; ) {
+		struct softnic_mtr_meter_profile *mp;
+
+		mp = TAILQ_FIRST(&p->mtr.meter_profiles);
+		if (mp == NULL)
+			break;
+
+		TAILQ_REMOVE(&p->mtr.meter_profiles, mp, node);
+		free(mp);
+	}
+}
+
+struct softnic_mtr_meter_profile *
+softnic_mtr_meter_profile_find(struct pmd_internals *p,
+	uint32_t meter_profile_id)
+{
+	struct softnic_mtr_meter_profile_list *mpl = &p->mtr.meter_profiles;
+	struct softnic_mtr_meter_profile *mp;
+
+	TAILQ_FOREACH(mp, mpl, node)
+		if (meter_profile_id == mp->meter_profile_id)
+			return mp;
+
+	return NULL;
+}
+
+static int
+meter_profile_check(struct rte_eth_dev *dev,
+	uint32_t meter_profile_id,
+	struct rte_mtr_meter_profile *profile,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_meter_profile *mp;
+
+	/* Meter profile ID must be valid. */
+	if (meter_profile_id == UINT32_MAX)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"Meter profile id not valid");
+
+	/* Meter profile must not exist. */
+	mp = softnic_mtr_meter_profile_find(p, meter_profile_id);
+	if (mp)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"Meter prfile already exists");
+
+	/* Profile must not be NULL. */
+	if (profile == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE,
+			NULL,
+			"profile null");
+
+	/* Traffic metering algorithm : TRTCM_RFC2698 */
+	if (profile->alg != RTE_MTR_TRTCM_RFC2698)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE,
+			NULL,
+			"Metering alg not supported");
+
+	return 0;
+}
+
+/* MTR meter profile add */
+static int
+pmd_mtr_meter_profile_add(struct rte_eth_dev *dev,
+	uint32_t meter_profile_id,
+	struct rte_mtr_meter_profile *profile,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_meter_profile_list *mpl = &p->mtr.meter_profiles;
+	struct softnic_mtr_meter_profile *mp;
+	int status;
+
+	/* Check input params */
+	status = meter_profile_check(dev, meter_profile_id, profile, error);
+	if (status)
+		return status;
+
+	/* Memory allocation */
+	mp = calloc(1, sizeof(struct softnic_mtr_meter_profile));
+	if (mp == NULL)
+		return -rte_mtr_error_set(error,
+			ENOMEM,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"Memory alloc failed");
+
+	/* Fill in */
+	mp->meter_profile_id = meter_profile_id;
+	memcpy(&mp->params, profile, sizeof(mp->params));
+
+	/* Add to list */
+	TAILQ_INSERT_TAIL(mpl, mp, node);
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
-	.meter_profile_add = NULL,
+	.meter_profile_add = pmd_mtr_meter_profile_add,
 	.meter_profile_delete = NULL,
 
 	.create = NULL,
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v2 03/10] net/softnic: delete meter profile
  2018-09-12 16:41   ` [dpdk-dev] [PATCH v2 00/10] net/softnic: implement metering and policing API Jasvinder Singh
  2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 01/10] net/softnic: add metering and policing support Jasvinder Singh
  2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 02/10] net/softnic: add meter profile Jasvinder Singh
@ 2018-09-12 16:41     ` Jasvinder Singh
  2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 04/10] net/softnic: create meter object Jasvinder Singh
                       ` (6 subsequent siblings)
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-12 16:41 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter profile delete function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_meter.c | 35 ++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 1222866..f3205bd 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -131,11 +131,44 @@ pmd_mtr_meter_profile_add(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* MTR meter profile delete */
+static int
+pmd_mtr_meter_profile_delete(struct rte_eth_dev *dev,
+	uint32_t meter_profile_id,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_meter_profile *mp;
+
+	/* Meter profile must exist */
+	mp = softnic_mtr_meter_profile_find(p, meter_profile_id);
+	if (mp == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"Meter profile id invalid");
+
+	/* Check unused */
+	if (mp->n_users)
+		return -rte_mtr_error_set(error,
+			EBUSY,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"Meter profile in use");
+
+	/* Remove from list */
+	TAILQ_REMOVE(&p->mtr.meter_profiles, mp, node);
+	free(mp);
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
 	.meter_profile_add = pmd_mtr_meter_profile_add,
-	.meter_profile_delete = NULL,
+	.meter_profile_delete = pmd_mtr_meter_profile_delete,
 
 	.create = NULL,
 	.destroy = NULL,
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v2 04/10] net/softnic: create meter object
  2018-09-12 16:41   ` [dpdk-dev] [PATCH v2 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                       ` (2 preceding siblings ...)
  2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 03/10] net/softnic: delete " Jasvinder Singh
@ 2018-09-12 16:41     ` Jasvinder Singh
  2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 05/10] net/softnic: destroy " Jasvinder Singh
                       ` (5 subsequent siblings)
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-12 16:41 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

implement meter object create function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_internals.h |  15 +++
 drivers/net/softnic/rte_eth_softnic_meter.c     | 123 +++++++++++++++++++++++-
 2 files changed, 137 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index 1db9310..50b7295 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -82,8 +82,19 @@ struct softnic_mtr_meter_profile {
 
 TAILQ_HEAD(softnic_mtr_meter_profile_list, softnic_mtr_meter_profile);
 
+/* MTR meter object */
+struct softnic_mtr {
+	TAILQ_ENTRY(softnic_mtr) node;
+	uint32_t mtr_id;
+	struct rte_mtr_params params;
+	struct rte_flow *flow;
+};
+
+TAILQ_HEAD(softnic_mtr_list, softnic_mtr);
+
 struct mtr_internals {
 	struct softnic_mtr_meter_profile_list meter_profiles;
+	struct softnic_mtr_list mtrs;
 };
 
 /**
@@ -601,6 +612,10 @@ softnic_mtr_init(struct pmd_internals *p);
 void
 softnic_mtr_free(struct pmd_internals *p);
 
+struct softnic_mtr *
+softnic_mtr_find(struct pmd_internals *p,
+	uint32_t mtr_id);
+
 struct softnic_mtr_meter_profile *
 softnic_mtr_meter_profile_find(struct pmd_internals *p,
 	uint32_t meter_profile_id);
diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index f3205bd..12dd79c 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -17,12 +17,27 @@ softnic_mtr_init(struct pmd_internals *p)
 	/* Initialize meter profiles list */
 	TAILQ_INIT(&p->mtr.meter_profiles);
 
+	/* Initialize MTR objects list */
+	TAILQ_INIT(&p->mtr.mtrs);
+
 	return 0;
 }
 
 void
 softnic_mtr_free(struct pmd_internals *p)
 {
+	/* Remove MTR objects */
+	for ( ; ; ) {
+		struct softnic_mtr *m;
+
+		m = TAILQ_FIRST(&p->mtr.mtrs);
+		if (m == NULL)
+			break;
+
+		TAILQ_REMOVE(&p->mtr.mtrs, m, node);
+		free(m);
+	}
+
 	/* Remove meter profiles */
 	for ( ; ; ) {
 		struct softnic_mtr_meter_profile *mp;
@@ -164,13 +179,119 @@ pmd_mtr_meter_profile_delete(struct rte_eth_dev *dev,
 	return 0;
 }
 
+struct softnic_mtr *
+softnic_mtr_find(struct pmd_internals *p, uint32_t mtr_id)
+{
+	struct softnic_mtr_list *ml = &p->mtr.mtrs;
+	struct softnic_mtr *m;
+
+	TAILQ_FOREACH(m, ml, node)
+		if (m->mtr_id == mtr_id)
+			return m;
+
+	return NULL;
+}
+
+
+static int
+mtr_check(struct pmd_internals *p,
+	uint32_t mtr_id,
+	struct rte_mtr_params *params,
+	int shared,
+	struct rte_mtr_error *error)
+{
+	/* MTR id valid  */
+	if (softnic_mtr_find(p, mtr_id))
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			"MTR object already exists");
+
+	/* MTR params must not be NULL */
+	if (params == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_MTR_PARAMS,
+			NULL,
+			"MTR object params null");
+
+	/* Previous meter color not supported */
+	if (params->use_prev_mtr_color)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_MTR_PARAMS,
+			NULL,
+			"Previous meter color not supported");
+
+	/* Shared MTR object not supported */
+	if (shared)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_SHARED,
+			NULL,
+			"Shared MTR object not supported");
+
+	return 0;
+}
+
+/* MTR object create */
+static int
+pmd_mtr_create(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	struct rte_mtr_params *params,
+	int shared,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_list *ml = &p->mtr.mtrs;
+	struct softnic_mtr_meter_profile *mp;
+	struct softnic_mtr *m;
+	int status;
+
+	/* Check parameters */
+	status = mtr_check(p, mtr_id, params, shared, error);
+	if (status)
+		return status;
+
+	/* Meter profile must exist */
+	mp = softnic_mtr_meter_profile_find(p, params->meter_profile_id);
+	if (mp == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"Meter profile id not valid");
+
+	/* Memory allocation */
+	m = calloc(1, sizeof(struct softnic_mtr));
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			ENOMEM,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"Memory alloc failed");
+
+	/* Fill in */
+	m->mtr_id = mtr_id;
+	memcpy(&m->params, params, sizeof(m->params));
+
+	/* Add to list */
+	TAILQ_INSERT_TAIL(ml, m, node);
+
+	/* Update dependencies */
+	mp->n_users++;
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
 	.meter_profile_add = pmd_mtr_meter_profile_add,
 	.meter_profile_delete = pmd_mtr_meter_profile_delete,
 
-	.create = NULL,
+	.create = pmd_mtr_create,
 	.destroy = NULL,
 	.meter_enable = NULL,
 	.meter_disable = NULL,
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v2 05/10] net/softnic: destroy meter object
  2018-09-12 16:41   ` [dpdk-dev] [PATCH v2 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                       ` (3 preceding siblings ...)
  2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 04/10] net/softnic: create meter object Jasvinder Singh
@ 2018-09-12 16:41     ` Jasvinder Singh
  2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 06/10] net/softnic: update meter profile Jasvinder Singh
                       ` (4 subsequent siblings)
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-12 16:41 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter object destroy function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_meter.c | 49 ++++++++++++++++++++++++++++-
 1 file changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 12dd79c..5103bda 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -285,6 +285,53 @@ pmd_mtr_create(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* MTR object destroy */
+static int
+pmd_mtr_destroy(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_list *ml = &p->mtr.mtrs;
+	struct softnic_mtr_meter_profile *mp;
+	struct softnic_mtr *m;
+
+	/* MTR object must exist */
+	m = softnic_mtr_find(p, mtr_id);
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			"MTR object id not valid");
+
+	/* MTR object must not have any owner */
+	if (m->flow != NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"MTR object is being used");
+
+	/* Get meter profile */
+	mp = softnic_mtr_meter_profile_find(p, m->params.meter_profile_id);
+	if (mp == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"MTR object meter profile invalid");
+
+	/* Update dependencies */
+	mp->n_users--;
+
+	/* Remove from list */
+	TAILQ_REMOVE(ml, m, node);
+	free(m);
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
@@ -292,7 +339,7 @@ const struct rte_mtr_ops pmd_mtr_ops = {
 	.meter_profile_delete = pmd_mtr_meter_profile_delete,
 
 	.create = pmd_mtr_create,
-	.destroy = NULL,
+	.destroy = pmd_mtr_destroy,
 	.meter_enable = NULL,
 	.meter_disable = NULL,
 
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v2 06/10] net/softnic: update meter profile
  2018-09-12 16:41   ` [dpdk-dev] [PATCH v2 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                       ` (4 preceding siblings ...)
  2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 05/10] net/softnic: destroy " Jasvinder Singh
@ 2018-09-12 16:41     ` Jasvinder Singh
  2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 07/10] net/softnic: update dscp table Jasvinder Singh
                       ` (3 subsequent siblings)
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-12 16:41 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter profile update function

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_internals.h |  14 ++++
 drivers/net/softnic/rte_eth_softnic_meter.c     | 104 +++++++++++++++++++++++-
 drivers/net/softnic/rte_eth_softnic_pipeline.c  |  12 +++
 3 files changed, 129 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index 50b7295..784035f 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -320,6 +320,15 @@ struct softnic_table_action_profile {
 
 TAILQ_HEAD(softnic_table_action_profile_list, softnic_table_action_profile);
 
+struct softnic_table_action_meter_profile {
+	TAILQ_ENTRY(softnic_table_action_meter_profile) node;
+	uint32_t meter_profile_id;
+	struct rte_table_action_meter_profile profile;
+};
+
+TAILQ_HEAD(softnic_table_action_meter_profile_list,
+	softnic_table_action_meter_profile);
+
 /**
  * Pipeline
  */
@@ -455,6 +464,7 @@ struct softnic_table {
 	struct softnic_table_action_profile *ap;
 	struct rte_table_action *a;
 	struct flow_list flows;
+	struct softnic_table_action_meter_profile_list meter_profiles;
 };
 
 struct pipeline {
@@ -620,6 +630,10 @@ struct softnic_mtr_meter_profile *
 softnic_mtr_meter_profile_find(struct pmd_internals *p,
 	uint32_t meter_profile_id);
 
+struct softnic_mtr_meter_profile *
+softnic_table_meter_profile_find(struct softnic_table *table,
+	uint32_t meter_profile_id);
+
 extern const struct rte_mtr_ops pmd_mtr_ops;
 
 /**
diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 5103bda..e5c8f09 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -332,6 +332,108 @@ pmd_mtr_destroy(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* MTR object meter profile update */
+static int
+pmd_mtr_meter_profile_update(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	uint32_t meter_profile_id,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct rte_table_action_meter_profile profile;
+	struct softnic_table_rule_action action;
+	struct softnic_mtr_meter_profile *mp_in, *mp_out;
+	struct softnic_mtr *m;
+	int status;
+
+	/* MTR object id must be valid */
+	m = softnic_mtr_find(p, mtr_id);
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			"MTR object id not valid");
+
+	/* Meter profile id must be valid */
+	mp_in = softnic_mtr_meter_profile_find(p, meter_profile_id);
+	if (mp_in == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"Meter profile not valid");
+
+	/* MTR object current meter profile */
+	mp_out = softnic_mtr_meter_profile_find(p, m->params.meter_profile_id);
+	if (mp_out == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"MTR object current meter profile invalid");
+
+	/* MTR object already set to meter profile id */
+	if (m->params.meter_profile_id == meter_profile_id)
+		return 0;
+
+	/*  MTR object owner table update */
+	if (m->flow) {
+		memset(&profile, 0, sizeof(profile));
+
+		profile.alg = RTE_TABLE_ACTION_METER_TRTCM;
+		profile.trtcm.cir = mp_in->params.trtcm_rfc2698.cir;
+		profile.trtcm.pir = mp_in->params.trtcm_rfc2698.pir;
+		profile.trtcm.cbs = mp_in->params.trtcm_rfc2698.cbs;
+		profile.trtcm.pbs = mp_in->params.trtcm_rfc2698.pbs;
+
+		/* Add meter profile to pipeline table */
+		status = softnic_pipeline_table_mtr_profile_add(p,
+				m->flow->pipeline->name,
+				m->flow->table_id,
+				meter_profile_id,
+				&profile);
+		if (status)
+			return -rte_mtr_error_set(error,
+				EINVAL,
+				RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+				NULL,
+				"Table meter profile add failed");
+
+		/* Set meter action */
+		memset(&action, 0, sizeof(action));
+		memcpy(&action, &m->flow->action, sizeof(action));
+
+		action.mtr.mtr[0].meter_profile_id = meter_profile_id;
+
+		/* Re-add rule */
+		status = softnic_pipeline_table_rule_add(p,
+			m->flow->pipeline->name,
+			m->flow->table_id,
+			&m->flow->match,
+			&action,
+			&m->flow->data);
+		if (status)
+			return -rte_mtr_error_set(error,
+				EINVAL,
+				RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+				NULL,
+				"Pipeline table rule add failed");
+
+		/* Update flow meter action */
+		memcpy(&m->flow->action, &action, sizeof(m->flow->action));
+	}
+
+	/* Fill in */
+	m->params.meter_profile_id = meter_profile_id;
+
+	/* Update dependencies*/
+	mp_out->n_users--;
+	mp_in->n_users++;
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
@@ -343,7 +445,7 @@ const struct rte_mtr_ops pmd_mtr_ops = {
 	.meter_enable = NULL,
 	.meter_disable = NULL,
 
-	.meter_profile_update = NULL,
+	.meter_profile_update = pmd_mtr_meter_profile_update,
 	.meter_dscp_table_update = NULL,
 	.policer_actions_update = NULL,
 	.stats_update = NULL,
diff --git a/drivers/net/softnic/rte_eth_softnic_pipeline.c b/drivers/net/softnic/rte_eth_softnic_pipeline.c
index d1127a1..26d10a1 100644
--- a/drivers/net/softnic/rte_eth_softnic_pipeline.c
+++ b/drivers/net/softnic/rte_eth_softnic_pipeline.c
@@ -55,6 +55,17 @@ softnic_pipeline_table_free(struct softnic_table *table)
 		TAILQ_REMOVE(&table->flows, flow, node);
 		free(flow);
 	}
+
+	for ( ; ; ) {
+		struct softnic_table_action_meter_profile *mp;
+
+		mp = TAILQ_FIRST(&table->meter_profiles);
+		if (mp == NULL)
+			break;
+
+		TAILQ_REMOVE(&table->meter_profiles, mp, node);
+		free(mp);
+	}
 }
 
 void
@@ -988,6 +999,7 @@ softnic_pipeline_table_create(struct pmd_internals *softnic,
 	table->ap = ap;
 	table->a = action;
 	TAILQ_INIT(&table->flows);
+	TAILQ_INIT(&table->meter_profiles);
 	pipeline->n_tables++;
 
 	return 0;
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v2 07/10] net/softnic: update dscp table
  2018-09-12 16:41   ` [dpdk-dev] [PATCH v2 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                       ` (5 preceding siblings ...)
  2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 06/10] net/softnic: update meter profile Jasvinder Singh
@ 2018-09-12 16:41     ` Jasvinder Singh
  2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 08/10] net/softnic: update policer actions Jasvinder Singh
                       ` (2 subsequent siblings)
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-12 16:41 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter object dscp table update.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_internals.h |  1 +
 drivers/net/softnic/rte_eth_softnic_meter.c     | 54 ++++++++++++++++++++++++-
 drivers/net/softnic/rte_eth_softnic_pipeline.c  |  1 +
 3 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index 784035f..ac05eba 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -464,6 +464,7 @@ struct softnic_table {
 	struct softnic_table_action_profile *ap;
 	struct rte_table_action *a;
 	struct flow_list flows;
+	struct rte_table_action_dscp_table dscp_table;
 	struct softnic_table_action_meter_profile_list meter_profiles;
 };
 
diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index e5c8f09..6135f21 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -434,6 +434,58 @@ pmd_mtr_meter_profile_update(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* MTR object meter DSCP table update */
+static int
+pmd_mtr_meter_dscp_table_update(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	enum rte_mtr_color *dscp_table,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct rte_table_action_dscp_table dt;
+	struct pipeline *pipeline;
+	struct softnic_table *table;
+	struct softnic_mtr *m;
+	uint32_t i;
+	int status;
+
+	/* MTR object id must be valid */
+	m = softnic_mtr_find(p, mtr_id);
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			"MTR object id not valid");
+
+	/* MTR object owner valid? */
+	if (m->flow == NULL)
+		return 0;
+
+	/* Update data plane table */
+	pipeline = m->flow->pipeline;
+	table = &pipeline->table[m->flow->table_id];
+
+	memcpy(&dt, &table->dscp_table, sizeof(dt));
+	for (i = 0; i < RTE_DIM(dt.entry); i++)
+		dt.entry[i].color = (enum rte_meter_color)dscp_table[i];
+
+	status = rte_table_action_dscp_table_update(table->a,
+			UINT64_MAX,
+			&dt);
+	if (status)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"Table action dscp table update failed");
+
+	/* Update table */
+	memcpy(&table->dscp_table, &dt, sizeof(table->dscp_table));
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
@@ -446,7 +498,7 @@ const struct rte_mtr_ops pmd_mtr_ops = {
 	.meter_disable = NULL,
 
 	.meter_profile_update = pmd_mtr_meter_profile_update,
-	.meter_dscp_table_update = NULL,
+	.meter_dscp_table_update = pmd_mtr_meter_dscp_table_update,
 	.policer_actions_update = NULL,
 	.stats_update = NULL,
 
diff --git a/drivers/net/softnic/rte_eth_softnic_pipeline.c b/drivers/net/softnic/rte_eth_softnic_pipeline.c
index 26d10a1..5deb93c 100644
--- a/drivers/net/softnic/rte_eth_softnic_pipeline.c
+++ b/drivers/net/softnic/rte_eth_softnic_pipeline.c
@@ -1000,6 +1000,7 @@ softnic_pipeline_table_create(struct pmd_internals *softnic,
 	table->a = action;
 	TAILQ_INIT(&table->flows);
 	TAILQ_INIT(&table->meter_profiles);
+	memset(&table->dscp_table, 0, sizeof(table->dscp_table));
 	pipeline->n_tables++;
 
 	return 0;
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v2 08/10] net/softnic: update policer actions
  2018-09-12 16:41   ` [dpdk-dev] [PATCH v2 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                       ` (6 preceding siblings ...)
  2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 07/10] net/softnic: update dscp table Jasvinder Singh
@ 2018-09-12 16:41     ` Jasvinder Singh
  2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 09/10] net/softnic: meter stats read Jasvinder Singh
  2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 10/10] net/softnic: enable flow rule with meter action Jasvinder Singh
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-12 16:41 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter object policer actions function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_meter.c | 96 ++++++++++++++++++++++++++++-
 1 file changed, 95 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 6135f21..bc1f2ea 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -486,6 +486,100 @@ pmd_mtr_meter_dscp_table_update(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* MTR object policer action update */
+static int
+pmd_mtr_policer_actions_update(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	uint32_t action_mask,
+	enum rte_mtr_policer_action *actions,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_table_rule_action action;
+	struct softnic_table *table;
+	struct pipeline *pipeline;
+	struct softnic_mtr *m;
+	uint32_t i, tc_mask = 1 << 0;
+	int status;
+
+	/* MTR object id must be valid */
+	m = softnic_mtr_find(p, mtr_id);
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			"MTR object id not valid");
+
+	/* Valid policer actions */
+	if (actions == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"Invalid actions");
+
+	for (i = 0; i < RTE_MTR_COLORS; i++) {
+		if ((action_mask >> i) & 1) {
+			if (actions[i] != MTR_POLICER_ACTION_COLOR_GREEN  &&
+				actions[i] != MTR_POLICER_ACTION_COLOR_YELLOW &&
+				actions[i] != MTR_POLICER_ACTION_COLOR_RED &&
+				actions[i] != MTR_POLICER_ACTION_DROP) {
+				return -rte_mtr_error_set(error,
+					EINVAL,
+					RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+					NULL,
+					" Invalid action value");
+			}
+		}
+	}
+
+	/* MTR object owner valid? */
+	if (m->flow) {
+		memset(&action, 0, sizeof(action));
+		memcpy(&action, &m->flow->action, sizeof(action));
+		pipeline = m->flow->pipeline;
+
+		/* Set action */
+		for (i = 0; i < RTE_MTR_COLORS; i++) {
+			if ((action_mask >> i) & 1)
+				action.mtr.mtr[0].policer[i] =
+					(enum rte_table_action_policer)actions[i];
+		}
+
+		/* Re-add the rule */
+		status = softnic_pipeline_table_rule_add(p,
+			pipeline->name,
+			m->flow->table_id,
+			&m->flow->match,
+			&action,
+			&m->flow->data);
+		if (status)
+			return -rte_mtr_error_set(error,
+				EINVAL,
+				RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+				NULL,
+				"Pipeline table rule re-add failed");
+
+		/* Update flow action */
+		memcpy(&m->flow->action, &action, sizeof(m->flow->action));
+
+		/* Reset the meter stats */
+		table = &pipeline->table[m->flow->table_id];
+
+		rte_table_action_meter_read(table->a, m->flow->data,
+			tc_mask, NULL, 1);
+	}
+
+	/* Update MTR object policer actions */
+	for (i = 0; i < RTE_MTR_COLORS; i++) {
+		if ((action_mask >> i) & 1)
+			m->params.action[i] = actions[i];
+	}
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
@@ -499,7 +593,7 @@ const struct rte_mtr_ops pmd_mtr_ops = {
 
 	.meter_profile_update = pmd_mtr_meter_profile_update,
 	.meter_dscp_table_update = pmd_mtr_meter_dscp_table_update,
-	.policer_actions_update = NULL,
+	.policer_actions_update = pmd_mtr_policer_actions_update,
 	.stats_update = NULL,
 
 	.stats_read = NULL,
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v2 09/10] net/softnic: meter stats read
  2018-09-12 16:41   ` [dpdk-dev] [PATCH v2 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                       ` (7 preceding siblings ...)
  2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 08/10] net/softnic: update policer actions Jasvinder Singh
@ 2018-09-12 16:41     ` Jasvinder Singh
  2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 10/10] net/softnic: enable flow rule with meter action Jasvinder Singh
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-12 16:41 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter object stats read function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_meter.c | 115 +++++++++++++++++++++++++++-
 1 file changed, 114 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index bc1f2ea..369f670 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -580,6 +580,119 @@ pmd_mtr_policer_actions_update(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* MTR object stats read */
+static int
+pmd_mtr_stats_read(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	struct rte_mtr_stats *stats,
+	uint64_t *stats_mask,
+	int clear,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct rte_table_action_mtr_counters counters;
+	struct rte_table_action_mtr_counters_tc *c;
+	struct rte_mtr_stats s;
+	struct softnic_table *table;
+	struct pipeline *pipeline;
+	struct softnic_mtr *m;
+	uint64_t mask = 0;
+	uint32_t i, tc_mask = 1 << 0;
+	int status;
+
+	/* MTR object id must be valid */
+	m = softnic_mtr_find(p, mtr_id);
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			"MTR object id not valid");
+
+	/* MTR meter object owner valid? */
+	if (m->flow == NULL)
+		return 0;
+
+	/* Meter stats */
+	pipeline = m->flow->pipeline;
+	table = &pipeline->table[m->flow->table_id];
+
+	status = rte_table_action_meter_read(table->a,
+		m->flow->data,
+		tc_mask,
+		&counters,
+		clear);
+	if (status)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"Meter stats read failed");
+
+	c = &counters.stats[0];
+	memset(&s, 0, sizeof(s));
+
+	if (c->n_packets_valid) {
+		for (i = 0; i < RTE_MTR_COLORS; i++) {
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_GREEN)
+				s.n_pkts[RTE_MTR_GREEN] += c->n_packets[i];
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_YELLOW)
+				s.n_pkts[RTE_MTR_YELLOW] += c->n_packets[i];
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_RED)
+				s.n_pkts[RTE_MTR_RED] += c->n_packets[i];
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_DROP)
+				s.n_pkts_dropped += c->n_packets[i];
+		}
+
+		mask = RTE_MTR_STATS_N_PKTS_GREEN |
+			RTE_MTR_STATS_N_PKTS_YELLOW |
+			RTE_MTR_STATS_N_PKTS_RED |
+			RTE_MTR_STATS_N_PKTS_DROPPED;
+	}
+
+	if (c->n_bytes_valid) {
+		for (i = 0; i < RTE_MTR_COLORS; i++) {
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_GREEN)
+				s.n_bytes[RTE_MTR_GREEN] += c->n_bytes[i];
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_YELLOW)
+				s.n_bytes[RTE_MTR_YELLOW] += c->n_bytes[i];
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_RED)
+				s.n_bytes[RTE_MTR_RED] += c->n_bytes[i];
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_DROP)
+				s.n_bytes_dropped += c->n_bytes[i];
+		}
+
+		mask |= RTE_MTR_STATS_N_BYTES_GREEN |
+			RTE_MTR_STATS_N_BYTES_YELLOW |
+			RTE_MTR_STATS_N_BYTES_RED |
+			RTE_MTR_STATS_N_BYTES_DROPPED;
+	}
+
+	/* Read */
+	if (stats) {
+		memset(stats, 0, sizeof(*stats));
+		memcpy(stats, &s, sizeof(*stats));
+	}
+
+	if (stats_mask) {
+		if (mask)
+			*stats_mask = mask;
+		else
+			*stats_mask = RTE_MTR_STATS_N_PKTS_GREEN |
+				RTE_MTR_STATS_N_PKTS_YELLOW |
+				RTE_MTR_STATS_N_PKTS_RED |
+				RTE_MTR_STATS_N_PKTS_DROPPED;
+	}
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
@@ -596,5 +709,5 @@ const struct rte_mtr_ops pmd_mtr_ops = {
 	.policer_actions_update = pmd_mtr_policer_actions_update,
 	.stats_update = NULL,
 
-	.stats_read = NULL,
+	.stats_read = pmd_mtr_stats_read,
 };
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v2 10/10] net/softnic: enable flow rule with meter action
  2018-09-12 16:41   ` [dpdk-dev] [PATCH v2 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                       ` (8 preceding siblings ...)
  2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 09/10] net/softnic: meter stats read Jasvinder Singh
@ 2018-09-12 16:41     ` Jasvinder Singh
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-12 16:41 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement flow rules with meter action.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_flow.c | 153 +++++++++++++++++++++++++++++
 1 file changed, 153 insertions(+)

diff --git a/drivers/net/softnic/rte_eth_softnic_flow.c b/drivers/net/softnic/rte_eth_softnic_flow.c
index fc7a0b0..f0eeff2 100644
--- a/drivers/net/softnic/rte_eth_softnic_flow.c
+++ b/drivers/net/softnic/rte_eth_softnic_flow.c
@@ -1474,6 +1474,101 @@ flow_rule_action_get(struct pmd_internals *softnic,
 			break;
 		} /* RTE_FLOW_ACTION_TYPE_COUNT */
 
+		case RTE_FLOW_ACTION_TYPE_METER:
+		{
+			struct rte_table_action_mtr_tc_params mtr_tc_params;
+			const struct rte_flow_action_meter *conf = action->conf;
+			struct rte_table_action_meter_profile profile;
+			struct softnic_mtr_meter_profile *mp;
+			struct softnic_mtr *m;
+			uint32_t i, meter_profile_id, table_id = UINT32_MAX;
+			int status;
+
+			if (conf == NULL)
+				return rte_flow_error_set(error,
+					EINVAL,
+					RTE_FLOW_ERROR_TYPE_ACTION,
+					action,
+					"METER: Null configuration");
+
+			if ((params->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) == 0)
+				return rte_flow_error_set(error,
+					EINVAL,
+					RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+					NULL,
+					"METER: table action not supported");
+
+			m = softnic_mtr_find(softnic, conf->mtr_id);
+			if (m == NULL)
+				return -rte_flow_error_set(error,
+					EINVAL,
+					RTE_FLOW_ERROR_TYPE_ACTION_CONF,
+					NULL,
+					"METER: invalid meter id");
+
+			if (m->flow)
+				return -rte_flow_error_set(error,
+					EINVAL,
+					RTE_FLOW_ERROR_TYPE_ACTION_CONF,
+					NULL,
+					"METER: meter already attached to flow");
+
+			if (params->mtr.n_tc != 1)
+				return -rte_flow_error_set(error,
+					EINVAL,
+					RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+					NULL,
+					"METER: multiple TCs not supported");
+
+			meter_profile_id = m->params.meter_profile_id;
+			mp = softnic_mtr_meter_profile_find(softnic, meter_profile_id);
+
+			memset(&profile, 0, sizeof(profile));
+			profile.alg = RTE_TABLE_ACTION_METER_TRTCM;
+			profile.trtcm.cir = mp->params.trtcm_rfc2698.cir;
+			profile.trtcm.pir = mp->params.trtcm_rfc2698.pir;
+			profile.trtcm.cbs = mp->params.trtcm_rfc2698.cbs;
+			profile.trtcm.pbs = mp->params.trtcm_rfc2698.pbs;
+
+			/* Identify the pipeline table to add this flow to. */
+			for (i = 0; i < pipeline->n_tables; i++) {
+				if (table == &pipeline->table[i]) {
+					table_id = i;
+					break;
+				}
+			}
+
+			/* Add meter profile to pipeline table */
+			status = softnic_pipeline_table_mtr_profile_add(softnic,
+					pipeline->name,
+					table_id,
+					meter_profile_id,
+					&profile);
+			if (status) {
+				rte_flow_error_set(error,
+					EINVAL,
+					RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+					NULL,
+					"Table meter profile add failed");
+				return -1;
+			}
+
+			/* RTE_TABLE_ACTION_METER */
+			mtr_tc_params.meter_profile_id = meter_profile_id;
+			mtr_tc_params.policer[e_RTE_METER_GREEN] =
+				(enum rte_table_action_policer)m->params.action[RTE_MTR_GREEN];
+			mtr_tc_params.policer[e_RTE_METER_YELLOW] =
+				(enum rte_table_action_policer)m->params.action[RTE_MTR_YELLOW];
+			mtr_tc_params.policer[e_RTE_METER_RED] =
+				(enum rte_table_action_policer)m->params.action[RTE_MTR_RED];
+
+			memcpy(&rule_action->mtr.mtr[0], &mtr_tc_params,
+				sizeof(rule_action->mtr.mtr[0]));
+			rule_action->mtr.tc_mask = 1 << 0;
+			rule_action->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
+			break;
+		} /* RTE_FLOW_ACTION_TYPE_METER */
+
 		default:
 			return -ENOTSUP;
 		}
@@ -1577,6 +1672,34 @@ pmd_flow_validate(struct rte_eth_dev *dev,
 	return 0;
 }
 
+static void set_meter_owner_to_flow(struct pmd_internals *softnic,
+	struct rte_flow *flow,
+	const struct rte_flow_action *action)
+{
+	for ( ; action->type != RTE_FLOW_ACTION_TYPE_END; action++) {
+		if (action->type == RTE_FLOW_ACTION_TYPE_VOID)
+			continue;
+
+		if (action->type == RTE_FLOW_ACTION_TYPE_METER) {
+			const struct rte_flow_action_meter *conf = action->conf;
+			struct softnic_mtr_list *ml = &softnic->mtr.mtrs;
+			struct softnic_mtr *m;
+
+			TAILQ_FOREACH(m, ml, node) {
+				if (m->flow == flow) {
+					m->flow = NULL;
+					break;
+				}
+			}
+
+			m = softnic_mtr_find(softnic, conf->mtr_id);
+			m->flow = flow;
+
+			break;
+		}
+	}
+}
+
 static struct rte_flow *
 pmd_flow_create(struct rte_eth_dev *dev,
 	const struct rte_flow_attr *attr,
@@ -1717,6 +1840,8 @@ pmd_flow_create(struct rte_eth_dev *dev,
 	flow->pipeline = pipeline;
 	flow->table_id = table_id;
 
+	set_meter_owner_to_flow(softnic, flow, action);
+
 	/* Flow add to list. */
 	if (new_flow)
 		TAILQ_INSERT_TAIL(&table->flows, flow, node);
@@ -1724,6 +1849,31 @@ pmd_flow_create(struct rte_eth_dev *dev,
 	return flow;
 }
 
+static void reset_meter_owner(struct pmd_internals *softnic,
+	struct softnic_table *table,
+	struct rte_flow *flow)
+{
+	struct softnic_table_action_profile *profile;
+	struct softnic_table_action_profile_params *params;
+
+	profile = softnic_table_action_profile_find(softnic,
+		table->params.action_profile_name);
+
+	params = &profile->params;
+
+	if ((params->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) == 0) {
+		struct softnic_mtr_list *ml = &softnic->mtr.mtrs;
+		struct softnic_mtr *m;
+
+		TAILQ_FOREACH(m, ml, node) {
+			if (m->flow == flow) {
+				m->flow = NULL;
+				break;
+			}
+		}
+	}
+}
+
 static int
 pmd_flow_destroy(struct rte_eth_dev *dev,
 	struct rte_flow *flow,
@@ -1759,6 +1909,9 @@ pmd_flow_destroy(struct rte_eth_dev *dev,
 	TAILQ_REMOVE(&table->flows, flow, node);
 	free(flow);
 
+	/* Update dependencies */
+	reset_meter_owner(softnic, table, flow);
+
 	return 0;
 }
 
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v3 00/10] net/softnic: implement metering and policing API
  2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 01/10] net/softnic: add metering and policing support Jasvinder Singh
@ 2018-09-14 17:45       ` Jasvinder Singh
  2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 01/10] net/softnic: add metering and policing support Jasvinder Singh
                           ` (9 more replies)
  0 siblings, 10 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-14 17:45 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

This series is prepared on top of following patchset;
https://mails.dpdk.org/archives/dev/2018-September/111379.html

v3 changes:
- update pipeline table with meter profiles
- update pipeline table with dscp table entry update

v2 changes:
- fix copyright year for rte_eth_softnic_meter.c
- Place all checks in a separate functions while creating meter object
- Use softnic_pipeline_table_mtr_profile_add() api to add meter profile
  instead of implementing new function
- Use stats type indicator to determine the stats_mask for meter stats read 
 
Jasvinder Singh (10):
  net/softnic: add metering and policing support
  net/softnic: add meter profile
  net/softnic: delete meter profile
  net/softnic: create meter object
  net/softnic: destroy meter object
  net/softnic: update meter profile
  net/softnic: update dscp table
  net/softnic: update policer actions
  net/softnic: meter stats read
  net/softnic: enable flow rule with meter action

 drivers/net/softnic/Makefile                    |   1 +
 drivers/net/softnic/meson.build                 |   1 +
 drivers/net/softnic/rte_eth_softnic.c           |  13 +
 drivers/net/softnic/rte_eth_softnic_flow.c      | 155 ++++-
 drivers/net/softnic/rte_eth_softnic_internals.h |  66 +++
 drivers/net/softnic/rte_eth_softnic_meter.c     | 728 ++++++++++++++++++++++++
 drivers/net/softnic/rte_eth_softnic_pipeline.c  |  26 +
 drivers/net/softnic/rte_eth_softnic_thread.c    |  33 ++
 8 files changed, 1022 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/softnic/rte_eth_softnic_meter.c

-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v3 01/10] net/softnic: add metering and policing support
  2018-09-14 17:45       ` [dpdk-dev] [PATCH v3 00/10] net/softnic: implement metering and policing API Jasvinder Singh
@ 2018-09-14 17:45         ` Jasvinder Singh
  2018-09-18 16:58           ` [dpdk-dev] [PATCH v4 00/10] net/softnic: implement metering and policing API Jasvinder Singh
  2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 02/10] net/softnic: add meter profile Jasvinder Singh
                           ` (8 subsequent siblings)
  9 siblings, 1 reply; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-14 17:45 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Enable metering and policing support for softnic.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/Makefile                    |  1 +
 drivers/net/softnic/meson.build                 |  1 +
 drivers/net/softnic/rte_eth_softnic.c           | 10 ++++++++
 drivers/net/softnic/rte_eth_softnic_internals.h |  5 ++++
 drivers/net/softnic/rte_eth_softnic_meter.c     | 31 +++++++++++++++++++++++++
 5 files changed, 48 insertions(+)
 create mode 100644 drivers/net/softnic/rte_eth_softnic_meter.c

diff --git a/drivers/net/softnic/Makefile b/drivers/net/softnic/Makefile
index 12515b1..720f067b 100644
--- a/drivers/net/softnic/Makefile
+++ b/drivers/net/softnic/Makefile
@@ -34,6 +34,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_pipeline.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_thread.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_cli.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_flow.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_meter.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += parser.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += conn.c
 
diff --git a/drivers/net/softnic/meson.build b/drivers/net/softnic/meson.build
index 56e5e2b..6b7a6cc 100644
--- a/drivers/net/softnic/meson.build
+++ b/drivers/net/softnic/meson.build
@@ -14,6 +14,7 @@ sources = files('rte_eth_softnic_tm.c',
 	'rte_eth_softnic_thread.c',
 	'rte_eth_softnic_cli.c',
 	'rte_eth_softnic_flow.c',
+	'rte_eth_softnic_meter.c',
 	'parser.c',
 	'conn.c')
 deps += ['pipeline', 'port', 'table', 'sched']
diff --git a/drivers/net/softnic/rte_eth_softnic.c b/drivers/net/softnic/rte_eth_softnic.c
index ae2a438..659a1b4 100644
--- a/drivers/net/softnic/rte_eth_softnic.c
+++ b/drivers/net/softnic/rte_eth_softnic.c
@@ -14,6 +14,7 @@
 #include <rte_errno.h>
 #include <rte_ring.h>
 #include <rte_tm_driver.h>
+#include <rte_mtr_driver.h>
 
 #include "rte_eth_softnic.h"
 #include "rte_eth_softnic_internals.h"
@@ -228,6 +229,14 @@ pmd_tm_ops_get(struct rte_eth_dev *dev __rte_unused, void *arg)
 	return 0;
 }
 
+static int
+pmd_mtr_ops_get(struct rte_eth_dev *dev __rte_unused, void *arg)
+{
+	*(const struct rte_mtr_ops **)arg = &pmd_mtr_ops;
+
+	return 0;
+}
+
 static const struct eth_dev_ops pmd_ops = {
 	.dev_configure = pmd_dev_configure,
 	.dev_start = pmd_dev_start,
@@ -239,6 +248,7 @@ static const struct eth_dev_ops pmd_ops = {
 	.tx_queue_setup = pmd_tx_queue_setup,
 	.filter_ctrl = pmd_filter_ctrl,
 	.tm_ops_get = pmd_tm_ops_get,
+	.mtr_ops_get = pmd_mtr_ops_get,
 };
 
 static uint16_t
diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index a1a2e15..92be4e8 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -572,6 +572,11 @@ flow_attr_map_get(struct pmd_internals *softnic,
 extern const struct rte_flow_ops pmd_flow_ops;
 
 /**
+ * Meter
+ */
+extern const struct rte_mtr_ops pmd_mtr_ops;
+
+/**
  * MEMPOOL
  */
 int
diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
new file mode 100644
index 0000000..0a5409b
--- /dev/null
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <rte_mtr.h>
+#include <rte_mtr_driver.h>
+
+#include "rte_eth_softnic_internals.h"
+
+const struct rte_mtr_ops pmd_mtr_ops = {
+	.capabilities_get = NULL,
+
+	.meter_profile_add = NULL,
+	.meter_profile_delete = NULL,
+
+	.create = NULL,
+	.destroy = NULL,
+	.meter_enable = NULL,
+	.meter_disable = NULL,
+
+	.meter_profile_update = NULL,
+	.meter_dscp_table_update = NULL,
+	.policer_actions_update = NULL,
+	.stats_update = NULL,
+
+	.stats_read = NULL,
+};
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v3 02/10] net/softnic: add meter profile
  2018-09-14 17:45       ` [dpdk-dev] [PATCH v3 00/10] net/softnic: implement metering and policing API Jasvinder Singh
  2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 01/10] net/softnic: add metering and policing support Jasvinder Singh
@ 2018-09-14 17:45         ` Jasvinder Singh
  2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 03/10] net/softnic: delete " Jasvinder Singh
                           ` (7 subsequent siblings)
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-14 17:45 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter profile add function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic.c           |   3 +
 drivers/net/softnic/rte_eth_softnic_internals.h |  31 ++++++
 drivers/net/softnic/rte_eth_softnic_meter.c     | 122 +++++++++++++++++++++++-
 3 files changed, 155 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic.c b/drivers/net/softnic/rte_eth_softnic.c
index 659a1b4..b7b2383 100644
--- a/drivers/net/softnic/rte_eth_softnic.c
+++ b/drivers/net/softnic/rte_eth_softnic.c
@@ -191,6 +191,7 @@ pmd_dev_stop(struct rte_eth_dev *dev)
 	softnic_mempool_free(p);
 
 	tm_hierarchy_free(p);
+	softnic_mtr_free(p);
 }
 
 static void
@@ -291,6 +292,7 @@ pmd_init(struct pmd_params *params)
 
 	/* Resources */
 	tm_hierarchy_init(p);
+	softnic_mtr_init(p);
 
 	softnic_mempool_init(p);
 	softnic_swq_init(p);
@@ -345,6 +347,7 @@ pmd_free(struct pmd_internals *p)
 	softnic_mempool_free(p);
 
 	tm_hierarchy_free(p);
+	softnic_mtr_free(p);
 
 	rte_free(p);
 }
diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index 92be4e8..1db9310 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -22,6 +22,7 @@
 #include <rte_ethdev_driver.h>
 #include <rte_tm_driver.h>
 #include <rte_flow_driver.h>
+#include <rte_mtr_driver.h>
 
 #include "rte_eth_softnic.h"
 #include "conn.h"
@@ -68,6 +69,24 @@ struct flow_internals {
 };
 
 /**
+ * Meter
+ */
+
+/* MTR meter profile */
+struct softnic_mtr_meter_profile {
+	TAILQ_ENTRY(softnic_mtr_meter_profile) node;
+	uint32_t meter_profile_id;
+	struct rte_mtr_meter_profile params;
+	uint32_t n_users;
+};
+
+TAILQ_HEAD(softnic_mtr_meter_profile_list, softnic_mtr_meter_profile);
+
+struct mtr_internals {
+	struct softnic_mtr_meter_profile_list meter_profiles;
+};
+
+/**
  * MEMPOOL
  */
 struct softnic_mempool_params {
@@ -525,6 +544,8 @@ struct pmd_internals {
 	} soft;
 
 	struct flow_internals flow;
+	struct mtr_internals mtr;
+
 	struct softnic_conn *conn;
 	struct softnic_mempool_list mempool_list;
 	struct softnic_swq_list swq_list;
@@ -574,6 +595,16 @@ extern const struct rte_flow_ops pmd_flow_ops;
 /**
  * Meter
  */
+int
+softnic_mtr_init(struct pmd_internals *p);
+
+void
+softnic_mtr_free(struct pmd_internals *p);
+
+struct softnic_mtr_meter_profile *
+softnic_mtr_meter_profile_find(struct pmd_internals *p,
+	uint32_t meter_profile_id);
+
 extern const struct rte_mtr_ops pmd_mtr_ops;
 
 /**
diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 0a5409b..1222866 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -11,10 +11,130 @@
 
 #include "rte_eth_softnic_internals.h"
 
+int
+softnic_mtr_init(struct pmd_internals *p)
+{
+	/* Initialize meter profiles list */
+	TAILQ_INIT(&p->mtr.meter_profiles);
+
+	return 0;
+}
+
+void
+softnic_mtr_free(struct pmd_internals *p)
+{
+	/* Remove meter profiles */
+	for ( ; ; ) {
+		struct softnic_mtr_meter_profile *mp;
+
+		mp = TAILQ_FIRST(&p->mtr.meter_profiles);
+		if (mp == NULL)
+			break;
+
+		TAILQ_REMOVE(&p->mtr.meter_profiles, mp, node);
+		free(mp);
+	}
+}
+
+struct softnic_mtr_meter_profile *
+softnic_mtr_meter_profile_find(struct pmd_internals *p,
+	uint32_t meter_profile_id)
+{
+	struct softnic_mtr_meter_profile_list *mpl = &p->mtr.meter_profiles;
+	struct softnic_mtr_meter_profile *mp;
+
+	TAILQ_FOREACH(mp, mpl, node)
+		if (meter_profile_id == mp->meter_profile_id)
+			return mp;
+
+	return NULL;
+}
+
+static int
+meter_profile_check(struct rte_eth_dev *dev,
+	uint32_t meter_profile_id,
+	struct rte_mtr_meter_profile *profile,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_meter_profile *mp;
+
+	/* Meter profile ID must be valid. */
+	if (meter_profile_id == UINT32_MAX)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"Meter profile id not valid");
+
+	/* Meter profile must not exist. */
+	mp = softnic_mtr_meter_profile_find(p, meter_profile_id);
+	if (mp)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"Meter prfile already exists");
+
+	/* Profile must not be NULL. */
+	if (profile == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE,
+			NULL,
+			"profile null");
+
+	/* Traffic metering algorithm : TRTCM_RFC2698 */
+	if (profile->alg != RTE_MTR_TRTCM_RFC2698)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE,
+			NULL,
+			"Metering alg not supported");
+
+	return 0;
+}
+
+/* MTR meter profile add */
+static int
+pmd_mtr_meter_profile_add(struct rte_eth_dev *dev,
+	uint32_t meter_profile_id,
+	struct rte_mtr_meter_profile *profile,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_meter_profile_list *mpl = &p->mtr.meter_profiles;
+	struct softnic_mtr_meter_profile *mp;
+	int status;
+
+	/* Check input params */
+	status = meter_profile_check(dev, meter_profile_id, profile, error);
+	if (status)
+		return status;
+
+	/* Memory allocation */
+	mp = calloc(1, sizeof(struct softnic_mtr_meter_profile));
+	if (mp == NULL)
+		return -rte_mtr_error_set(error,
+			ENOMEM,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"Memory alloc failed");
+
+	/* Fill in */
+	mp->meter_profile_id = meter_profile_id;
+	memcpy(&mp->params, profile, sizeof(mp->params));
+
+	/* Add to list */
+	TAILQ_INSERT_TAIL(mpl, mp, node);
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
-	.meter_profile_add = NULL,
+	.meter_profile_add = pmd_mtr_meter_profile_add,
 	.meter_profile_delete = NULL,
 
 	.create = NULL,
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v3 03/10] net/softnic: delete meter profile
  2018-09-14 17:45       ` [dpdk-dev] [PATCH v3 00/10] net/softnic: implement metering and policing API Jasvinder Singh
  2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 01/10] net/softnic: add metering and policing support Jasvinder Singh
  2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 02/10] net/softnic: add meter profile Jasvinder Singh
@ 2018-09-14 17:45         ` Jasvinder Singh
  2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 04/10] net/softnic: create meter object Jasvinder Singh
                           ` (6 subsequent siblings)
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-14 17:45 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter profile delete function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_meter.c | 35 ++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 1222866..f3205bd 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -131,11 +131,44 @@ pmd_mtr_meter_profile_add(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* MTR meter profile delete */
+static int
+pmd_mtr_meter_profile_delete(struct rte_eth_dev *dev,
+	uint32_t meter_profile_id,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_meter_profile *mp;
+
+	/* Meter profile must exist */
+	mp = softnic_mtr_meter_profile_find(p, meter_profile_id);
+	if (mp == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"Meter profile id invalid");
+
+	/* Check unused */
+	if (mp->n_users)
+		return -rte_mtr_error_set(error,
+			EBUSY,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"Meter profile in use");
+
+	/* Remove from list */
+	TAILQ_REMOVE(&p->mtr.meter_profiles, mp, node);
+	free(mp);
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
 	.meter_profile_add = pmd_mtr_meter_profile_add,
-	.meter_profile_delete = NULL,
+	.meter_profile_delete = pmd_mtr_meter_profile_delete,
 
 	.create = NULL,
 	.destroy = NULL,
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v3 04/10] net/softnic: create meter object
  2018-09-14 17:45       ` [dpdk-dev] [PATCH v3 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                           ` (2 preceding siblings ...)
  2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 03/10] net/softnic: delete " Jasvinder Singh
@ 2018-09-14 17:45         ` Jasvinder Singh
  2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 05/10] net/softnic: destroy " Jasvinder Singh
                           ` (5 subsequent siblings)
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-14 17:45 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

implement meter object create function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_internals.h |  15 +++
 drivers/net/softnic/rte_eth_softnic_meter.c     | 123 +++++++++++++++++++++++-
 2 files changed, 137 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index 1db9310..50b7295 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -82,8 +82,19 @@ struct softnic_mtr_meter_profile {
 
 TAILQ_HEAD(softnic_mtr_meter_profile_list, softnic_mtr_meter_profile);
 
+/* MTR meter object */
+struct softnic_mtr {
+	TAILQ_ENTRY(softnic_mtr) node;
+	uint32_t mtr_id;
+	struct rte_mtr_params params;
+	struct rte_flow *flow;
+};
+
+TAILQ_HEAD(softnic_mtr_list, softnic_mtr);
+
 struct mtr_internals {
 	struct softnic_mtr_meter_profile_list meter_profiles;
+	struct softnic_mtr_list mtrs;
 };
 
 /**
@@ -601,6 +612,10 @@ softnic_mtr_init(struct pmd_internals *p);
 void
 softnic_mtr_free(struct pmd_internals *p);
 
+struct softnic_mtr *
+softnic_mtr_find(struct pmd_internals *p,
+	uint32_t mtr_id);
+
 struct softnic_mtr_meter_profile *
 softnic_mtr_meter_profile_find(struct pmd_internals *p,
 	uint32_t meter_profile_id);
diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index f3205bd..12dd79c 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -17,12 +17,27 @@ softnic_mtr_init(struct pmd_internals *p)
 	/* Initialize meter profiles list */
 	TAILQ_INIT(&p->mtr.meter_profiles);
 
+	/* Initialize MTR objects list */
+	TAILQ_INIT(&p->mtr.mtrs);
+
 	return 0;
 }
 
 void
 softnic_mtr_free(struct pmd_internals *p)
 {
+	/* Remove MTR objects */
+	for ( ; ; ) {
+		struct softnic_mtr *m;
+
+		m = TAILQ_FIRST(&p->mtr.mtrs);
+		if (m == NULL)
+			break;
+
+		TAILQ_REMOVE(&p->mtr.mtrs, m, node);
+		free(m);
+	}
+
 	/* Remove meter profiles */
 	for ( ; ; ) {
 		struct softnic_mtr_meter_profile *mp;
@@ -164,13 +179,119 @@ pmd_mtr_meter_profile_delete(struct rte_eth_dev *dev,
 	return 0;
 }
 
+struct softnic_mtr *
+softnic_mtr_find(struct pmd_internals *p, uint32_t mtr_id)
+{
+	struct softnic_mtr_list *ml = &p->mtr.mtrs;
+	struct softnic_mtr *m;
+
+	TAILQ_FOREACH(m, ml, node)
+		if (m->mtr_id == mtr_id)
+			return m;
+
+	return NULL;
+}
+
+
+static int
+mtr_check(struct pmd_internals *p,
+	uint32_t mtr_id,
+	struct rte_mtr_params *params,
+	int shared,
+	struct rte_mtr_error *error)
+{
+	/* MTR id valid  */
+	if (softnic_mtr_find(p, mtr_id))
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			"MTR object already exists");
+
+	/* MTR params must not be NULL */
+	if (params == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_MTR_PARAMS,
+			NULL,
+			"MTR object params null");
+
+	/* Previous meter color not supported */
+	if (params->use_prev_mtr_color)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_MTR_PARAMS,
+			NULL,
+			"Previous meter color not supported");
+
+	/* Shared MTR object not supported */
+	if (shared)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_SHARED,
+			NULL,
+			"Shared MTR object not supported");
+
+	return 0;
+}
+
+/* MTR object create */
+static int
+pmd_mtr_create(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	struct rte_mtr_params *params,
+	int shared,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_list *ml = &p->mtr.mtrs;
+	struct softnic_mtr_meter_profile *mp;
+	struct softnic_mtr *m;
+	int status;
+
+	/* Check parameters */
+	status = mtr_check(p, mtr_id, params, shared, error);
+	if (status)
+		return status;
+
+	/* Meter profile must exist */
+	mp = softnic_mtr_meter_profile_find(p, params->meter_profile_id);
+	if (mp == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"Meter profile id not valid");
+
+	/* Memory allocation */
+	m = calloc(1, sizeof(struct softnic_mtr));
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			ENOMEM,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"Memory alloc failed");
+
+	/* Fill in */
+	m->mtr_id = mtr_id;
+	memcpy(&m->params, params, sizeof(m->params));
+
+	/* Add to list */
+	TAILQ_INSERT_TAIL(ml, m, node);
+
+	/* Update dependencies */
+	mp->n_users++;
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
 	.meter_profile_add = pmd_mtr_meter_profile_add,
 	.meter_profile_delete = pmd_mtr_meter_profile_delete,
 
-	.create = NULL,
+	.create = pmd_mtr_create,
 	.destroy = NULL,
 	.meter_enable = NULL,
 	.meter_disable = NULL,
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v3 05/10] net/softnic: destroy meter object
  2018-09-14 17:45       ` [dpdk-dev] [PATCH v3 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                           ` (3 preceding siblings ...)
  2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 04/10] net/softnic: create meter object Jasvinder Singh
@ 2018-09-14 17:45         ` Jasvinder Singh
  2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 06/10] net/softnic: update meter profile Jasvinder Singh
                           ` (4 subsequent siblings)
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-14 17:45 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter object destroy function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_meter.c | 49 ++++++++++++++++++++++++++++-
 1 file changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 12dd79c..5103bda 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -285,6 +285,53 @@ pmd_mtr_create(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* MTR object destroy */
+static int
+pmd_mtr_destroy(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_list *ml = &p->mtr.mtrs;
+	struct softnic_mtr_meter_profile *mp;
+	struct softnic_mtr *m;
+
+	/* MTR object must exist */
+	m = softnic_mtr_find(p, mtr_id);
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			"MTR object id not valid");
+
+	/* MTR object must not have any owner */
+	if (m->flow != NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"MTR object is being used");
+
+	/* Get meter profile */
+	mp = softnic_mtr_meter_profile_find(p, m->params.meter_profile_id);
+	if (mp == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"MTR object meter profile invalid");
+
+	/* Update dependencies */
+	mp->n_users--;
+
+	/* Remove from list */
+	TAILQ_REMOVE(ml, m, node);
+	free(m);
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
@@ -292,7 +339,7 @@ const struct rte_mtr_ops pmd_mtr_ops = {
 	.meter_profile_delete = pmd_mtr_meter_profile_delete,
 
 	.create = pmd_mtr_create,
-	.destroy = NULL,
+	.destroy = pmd_mtr_destroy,
 	.meter_enable = NULL,
 	.meter_disable = NULL,
 
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v3 06/10] net/softnic: update meter profile
  2018-09-14 17:45       ` [dpdk-dev] [PATCH v3 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                           ` (4 preceding siblings ...)
  2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 05/10] net/softnic: destroy " Jasvinder Singh
@ 2018-09-14 17:45         ` Jasvinder Singh
  2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 07/10] net/softnic: update dscp table Jasvinder Singh
                           ` (3 subsequent siblings)
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-14 17:45 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter profile update function

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_internals.h |  14 ++++
 drivers/net/softnic/rte_eth_softnic_meter.c     | 103 +++++++++++++++++++++++-
 drivers/net/softnic/rte_eth_softnic_pipeline.c  |  25 ++++++
 drivers/net/softnic/rte_eth_softnic_thread.c    |  23 ++++++
 4 files changed, 164 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index 50b7295..4b0f54c 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -320,6 +320,15 @@ struct softnic_table_action_profile {
 
 TAILQ_HEAD(softnic_table_action_profile_list, softnic_table_action_profile);
 
+struct softnic_table_meter_profile {
+	TAILQ_ENTRY(softnic_table_meter_profile) node;
+	uint32_t meter_profile_id;
+	struct rte_table_action_meter_profile profile;
+};
+
+TAILQ_HEAD(softnic_table_meter_profile_list,
+	softnic_table_meter_profile);
+
 /**
  * Pipeline
  */
@@ -455,6 +464,7 @@ struct softnic_table {
 	struct softnic_table_action_profile *ap;
 	struct rte_table_action *a;
 	struct flow_list flows;
+	struct softnic_table_meter_profile_list meter_profiles;
 };
 
 struct pipeline {
@@ -813,6 +823,10 @@ softnic_pipeline_table_create(struct pmd_internals *p,
 	const char *pipeline_name,
 	struct softnic_table_params *params);
 
+struct softnic_table_meter_profile *
+softnic_pipeline_table_meter_profile_find(struct softnic_table *table,
+	uint32_t meter_profile_id);
+
 struct softnic_table_rule_match_acl {
 	int ip_version;
 
diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 5103bda..5ce5037 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -332,6 +332,107 @@ pmd_mtr_destroy(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* MTR object meter profile update */
+static int
+pmd_mtr_meter_profile_update(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	uint32_t meter_profile_id,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_meter_profile *mp0, *mp1;
+	struct softnic_mtr *m;
+	int status;
+
+	/* MTR object id must be valid */
+	m = softnic_mtr_find(p, mtr_id);
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			"MTR object id not valid");
+
+	/* Meter profile id must be valid */
+	mp0 = softnic_mtr_meter_profile_find(p, meter_profile_id);
+	if (mp0 == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"Meter profile not valid");
+
+	/* MTR object already set to meter profile id */
+	if (m->params.meter_profile_id == meter_profile_id)
+		return 0;
+
+	/*  MTR object owner table update */
+	if (m->flow) {
+		uint32_t table_id = m->flow->table_id;
+		struct softnic_table *table = &m->flow->pipeline->table[table_id];
+		struct softnic_table_rule_action action;
+
+		if (!softnic_pipeline_table_meter_profile_find(table,
+			meter_profile_id)) {
+			struct rte_table_action_meter_profile profile;
+
+			memset(&profile, 0, sizeof(profile));
+
+			profile.alg = RTE_TABLE_ACTION_METER_TRTCM;
+			profile.trtcm.cir = mp0->params.trtcm_rfc2698.cir;
+			profile.trtcm.pir = mp0->params.trtcm_rfc2698.pir;
+			profile.trtcm.cbs = mp0->params.trtcm_rfc2698.cbs;
+			profile.trtcm.pbs = mp0->params.trtcm_rfc2698.pbs;
+
+			/* Add meter profile to pipeline table */
+			status = softnic_pipeline_table_mtr_profile_add(p,
+					m->flow->pipeline->name,
+					table_id,
+					meter_profile_id,
+					&profile);
+			if (status)
+				return -rte_mtr_error_set(error,
+					EINVAL,
+					RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+					NULL,
+					"Table meter profile add failed");
+		}
+
+		/* Set meter action */
+		memcpy(&action, &m->flow->action, sizeof(action));
+
+		action.mtr.mtr[0].meter_profile_id = meter_profile_id;
+
+		/* Re-add rule */
+		status = softnic_pipeline_table_rule_add(p,
+			m->flow->pipeline->name,
+			table_id,
+			&m->flow->match,
+			&action,
+			&m->flow->data);
+		if (status)
+			return -rte_mtr_error_set(error,
+				EINVAL,
+				RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+				NULL,
+				"Pipeline table rule add failed");
+
+		/* Flow: update meter action */
+		memcpy(&m->flow->action, &action, sizeof(m->flow->action));
+	}
+
+	mp1 = softnic_mtr_meter_profile_find(p, m->params.meter_profile_id);
+
+	/* Meter: Set meter profile */
+	m->params.meter_profile_id = meter_profile_id;
+
+	/* Update dependencies*/
+	mp1->n_users--;
+	mp0->n_users++;
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
@@ -343,7 +444,7 @@ const struct rte_mtr_ops pmd_mtr_ops = {
 	.meter_enable = NULL,
 	.meter_disable = NULL,
 
-	.meter_profile_update = NULL,
+	.meter_profile_update = pmd_mtr_meter_profile_update,
 	.meter_dscp_table_update = NULL,
 	.policer_actions_update = NULL,
 	.stats_update = NULL,
diff --git a/drivers/net/softnic/rte_eth_softnic_pipeline.c b/drivers/net/softnic/rte_eth_softnic_pipeline.c
index d1127a1..9c544f4 100644
--- a/drivers/net/softnic/rte_eth_softnic_pipeline.c
+++ b/drivers/net/softnic/rte_eth_softnic_pipeline.c
@@ -55,6 +55,17 @@ softnic_pipeline_table_free(struct softnic_table *table)
 		TAILQ_REMOVE(&table->flows, flow, node);
 		free(flow);
 	}
+
+	for ( ; ; ) {
+		struct softnic_table_meter_profile *mp;
+
+		mp = TAILQ_FIRST(&table->meter_profiles);
+		if (mp == NULL)
+			break;
+
+		TAILQ_REMOVE(&table->meter_profiles, mp, node);
+		free(mp);
+	}
 }
 
 void
@@ -988,6 +999,7 @@ softnic_pipeline_table_create(struct pmd_internals *softnic,
 	table->ap = ap;
 	table->a = action;
 	TAILQ_INIT(&table->flows);
+	TAILQ_INIT(&table->meter_profiles);
 	pipeline->n_tables++;
 
 	return 0;
@@ -1020,3 +1032,16 @@ softnic_pipeline_port_out_find(struct pmd_internals *softnic,
 
 	return -1;
 }
+
+struct softnic_table_meter_profile *
+softnic_pipeline_table_meter_profile_find(struct softnic_table *table,
+	uint32_t meter_profile_id)
+{
+	struct softnic_table_meter_profile *mp;
+
+	TAILQ_FOREACH(mp, &table->meter_profiles, node)
+		if (mp->meter_profile_id == meter_profile_id)
+			return mp;
+
+	return NULL;
+}
\ No newline at end of file
diff --git a/drivers/net/softnic/rte_eth_softnic_thread.c b/drivers/net/softnic/rte_eth_softnic_thread.c
index 8a15090..df61832 100644
--- a/drivers/net/softnic/rte_eth_softnic_thread.c
+++ b/drivers/net/softnic/rte_eth_softnic_thread.c
@@ -1680,6 +1680,7 @@ softnic_pipeline_table_mtr_profile_add(struct pmd_internals *softnic,
 	struct pipeline *p;
 	struct pipeline_msg_req *req;
 	struct pipeline_msg_rsp *rsp;
+	struct softnic_table_meter_profile *mp;
 	int status;
 
 	/* Check input params */
@@ -1692,12 +1693,25 @@ softnic_pipeline_table_mtr_profile_add(struct pmd_internals *softnic,
 		table_id >= p->n_tables)
 		return -1;
 
+	/* Resource Allocation */
+	mp = calloc(1, sizeof(struct softnic_table_meter_profile));
+	if (mp == NULL)
+		return -1;
+
 	if (!pipeline_is_running(p)) {
 		struct rte_table_action *a = p->table[table_id].a;
 
 		status = rte_table_action_meter_profile_add(a,
 			meter_profile_id,
 			profile);
+		if (status)
+			free(mp);
+		else {
+			/* Add profile to the list */
+			mp->meter_profile_id = meter_profile_id;
+			memcpy(&mp->profile, &profile, sizeof(mp->profile));
+			TAILQ_INSERT_TAIL(&p->table[table_id].meter_profiles, mp, node);
+		}
 
 		return status;
 	}
@@ -1721,6 +1735,15 @@ softnic_pipeline_table_mtr_profile_add(struct pmd_internals *softnic,
 	/* Read response */
 	status = rsp->status;
 
+	if (status)
+		free(mp);
+	else {
+		/* Add profile to the list */
+		mp->meter_profile_id = meter_profile_id;
+		memcpy(&mp->profile, &profile, sizeof(mp->profile));
+		TAILQ_INSERT_TAIL(&p->table[table_id].meter_profiles, mp, node);
+	}
+
 	/* Free response */
 	pipeline_msg_free(rsp);
 
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v3 07/10] net/softnic: update dscp table
  2018-09-14 17:45       ` [dpdk-dev] [PATCH v3 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                           ` (5 preceding siblings ...)
  2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 06/10] net/softnic: update meter profile Jasvinder Singh
@ 2018-09-14 17:45         ` Jasvinder Singh
  2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 08/10] net/softnic: update policer actions Jasvinder Singh
                           ` (2 subsequent siblings)
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-14 17:45 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter object dscp table update.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_internals.h |  1 +
 drivers/net/softnic/rte_eth_softnic_meter.c     | 54 ++++++++++++++++++++++++-
 drivers/net/softnic/rte_eth_softnic_pipeline.c  |  1 +
 drivers/net/softnic/rte_eth_softnic_thread.c    | 10 +++++
 4 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index 4b0f54c..78864e7 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -464,6 +464,7 @@ struct softnic_table {
 	struct softnic_table_action_profile *ap;
 	struct rte_table_action *a;
 	struct flow_list flows;
+	struct rte_table_action_dscp_table dscp_table;
 	struct softnic_table_meter_profile_list meter_profiles;
 };
 
diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 5ce5037..68373ee 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -433,6 +433,58 @@ pmd_mtr_meter_profile_update(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* MTR object meter DSCP table update */
+static int
+pmd_mtr_meter_dscp_table_update(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	enum rte_mtr_color *dscp_table,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct rte_table_action_dscp_table dt;
+	struct pipeline *pipeline;
+	struct softnic_table *table;
+	struct softnic_mtr *m;
+	uint32_t table_id, i;
+	int status;
+
+	/* MTR object id must be valid */
+	m = softnic_mtr_find(p, mtr_id);
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			"MTR object id not valid");
+
+	/* MTR object owner valid? */
+	if (m->flow == NULL)
+		return 0;
+
+	pipeline = m->flow->pipeline;
+	table_id = m->flow->table_id;
+	table = &pipeline->table[table_id];
+
+	memcpy(&dt, &table->dscp_table, sizeof(dt));
+	for (i = 0; i < RTE_DIM(dt.entry); i++)
+		dt.entry[i].color = (enum rte_meter_color)dscp_table[i];
+
+	/* Update table */
+	status = softnic_pipeline_table_dscp_table_update(p,
+			pipeline->name,
+			table_id,
+			UINT64_MAX,
+			&dt);
+	if (status)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"Table action dscp table update failed");
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
@@ -445,7 +497,7 @@ const struct rte_mtr_ops pmd_mtr_ops = {
 	.meter_disable = NULL,
 
 	.meter_profile_update = pmd_mtr_meter_profile_update,
-	.meter_dscp_table_update = NULL,
+	.meter_dscp_table_update = pmd_mtr_meter_dscp_table_update,
 	.policer_actions_update = NULL,
 	.stats_update = NULL,
 
diff --git a/drivers/net/softnic/rte_eth_softnic_pipeline.c b/drivers/net/softnic/rte_eth_softnic_pipeline.c
index 9c544f4..7c81152 100644
--- a/drivers/net/softnic/rte_eth_softnic_pipeline.c
+++ b/drivers/net/softnic/rte_eth_softnic_pipeline.c
@@ -1000,6 +1000,7 @@ softnic_pipeline_table_create(struct pmd_internals *softnic,
 	table->a = action;
 	TAILQ_INIT(&table->flows);
 	TAILQ_INIT(&table->meter_profiles);
+	memset(&table->dscp_table, 0, sizeof(table->dscp_table));
 	pipeline->n_tables++;
 
 	return 0;
diff --git a/drivers/net/softnic/rte_eth_softnic_thread.c b/drivers/net/softnic/rte_eth_softnic_thread.c
index df61832..af659b9 100644
--- a/drivers/net/softnic/rte_eth_softnic_thread.c
+++ b/drivers/net/softnic/rte_eth_softnic_thread.c
@@ -1897,6 +1897,11 @@ softnic_pipeline_table_dscp_table_update(struct pmd_internals *softnic,
 				dscp_mask,
 				dscp_table);
 
+		/* Update table dscp table */
+		if (!status)
+			memcpy(&p->table[table_id].dscp_table, dscp_table,
+				sizeof(p->table[table_id].dscp_table));
+
 		return status;
 	}
 
@@ -1920,6 +1925,11 @@ softnic_pipeline_table_dscp_table_update(struct pmd_internals *softnic,
 	/* Read response */
 	status = rsp->status;
 
+	/* Update table dscp table */
+	if (!status)
+		memcpy(&p->table[table_id].dscp_table, dscp_table,
+			sizeof(p->table[table_id].dscp_table));
+
 	/* Free response */
 	pipeline_msg_free(rsp);
 
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v3 08/10] net/softnic: update policer actions
  2018-09-14 17:45       ` [dpdk-dev] [PATCH v3 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                           ` (6 preceding siblings ...)
  2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 07/10] net/softnic: update dscp table Jasvinder Singh
@ 2018-09-14 17:45         ` Jasvinder Singh
  2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 09/10] net/softnic: meter stats read Jasvinder Singh
  2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 10/10] net/softnic: enable flow rule with meter action Jasvinder Singh
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-14 17:45 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter object policer actions function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_meter.c | 91 ++++++++++++++++++++++++++++-
 1 file changed, 90 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 68373ee..6774eb6 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -485,6 +485,95 @@ pmd_mtr_meter_dscp_table_update(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* MTR object policer action update */
+static int
+pmd_mtr_policer_actions_update(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	uint32_t action_mask,
+	enum rte_mtr_policer_action *actions,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr *m;
+	uint32_t i;
+	int status;
+
+	/* MTR object id must be valid */
+	m = softnic_mtr_find(p, mtr_id);
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			"MTR object id not valid");
+
+	/* Valid policer actions */
+	if (actions == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"Invalid actions");
+
+	for (i = 0; i < RTE_MTR_COLORS; i++) {
+		if (action_mask & (1 << i)) {
+			if (actions[i] != MTR_POLICER_ACTION_COLOR_GREEN  &&
+				actions[i] != MTR_POLICER_ACTION_COLOR_YELLOW &&
+				actions[i] != MTR_POLICER_ACTION_COLOR_RED &&
+				actions[i] != MTR_POLICER_ACTION_DROP) {
+				return -rte_mtr_error_set(error,
+					EINVAL,
+					RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+					NULL,
+					" Invalid action value");
+			}
+		}
+	}
+
+	/* MTR object owner valid? */
+	if (m->flow) {
+		struct pipeline *pipeline = m->flow->pipeline;
+		struct softnic_table *table = &pipeline->table[m->flow->table_id];
+		struct softnic_table_rule_action action;
+
+		memcpy(&action, &m->flow->action, sizeof(action));
+
+		/* Set action */
+		for (i = 0; i < RTE_MTR_COLORS; i++)
+			if (action_mask & (1 << i))
+				action.mtr.mtr[0].policer[i] =
+					(enum rte_table_action_policer)actions[i];
+
+		/* Re-add the rule */
+		status = softnic_pipeline_table_rule_add(p,
+			pipeline->name,
+			m->flow->table_id,
+			&m->flow->match,
+			&action,
+			&m->flow->data);
+		if (status)
+			return -rte_mtr_error_set(error,
+				EINVAL,
+				RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+				NULL,
+				"Pipeline table rule re-add failed");
+
+		/* Flow: Update meter action */
+		memcpy(&m->flow->action, &action, sizeof(m->flow->action));
+
+		/* Reset the meter stats */
+		rte_table_action_meter_read(table->a, m->flow->data,
+			1, NULL, 1);
+	}
+
+	/* Meter: Update policer actions */
+	for (i = 0; i < RTE_MTR_COLORS; i++)
+		if (action_mask & (1 << i))
+			m->params.action[i] = actions[i];
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
@@ -498,7 +587,7 @@ const struct rte_mtr_ops pmd_mtr_ops = {
 
 	.meter_profile_update = pmd_mtr_meter_profile_update,
 	.meter_dscp_table_update = pmd_mtr_meter_dscp_table_update,
-	.policer_actions_update = NULL,
+	.policer_actions_update = pmd_mtr_policer_actions_update,
 	.stats_update = NULL,
 
 	.stats_read = NULL,
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v3 09/10] net/softnic: meter stats read
  2018-09-14 17:45       ` [dpdk-dev] [PATCH v3 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                           ` (7 preceding siblings ...)
  2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 08/10] net/softnic: update policer actions Jasvinder Singh
@ 2018-09-14 17:45         ` Jasvinder Singh
  2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 10/10] net/softnic: enable flow rule with meter action Jasvinder Singh
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-14 17:45 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter object stats read function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_meter.c | 136 +++++++++++++++++++++++++++-
 1 file changed, 135 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 6774eb6..d73f489 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -574,6 +574,140 @@ pmd_mtr_policer_actions_update(struct rte_eth_dev *dev,
 	return 0;
 }
 
+#define MTR_STATS_PKTS_DEFAULT (RTE_MTR_STATS_N_PKTS_GREEN | \
+				RTE_MTR_STATS_N_PKTS_YELLOW | \
+				RTE_MTR_STATS_N_PKTS_RED | \
+				RTE_MTR_STATS_N_PKTS_DROPPED)
+
+#define MTR_STATS_BYTES_DEFAULT (RTE_MTR_STATS_N_BYTES_GREEN | \
+				RTE_MTR_STATS_N_BYTES_YELLOW | \
+				RTE_MTR_STATS_N_BYTES_RED | \
+				RTE_MTR_STATS_N_BYTES_DROPPED)
+
+/* MTR object stats read */
+static void
+mtr_stats_convert(struct softnic_mtr *m,
+	struct rte_table_action_mtr_counters_tc *in,
+	struct rte_mtr_stats *out,
+	uint64_t *out_mask)
+{
+	memset(&out, 0, sizeof(out));
+	*out_mask = 0;
+
+	if (in->n_packets_valid) {
+		uint32_t i;
+
+		for (i = 0; i < RTE_MTR_COLORS; i++) {
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_GREEN)
+				out->n_pkts[RTE_MTR_GREEN] += in->n_packets[i];
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_YELLOW)
+				out->n_pkts[RTE_MTR_YELLOW] += in->n_packets[i];
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_RED)
+				out->n_pkts[RTE_MTR_RED] += in->n_packets[i];
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_DROP)
+				out->n_pkts_dropped += in->n_packets[i];
+		}
+
+		*out_mask |= MTR_STATS_PKTS_DEFAULT;
+	}
+
+	if (in->n_bytes_valid) {
+		uint32_t i;
+
+		for (i = 0; i < RTE_MTR_COLORS; i++) {
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_GREEN)
+				out->n_bytes[RTE_MTR_GREEN] += in->n_bytes[i];
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_YELLOW)
+				out->n_bytes[RTE_MTR_YELLOW] += in->n_bytes[i];
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_RED)
+				out->n_bytes[RTE_MTR_RED] += in->n_bytes[i];
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_DROP)
+				out->n_bytes_dropped += in->n_bytes[i];
+		}
+
+		*out_mask |= MTR_STATS_BYTES_DEFAULT;
+	}
+}
+
+/* MTR object stats read */
+static int
+pmd_mtr_stats_read(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	struct rte_mtr_stats *stats,
+	uint64_t *stats_mask,
+	int clear,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct rte_table_action_mtr_counters counters;
+	struct pipeline *pipeline;
+	struct softnic_table *table;
+	struct softnic_mtr *m;
+	int status;
+
+	/* MTR object id must be valid */
+	m = softnic_mtr_find(p, mtr_id);
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			"MTR object id not valid");
+
+	/* MTR meter object owner valid? */
+	if (m->flow == NULL) {
+		if (stats != NULL)
+			memset(stats, 0, sizeof(*stats));
+
+		if (stats_mask)
+			*stats_mask = MTR_STATS_PKTS_DEFAULT |
+				MTR_STATS_BYTES_DEFAULT;
+
+		return 0;
+	}
+
+	pipeline = m->flow->pipeline;
+	table = &pipeline->table[m->flow->table_id];
+
+	/* Meter stats read. */
+	status = rte_table_action_meter_read(table->a,
+		m->flow->data,
+		1,
+		&counters,
+		clear);
+	if (status)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"Meter stats read failed");
+
+	/* Stats format conversion. */
+	if (stats || stats_mask) {
+		struct rte_mtr_stats s;
+		uint64_t s_mask = 0;
+
+		mtr_stats_convert(m,
+			&counters.stats[0],
+			&s,
+			&s_mask);
+
+		if (stats)
+			memcpy(stats, &s, sizeof(*stats));
+
+		if (stats_mask)
+			*stats_mask = s_mask;
+	}
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
@@ -590,5 +724,5 @@ const struct rte_mtr_ops pmd_mtr_ops = {
 	.policer_actions_update = pmd_mtr_policer_actions_update,
 	.stats_update = NULL,
 
-	.stats_read = NULL,
+	.stats_read = pmd_mtr_stats_read,
 };
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v3 10/10] net/softnic: enable flow rule with meter action
  2018-09-14 17:45       ` [dpdk-dev] [PATCH v3 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                           ` (8 preceding siblings ...)
  2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 09/10] net/softnic: meter stats read Jasvinder Singh
@ 2018-09-14 17:45         ` Jasvinder Singh
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-14 17:45 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement flow rules with meter action.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_flow.c | 155 ++++++++++++++++++++++++++++-
 1 file changed, 154 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_flow.c b/drivers/net/softnic/rte_eth_softnic_flow.c
index 6562004..b7d2626 100644
--- a/drivers/net/softnic/rte_eth_softnic_flow.c
+++ b/drivers/net/softnic/rte_eth_softnic_flow.c
@@ -1146,7 +1146,7 @@ flow_rule_action_get(struct pmd_internals *softnic,
 	const struct rte_flow_attr *attr,
 	const struct rte_flow_action *action,
 	struct softnic_table_rule_action *rule_action,
-	struct rte_flow_error *error __rte_unused)
+	struct rte_flow_error *error)
 {
 	struct softnic_table_action_profile *profile;
 	struct softnic_table_action_profile_params *params;
@@ -1459,6 +1459,95 @@ flow_rule_action_get(struct pmd_internals *softnic,
 			break;
 		} /* RTE_FLOW_ACTION_TYPE_COUNT */
 
+		case RTE_FLOW_ACTION_TYPE_METER:
+		{
+			const struct rte_flow_action_meter *conf = action->conf;
+			struct softnic_mtr_meter_profile *mp;
+			struct softnic_mtr *m;
+			uint32_t table_id = table - pipeline->table;
+			uint32_t meter_profile_id;
+			int status;
+
+			if ((params->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) == 0)
+				return rte_flow_error_set(error,
+					EINVAL,
+					RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+					NULL,
+					"METER: Table action not supported");
+
+			if (params->mtr.n_tc != 1)
+				return rte_flow_error_set(error,
+					EINVAL,
+					RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+					NULL,
+					"METER: Multiple TCs not supported");
+
+			if (conf == NULL)
+				return rte_flow_error_set(error,
+					EINVAL,
+					RTE_FLOW_ERROR_TYPE_ACTION,
+					action,
+					"METER: Null configuration");
+
+			m = softnic_mtr_find(softnic, conf->mtr_id);
+
+			if (m == NULL)
+				return rte_flow_error_set(error,
+					EINVAL,
+					RTE_FLOW_ERROR_TYPE_ACTION_CONF,
+					NULL,
+					"METER: Invalid meter ID");
+
+			if (m->flow)
+				return rte_flow_error_set(error,
+					EINVAL,
+					RTE_FLOW_ERROR_TYPE_ACTION_CONF,
+					NULL,
+					"METER: Meter already attached to a flow");
+
+			meter_profile_id = m->params.meter_profile_id;
+			mp = softnic_mtr_meter_profile_find(softnic, meter_profile_id);
+
+			/* Add meter profile to pipeline table */
+			if (!softnic_pipeline_table_meter_profile_find(table,
+					meter_profile_id)) {
+				struct rte_table_action_meter_profile profile;
+
+				memset(&profile, 0, sizeof(profile));
+				profile.alg = RTE_TABLE_ACTION_METER_TRTCM;
+				profile.trtcm.cir = mp->params.trtcm_rfc2698.cir;
+				profile.trtcm.pir = mp->params.trtcm_rfc2698.pir;
+				profile.trtcm.cbs = mp->params.trtcm_rfc2698.cbs;
+				profile.trtcm.pbs = mp->params.trtcm_rfc2698.pbs;
+
+				status = softnic_pipeline_table_mtr_profile_add(softnic,
+						pipeline->name,
+						table_id,
+						meter_profile_id,
+						&profile);
+				if (status) {
+					rte_flow_error_set(error,
+						EINVAL,
+						RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+						NULL,
+						"METER: Table meter profile add failed");
+					return -1;
+				}
+			}
+
+			/* RTE_TABLE_ACTION_METER */
+			rule_action->mtr.mtr[0].meter_profile_id = meter_profile_id;
+			rule_action->mtr.mtr[0].policer[e_RTE_METER_GREEN] =
+				(enum rte_table_action_policer)m->params.action[RTE_MTR_GREEN];
+			rule_action->mtr.mtr[0].policer[e_RTE_METER_YELLOW] =
+				(enum rte_table_action_policer)m->params.action[RTE_MTR_YELLOW];
+			rule_action->mtr.mtr[0].policer[e_RTE_METER_RED] =
+				(enum rte_table_action_policer)m->params.action[RTE_MTR_RED];
+			rule_action->mtr.tc_mask = 1;
+			rule_action->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
+			break;
+		} /* RTE_FLOW_ACTION_TYPE_METER */
+
 		default:
 			return -ENOTSUP;
 		}
@@ -1562,6 +1651,61 @@ pmd_flow_validate(struct rte_eth_dev *dev,
 	return 0;
 }
 
+static struct softnic_mtr *
+flow_action_meter_get(struct pmd_internals *softnic,
+	const struct rte_flow_action *action)
+{
+	for ( ; action->type != RTE_FLOW_ACTION_TYPE_END; action++)
+		if (action->type == RTE_FLOW_ACTION_TYPE_METER) {
+			const struct rte_flow_action_meter *conf = action->conf;
+
+			if (conf == NULL)
+				return NULL;
+
+			return softnic_mtr_find(softnic, conf->mtr_id);
+		}
+
+	return NULL;
+}
+
+static void
+flow_meter_owner_reset(struct pmd_internals *softnic,
+	struct rte_flow *flow)
+{
+	struct softnic_mtr_list *ml = &softnic->mtr.mtrs;
+	struct softnic_mtr *m;
+
+	TAILQ_FOREACH(m, ml, node)
+		if (m->flow == flow) {
+			m->flow = NULL;
+			break;
+		}
+}
+
+static void
+flow_meter_owner_set(struct pmd_internals *softnic,
+	struct rte_flow *flow,
+	struct softnic_mtr *mtr)
+{
+	/* Reset current flow meter  */
+	flow_meter_owner_reset(softnic, flow);
+
+	/* Set new flow meter */
+	mtr->flow = flow;
+}
+
+static int
+is_meter_action_enable(struct pmd_internals *softnic,
+	struct softnic_table *table)
+{
+	struct softnic_table_action_profile *profile =
+		softnic_table_action_profile_find(softnic,
+			table->params.action_profile_name);
+	struct softnic_table_action_profile_params *params = &profile->params;
+
+	return (params->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) ? 1 : 0;
+}
+
 static struct rte_flow *
 pmd_flow_create(struct rte_eth_dev *dev,
 	const struct rte_flow_attr *attr,
@@ -1577,6 +1721,7 @@ pmd_flow_create(struct rte_eth_dev *dev,
 	struct pipeline *pipeline;
 	struct softnic_table *table;
 	struct rte_flow *flow;
+	struct softnic_mtr *mtr;
 	const char *pipeline_name = NULL;
 	uint32_t table_id = 0;
 	int new_flow, status;
@@ -1702,6 +1847,10 @@ pmd_flow_create(struct rte_eth_dev *dev,
 	flow->pipeline = pipeline;
 	flow->table_id = table_id;
 
+	mtr = flow_action_meter_get(softnic, action);
+	if (mtr)
+		flow_meter_owner_set(softnic, flow, mtr);
+
 	/* Flow add to list. */
 	if (new_flow)
 		TAILQ_INSERT_TAIL(&table->flows, flow, node);
@@ -1740,6 +1889,10 @@ pmd_flow_destroy(struct rte_eth_dev *dev,
 			NULL,
 			"Pipeline table rule delete failed");
 
+	/* Update dependencies */
+	if (is_meter_action_enable(softnic, table))
+		flow_meter_owner_reset(softnic, flow);
+
 	/* Flow delete. */
 	TAILQ_REMOVE(&table->flows, flow, node);
 	free(flow);
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v4 00/10] net/softnic: implement metering and policing API
  2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 01/10] net/softnic: add metering and policing support Jasvinder Singh
@ 2018-09-18 16:58           ` Jasvinder Singh
  2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 01/10] net/softnic: add metering and policing support Jasvinder Singh
                               ` (9 more replies)
  0 siblings, 10 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-18 16:58 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

This series is prepared on top of following patchset;
https://mails.dpdk.org/archives/dev/2018-September/111379.html

v4 changes
- introduce the table meter profile check in softnic pipeline table meter
  profile add function (rte_eth_softnic_thread.c)
- change the table action check function to more generic form
  softnic_table_is_action_enabled() (rte_eth_softnic_flow.c)
  
v3 changes:
- update pipeline table with meter profiles
- update pipeline table with dscp table entry update

v2 changes:
- fix copyright year for rte_eth_softnic_meter.c
- Place all checks in a separate functions while creating meter object
- Use softnic_pipeline_table_mtr_profile_add() api to add meter profile
  instead of implementing new function
- Use stats type indicator to determine the stats_mask for meter stats read 
 
Jasvinder Singh (10):
  net/softnic: add metering and policing support
  net/softnic: add meter profile
  net/softnic: delete meter profile
  net/softnic: create meter object
  net/softnic: destroy meter object
  net/softnic: update meter profile
  net/softnic: update dscp table
  net/softnic: update policer actions
  net/softnic: meter stats read
  net/softnic: enable flow rule with meter action

 drivers/net/softnic/Makefile                    |   1 +
 drivers/net/softnic/meson.build                 |   1 +
 drivers/net/softnic/rte_eth_softnic.c           |  13 +
 drivers/net/softnic/rte_eth_softnic_flow.c      | 155 ++++-
 drivers/net/softnic/rte_eth_softnic_internals.h |  66 +++
 drivers/net/softnic/rte_eth_softnic_meter.c     | 728 ++++++++++++++++++++++++
 drivers/net/softnic/rte_eth_softnic_pipeline.c  |  26 +
 drivers/net/softnic/rte_eth_softnic_thread.c    |  48 +-
 8 files changed, 1032 insertions(+), 6 deletions(-)
 create mode 100644 drivers/net/softnic/rte_eth_softnic_meter.c

-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v4 01/10] net/softnic: add metering and policing support
  2018-09-18 16:58           ` [dpdk-dev] [PATCH v4 00/10] net/softnic: implement metering and policing API Jasvinder Singh
@ 2018-09-18 16:58             ` Jasvinder Singh
  2018-09-26 13:08               ` [dpdk-dev] [PATCH v5 00/10] net/softnic: implement metering and policing API Jasvinder Singh
  2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 02/10] net/softnic: add meter profile Jasvinder Singh
                               ` (8 subsequent siblings)
  9 siblings, 1 reply; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-18 16:58 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Enable metering and policing support for softnic.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/Makefile                    |  1 +
 drivers/net/softnic/meson.build                 |  1 +
 drivers/net/softnic/rte_eth_softnic.c           | 10 ++++++++
 drivers/net/softnic/rte_eth_softnic_internals.h |  5 ++++
 drivers/net/softnic/rte_eth_softnic_meter.c     | 31 +++++++++++++++++++++++++
 5 files changed, 48 insertions(+)
 create mode 100644 drivers/net/softnic/rte_eth_softnic_meter.c

diff --git a/drivers/net/softnic/Makefile b/drivers/net/softnic/Makefile
index 12515b1..720f067b 100644
--- a/drivers/net/softnic/Makefile
+++ b/drivers/net/softnic/Makefile
@@ -34,6 +34,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_pipeline.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_thread.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_cli.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_flow.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_meter.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += parser.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += conn.c
 
diff --git a/drivers/net/softnic/meson.build b/drivers/net/softnic/meson.build
index 56e5e2b..6b7a6cc 100644
--- a/drivers/net/softnic/meson.build
+++ b/drivers/net/softnic/meson.build
@@ -14,6 +14,7 @@ sources = files('rte_eth_softnic_tm.c',
 	'rte_eth_softnic_thread.c',
 	'rte_eth_softnic_cli.c',
 	'rte_eth_softnic_flow.c',
+	'rte_eth_softnic_meter.c',
 	'parser.c',
 	'conn.c')
 deps += ['pipeline', 'port', 'table', 'sched']
diff --git a/drivers/net/softnic/rte_eth_softnic.c b/drivers/net/softnic/rte_eth_softnic.c
index ae2a438..659a1b4 100644
--- a/drivers/net/softnic/rte_eth_softnic.c
+++ b/drivers/net/softnic/rte_eth_softnic.c
@@ -14,6 +14,7 @@
 #include <rte_errno.h>
 #include <rte_ring.h>
 #include <rte_tm_driver.h>
+#include <rte_mtr_driver.h>
 
 #include "rte_eth_softnic.h"
 #include "rte_eth_softnic_internals.h"
@@ -228,6 +229,14 @@ pmd_tm_ops_get(struct rte_eth_dev *dev __rte_unused, void *arg)
 	return 0;
 }
 
+static int
+pmd_mtr_ops_get(struct rte_eth_dev *dev __rte_unused, void *arg)
+{
+	*(const struct rte_mtr_ops **)arg = &pmd_mtr_ops;
+
+	return 0;
+}
+
 static const struct eth_dev_ops pmd_ops = {
 	.dev_configure = pmd_dev_configure,
 	.dev_start = pmd_dev_start,
@@ -239,6 +248,7 @@ static const struct eth_dev_ops pmd_ops = {
 	.tx_queue_setup = pmd_tx_queue_setup,
 	.filter_ctrl = pmd_filter_ctrl,
 	.tm_ops_get = pmd_tm_ops_get,
+	.mtr_ops_get = pmd_mtr_ops_get,
 };
 
 static uint16_t
diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index a1a2e15..92be4e8 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -572,6 +572,11 @@ flow_attr_map_get(struct pmd_internals *softnic,
 extern const struct rte_flow_ops pmd_flow_ops;
 
 /**
+ * Meter
+ */
+extern const struct rte_mtr_ops pmd_mtr_ops;
+
+/**
  * MEMPOOL
  */
 int
diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
new file mode 100644
index 0000000..0a5409b
--- /dev/null
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <rte_mtr.h>
+#include <rte_mtr_driver.h>
+
+#include "rte_eth_softnic_internals.h"
+
+const struct rte_mtr_ops pmd_mtr_ops = {
+	.capabilities_get = NULL,
+
+	.meter_profile_add = NULL,
+	.meter_profile_delete = NULL,
+
+	.create = NULL,
+	.destroy = NULL,
+	.meter_enable = NULL,
+	.meter_disable = NULL,
+
+	.meter_profile_update = NULL,
+	.meter_dscp_table_update = NULL,
+	.policer_actions_update = NULL,
+	.stats_update = NULL,
+
+	.stats_read = NULL,
+};
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v4 02/10] net/softnic: add meter profile
  2018-09-18 16:58           ` [dpdk-dev] [PATCH v4 00/10] net/softnic: implement metering and policing API Jasvinder Singh
  2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 01/10] net/softnic: add metering and policing support Jasvinder Singh
@ 2018-09-18 16:58             ` Jasvinder Singh
  2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 03/10] net/softnic: delete " Jasvinder Singh
                               ` (7 subsequent siblings)
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-18 16:58 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter profile add function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic.c           |   3 +
 drivers/net/softnic/rte_eth_softnic_internals.h |  31 ++++++
 drivers/net/softnic/rte_eth_softnic_meter.c     | 122 +++++++++++++++++++++++-
 3 files changed, 155 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic.c b/drivers/net/softnic/rte_eth_softnic.c
index 659a1b4..b7b2383 100644
--- a/drivers/net/softnic/rte_eth_softnic.c
+++ b/drivers/net/softnic/rte_eth_softnic.c
@@ -191,6 +191,7 @@ pmd_dev_stop(struct rte_eth_dev *dev)
 	softnic_mempool_free(p);
 
 	tm_hierarchy_free(p);
+	softnic_mtr_free(p);
 }
 
 static void
@@ -291,6 +292,7 @@ pmd_init(struct pmd_params *params)
 
 	/* Resources */
 	tm_hierarchy_init(p);
+	softnic_mtr_init(p);
 
 	softnic_mempool_init(p);
 	softnic_swq_init(p);
@@ -345,6 +347,7 @@ pmd_free(struct pmd_internals *p)
 	softnic_mempool_free(p);
 
 	tm_hierarchy_free(p);
+	softnic_mtr_free(p);
 
 	rte_free(p);
 }
diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index 92be4e8..1db9310 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -22,6 +22,7 @@
 #include <rte_ethdev_driver.h>
 #include <rte_tm_driver.h>
 #include <rte_flow_driver.h>
+#include <rte_mtr_driver.h>
 
 #include "rte_eth_softnic.h"
 #include "conn.h"
@@ -68,6 +69,24 @@ struct flow_internals {
 };
 
 /**
+ * Meter
+ */
+
+/* MTR meter profile */
+struct softnic_mtr_meter_profile {
+	TAILQ_ENTRY(softnic_mtr_meter_profile) node;
+	uint32_t meter_profile_id;
+	struct rte_mtr_meter_profile params;
+	uint32_t n_users;
+};
+
+TAILQ_HEAD(softnic_mtr_meter_profile_list, softnic_mtr_meter_profile);
+
+struct mtr_internals {
+	struct softnic_mtr_meter_profile_list meter_profiles;
+};
+
+/**
  * MEMPOOL
  */
 struct softnic_mempool_params {
@@ -525,6 +544,8 @@ struct pmd_internals {
 	} soft;
 
 	struct flow_internals flow;
+	struct mtr_internals mtr;
+
 	struct softnic_conn *conn;
 	struct softnic_mempool_list mempool_list;
 	struct softnic_swq_list swq_list;
@@ -574,6 +595,16 @@ extern const struct rte_flow_ops pmd_flow_ops;
 /**
  * Meter
  */
+int
+softnic_mtr_init(struct pmd_internals *p);
+
+void
+softnic_mtr_free(struct pmd_internals *p);
+
+struct softnic_mtr_meter_profile *
+softnic_mtr_meter_profile_find(struct pmd_internals *p,
+	uint32_t meter_profile_id);
+
 extern const struct rte_mtr_ops pmd_mtr_ops;
 
 /**
diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 0a5409b..1222866 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -11,10 +11,130 @@
 
 #include "rte_eth_softnic_internals.h"
 
+int
+softnic_mtr_init(struct pmd_internals *p)
+{
+	/* Initialize meter profiles list */
+	TAILQ_INIT(&p->mtr.meter_profiles);
+
+	return 0;
+}
+
+void
+softnic_mtr_free(struct pmd_internals *p)
+{
+	/* Remove meter profiles */
+	for ( ; ; ) {
+		struct softnic_mtr_meter_profile *mp;
+
+		mp = TAILQ_FIRST(&p->mtr.meter_profiles);
+		if (mp == NULL)
+			break;
+
+		TAILQ_REMOVE(&p->mtr.meter_profiles, mp, node);
+		free(mp);
+	}
+}
+
+struct softnic_mtr_meter_profile *
+softnic_mtr_meter_profile_find(struct pmd_internals *p,
+	uint32_t meter_profile_id)
+{
+	struct softnic_mtr_meter_profile_list *mpl = &p->mtr.meter_profiles;
+	struct softnic_mtr_meter_profile *mp;
+
+	TAILQ_FOREACH(mp, mpl, node)
+		if (meter_profile_id == mp->meter_profile_id)
+			return mp;
+
+	return NULL;
+}
+
+static int
+meter_profile_check(struct rte_eth_dev *dev,
+	uint32_t meter_profile_id,
+	struct rte_mtr_meter_profile *profile,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_meter_profile *mp;
+
+	/* Meter profile ID must be valid. */
+	if (meter_profile_id == UINT32_MAX)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"Meter profile id not valid");
+
+	/* Meter profile must not exist. */
+	mp = softnic_mtr_meter_profile_find(p, meter_profile_id);
+	if (mp)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"Meter prfile already exists");
+
+	/* Profile must not be NULL. */
+	if (profile == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE,
+			NULL,
+			"profile null");
+
+	/* Traffic metering algorithm : TRTCM_RFC2698 */
+	if (profile->alg != RTE_MTR_TRTCM_RFC2698)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE,
+			NULL,
+			"Metering alg not supported");
+
+	return 0;
+}
+
+/* MTR meter profile add */
+static int
+pmd_mtr_meter_profile_add(struct rte_eth_dev *dev,
+	uint32_t meter_profile_id,
+	struct rte_mtr_meter_profile *profile,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_meter_profile_list *mpl = &p->mtr.meter_profiles;
+	struct softnic_mtr_meter_profile *mp;
+	int status;
+
+	/* Check input params */
+	status = meter_profile_check(dev, meter_profile_id, profile, error);
+	if (status)
+		return status;
+
+	/* Memory allocation */
+	mp = calloc(1, sizeof(struct softnic_mtr_meter_profile));
+	if (mp == NULL)
+		return -rte_mtr_error_set(error,
+			ENOMEM,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"Memory alloc failed");
+
+	/* Fill in */
+	mp->meter_profile_id = meter_profile_id;
+	memcpy(&mp->params, profile, sizeof(mp->params));
+
+	/* Add to list */
+	TAILQ_INSERT_TAIL(mpl, mp, node);
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
-	.meter_profile_add = NULL,
+	.meter_profile_add = pmd_mtr_meter_profile_add,
 	.meter_profile_delete = NULL,
 
 	.create = NULL,
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v4 03/10] net/softnic: delete meter profile
  2018-09-18 16:58           ` [dpdk-dev] [PATCH v4 00/10] net/softnic: implement metering and policing API Jasvinder Singh
  2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 01/10] net/softnic: add metering and policing support Jasvinder Singh
  2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 02/10] net/softnic: add meter profile Jasvinder Singh
@ 2018-09-18 16:58             ` Jasvinder Singh
  2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 04/10] net/softnic: create meter object Jasvinder Singh
                               ` (6 subsequent siblings)
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-18 16:58 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter profile delete function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_meter.c | 35 ++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 1222866..f3205bd 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -131,11 +131,44 @@ pmd_mtr_meter_profile_add(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* MTR meter profile delete */
+static int
+pmd_mtr_meter_profile_delete(struct rte_eth_dev *dev,
+	uint32_t meter_profile_id,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_meter_profile *mp;
+
+	/* Meter profile must exist */
+	mp = softnic_mtr_meter_profile_find(p, meter_profile_id);
+	if (mp == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"Meter profile id invalid");
+
+	/* Check unused */
+	if (mp->n_users)
+		return -rte_mtr_error_set(error,
+			EBUSY,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"Meter profile in use");
+
+	/* Remove from list */
+	TAILQ_REMOVE(&p->mtr.meter_profiles, mp, node);
+	free(mp);
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
 	.meter_profile_add = pmd_mtr_meter_profile_add,
-	.meter_profile_delete = NULL,
+	.meter_profile_delete = pmd_mtr_meter_profile_delete,
 
 	.create = NULL,
 	.destroy = NULL,
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v4 04/10] net/softnic: create meter object
  2018-09-18 16:58           ` [dpdk-dev] [PATCH v4 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                               ` (2 preceding siblings ...)
  2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 03/10] net/softnic: delete " Jasvinder Singh
@ 2018-09-18 16:58             ` Jasvinder Singh
  2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 05/10] net/softnic: destroy " Jasvinder Singh
                               ` (5 subsequent siblings)
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-18 16:58 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

implement meter object create function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_internals.h |  15 +++
 drivers/net/softnic/rte_eth_softnic_meter.c     | 123 +++++++++++++++++++++++-
 2 files changed, 137 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index 1db9310..50b7295 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -82,8 +82,19 @@ struct softnic_mtr_meter_profile {
 
 TAILQ_HEAD(softnic_mtr_meter_profile_list, softnic_mtr_meter_profile);
 
+/* MTR meter object */
+struct softnic_mtr {
+	TAILQ_ENTRY(softnic_mtr) node;
+	uint32_t mtr_id;
+	struct rte_mtr_params params;
+	struct rte_flow *flow;
+};
+
+TAILQ_HEAD(softnic_mtr_list, softnic_mtr);
+
 struct mtr_internals {
 	struct softnic_mtr_meter_profile_list meter_profiles;
+	struct softnic_mtr_list mtrs;
 };
 
 /**
@@ -601,6 +612,10 @@ softnic_mtr_init(struct pmd_internals *p);
 void
 softnic_mtr_free(struct pmd_internals *p);
 
+struct softnic_mtr *
+softnic_mtr_find(struct pmd_internals *p,
+	uint32_t mtr_id);
+
 struct softnic_mtr_meter_profile *
 softnic_mtr_meter_profile_find(struct pmd_internals *p,
 	uint32_t meter_profile_id);
diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index f3205bd..12dd79c 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -17,12 +17,27 @@ softnic_mtr_init(struct pmd_internals *p)
 	/* Initialize meter profiles list */
 	TAILQ_INIT(&p->mtr.meter_profiles);
 
+	/* Initialize MTR objects list */
+	TAILQ_INIT(&p->mtr.mtrs);
+
 	return 0;
 }
 
 void
 softnic_mtr_free(struct pmd_internals *p)
 {
+	/* Remove MTR objects */
+	for ( ; ; ) {
+		struct softnic_mtr *m;
+
+		m = TAILQ_FIRST(&p->mtr.mtrs);
+		if (m == NULL)
+			break;
+
+		TAILQ_REMOVE(&p->mtr.mtrs, m, node);
+		free(m);
+	}
+
 	/* Remove meter profiles */
 	for ( ; ; ) {
 		struct softnic_mtr_meter_profile *mp;
@@ -164,13 +179,119 @@ pmd_mtr_meter_profile_delete(struct rte_eth_dev *dev,
 	return 0;
 }
 
+struct softnic_mtr *
+softnic_mtr_find(struct pmd_internals *p, uint32_t mtr_id)
+{
+	struct softnic_mtr_list *ml = &p->mtr.mtrs;
+	struct softnic_mtr *m;
+
+	TAILQ_FOREACH(m, ml, node)
+		if (m->mtr_id == mtr_id)
+			return m;
+
+	return NULL;
+}
+
+
+static int
+mtr_check(struct pmd_internals *p,
+	uint32_t mtr_id,
+	struct rte_mtr_params *params,
+	int shared,
+	struct rte_mtr_error *error)
+{
+	/* MTR id valid  */
+	if (softnic_mtr_find(p, mtr_id))
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			"MTR object already exists");
+
+	/* MTR params must not be NULL */
+	if (params == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_MTR_PARAMS,
+			NULL,
+			"MTR object params null");
+
+	/* Previous meter color not supported */
+	if (params->use_prev_mtr_color)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_MTR_PARAMS,
+			NULL,
+			"Previous meter color not supported");
+
+	/* Shared MTR object not supported */
+	if (shared)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_SHARED,
+			NULL,
+			"Shared MTR object not supported");
+
+	return 0;
+}
+
+/* MTR object create */
+static int
+pmd_mtr_create(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	struct rte_mtr_params *params,
+	int shared,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_list *ml = &p->mtr.mtrs;
+	struct softnic_mtr_meter_profile *mp;
+	struct softnic_mtr *m;
+	int status;
+
+	/* Check parameters */
+	status = mtr_check(p, mtr_id, params, shared, error);
+	if (status)
+		return status;
+
+	/* Meter profile must exist */
+	mp = softnic_mtr_meter_profile_find(p, params->meter_profile_id);
+	if (mp == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"Meter profile id not valid");
+
+	/* Memory allocation */
+	m = calloc(1, sizeof(struct softnic_mtr));
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			ENOMEM,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"Memory alloc failed");
+
+	/* Fill in */
+	m->mtr_id = mtr_id;
+	memcpy(&m->params, params, sizeof(m->params));
+
+	/* Add to list */
+	TAILQ_INSERT_TAIL(ml, m, node);
+
+	/* Update dependencies */
+	mp->n_users++;
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
 	.meter_profile_add = pmd_mtr_meter_profile_add,
 	.meter_profile_delete = pmd_mtr_meter_profile_delete,
 
-	.create = NULL,
+	.create = pmd_mtr_create,
 	.destroy = NULL,
 	.meter_enable = NULL,
 	.meter_disable = NULL,
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v4 05/10] net/softnic: destroy meter object
  2018-09-18 16:58           ` [dpdk-dev] [PATCH v4 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                               ` (3 preceding siblings ...)
  2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 04/10] net/softnic: create meter object Jasvinder Singh
@ 2018-09-18 16:58             ` Jasvinder Singh
  2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 06/10] net/softnic: update meter profile Jasvinder Singh
                               ` (4 subsequent siblings)
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-18 16:58 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter object destroy function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_meter.c | 49 ++++++++++++++++++++++++++++-
 1 file changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 12dd79c..5103bda 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -285,6 +285,53 @@ pmd_mtr_create(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* MTR object destroy */
+static int
+pmd_mtr_destroy(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_list *ml = &p->mtr.mtrs;
+	struct softnic_mtr_meter_profile *mp;
+	struct softnic_mtr *m;
+
+	/* MTR object must exist */
+	m = softnic_mtr_find(p, mtr_id);
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			"MTR object id not valid");
+
+	/* MTR object must not have any owner */
+	if (m->flow != NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"MTR object is being used");
+
+	/* Get meter profile */
+	mp = softnic_mtr_meter_profile_find(p, m->params.meter_profile_id);
+	if (mp == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"MTR object meter profile invalid");
+
+	/* Update dependencies */
+	mp->n_users--;
+
+	/* Remove from list */
+	TAILQ_REMOVE(ml, m, node);
+	free(m);
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
@@ -292,7 +339,7 @@ const struct rte_mtr_ops pmd_mtr_ops = {
 	.meter_profile_delete = pmd_mtr_meter_profile_delete,
 
 	.create = pmd_mtr_create,
-	.destroy = NULL,
+	.destroy = pmd_mtr_destroy,
 	.meter_enable = NULL,
 	.meter_disable = NULL,
 
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v4 06/10] net/softnic: update meter profile
  2018-09-18 16:58           ` [dpdk-dev] [PATCH v4 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                               ` (4 preceding siblings ...)
  2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 05/10] net/softnic: destroy " Jasvinder Singh
@ 2018-09-18 16:58             ` Jasvinder Singh
  2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 07/10] net/softnic: update dscp table Jasvinder Singh
                               ` (3 subsequent siblings)
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-18 16:58 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter profile update function

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_internals.h |  14 ++++
 drivers/net/softnic/rte_eth_softnic_meter.c     | 103 +++++++++++++++++++++++-
 drivers/net/softnic/rte_eth_softnic_pipeline.c  |  25 ++++++
 drivers/net/softnic/rte_eth_softnic_thread.c    |  38 +++++++--
 4 files changed, 174 insertions(+), 6 deletions(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index 50b7295..4b0f54c 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -320,6 +320,15 @@ struct softnic_table_action_profile {
 
 TAILQ_HEAD(softnic_table_action_profile_list, softnic_table_action_profile);
 
+struct softnic_table_meter_profile {
+	TAILQ_ENTRY(softnic_table_meter_profile) node;
+	uint32_t meter_profile_id;
+	struct rte_table_action_meter_profile profile;
+};
+
+TAILQ_HEAD(softnic_table_meter_profile_list,
+	softnic_table_meter_profile);
+
 /**
  * Pipeline
  */
@@ -455,6 +464,7 @@ struct softnic_table {
 	struct softnic_table_action_profile *ap;
 	struct rte_table_action *a;
 	struct flow_list flows;
+	struct softnic_table_meter_profile_list meter_profiles;
 };
 
 struct pipeline {
@@ -813,6 +823,10 @@ softnic_pipeline_table_create(struct pmd_internals *p,
 	const char *pipeline_name,
 	struct softnic_table_params *params);
 
+struct softnic_table_meter_profile *
+softnic_pipeline_table_meter_profile_find(struct softnic_table *table,
+	uint32_t meter_profile_id);
+
 struct softnic_table_rule_match_acl {
 	int ip_version;
 
diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 5103bda..68daf8a 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -332,6 +332,107 @@ pmd_mtr_destroy(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* MTR object meter profile update */
+static int
+pmd_mtr_meter_profile_update(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	uint32_t meter_profile_id,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_meter_profile *mp_new, *mp_old;
+	struct softnic_mtr *m;
+	int status;
+
+	/* MTR object id must be valid */
+	m = softnic_mtr_find(p, mtr_id);
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			"MTR object id not valid");
+
+	/* Meter profile id must be valid */
+	mp_new = softnic_mtr_meter_profile_find(p, meter_profile_id);
+	if (mp_new == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"Meter profile not valid");
+
+	/* MTR object already set to meter profile id */
+	if (m->params.meter_profile_id == meter_profile_id)
+		return 0;
+
+	/*  MTR object owner table update */
+	if (m->flow) {
+		uint32_t table_id = m->flow->table_id;
+		struct softnic_table *table = &m->flow->pipeline->table[table_id];
+		struct softnic_table_rule_action action;
+
+		if (!softnic_pipeline_table_meter_profile_find(table,
+			meter_profile_id)) {
+			struct rte_table_action_meter_profile profile;
+
+			memset(&profile, 0, sizeof(profile));
+
+			profile.alg = RTE_TABLE_ACTION_METER_TRTCM;
+			profile.trtcm.cir = mp_new->params.trtcm_rfc2698.cir;
+			profile.trtcm.pir = mp_new->params.trtcm_rfc2698.pir;
+			profile.trtcm.cbs = mp_new->params.trtcm_rfc2698.cbs;
+			profile.trtcm.pbs = mp_new->params.trtcm_rfc2698.pbs;
+
+			/* Add meter profile to pipeline table */
+			status = softnic_pipeline_table_mtr_profile_add(p,
+					m->flow->pipeline->name,
+					table_id,
+					meter_profile_id,
+					&profile);
+			if (status)
+				return -rte_mtr_error_set(error,
+					EINVAL,
+					RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+					NULL,
+					"Table meter profile add failed");
+		}
+
+		/* Set meter action */
+		memcpy(&action, &m->flow->action, sizeof(action));
+
+		action.mtr.mtr[0].meter_profile_id = meter_profile_id;
+
+		/* Re-add rule */
+		status = softnic_pipeline_table_rule_add(p,
+			m->flow->pipeline->name,
+			table_id,
+			&m->flow->match,
+			&action,
+			&m->flow->data);
+		if (status)
+			return -rte_mtr_error_set(error,
+				EINVAL,
+				RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+				NULL,
+				"Pipeline table rule add failed");
+
+		/* Flow: update meter action */
+		memcpy(&m->flow->action, &action, sizeof(m->flow->action));
+	}
+
+	mp_old = softnic_mtr_meter_profile_find(p, m->params.meter_profile_id);
+
+	/* Meter: Set meter profile */
+	m->params.meter_profile_id = meter_profile_id;
+
+	/* Update dependencies*/
+	mp_old->n_users--;
+	mp_new->n_users++;
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
@@ -343,7 +444,7 @@ const struct rte_mtr_ops pmd_mtr_ops = {
 	.meter_enable = NULL,
 	.meter_disable = NULL,
 
-	.meter_profile_update = NULL,
+	.meter_profile_update = pmd_mtr_meter_profile_update,
 	.meter_dscp_table_update = NULL,
 	.policer_actions_update = NULL,
 	.stats_update = NULL,
diff --git a/drivers/net/softnic/rte_eth_softnic_pipeline.c b/drivers/net/softnic/rte_eth_softnic_pipeline.c
index d1127a1..17830d3 100644
--- a/drivers/net/softnic/rte_eth_softnic_pipeline.c
+++ b/drivers/net/softnic/rte_eth_softnic_pipeline.c
@@ -55,6 +55,17 @@ softnic_pipeline_table_free(struct softnic_table *table)
 		TAILQ_REMOVE(&table->flows, flow, node);
 		free(flow);
 	}
+
+	for ( ; ; ) {
+		struct softnic_table_meter_profile *mp;
+
+		mp = TAILQ_FIRST(&table->meter_profiles);
+		if (mp == NULL)
+			break;
+
+		TAILQ_REMOVE(&table->meter_profiles, mp, node);
+		free(mp);
+	}
 }
 
 void
@@ -988,6 +999,7 @@ softnic_pipeline_table_create(struct pmd_internals *softnic,
 	table->ap = ap;
 	table->a = action;
 	TAILQ_INIT(&table->flows);
+	TAILQ_INIT(&table->meter_profiles);
 	pipeline->n_tables++;
 
 	return 0;
@@ -1020,3 +1032,16 @@ softnic_pipeline_port_out_find(struct pmd_internals *softnic,
 
 	return -1;
 }
+
+struct softnic_table_meter_profile *
+softnic_pipeline_table_meter_profile_find(struct softnic_table *table,
+	uint32_t meter_profile_id)
+{
+	struct softnic_table_meter_profile *mp;
+
+	TAILQ_FOREACH(mp, &table->meter_profiles, node)
+		if (mp->meter_profile_id == meter_profile_id)
+			return mp;
+
+	return NULL;
+}
diff --git a/drivers/net/softnic/rte_eth_softnic_thread.c b/drivers/net/softnic/rte_eth_softnic_thread.c
index 8a15090..83cd07b 100644
--- a/drivers/net/softnic/rte_eth_softnic_thread.c
+++ b/drivers/net/softnic/rte_eth_softnic_thread.c
@@ -1680,6 +1680,8 @@ softnic_pipeline_table_mtr_profile_add(struct pmd_internals *softnic,
 	struct pipeline *p;
 	struct pipeline_msg_req *req;
 	struct pipeline_msg_rsp *rsp;
+	struct softnic_table *table;
+	struct softnic_table_meter_profile *mp;
 	int status;
 
 	/* Check input params */
@@ -1692,20 +1694,40 @@ softnic_pipeline_table_mtr_profile_add(struct pmd_internals *softnic,
 		table_id >= p->n_tables)
 		return -1;
 
-	if (!pipeline_is_running(p)) {
-		struct rte_table_action *a = p->table[table_id].a;
+	table = &p->table[table_id];
+	mp = softnic_pipeline_table_meter_profile_find(table, meter_profile_id);
+	if (mp)
+		return -1;
 
-		status = rte_table_action_meter_profile_add(a,
+	/* Resource Allocation */
+	mp = calloc(1, sizeof(struct softnic_table_meter_profile));
+	if (mp == NULL)
+		return -1;
+
+	mp->meter_profile_id = meter_profile_id;
+	memcpy(&mp->profile, &profile, sizeof(mp->profile));
+
+	if (!pipeline_is_running(p)) {
+		status = rte_table_action_meter_profile_add(table->a,
 			meter_profile_id,
 			profile);
+		if (status) {
+			free(mp);
+			return status;
+		}
+
+		/* Add profile to the table. */
+		TAILQ_INSERT_TAIL(&table->meter_profiles, mp, node);
 
 		return status;
 	}
 
 	/* Allocate request */
 	req = pipeline_msg_alloc();
-	if (req == NULL)
+	if (req == NULL) {
+		free(mp);
 		return -1;
+	}
 
 	/* Write request */
 	req->type = PIPELINE_REQ_TABLE_MTR_PROFILE_ADD;
@@ -1715,11 +1737,17 @@ softnic_pipeline_table_mtr_profile_add(struct pmd_internals *softnic,
 
 	/* Send request and wait for response */
 	rsp = pipeline_msg_send_recv(p, req);
-	if (rsp == NULL)
+	if (rsp == NULL) {
+		free(mp);
 		return -1;
+	}
 
 	/* Read response */
 	status = rsp->status;
+	if (status == 0)
+		TAILQ_INSERT_TAIL(&table->meter_profiles, mp, node);
+	else
+		free(mp);
 
 	/* Free response */
 	pipeline_msg_free(rsp);
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v4 07/10] net/softnic: update dscp table
  2018-09-18 16:58           ` [dpdk-dev] [PATCH v4 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                               ` (5 preceding siblings ...)
  2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 06/10] net/softnic: update meter profile Jasvinder Singh
@ 2018-09-18 16:58             ` Jasvinder Singh
  2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 08/10] net/softnic: update policer actions Jasvinder Singh
                               ` (2 subsequent siblings)
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-18 16:58 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter object dscp table update.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_internals.h |  1 +
 drivers/net/softnic/rte_eth_softnic_meter.c     | 54 ++++++++++++++++++++++++-
 drivers/net/softnic/rte_eth_softnic_pipeline.c  |  1 +
 drivers/net/softnic/rte_eth_softnic_thread.c    | 10 +++++
 4 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index 4b0f54c..78864e7 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -464,6 +464,7 @@ struct softnic_table {
 	struct softnic_table_action_profile *ap;
 	struct rte_table_action *a;
 	struct flow_list flows;
+	struct rte_table_action_dscp_table dscp_table;
 	struct softnic_table_meter_profile_list meter_profiles;
 };
 
diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 68daf8a..ed44767 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -433,6 +433,58 @@ pmd_mtr_meter_profile_update(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* MTR object meter DSCP table update */
+static int
+pmd_mtr_meter_dscp_table_update(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	enum rte_mtr_color *dscp_table,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct rte_table_action_dscp_table dt;
+	struct pipeline *pipeline;
+	struct softnic_table *table;
+	struct softnic_mtr *m;
+	uint32_t table_id, i;
+	int status;
+
+	/* MTR object id must be valid */
+	m = softnic_mtr_find(p, mtr_id);
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			"MTR object id not valid");
+
+	/* MTR object owner valid? */
+	if (m->flow == NULL)
+		return 0;
+
+	pipeline = m->flow->pipeline;
+	table_id = m->flow->table_id;
+	table = &pipeline->table[table_id];
+
+	memcpy(&dt, &table->dscp_table, sizeof(dt));
+	for (i = 0; i < RTE_DIM(dt.entry); i++)
+		dt.entry[i].color = (enum rte_meter_color)dscp_table[i];
+
+	/* Update table */
+	status = softnic_pipeline_table_dscp_table_update(p,
+			pipeline->name,
+			table_id,
+			UINT64_MAX,
+			&dt);
+	if (status)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"Table action dscp table update failed");
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
@@ -445,7 +497,7 @@ const struct rte_mtr_ops pmd_mtr_ops = {
 	.meter_disable = NULL,
 
 	.meter_profile_update = pmd_mtr_meter_profile_update,
-	.meter_dscp_table_update = NULL,
+	.meter_dscp_table_update = pmd_mtr_meter_dscp_table_update,
 	.policer_actions_update = NULL,
 	.stats_update = NULL,
 
diff --git a/drivers/net/softnic/rte_eth_softnic_pipeline.c b/drivers/net/softnic/rte_eth_softnic_pipeline.c
index 17830d3..3d37ba3 100644
--- a/drivers/net/softnic/rte_eth_softnic_pipeline.c
+++ b/drivers/net/softnic/rte_eth_softnic_pipeline.c
@@ -1000,6 +1000,7 @@ softnic_pipeline_table_create(struct pmd_internals *softnic,
 	table->a = action;
 	TAILQ_INIT(&table->flows);
 	TAILQ_INIT(&table->meter_profiles);
+	memset(&table->dscp_table, 0, sizeof(table->dscp_table));
 	pipeline->n_tables++;
 
 	return 0;
diff --git a/drivers/net/softnic/rte_eth_softnic_thread.c b/drivers/net/softnic/rte_eth_softnic_thread.c
index 83cd07b..e93a355 100644
--- a/drivers/net/softnic/rte_eth_softnic_thread.c
+++ b/drivers/net/softnic/rte_eth_softnic_thread.c
@@ -1902,6 +1902,11 @@ softnic_pipeline_table_dscp_table_update(struct pmd_internals *softnic,
 				dscp_mask,
 				dscp_table);
 
+		/* Update table dscp table */
+		if (!status)
+			memcpy(&p->table[table_id].dscp_table, dscp_table,
+				sizeof(p->table[table_id].dscp_table));
+
 		return status;
 	}
 
@@ -1925,6 +1930,11 @@ softnic_pipeline_table_dscp_table_update(struct pmd_internals *softnic,
 	/* Read response */
 	status = rsp->status;
 
+	/* Update table dscp table */
+	if (!status)
+		memcpy(&p->table[table_id].dscp_table, dscp_table,
+			sizeof(p->table[table_id].dscp_table));
+
 	/* Free response */
 	pipeline_msg_free(rsp);
 
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v4 08/10] net/softnic: update policer actions
  2018-09-18 16:58           ` [dpdk-dev] [PATCH v4 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                               ` (6 preceding siblings ...)
  2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 07/10] net/softnic: update dscp table Jasvinder Singh
@ 2018-09-18 16:58             ` Jasvinder Singh
  2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 09/10] net/softnic: meter stats read Jasvinder Singh
  2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 10/10] net/softnic: enable flow rule with meter action Jasvinder Singh
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-18 16:58 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter object policer actions function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_meter.c | 91 ++++++++++++++++++++++++++++-
 1 file changed, 90 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index ed44767..05d54d4 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -485,6 +485,95 @@ pmd_mtr_meter_dscp_table_update(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* MTR object policer action update */
+static int
+pmd_mtr_policer_actions_update(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	uint32_t action_mask,
+	enum rte_mtr_policer_action *actions,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr *m;
+	uint32_t i;
+	int status;
+
+	/* MTR object id must be valid */
+	m = softnic_mtr_find(p, mtr_id);
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			"MTR object id not valid");
+
+	/* Valid policer actions */
+	if (actions == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"Invalid actions");
+
+	for (i = 0; i < RTE_MTR_COLORS; i++) {
+		if (action_mask & (1 << i)) {
+			if (actions[i] != MTR_POLICER_ACTION_COLOR_GREEN  &&
+				actions[i] != MTR_POLICER_ACTION_COLOR_YELLOW &&
+				actions[i] != MTR_POLICER_ACTION_COLOR_RED &&
+				actions[i] != MTR_POLICER_ACTION_DROP) {
+				return -rte_mtr_error_set(error,
+					EINVAL,
+					RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+					NULL,
+					" Invalid action value");
+			}
+		}
+	}
+
+	/* MTR object owner valid? */
+	if (m->flow) {
+		struct pipeline *pipeline = m->flow->pipeline;
+		struct softnic_table *table = &pipeline->table[m->flow->table_id];
+		struct softnic_table_rule_action action;
+
+		memcpy(&action, &m->flow->action, sizeof(action));
+
+		/* Set action */
+		for (i = 0; i < RTE_MTR_COLORS; i++)
+			if (action_mask & (1 << i))
+				action.mtr.mtr[0].policer[i] =
+					(enum rte_table_action_policer)actions[i];
+
+		/* Re-add the rule */
+		status = softnic_pipeline_table_rule_add(p,
+			pipeline->name,
+			m->flow->table_id,
+			&m->flow->match,
+			&action,
+			&m->flow->data);
+		if (status)
+			return -rte_mtr_error_set(error,
+				EINVAL,
+				RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+				NULL,
+				"Pipeline table rule re-add failed");
+
+		/* Flow: Update meter action */
+		memcpy(&m->flow->action, &action, sizeof(m->flow->action));
+
+		/* Reset the meter stats */
+		rte_table_action_meter_read(table->a, m->flow->data,
+			1, NULL, 1);
+	}
+
+	/* Meter: Update policer actions */
+	for (i = 0; i < RTE_MTR_COLORS; i++)
+		if (action_mask & (1 << i))
+			m->params.action[i] = actions[i];
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
@@ -498,7 +587,7 @@ const struct rte_mtr_ops pmd_mtr_ops = {
 
 	.meter_profile_update = pmd_mtr_meter_profile_update,
 	.meter_dscp_table_update = pmd_mtr_meter_dscp_table_update,
-	.policer_actions_update = NULL,
+	.policer_actions_update = pmd_mtr_policer_actions_update,
 	.stats_update = NULL,
 
 	.stats_read = NULL,
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v4 09/10] net/softnic: meter stats read
  2018-09-18 16:58           ` [dpdk-dev] [PATCH v4 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                               ` (7 preceding siblings ...)
  2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 08/10] net/softnic: update policer actions Jasvinder Singh
@ 2018-09-18 16:58             ` Jasvinder Singh
  2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 10/10] net/softnic: enable flow rule with meter action Jasvinder Singh
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-18 16:58 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter object stats read function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_meter.c | 136 +++++++++++++++++++++++++++-
 1 file changed, 135 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 05d54d4..73ecf3b 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -574,6 +574,140 @@ pmd_mtr_policer_actions_update(struct rte_eth_dev *dev,
 	return 0;
 }
 
+#define MTR_STATS_PKTS_DEFAULT (RTE_MTR_STATS_N_PKTS_GREEN | \
+				RTE_MTR_STATS_N_PKTS_YELLOW | \
+				RTE_MTR_STATS_N_PKTS_RED | \
+				RTE_MTR_STATS_N_PKTS_DROPPED)
+
+#define MTR_STATS_BYTES_DEFAULT (RTE_MTR_STATS_N_BYTES_GREEN | \
+				RTE_MTR_STATS_N_BYTES_YELLOW | \
+				RTE_MTR_STATS_N_BYTES_RED | \
+				RTE_MTR_STATS_N_BYTES_DROPPED)
+
+/* MTR object stats read */
+static void
+mtr_stats_convert(struct softnic_mtr *m,
+	struct rte_table_action_mtr_counters_tc *in,
+	struct rte_mtr_stats *out,
+	uint64_t *out_mask)
+{
+	memset(&out, 0, sizeof(out));
+	*out_mask = 0;
+
+	if (in->n_packets_valid) {
+		uint32_t i;
+
+		for (i = 0; i < RTE_MTR_COLORS; i++) {
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_GREEN)
+				out->n_pkts[RTE_MTR_GREEN] += in->n_packets[i];
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_YELLOW)
+				out->n_pkts[RTE_MTR_YELLOW] += in->n_packets[i];
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_RED)
+				out->n_pkts[RTE_MTR_RED] += in->n_packets[i];
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_DROP)
+				out->n_pkts_dropped += in->n_packets[i];
+		}
+
+		*out_mask |= MTR_STATS_PKTS_DEFAULT;
+	}
+
+	if (in->n_bytes_valid) {
+		uint32_t i;
+
+		for (i = 0; i < RTE_MTR_COLORS; i++) {
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_GREEN)
+				out->n_bytes[RTE_MTR_GREEN] += in->n_bytes[i];
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_YELLOW)
+				out->n_bytes[RTE_MTR_YELLOW] += in->n_bytes[i];
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_RED)
+				out->n_bytes[RTE_MTR_RED] += in->n_bytes[i];
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_DROP)
+				out->n_bytes_dropped += in->n_bytes[i];
+		}
+
+		*out_mask |= MTR_STATS_BYTES_DEFAULT;
+	}
+}
+
+/* MTR object stats read */
+static int
+pmd_mtr_stats_read(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	struct rte_mtr_stats *stats,
+	uint64_t *stats_mask,
+	int clear,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct rte_table_action_mtr_counters counters;
+	struct pipeline *pipeline;
+	struct softnic_table *table;
+	struct softnic_mtr *m;
+	int status;
+
+	/* MTR object id must be valid */
+	m = softnic_mtr_find(p, mtr_id);
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			"MTR object id not valid");
+
+	/* MTR meter object owner valid? */
+	if (m->flow == NULL) {
+		if (stats != NULL)
+			memset(stats, 0, sizeof(*stats));
+
+		if (stats_mask)
+			*stats_mask = MTR_STATS_PKTS_DEFAULT |
+				MTR_STATS_BYTES_DEFAULT;
+
+		return 0;
+	}
+
+	pipeline = m->flow->pipeline;
+	table = &pipeline->table[m->flow->table_id];
+
+	/* Meter stats read. */
+	status = rte_table_action_meter_read(table->a,
+		m->flow->data,
+		1,
+		&counters,
+		clear);
+	if (status)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"Meter stats read failed");
+
+	/* Stats format conversion. */
+	if (stats || stats_mask) {
+		struct rte_mtr_stats s;
+		uint64_t s_mask = 0;
+
+		mtr_stats_convert(m,
+			&counters.stats[0],
+			&s,
+			&s_mask);
+
+		if (stats)
+			memcpy(stats, &s, sizeof(*stats));
+
+		if (stats_mask)
+			*stats_mask = s_mask;
+	}
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
@@ -590,5 +724,5 @@ const struct rte_mtr_ops pmd_mtr_ops = {
 	.policer_actions_update = pmd_mtr_policer_actions_update,
 	.stats_update = NULL,
 
-	.stats_read = NULL,
+	.stats_read = pmd_mtr_stats_read,
 };
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v4 10/10] net/softnic: enable flow rule with meter action
  2018-09-18 16:58           ` [dpdk-dev] [PATCH v4 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                               ` (8 preceding siblings ...)
  2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 09/10] net/softnic: meter stats read Jasvinder Singh
@ 2018-09-18 16:58             ` Jasvinder Singh
  9 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-18 16:58 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement flow rules with meter action.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_flow.c | 155 ++++++++++++++++++++++++++++-
 1 file changed, 154 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_flow.c b/drivers/net/softnic/rte_eth_softnic_flow.c
index fc7a0b0..03d41bc 100644
--- a/drivers/net/softnic/rte_eth_softnic_flow.c
+++ b/drivers/net/softnic/rte_eth_softnic_flow.c
@@ -1161,7 +1161,7 @@ flow_rule_action_get(struct pmd_internals *softnic,
 	const struct rte_flow_attr *attr,
 	const struct rte_flow_action *action,
 	struct softnic_table_rule_action *rule_action,
-	struct rte_flow_error *error __rte_unused)
+	struct rte_flow_error *error)
 {
 	struct softnic_table_action_profile *profile;
 	struct softnic_table_action_profile_params *params;
@@ -1474,6 +1474,95 @@ flow_rule_action_get(struct pmd_internals *softnic,
 			break;
 		} /* RTE_FLOW_ACTION_TYPE_COUNT */
 
+		case RTE_FLOW_ACTION_TYPE_METER:
+		{
+			const struct rte_flow_action_meter *conf = action->conf;
+			struct softnic_mtr_meter_profile *mp;
+			struct softnic_mtr *m;
+			uint32_t table_id = table - pipeline->table;
+			uint32_t meter_profile_id;
+			int status;
+
+			if ((params->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) == 0)
+				return rte_flow_error_set(error,
+					EINVAL,
+					RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+					NULL,
+					"METER: Table action not supported");
+
+			if (params->mtr.n_tc != 1)
+				return rte_flow_error_set(error,
+					EINVAL,
+					RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+					NULL,
+					"METER: Multiple TCs not supported");
+
+			if (conf == NULL)
+				return rte_flow_error_set(error,
+					EINVAL,
+					RTE_FLOW_ERROR_TYPE_ACTION,
+					action,
+					"METER: Null configuration");
+
+			m = softnic_mtr_find(softnic, conf->mtr_id);
+
+			if (m == NULL)
+				return rte_flow_error_set(error,
+					EINVAL,
+					RTE_FLOW_ERROR_TYPE_ACTION_CONF,
+					NULL,
+					"METER: Invalid meter ID");
+
+			if (m->flow)
+				return rte_flow_error_set(error,
+					EINVAL,
+					RTE_FLOW_ERROR_TYPE_ACTION_CONF,
+					NULL,
+					"METER: Meter already attached to a flow");
+
+			meter_profile_id = m->params.meter_profile_id;
+			mp = softnic_mtr_meter_profile_find(softnic, meter_profile_id);
+
+			/* Add meter profile to pipeline table */
+			if (!softnic_pipeline_table_meter_profile_find(table,
+					meter_profile_id)) {
+				struct rte_table_action_meter_profile profile;
+
+				memset(&profile, 0, sizeof(profile));
+				profile.alg = RTE_TABLE_ACTION_METER_TRTCM;
+				profile.trtcm.cir = mp->params.trtcm_rfc2698.cir;
+				profile.trtcm.pir = mp->params.trtcm_rfc2698.pir;
+				profile.trtcm.cbs = mp->params.trtcm_rfc2698.cbs;
+				profile.trtcm.pbs = mp->params.trtcm_rfc2698.pbs;
+
+				status = softnic_pipeline_table_mtr_profile_add(softnic,
+						pipeline->name,
+						table_id,
+						meter_profile_id,
+						&profile);
+				if (status) {
+					rte_flow_error_set(error,
+						EINVAL,
+						RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+						NULL,
+						"METER: Table meter profile add failed");
+					return -1;
+				}
+			}
+
+			/* RTE_TABLE_ACTION_METER */
+			rule_action->mtr.mtr[0].meter_profile_id = meter_profile_id;
+			rule_action->mtr.mtr[0].policer[e_RTE_METER_GREEN] =
+				(enum rte_table_action_policer)m->params.action[RTE_MTR_GREEN];
+			rule_action->mtr.mtr[0].policer[e_RTE_METER_YELLOW] =
+				(enum rte_table_action_policer)m->params.action[RTE_MTR_YELLOW];
+			rule_action->mtr.mtr[0].policer[e_RTE_METER_RED] =
+				(enum rte_table_action_policer)m->params.action[RTE_MTR_RED];
+			rule_action->mtr.tc_mask = 1;
+			rule_action->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
+			break;
+		} /* RTE_FLOW_ACTION_TYPE_METER */
+
 		default:
 			return -ENOTSUP;
 		}
@@ -1577,6 +1666,61 @@ pmd_flow_validate(struct rte_eth_dev *dev,
 	return 0;
 }
 
+static struct softnic_mtr *
+flow_action_meter_get(struct pmd_internals *softnic,
+	const struct rte_flow_action *action)
+{
+	for ( ; action->type != RTE_FLOW_ACTION_TYPE_END; action++)
+		if (action->type == RTE_FLOW_ACTION_TYPE_METER) {
+			const struct rte_flow_action_meter *conf = action->conf;
+
+			if (conf == NULL)
+				return NULL;
+
+			return softnic_mtr_find(softnic, conf->mtr_id);
+		}
+
+	return NULL;
+}
+
+static void
+flow_meter_owner_reset(struct pmd_internals *softnic,
+	struct rte_flow *flow)
+{
+	struct softnic_mtr_list *ml = &softnic->mtr.mtrs;
+	struct softnic_mtr *m;
+
+	TAILQ_FOREACH(m, ml, node)
+		if (m->flow == flow) {
+			m->flow = NULL;
+			break;
+		}
+}
+
+static void
+flow_meter_owner_set(struct pmd_internals *softnic,
+	struct rte_flow *flow,
+	struct softnic_mtr *mtr)
+{
+	/* Reset current flow meter  */
+	flow_meter_owner_reset(softnic, flow);
+
+	/* Set new flow meter */
+	mtr->flow = flow;
+}
+
+static int
+is_meter_action_enable(struct pmd_internals *softnic,
+	struct softnic_table *table)
+{
+	struct softnic_table_action_profile *profile =
+		softnic_table_action_profile_find(softnic,
+			table->params.action_profile_name);
+	struct softnic_table_action_profile_params *params = &profile->params;
+
+	return (params->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) ? 1 : 0;
+}
+
 static struct rte_flow *
 pmd_flow_create(struct rte_eth_dev *dev,
 	const struct rte_flow_attr *attr,
@@ -1592,6 +1736,7 @@ pmd_flow_create(struct rte_eth_dev *dev,
 	struct pipeline *pipeline;
 	struct softnic_table *table;
 	struct rte_flow *flow;
+	struct softnic_mtr *mtr;
 	const char *pipeline_name = NULL;
 	uint32_t table_id = 0;
 	int new_flow, status;
@@ -1717,6 +1862,10 @@ pmd_flow_create(struct rte_eth_dev *dev,
 	flow->pipeline = pipeline;
 	flow->table_id = table_id;
 
+	mtr = flow_action_meter_get(softnic, action);
+	if (mtr)
+		flow_meter_owner_set(softnic, flow, mtr);
+
 	/* Flow add to list. */
 	if (new_flow)
 		TAILQ_INSERT_TAIL(&table->flows, flow, node);
@@ -1755,6 +1904,10 @@ pmd_flow_destroy(struct rte_eth_dev *dev,
 			NULL,
 			"Pipeline table rule delete failed");
 
+	/* Update dependencies */
+	if (is_meter_action_enable(softnic, table))
+		flow_meter_owner_reset(softnic, flow);
+
 	/* Flow delete. */
 	TAILQ_REMOVE(&table->flows, flow, node);
 	free(flow);
-- 
2.9.3

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v5 00/10] net/softnic: implement metering and policing API
  2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 01/10] net/softnic: add metering and policing support Jasvinder Singh
@ 2018-09-26 13:08               ` Jasvinder Singh
  2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 01/10] net/softnic: add metering and policing support Jasvinder Singh
                                   ` (10 more replies)
  0 siblings, 11 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-26 13:08 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

This series is prepared on top of following patchset;
https://mails.dpdk.org/archives/dev/2018-September/111379.html

v5 changes
- fix wrong parameter in memcpy for table meter profile update
  
v4 changes
- introduce the table meter profile check in softnic pipeline table meter
  profile add function (rte_eth_softnic_thread.c)
- change the table action check function to more generic form
  softnic_table_is_action_enabled() (rte_eth_softnic_flow.c)
  
v3 changes:
- update pipeline table with meter profiles
- update pipeline table with dscp table entry update

v2 changes:
- fix copyright year for rte_eth_softnic_meter.c
- Place all checks in a separate functions while creating meter object
- Use softnic_pipeline_table_mtr_profile_add() api to add meter profile
  instead of implementing new function
- Use stats type indicator to determine the stats_mask for meter stats read 
 
Jasvinder Singh (10):
  net/softnic: add metering and policing support
  net/softnic: add meter profile
  net/softnic: delete meter profile
  net/softnic: create meter object
  net/softnic: destroy meter object
  net/softnic: update meter profile
  net/softnic: update dscp table
  net/softnic: update policer actions
  net/softnic: meter stats read
  net/softnic: enable flow rule with meter action

 drivers/net/softnic/Makefile                  |   1 +
 drivers/net/softnic/meson.build               |   1 +
 drivers/net/softnic/rte_eth_softnic.c         |  13 +
 drivers/net/softnic/rte_eth_softnic_flow.c    | 155 +++-
 .../net/softnic/rte_eth_softnic_internals.h   |  66 ++
 drivers/net/softnic/rte_eth_softnic_meter.c   | 728 ++++++++++++++++++
 .../net/softnic/rte_eth_softnic_pipeline.c    |  26 +
 drivers/net/softnic/rte_eth_softnic_thread.c  |  48 +-
 8 files changed, 1032 insertions(+), 6 deletions(-)
 create mode 100644 drivers/net/softnic/rte_eth_softnic_meter.c

-- 
2.17.1

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v5 01/10] net/softnic: add metering and policing support
  2018-09-26 13:08               ` [dpdk-dev] [PATCH v5 00/10] net/softnic: implement metering and policing API Jasvinder Singh
@ 2018-09-26 13:08                 ` Jasvinder Singh
  2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 02/10] net/softnic: add meter profile Jasvinder Singh
                                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-26 13:08 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Enable metering and policing support for softnic.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/Makefile                  |  1 +
 drivers/net/softnic/meson.build               |  1 +
 drivers/net/softnic/rte_eth_softnic.c         | 10 ++++++
 .../net/softnic/rte_eth_softnic_internals.h   |  5 +++
 drivers/net/softnic/rte_eth_softnic_meter.c   | 31 +++++++++++++++++++
 5 files changed, 48 insertions(+)
 create mode 100644 drivers/net/softnic/rte_eth_softnic_meter.c

diff --git a/drivers/net/softnic/Makefile b/drivers/net/softnic/Makefile
index 12515b10d..720f067bc 100644
--- a/drivers/net/softnic/Makefile
+++ b/drivers/net/softnic/Makefile
@@ -34,6 +34,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_pipeline.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_thread.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_cli.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_flow.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_meter.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += parser.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += conn.c
 
diff --git a/drivers/net/softnic/meson.build b/drivers/net/softnic/meson.build
index 56e5e2b21..6b7a6ccf2 100644
--- a/drivers/net/softnic/meson.build
+++ b/drivers/net/softnic/meson.build
@@ -14,6 +14,7 @@ sources = files('rte_eth_softnic_tm.c',
 	'rte_eth_softnic_thread.c',
 	'rte_eth_softnic_cli.c',
 	'rte_eth_softnic_flow.c',
+	'rte_eth_softnic_meter.c',
 	'parser.c',
 	'conn.c')
 deps += ['pipeline', 'port', 'table', 'sched']
diff --git a/drivers/net/softnic/rte_eth_softnic.c b/drivers/net/softnic/rte_eth_softnic.c
index 148b82ecb..25599aeea 100644
--- a/drivers/net/softnic/rte_eth_softnic.c
+++ b/drivers/net/softnic/rte_eth_softnic.c
@@ -14,6 +14,7 @@
 #include <rte_errno.h>
 #include <rte_ring.h>
 #include <rte_tm_driver.h>
+#include <rte_mtr_driver.h>
 
 #include "rte_eth_softnic.h"
 #include "rte_eth_softnic_internals.h"
@@ -227,6 +228,14 @@ pmd_tm_ops_get(struct rte_eth_dev *dev __rte_unused, void *arg)
 	return 0;
 }
 
+static int
+pmd_mtr_ops_get(struct rte_eth_dev *dev __rte_unused, void *arg)
+{
+	*(const struct rte_mtr_ops **)arg = &pmd_mtr_ops;
+
+	return 0;
+}
+
 static const struct eth_dev_ops pmd_ops = {
 	.dev_configure = pmd_dev_configure,
 	.dev_start = pmd_dev_start,
@@ -238,6 +247,7 @@ static const struct eth_dev_ops pmd_ops = {
 	.tx_queue_setup = pmd_tx_queue_setup,
 	.filter_ctrl = pmd_filter_ctrl,
 	.tm_ops_get = pmd_tm_ops_get,
+	.mtr_ops_get = pmd_mtr_ops_get,
 };
 
 static uint16_t
diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index a1a2e1558..92be4e8c1 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -571,6 +571,11 @@ flow_attr_map_get(struct pmd_internals *softnic,
 
 extern const struct rte_flow_ops pmd_flow_ops;
 
+/**
+ * Meter
+ */
+extern const struct rte_mtr_ops pmd_mtr_ops;
+
 /**
  * MEMPOOL
  */
diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
new file mode 100644
index 000000000..0a5409b6e
--- /dev/null
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <rte_mtr.h>
+#include <rte_mtr_driver.h>
+
+#include "rte_eth_softnic_internals.h"
+
+const struct rte_mtr_ops pmd_mtr_ops = {
+	.capabilities_get = NULL,
+
+	.meter_profile_add = NULL,
+	.meter_profile_delete = NULL,
+
+	.create = NULL,
+	.destroy = NULL,
+	.meter_enable = NULL,
+	.meter_disable = NULL,
+
+	.meter_profile_update = NULL,
+	.meter_dscp_table_update = NULL,
+	.policer_actions_update = NULL,
+	.stats_update = NULL,
+
+	.stats_read = NULL,
+};
-- 
2.17.1

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v5 02/10] net/softnic: add meter profile
  2018-09-26 13:08               ` [dpdk-dev] [PATCH v5 00/10] net/softnic: implement metering and policing API Jasvinder Singh
  2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 01/10] net/softnic: add metering and policing support Jasvinder Singh
@ 2018-09-26 13:08                 ` Jasvinder Singh
  2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 03/10] net/softnic: delete " Jasvinder Singh
                                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-26 13:08 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter profile add function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic.c         |   3 +
 .../net/softnic/rte_eth_softnic_internals.h   |  31 +++++
 drivers/net/softnic/rte_eth_softnic_meter.c   | 122 +++++++++++++++++-
 3 files changed, 155 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic.c b/drivers/net/softnic/rte_eth_softnic.c
index 25599aeea..0fd264e25 100644
--- a/drivers/net/softnic/rte_eth_softnic.c
+++ b/drivers/net/softnic/rte_eth_softnic.c
@@ -190,6 +190,7 @@ pmd_dev_stop(struct rte_eth_dev *dev)
 	softnic_mempool_free(p);
 
 	tm_hierarchy_free(p);
+	softnic_mtr_free(p);
 }
 
 static void
@@ -290,6 +291,7 @@ pmd_init(struct pmd_params *params)
 
 	/* Resources */
 	tm_hierarchy_init(p);
+	softnic_mtr_init(p);
 
 	softnic_mempool_init(p);
 	softnic_swq_init(p);
@@ -344,6 +346,7 @@ pmd_free(struct pmd_internals *p)
 	softnic_mempool_free(p);
 
 	tm_hierarchy_free(p);
+	softnic_mtr_free(p);
 
 	rte_free(p);
 }
diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index 92be4e8c1..1db93101c 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -22,6 +22,7 @@
 #include <rte_ethdev_driver.h>
 #include <rte_tm_driver.h>
 #include <rte_flow_driver.h>
+#include <rte_mtr_driver.h>
 
 #include "rte_eth_softnic.h"
 #include "conn.h"
@@ -67,6 +68,24 @@ struct flow_internals {
 	struct flow_attr_map egress_map[SOFTNIC_FLOW_MAX_GROUPS];
 };
 
+/**
+ * Meter
+ */
+
+/* MTR meter profile */
+struct softnic_mtr_meter_profile {
+	TAILQ_ENTRY(softnic_mtr_meter_profile) node;
+	uint32_t meter_profile_id;
+	struct rte_mtr_meter_profile params;
+	uint32_t n_users;
+};
+
+TAILQ_HEAD(softnic_mtr_meter_profile_list, softnic_mtr_meter_profile);
+
+struct mtr_internals {
+	struct softnic_mtr_meter_profile_list meter_profiles;
+};
+
 /**
  * MEMPOOL
  */
@@ -525,6 +544,8 @@ struct pmd_internals {
 	} soft;
 
 	struct flow_internals flow;
+	struct mtr_internals mtr;
+
 	struct softnic_conn *conn;
 	struct softnic_mempool_list mempool_list;
 	struct softnic_swq_list swq_list;
@@ -574,6 +595,16 @@ extern const struct rte_flow_ops pmd_flow_ops;
 /**
  * Meter
  */
+int
+softnic_mtr_init(struct pmd_internals *p);
+
+void
+softnic_mtr_free(struct pmd_internals *p);
+
+struct softnic_mtr_meter_profile *
+softnic_mtr_meter_profile_find(struct pmd_internals *p,
+	uint32_t meter_profile_id);
+
 extern const struct rte_mtr_ops pmd_mtr_ops;
 
 /**
diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 0a5409b6e..12228667c 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -11,10 +11,130 @@
 
 #include "rte_eth_softnic_internals.h"
 
+int
+softnic_mtr_init(struct pmd_internals *p)
+{
+	/* Initialize meter profiles list */
+	TAILQ_INIT(&p->mtr.meter_profiles);
+
+	return 0;
+}
+
+void
+softnic_mtr_free(struct pmd_internals *p)
+{
+	/* Remove meter profiles */
+	for ( ; ; ) {
+		struct softnic_mtr_meter_profile *mp;
+
+		mp = TAILQ_FIRST(&p->mtr.meter_profiles);
+		if (mp == NULL)
+			break;
+
+		TAILQ_REMOVE(&p->mtr.meter_profiles, mp, node);
+		free(mp);
+	}
+}
+
+struct softnic_mtr_meter_profile *
+softnic_mtr_meter_profile_find(struct pmd_internals *p,
+	uint32_t meter_profile_id)
+{
+	struct softnic_mtr_meter_profile_list *mpl = &p->mtr.meter_profiles;
+	struct softnic_mtr_meter_profile *mp;
+
+	TAILQ_FOREACH(mp, mpl, node)
+		if (meter_profile_id == mp->meter_profile_id)
+			return mp;
+
+	return NULL;
+}
+
+static int
+meter_profile_check(struct rte_eth_dev *dev,
+	uint32_t meter_profile_id,
+	struct rte_mtr_meter_profile *profile,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_meter_profile *mp;
+
+	/* Meter profile ID must be valid. */
+	if (meter_profile_id == UINT32_MAX)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"Meter profile id not valid");
+
+	/* Meter profile must not exist. */
+	mp = softnic_mtr_meter_profile_find(p, meter_profile_id);
+	if (mp)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"Meter prfile already exists");
+
+	/* Profile must not be NULL. */
+	if (profile == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE,
+			NULL,
+			"profile null");
+
+	/* Traffic metering algorithm : TRTCM_RFC2698 */
+	if (profile->alg != RTE_MTR_TRTCM_RFC2698)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE,
+			NULL,
+			"Metering alg not supported");
+
+	return 0;
+}
+
+/* MTR meter profile add */
+static int
+pmd_mtr_meter_profile_add(struct rte_eth_dev *dev,
+	uint32_t meter_profile_id,
+	struct rte_mtr_meter_profile *profile,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_meter_profile_list *mpl = &p->mtr.meter_profiles;
+	struct softnic_mtr_meter_profile *mp;
+	int status;
+
+	/* Check input params */
+	status = meter_profile_check(dev, meter_profile_id, profile, error);
+	if (status)
+		return status;
+
+	/* Memory allocation */
+	mp = calloc(1, sizeof(struct softnic_mtr_meter_profile));
+	if (mp == NULL)
+		return -rte_mtr_error_set(error,
+			ENOMEM,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"Memory alloc failed");
+
+	/* Fill in */
+	mp->meter_profile_id = meter_profile_id;
+	memcpy(&mp->params, profile, sizeof(mp->params));
+
+	/* Add to list */
+	TAILQ_INSERT_TAIL(mpl, mp, node);
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
-	.meter_profile_add = NULL,
+	.meter_profile_add = pmd_mtr_meter_profile_add,
 	.meter_profile_delete = NULL,
 
 	.create = NULL,
-- 
2.17.1

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v5 03/10] net/softnic: delete meter profile
  2018-09-26 13:08               ` [dpdk-dev] [PATCH v5 00/10] net/softnic: implement metering and policing API Jasvinder Singh
  2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 01/10] net/softnic: add metering and policing support Jasvinder Singh
  2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 02/10] net/softnic: add meter profile Jasvinder Singh
@ 2018-09-26 13:08                 ` Jasvinder Singh
  2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 04/10] net/softnic: create meter object Jasvinder Singh
                                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-26 13:08 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter profile delete function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_meter.c | 35 ++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 12228667c..f3205bd0f 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -131,11 +131,44 @@ pmd_mtr_meter_profile_add(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* MTR meter profile delete */
+static int
+pmd_mtr_meter_profile_delete(struct rte_eth_dev *dev,
+	uint32_t meter_profile_id,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_meter_profile *mp;
+
+	/* Meter profile must exist */
+	mp = softnic_mtr_meter_profile_find(p, meter_profile_id);
+	if (mp == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"Meter profile id invalid");
+
+	/* Check unused */
+	if (mp->n_users)
+		return -rte_mtr_error_set(error,
+			EBUSY,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"Meter profile in use");
+
+	/* Remove from list */
+	TAILQ_REMOVE(&p->mtr.meter_profiles, mp, node);
+	free(mp);
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
 	.meter_profile_add = pmd_mtr_meter_profile_add,
-	.meter_profile_delete = NULL,
+	.meter_profile_delete = pmd_mtr_meter_profile_delete,
 
 	.create = NULL,
 	.destroy = NULL,
-- 
2.17.1

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v5 04/10] net/softnic: create meter object
  2018-09-26 13:08               ` [dpdk-dev] [PATCH v5 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                                   ` (2 preceding siblings ...)
  2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 03/10] net/softnic: delete " Jasvinder Singh
@ 2018-09-26 13:08                 ` Jasvinder Singh
  2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 05/10] net/softnic: destroy " Jasvinder Singh
                                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-26 13:08 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

implement meter object create function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 .../net/softnic/rte_eth_softnic_internals.h   |  15 +++
 drivers/net/softnic/rte_eth_softnic_meter.c   | 123 +++++++++++++++++-
 2 files changed, 137 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index 1db93101c..50b72956f 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -82,8 +82,19 @@ struct softnic_mtr_meter_profile {
 
 TAILQ_HEAD(softnic_mtr_meter_profile_list, softnic_mtr_meter_profile);
 
+/* MTR meter object */
+struct softnic_mtr {
+	TAILQ_ENTRY(softnic_mtr) node;
+	uint32_t mtr_id;
+	struct rte_mtr_params params;
+	struct rte_flow *flow;
+};
+
+TAILQ_HEAD(softnic_mtr_list, softnic_mtr);
+
 struct mtr_internals {
 	struct softnic_mtr_meter_profile_list meter_profiles;
+	struct softnic_mtr_list mtrs;
 };
 
 /**
@@ -601,6 +612,10 @@ softnic_mtr_init(struct pmd_internals *p);
 void
 softnic_mtr_free(struct pmd_internals *p);
 
+struct softnic_mtr *
+softnic_mtr_find(struct pmd_internals *p,
+	uint32_t mtr_id);
+
 struct softnic_mtr_meter_profile *
 softnic_mtr_meter_profile_find(struct pmd_internals *p,
 	uint32_t meter_profile_id);
diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index f3205bd0f..12dd79cfc 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -17,12 +17,27 @@ softnic_mtr_init(struct pmd_internals *p)
 	/* Initialize meter profiles list */
 	TAILQ_INIT(&p->mtr.meter_profiles);
 
+	/* Initialize MTR objects list */
+	TAILQ_INIT(&p->mtr.mtrs);
+
 	return 0;
 }
 
 void
 softnic_mtr_free(struct pmd_internals *p)
 {
+	/* Remove MTR objects */
+	for ( ; ; ) {
+		struct softnic_mtr *m;
+
+		m = TAILQ_FIRST(&p->mtr.mtrs);
+		if (m == NULL)
+			break;
+
+		TAILQ_REMOVE(&p->mtr.mtrs, m, node);
+		free(m);
+	}
+
 	/* Remove meter profiles */
 	for ( ; ; ) {
 		struct softnic_mtr_meter_profile *mp;
@@ -164,13 +179,119 @@ pmd_mtr_meter_profile_delete(struct rte_eth_dev *dev,
 	return 0;
 }
 
+struct softnic_mtr *
+softnic_mtr_find(struct pmd_internals *p, uint32_t mtr_id)
+{
+	struct softnic_mtr_list *ml = &p->mtr.mtrs;
+	struct softnic_mtr *m;
+
+	TAILQ_FOREACH(m, ml, node)
+		if (m->mtr_id == mtr_id)
+			return m;
+
+	return NULL;
+}
+
+
+static int
+mtr_check(struct pmd_internals *p,
+	uint32_t mtr_id,
+	struct rte_mtr_params *params,
+	int shared,
+	struct rte_mtr_error *error)
+{
+	/* MTR id valid  */
+	if (softnic_mtr_find(p, mtr_id))
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			"MTR object already exists");
+
+	/* MTR params must not be NULL */
+	if (params == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_MTR_PARAMS,
+			NULL,
+			"MTR object params null");
+
+	/* Previous meter color not supported */
+	if (params->use_prev_mtr_color)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_MTR_PARAMS,
+			NULL,
+			"Previous meter color not supported");
+
+	/* Shared MTR object not supported */
+	if (shared)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_SHARED,
+			NULL,
+			"Shared MTR object not supported");
+
+	return 0;
+}
+
+/* MTR object create */
+static int
+pmd_mtr_create(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	struct rte_mtr_params *params,
+	int shared,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_list *ml = &p->mtr.mtrs;
+	struct softnic_mtr_meter_profile *mp;
+	struct softnic_mtr *m;
+	int status;
+
+	/* Check parameters */
+	status = mtr_check(p, mtr_id, params, shared, error);
+	if (status)
+		return status;
+
+	/* Meter profile must exist */
+	mp = softnic_mtr_meter_profile_find(p, params->meter_profile_id);
+	if (mp == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"Meter profile id not valid");
+
+	/* Memory allocation */
+	m = calloc(1, sizeof(struct softnic_mtr));
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			ENOMEM,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"Memory alloc failed");
+
+	/* Fill in */
+	m->mtr_id = mtr_id;
+	memcpy(&m->params, params, sizeof(m->params));
+
+	/* Add to list */
+	TAILQ_INSERT_TAIL(ml, m, node);
+
+	/* Update dependencies */
+	mp->n_users++;
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
 	.meter_profile_add = pmd_mtr_meter_profile_add,
 	.meter_profile_delete = pmd_mtr_meter_profile_delete,
 
-	.create = NULL,
+	.create = pmd_mtr_create,
 	.destroy = NULL,
 	.meter_enable = NULL,
 	.meter_disable = NULL,
-- 
2.17.1

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v5 05/10] net/softnic: destroy meter object
  2018-09-26 13:08               ` [dpdk-dev] [PATCH v5 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                                   ` (3 preceding siblings ...)
  2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 04/10] net/softnic: create meter object Jasvinder Singh
@ 2018-09-26 13:08                 ` Jasvinder Singh
  2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 06/10] net/softnic: update meter profile Jasvinder Singh
                                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-26 13:08 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter object destroy function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_meter.c | 49 ++++++++++++++++++++-
 1 file changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 12dd79cfc..5103bdadc 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -285,6 +285,53 @@ pmd_mtr_create(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* MTR object destroy */
+static int
+pmd_mtr_destroy(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_list *ml = &p->mtr.mtrs;
+	struct softnic_mtr_meter_profile *mp;
+	struct softnic_mtr *m;
+
+	/* MTR object must exist */
+	m = softnic_mtr_find(p, mtr_id);
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			"MTR object id not valid");
+
+	/* MTR object must not have any owner */
+	if (m->flow != NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"MTR object is being used");
+
+	/* Get meter profile */
+	mp = softnic_mtr_meter_profile_find(p, m->params.meter_profile_id);
+	if (mp == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"MTR object meter profile invalid");
+
+	/* Update dependencies */
+	mp->n_users--;
+
+	/* Remove from list */
+	TAILQ_REMOVE(ml, m, node);
+	free(m);
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
@@ -292,7 +339,7 @@ const struct rte_mtr_ops pmd_mtr_ops = {
 	.meter_profile_delete = pmd_mtr_meter_profile_delete,
 
 	.create = pmd_mtr_create,
-	.destroy = NULL,
+	.destroy = pmd_mtr_destroy,
 	.meter_enable = NULL,
 	.meter_disable = NULL,
 
-- 
2.17.1

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v5 06/10] net/softnic: update meter profile
  2018-09-26 13:08               ` [dpdk-dev] [PATCH v5 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                                   ` (4 preceding siblings ...)
  2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 05/10] net/softnic: destroy " Jasvinder Singh
@ 2018-09-26 13:08                 ` Jasvinder Singh
  2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 07/10] net/softnic: update dscp table Jasvinder Singh
                                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-26 13:08 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter profile update function

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 .../net/softnic/rte_eth_softnic_internals.h   |  14 +++
 drivers/net/softnic/rte_eth_softnic_meter.c   | 103 +++++++++++++++++-
 .../net/softnic/rte_eth_softnic_pipeline.c    |  25 +++++
 drivers/net/softnic/rte_eth_softnic_thread.c  |  38 ++++++-
 4 files changed, 174 insertions(+), 6 deletions(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index 50b72956f..4b0f54c84 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -320,6 +320,15 @@ struct softnic_table_action_profile {
 
 TAILQ_HEAD(softnic_table_action_profile_list, softnic_table_action_profile);
 
+struct softnic_table_meter_profile {
+	TAILQ_ENTRY(softnic_table_meter_profile) node;
+	uint32_t meter_profile_id;
+	struct rte_table_action_meter_profile profile;
+};
+
+TAILQ_HEAD(softnic_table_meter_profile_list,
+	softnic_table_meter_profile);
+
 /**
  * Pipeline
  */
@@ -455,6 +464,7 @@ struct softnic_table {
 	struct softnic_table_action_profile *ap;
 	struct rte_table_action *a;
 	struct flow_list flows;
+	struct softnic_table_meter_profile_list meter_profiles;
 };
 
 struct pipeline {
@@ -813,6 +823,10 @@ softnic_pipeline_table_create(struct pmd_internals *p,
 	const char *pipeline_name,
 	struct softnic_table_params *params);
 
+struct softnic_table_meter_profile *
+softnic_pipeline_table_meter_profile_find(struct softnic_table *table,
+	uint32_t meter_profile_id);
+
 struct softnic_table_rule_match_acl {
 	int ip_version;
 
diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 5103bdadc..68daf8af6 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -332,6 +332,107 @@ pmd_mtr_destroy(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* MTR object meter profile update */
+static int
+pmd_mtr_meter_profile_update(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	uint32_t meter_profile_id,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr_meter_profile *mp_new, *mp_old;
+	struct softnic_mtr *m;
+	int status;
+
+	/* MTR object id must be valid */
+	m = softnic_mtr_find(p, mtr_id);
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			"MTR object id not valid");
+
+	/* Meter profile id must be valid */
+	mp_new = softnic_mtr_meter_profile_find(p, meter_profile_id);
+	if (mp_new == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+			NULL,
+			"Meter profile not valid");
+
+	/* MTR object already set to meter profile id */
+	if (m->params.meter_profile_id == meter_profile_id)
+		return 0;
+
+	/*  MTR object owner table update */
+	if (m->flow) {
+		uint32_t table_id = m->flow->table_id;
+		struct softnic_table *table = &m->flow->pipeline->table[table_id];
+		struct softnic_table_rule_action action;
+
+		if (!softnic_pipeline_table_meter_profile_find(table,
+			meter_profile_id)) {
+			struct rte_table_action_meter_profile profile;
+
+			memset(&profile, 0, sizeof(profile));
+
+			profile.alg = RTE_TABLE_ACTION_METER_TRTCM;
+			profile.trtcm.cir = mp_new->params.trtcm_rfc2698.cir;
+			profile.trtcm.pir = mp_new->params.trtcm_rfc2698.pir;
+			profile.trtcm.cbs = mp_new->params.trtcm_rfc2698.cbs;
+			profile.trtcm.pbs = mp_new->params.trtcm_rfc2698.pbs;
+
+			/* Add meter profile to pipeline table */
+			status = softnic_pipeline_table_mtr_profile_add(p,
+					m->flow->pipeline->name,
+					table_id,
+					meter_profile_id,
+					&profile);
+			if (status)
+				return -rte_mtr_error_set(error,
+					EINVAL,
+					RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+					NULL,
+					"Table meter profile add failed");
+		}
+
+		/* Set meter action */
+		memcpy(&action, &m->flow->action, sizeof(action));
+
+		action.mtr.mtr[0].meter_profile_id = meter_profile_id;
+
+		/* Re-add rule */
+		status = softnic_pipeline_table_rule_add(p,
+			m->flow->pipeline->name,
+			table_id,
+			&m->flow->match,
+			&action,
+			&m->flow->data);
+		if (status)
+			return -rte_mtr_error_set(error,
+				EINVAL,
+				RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+				NULL,
+				"Pipeline table rule add failed");
+
+		/* Flow: update meter action */
+		memcpy(&m->flow->action, &action, sizeof(m->flow->action));
+	}
+
+	mp_old = softnic_mtr_meter_profile_find(p, m->params.meter_profile_id);
+
+	/* Meter: Set meter profile */
+	m->params.meter_profile_id = meter_profile_id;
+
+	/* Update dependencies*/
+	mp_old->n_users--;
+	mp_new->n_users++;
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
@@ -343,7 +444,7 @@ const struct rte_mtr_ops pmd_mtr_ops = {
 	.meter_enable = NULL,
 	.meter_disable = NULL,
 
-	.meter_profile_update = NULL,
+	.meter_profile_update = pmd_mtr_meter_profile_update,
 	.meter_dscp_table_update = NULL,
 	.policer_actions_update = NULL,
 	.stats_update = NULL,
diff --git a/drivers/net/softnic/rte_eth_softnic_pipeline.c b/drivers/net/softnic/rte_eth_softnic_pipeline.c
index d1127a195..17830d319 100644
--- a/drivers/net/softnic/rte_eth_softnic_pipeline.c
+++ b/drivers/net/softnic/rte_eth_softnic_pipeline.c
@@ -55,6 +55,17 @@ softnic_pipeline_table_free(struct softnic_table *table)
 		TAILQ_REMOVE(&table->flows, flow, node);
 		free(flow);
 	}
+
+	for ( ; ; ) {
+		struct softnic_table_meter_profile *mp;
+
+		mp = TAILQ_FIRST(&table->meter_profiles);
+		if (mp == NULL)
+			break;
+
+		TAILQ_REMOVE(&table->meter_profiles, mp, node);
+		free(mp);
+	}
 }
 
 void
@@ -988,6 +999,7 @@ softnic_pipeline_table_create(struct pmd_internals *softnic,
 	table->ap = ap;
 	table->a = action;
 	TAILQ_INIT(&table->flows);
+	TAILQ_INIT(&table->meter_profiles);
 	pipeline->n_tables++;
 
 	return 0;
@@ -1020,3 +1032,16 @@ softnic_pipeline_port_out_find(struct pmd_internals *softnic,
 
 	return -1;
 }
+
+struct softnic_table_meter_profile *
+softnic_pipeline_table_meter_profile_find(struct softnic_table *table,
+	uint32_t meter_profile_id)
+{
+	struct softnic_table_meter_profile *mp;
+
+	TAILQ_FOREACH(mp, &table->meter_profiles, node)
+		if (mp->meter_profile_id == meter_profile_id)
+			return mp;
+
+	return NULL;
+}
diff --git a/drivers/net/softnic/rte_eth_softnic_thread.c b/drivers/net/softnic/rte_eth_softnic_thread.c
index 8a1509030..11d08d416 100644
--- a/drivers/net/softnic/rte_eth_softnic_thread.c
+++ b/drivers/net/softnic/rte_eth_softnic_thread.c
@@ -1680,6 +1680,8 @@ softnic_pipeline_table_mtr_profile_add(struct pmd_internals *softnic,
 	struct pipeline *p;
 	struct pipeline_msg_req *req;
 	struct pipeline_msg_rsp *rsp;
+	struct softnic_table *table;
+	struct softnic_table_meter_profile *mp;
 	int status;
 
 	/* Check input params */
@@ -1692,20 +1694,40 @@ softnic_pipeline_table_mtr_profile_add(struct pmd_internals *softnic,
 		table_id >= p->n_tables)
 		return -1;
 
-	if (!pipeline_is_running(p)) {
-		struct rte_table_action *a = p->table[table_id].a;
+	table = &p->table[table_id];
+	mp = softnic_pipeline_table_meter_profile_find(table, meter_profile_id);
+	if (mp)
+		return -1;
 
-		status = rte_table_action_meter_profile_add(a,
+	/* Resource Allocation */
+	mp = calloc(1, sizeof(struct softnic_table_meter_profile));
+	if (mp == NULL)
+		return -1;
+
+	mp->meter_profile_id = meter_profile_id;
+	memcpy(&mp->profile, profile, sizeof(mp->profile));
+
+	if (!pipeline_is_running(p)) {
+		status = rte_table_action_meter_profile_add(table->a,
 			meter_profile_id,
 			profile);
+		if (status) {
+			free(mp);
+			return status;
+		}
+
+		/* Add profile to the table. */
+		TAILQ_INSERT_TAIL(&table->meter_profiles, mp, node);
 
 		return status;
 	}
 
 	/* Allocate request */
 	req = pipeline_msg_alloc();
-	if (req == NULL)
+	if (req == NULL) {
+		free(mp);
 		return -1;
+	}
 
 	/* Write request */
 	req->type = PIPELINE_REQ_TABLE_MTR_PROFILE_ADD;
@@ -1715,11 +1737,17 @@ softnic_pipeline_table_mtr_profile_add(struct pmd_internals *softnic,
 
 	/* Send request and wait for response */
 	rsp = pipeline_msg_send_recv(p, req);
-	if (rsp == NULL)
+	if (rsp == NULL) {
+		free(mp);
 		return -1;
+	}
 
 	/* Read response */
 	status = rsp->status;
+	if (status == 0)
+		TAILQ_INSERT_TAIL(&table->meter_profiles, mp, node);
+	else
+		free(mp);
 
 	/* Free response */
 	pipeline_msg_free(rsp);
-- 
2.17.1

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v5 07/10] net/softnic: update dscp table
  2018-09-26 13:08               ` [dpdk-dev] [PATCH v5 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                                   ` (5 preceding siblings ...)
  2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 06/10] net/softnic: update meter profile Jasvinder Singh
@ 2018-09-26 13:08                 ` Jasvinder Singh
  2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 08/10] net/softnic: update policer actions Jasvinder Singh
                                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-26 13:08 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter object dscp table update.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 .../net/softnic/rte_eth_softnic_internals.h   |  1 +
 drivers/net/softnic/rte_eth_softnic_meter.c   | 54 ++++++++++++++++++-
 .../net/softnic/rte_eth_softnic_pipeline.c    |  1 +
 drivers/net/softnic/rte_eth_softnic_thread.c  | 10 ++++
 4 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index 4b0f54c84..78864e7aa 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -464,6 +464,7 @@ struct softnic_table {
 	struct softnic_table_action_profile *ap;
 	struct rte_table_action *a;
 	struct flow_list flows;
+	struct rte_table_action_dscp_table dscp_table;
 	struct softnic_table_meter_profile_list meter_profiles;
 };
 
diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 68daf8af6..ed44767fe 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -433,6 +433,58 @@ pmd_mtr_meter_profile_update(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* MTR object meter DSCP table update */
+static int
+pmd_mtr_meter_dscp_table_update(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	enum rte_mtr_color *dscp_table,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct rte_table_action_dscp_table dt;
+	struct pipeline *pipeline;
+	struct softnic_table *table;
+	struct softnic_mtr *m;
+	uint32_t table_id, i;
+	int status;
+
+	/* MTR object id must be valid */
+	m = softnic_mtr_find(p, mtr_id);
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			"MTR object id not valid");
+
+	/* MTR object owner valid? */
+	if (m->flow == NULL)
+		return 0;
+
+	pipeline = m->flow->pipeline;
+	table_id = m->flow->table_id;
+	table = &pipeline->table[table_id];
+
+	memcpy(&dt, &table->dscp_table, sizeof(dt));
+	for (i = 0; i < RTE_DIM(dt.entry); i++)
+		dt.entry[i].color = (enum rte_meter_color)dscp_table[i];
+
+	/* Update table */
+	status = softnic_pipeline_table_dscp_table_update(p,
+			pipeline->name,
+			table_id,
+			UINT64_MAX,
+			&dt);
+	if (status)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"Table action dscp table update failed");
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
@@ -445,7 +497,7 @@ const struct rte_mtr_ops pmd_mtr_ops = {
 	.meter_disable = NULL,
 
 	.meter_profile_update = pmd_mtr_meter_profile_update,
-	.meter_dscp_table_update = NULL,
+	.meter_dscp_table_update = pmd_mtr_meter_dscp_table_update,
 	.policer_actions_update = NULL,
 	.stats_update = NULL,
 
diff --git a/drivers/net/softnic/rte_eth_softnic_pipeline.c b/drivers/net/softnic/rte_eth_softnic_pipeline.c
index 17830d319..3d37ba3fe 100644
--- a/drivers/net/softnic/rte_eth_softnic_pipeline.c
+++ b/drivers/net/softnic/rte_eth_softnic_pipeline.c
@@ -1000,6 +1000,7 @@ softnic_pipeline_table_create(struct pmd_internals *softnic,
 	table->a = action;
 	TAILQ_INIT(&table->flows);
 	TAILQ_INIT(&table->meter_profiles);
+	memset(&table->dscp_table, 0, sizeof(table->dscp_table));
 	pipeline->n_tables++;
 
 	return 0;
diff --git a/drivers/net/softnic/rte_eth_softnic_thread.c b/drivers/net/softnic/rte_eth_softnic_thread.c
index 11d08d416..76217fcde 100644
--- a/drivers/net/softnic/rte_eth_softnic_thread.c
+++ b/drivers/net/softnic/rte_eth_softnic_thread.c
@@ -1902,6 +1902,11 @@ softnic_pipeline_table_dscp_table_update(struct pmd_internals *softnic,
 				dscp_mask,
 				dscp_table);
 
+		/* Update table dscp table */
+		if (!status)
+			memcpy(&p->table[table_id].dscp_table, dscp_table,
+				sizeof(p->table[table_id].dscp_table));
+
 		return status;
 	}
 
@@ -1925,6 +1930,11 @@ softnic_pipeline_table_dscp_table_update(struct pmd_internals *softnic,
 	/* Read response */
 	status = rsp->status;
 
+	/* Update table dscp table */
+	if (!status)
+		memcpy(&p->table[table_id].dscp_table, dscp_table,
+			sizeof(p->table[table_id].dscp_table));
+
 	/* Free response */
 	pipeline_msg_free(rsp);
 
-- 
2.17.1

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v5 08/10] net/softnic: update policer actions
  2018-09-26 13:08               ` [dpdk-dev] [PATCH v5 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                                   ` (6 preceding siblings ...)
  2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 07/10] net/softnic: update dscp table Jasvinder Singh
@ 2018-09-26 13:08                 ` Jasvinder Singh
  2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 09/10] net/softnic: meter stats read Jasvinder Singh
                                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-26 13:08 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter object policer actions function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_meter.c | 91 ++++++++++++++++++++-
 1 file changed, 90 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index ed44767fe..05d54d4d4 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -485,6 +485,95 @@ pmd_mtr_meter_dscp_table_update(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* MTR object policer action update */
+static int
+pmd_mtr_policer_actions_update(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	uint32_t action_mask,
+	enum rte_mtr_policer_action *actions,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct softnic_mtr *m;
+	uint32_t i;
+	int status;
+
+	/* MTR object id must be valid */
+	m = softnic_mtr_find(p, mtr_id);
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			"MTR object id not valid");
+
+	/* Valid policer actions */
+	if (actions == NULL)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"Invalid actions");
+
+	for (i = 0; i < RTE_MTR_COLORS; i++) {
+		if (action_mask & (1 << i)) {
+			if (actions[i] != MTR_POLICER_ACTION_COLOR_GREEN  &&
+				actions[i] != MTR_POLICER_ACTION_COLOR_YELLOW &&
+				actions[i] != MTR_POLICER_ACTION_COLOR_RED &&
+				actions[i] != MTR_POLICER_ACTION_DROP) {
+				return -rte_mtr_error_set(error,
+					EINVAL,
+					RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+					NULL,
+					" Invalid action value");
+			}
+		}
+	}
+
+	/* MTR object owner valid? */
+	if (m->flow) {
+		struct pipeline *pipeline = m->flow->pipeline;
+		struct softnic_table *table = &pipeline->table[m->flow->table_id];
+		struct softnic_table_rule_action action;
+
+		memcpy(&action, &m->flow->action, sizeof(action));
+
+		/* Set action */
+		for (i = 0; i < RTE_MTR_COLORS; i++)
+			if (action_mask & (1 << i))
+				action.mtr.mtr[0].policer[i] =
+					(enum rte_table_action_policer)actions[i];
+
+		/* Re-add the rule */
+		status = softnic_pipeline_table_rule_add(p,
+			pipeline->name,
+			m->flow->table_id,
+			&m->flow->match,
+			&action,
+			&m->flow->data);
+		if (status)
+			return -rte_mtr_error_set(error,
+				EINVAL,
+				RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+				NULL,
+				"Pipeline table rule re-add failed");
+
+		/* Flow: Update meter action */
+		memcpy(&m->flow->action, &action, sizeof(m->flow->action));
+
+		/* Reset the meter stats */
+		rte_table_action_meter_read(table->a, m->flow->data,
+			1, NULL, 1);
+	}
+
+	/* Meter: Update policer actions */
+	for (i = 0; i < RTE_MTR_COLORS; i++)
+		if (action_mask & (1 << i))
+			m->params.action[i] = actions[i];
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
@@ -498,7 +587,7 @@ const struct rte_mtr_ops pmd_mtr_ops = {
 
 	.meter_profile_update = pmd_mtr_meter_profile_update,
 	.meter_dscp_table_update = pmd_mtr_meter_dscp_table_update,
-	.policer_actions_update = NULL,
+	.policer_actions_update = pmd_mtr_policer_actions_update,
 	.stats_update = NULL,
 
 	.stats_read = NULL,
-- 
2.17.1

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v5 09/10] net/softnic: meter stats read
  2018-09-26 13:08               ` [dpdk-dev] [PATCH v5 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                                   ` (7 preceding siblings ...)
  2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 08/10] net/softnic: update policer actions Jasvinder Singh
@ 2018-09-26 13:08                 ` Jasvinder Singh
  2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 10/10] net/softnic: enable flow rule with meter action Jasvinder Singh
  2018-09-28 10:36                 ` [dpdk-dev] [PATCH v5 00/10] net/softnic: implement metering and policing API Dumitrescu, Cristian
  10 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-26 13:08 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement meter object stats read function.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_meter.c | 136 +++++++++++++++++++-
 1 file changed, 135 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c
index 05d54d4d4..73ecf3b16 100644
--- a/drivers/net/softnic/rte_eth_softnic_meter.c
+++ b/drivers/net/softnic/rte_eth_softnic_meter.c
@@ -574,6 +574,140 @@ pmd_mtr_policer_actions_update(struct rte_eth_dev *dev,
 	return 0;
 }
 
+#define MTR_STATS_PKTS_DEFAULT (RTE_MTR_STATS_N_PKTS_GREEN | \
+				RTE_MTR_STATS_N_PKTS_YELLOW | \
+				RTE_MTR_STATS_N_PKTS_RED | \
+				RTE_MTR_STATS_N_PKTS_DROPPED)
+
+#define MTR_STATS_BYTES_DEFAULT (RTE_MTR_STATS_N_BYTES_GREEN | \
+				RTE_MTR_STATS_N_BYTES_YELLOW | \
+				RTE_MTR_STATS_N_BYTES_RED | \
+				RTE_MTR_STATS_N_BYTES_DROPPED)
+
+/* MTR object stats read */
+static void
+mtr_stats_convert(struct softnic_mtr *m,
+	struct rte_table_action_mtr_counters_tc *in,
+	struct rte_mtr_stats *out,
+	uint64_t *out_mask)
+{
+	memset(&out, 0, sizeof(out));
+	*out_mask = 0;
+
+	if (in->n_packets_valid) {
+		uint32_t i;
+
+		for (i = 0; i < RTE_MTR_COLORS; i++) {
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_GREEN)
+				out->n_pkts[RTE_MTR_GREEN] += in->n_packets[i];
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_YELLOW)
+				out->n_pkts[RTE_MTR_YELLOW] += in->n_packets[i];
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_RED)
+				out->n_pkts[RTE_MTR_RED] += in->n_packets[i];
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_DROP)
+				out->n_pkts_dropped += in->n_packets[i];
+		}
+
+		*out_mask |= MTR_STATS_PKTS_DEFAULT;
+	}
+
+	if (in->n_bytes_valid) {
+		uint32_t i;
+
+		for (i = 0; i < RTE_MTR_COLORS; i++) {
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_GREEN)
+				out->n_bytes[RTE_MTR_GREEN] += in->n_bytes[i];
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_YELLOW)
+				out->n_bytes[RTE_MTR_YELLOW] += in->n_bytes[i];
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_RED)
+				out->n_bytes[RTE_MTR_RED] += in->n_bytes[i];
+
+			if (m->params.action[i] == MTR_POLICER_ACTION_DROP)
+				out->n_bytes_dropped += in->n_bytes[i];
+		}
+
+		*out_mask |= MTR_STATS_BYTES_DEFAULT;
+	}
+}
+
+/* MTR object stats read */
+static int
+pmd_mtr_stats_read(struct rte_eth_dev *dev,
+	uint32_t mtr_id,
+	struct rte_mtr_stats *stats,
+	uint64_t *stats_mask,
+	int clear,
+	struct rte_mtr_error *error)
+{
+	struct pmd_internals *p = dev->data->dev_private;
+	struct rte_table_action_mtr_counters counters;
+	struct pipeline *pipeline;
+	struct softnic_table *table;
+	struct softnic_mtr *m;
+	int status;
+
+	/* MTR object id must be valid */
+	m = softnic_mtr_find(p, mtr_id);
+	if (m == NULL)
+		return -rte_mtr_error_set(error,
+			EEXIST,
+			RTE_MTR_ERROR_TYPE_MTR_ID,
+			NULL,
+			"MTR object id not valid");
+
+	/* MTR meter object owner valid? */
+	if (m->flow == NULL) {
+		if (stats != NULL)
+			memset(stats, 0, sizeof(*stats));
+
+		if (stats_mask)
+			*stats_mask = MTR_STATS_PKTS_DEFAULT |
+				MTR_STATS_BYTES_DEFAULT;
+
+		return 0;
+	}
+
+	pipeline = m->flow->pipeline;
+	table = &pipeline->table[m->flow->table_id];
+
+	/* Meter stats read. */
+	status = rte_table_action_meter_read(table->a,
+		m->flow->data,
+		1,
+		&counters,
+		clear);
+	if (status)
+		return -rte_mtr_error_set(error,
+			EINVAL,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+			NULL,
+			"Meter stats read failed");
+
+	/* Stats format conversion. */
+	if (stats || stats_mask) {
+		struct rte_mtr_stats s;
+		uint64_t s_mask = 0;
+
+		mtr_stats_convert(m,
+			&counters.stats[0],
+			&s,
+			&s_mask);
+
+		if (stats)
+			memcpy(stats, &s, sizeof(*stats));
+
+		if (stats_mask)
+			*stats_mask = s_mask;
+	}
+
+	return 0;
+}
+
 const struct rte_mtr_ops pmd_mtr_ops = {
 	.capabilities_get = NULL,
 
@@ -590,5 +724,5 @@ const struct rte_mtr_ops pmd_mtr_ops = {
 	.policer_actions_update = pmd_mtr_policer_actions_update,
 	.stats_update = NULL,
 
-	.stats_read = NULL,
+	.stats_read = pmd_mtr_stats_read,
 };
-- 
2.17.1

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [dpdk-dev] [PATCH v5 10/10] net/softnic: enable flow rule with meter action
  2018-09-26 13:08               ` [dpdk-dev] [PATCH v5 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                                   ` (8 preceding siblings ...)
  2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 09/10] net/softnic: meter stats read Jasvinder Singh
@ 2018-09-26 13:08                 ` Jasvinder Singh
  2018-09-28 10:36                 ` [dpdk-dev] [PATCH v5 00/10] net/softnic: implement metering and policing API Dumitrescu, Cristian
  10 siblings, 0 replies; 56+ messages in thread
From: Jasvinder Singh @ 2018-09-26 13:08 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Implement flow rules with meter action.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_flow.c | 155 ++++++++++++++++++++-
 1 file changed, 154 insertions(+), 1 deletion(-)

diff --git a/drivers/net/softnic/rte_eth_softnic_flow.c b/drivers/net/softnic/rte_eth_softnic_flow.c
index fc7a0b02a..03d41bc01 100644
--- a/drivers/net/softnic/rte_eth_softnic_flow.c
+++ b/drivers/net/softnic/rte_eth_softnic_flow.c
@@ -1161,7 +1161,7 @@ flow_rule_action_get(struct pmd_internals *softnic,
 	const struct rte_flow_attr *attr,
 	const struct rte_flow_action *action,
 	struct softnic_table_rule_action *rule_action,
-	struct rte_flow_error *error __rte_unused)
+	struct rte_flow_error *error)
 {
 	struct softnic_table_action_profile *profile;
 	struct softnic_table_action_profile_params *params;
@@ -1474,6 +1474,95 @@ flow_rule_action_get(struct pmd_internals *softnic,
 			break;
 		} /* RTE_FLOW_ACTION_TYPE_COUNT */
 
+		case RTE_FLOW_ACTION_TYPE_METER:
+		{
+			const struct rte_flow_action_meter *conf = action->conf;
+			struct softnic_mtr_meter_profile *mp;
+			struct softnic_mtr *m;
+			uint32_t table_id = table - pipeline->table;
+			uint32_t meter_profile_id;
+			int status;
+
+			if ((params->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) == 0)
+				return rte_flow_error_set(error,
+					EINVAL,
+					RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+					NULL,
+					"METER: Table action not supported");
+
+			if (params->mtr.n_tc != 1)
+				return rte_flow_error_set(error,
+					EINVAL,
+					RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+					NULL,
+					"METER: Multiple TCs not supported");
+
+			if (conf == NULL)
+				return rte_flow_error_set(error,
+					EINVAL,
+					RTE_FLOW_ERROR_TYPE_ACTION,
+					action,
+					"METER: Null configuration");
+
+			m = softnic_mtr_find(softnic, conf->mtr_id);
+
+			if (m == NULL)
+				return rte_flow_error_set(error,
+					EINVAL,
+					RTE_FLOW_ERROR_TYPE_ACTION_CONF,
+					NULL,
+					"METER: Invalid meter ID");
+
+			if (m->flow)
+				return rte_flow_error_set(error,
+					EINVAL,
+					RTE_FLOW_ERROR_TYPE_ACTION_CONF,
+					NULL,
+					"METER: Meter already attached to a flow");
+
+			meter_profile_id = m->params.meter_profile_id;
+			mp = softnic_mtr_meter_profile_find(softnic, meter_profile_id);
+
+			/* Add meter profile to pipeline table */
+			if (!softnic_pipeline_table_meter_profile_find(table,
+					meter_profile_id)) {
+				struct rte_table_action_meter_profile profile;
+
+				memset(&profile, 0, sizeof(profile));
+				profile.alg = RTE_TABLE_ACTION_METER_TRTCM;
+				profile.trtcm.cir = mp->params.trtcm_rfc2698.cir;
+				profile.trtcm.pir = mp->params.trtcm_rfc2698.pir;
+				profile.trtcm.cbs = mp->params.trtcm_rfc2698.cbs;
+				profile.trtcm.pbs = mp->params.trtcm_rfc2698.pbs;
+
+				status = softnic_pipeline_table_mtr_profile_add(softnic,
+						pipeline->name,
+						table_id,
+						meter_profile_id,
+						&profile);
+				if (status) {
+					rte_flow_error_set(error,
+						EINVAL,
+						RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+						NULL,
+						"METER: Table meter profile add failed");
+					return -1;
+				}
+			}
+
+			/* RTE_TABLE_ACTION_METER */
+			rule_action->mtr.mtr[0].meter_profile_id = meter_profile_id;
+			rule_action->mtr.mtr[0].policer[e_RTE_METER_GREEN] =
+				(enum rte_table_action_policer)m->params.action[RTE_MTR_GREEN];
+			rule_action->mtr.mtr[0].policer[e_RTE_METER_YELLOW] =
+				(enum rte_table_action_policer)m->params.action[RTE_MTR_YELLOW];
+			rule_action->mtr.mtr[0].policer[e_RTE_METER_RED] =
+				(enum rte_table_action_policer)m->params.action[RTE_MTR_RED];
+			rule_action->mtr.tc_mask = 1;
+			rule_action->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
+			break;
+		} /* RTE_FLOW_ACTION_TYPE_METER */
+
 		default:
 			return -ENOTSUP;
 		}
@@ -1577,6 +1666,61 @@ pmd_flow_validate(struct rte_eth_dev *dev,
 	return 0;
 }
 
+static struct softnic_mtr *
+flow_action_meter_get(struct pmd_internals *softnic,
+	const struct rte_flow_action *action)
+{
+	for ( ; action->type != RTE_FLOW_ACTION_TYPE_END; action++)
+		if (action->type == RTE_FLOW_ACTION_TYPE_METER) {
+			const struct rte_flow_action_meter *conf = action->conf;
+
+			if (conf == NULL)
+				return NULL;
+
+			return softnic_mtr_find(softnic, conf->mtr_id);
+		}
+
+	return NULL;
+}
+
+static void
+flow_meter_owner_reset(struct pmd_internals *softnic,
+	struct rte_flow *flow)
+{
+	struct softnic_mtr_list *ml = &softnic->mtr.mtrs;
+	struct softnic_mtr *m;
+
+	TAILQ_FOREACH(m, ml, node)
+		if (m->flow == flow) {
+			m->flow = NULL;
+			break;
+		}
+}
+
+static void
+flow_meter_owner_set(struct pmd_internals *softnic,
+	struct rte_flow *flow,
+	struct softnic_mtr *mtr)
+{
+	/* Reset current flow meter  */
+	flow_meter_owner_reset(softnic, flow);
+
+	/* Set new flow meter */
+	mtr->flow = flow;
+}
+
+static int
+is_meter_action_enable(struct pmd_internals *softnic,
+	struct softnic_table *table)
+{
+	struct softnic_table_action_profile *profile =
+		softnic_table_action_profile_find(softnic,
+			table->params.action_profile_name);
+	struct softnic_table_action_profile_params *params = &profile->params;
+
+	return (params->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) ? 1 : 0;
+}
+
 static struct rte_flow *
 pmd_flow_create(struct rte_eth_dev *dev,
 	const struct rte_flow_attr *attr,
@@ -1592,6 +1736,7 @@ pmd_flow_create(struct rte_eth_dev *dev,
 	struct pipeline *pipeline;
 	struct softnic_table *table;
 	struct rte_flow *flow;
+	struct softnic_mtr *mtr;
 	const char *pipeline_name = NULL;
 	uint32_t table_id = 0;
 	int new_flow, status;
@@ -1717,6 +1862,10 @@ pmd_flow_create(struct rte_eth_dev *dev,
 	flow->pipeline = pipeline;
 	flow->table_id = table_id;
 
+	mtr = flow_action_meter_get(softnic, action);
+	if (mtr)
+		flow_meter_owner_set(softnic, flow, mtr);
+
 	/* Flow add to list. */
 	if (new_flow)
 		TAILQ_INSERT_TAIL(&table->flows, flow, node);
@@ -1755,6 +1904,10 @@ pmd_flow_destroy(struct rte_eth_dev *dev,
 			NULL,
 			"Pipeline table rule delete failed");
 
+	/* Update dependencies */
+	if (is_meter_action_enable(softnic, table))
+		flow_meter_owner_reset(softnic, flow);
+
 	/* Flow delete. */
 	TAILQ_REMOVE(&table->flows, flow, node);
 	free(flow);
-- 
2.17.1

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [dpdk-dev] [PATCH v5 00/10] net/softnic: implement metering and policing API
  2018-09-26 13:08               ` [dpdk-dev] [PATCH v5 00/10] net/softnic: implement metering and policing API Jasvinder Singh
                                   ` (9 preceding siblings ...)
  2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 10/10] net/softnic: enable flow rule with meter action Jasvinder Singh
@ 2018-09-28 10:36                 ` Dumitrescu, Cristian
  10 siblings, 0 replies; 56+ messages in thread
From: Dumitrescu, Cristian @ 2018-09-28 10:36 UTC (permalink / raw)
  To: Singh, Jasvinder, dev



> -----Original Message-----
> From: Singh, Jasvinder
> Sent: Wednesday, September 26, 2018 2:09 PM
> To: dev@dpdk.org
> Cc: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>
> Subject: [PATCH v5 00/10] net/softnic: implement metering and policing API
> 
> This series is prepared on top of following patchset;
> https://mails.dpdk.org/archives/dev/2018-September/111379.html
> 
> v5 changes
> - fix wrong parameter in memcpy for table meter profile update
> 
> v4 changes
> - introduce the table meter profile check in softnic pipeline table meter
>   profile add function (rte_eth_softnic_thread.c)
> - change the table action check function to more generic form
>   softnic_table_is_action_enabled() (rte_eth_softnic_flow.c)
> 
> v3 changes:
> - update pipeline table with meter profiles
> - update pipeline table with dscp table entry update
> 
> v2 changes:
> - fix copyright year for rte_eth_softnic_meter.c
> - Place all checks in a separate functions while creating meter object
> - Use softnic_pipeline_table_mtr_profile_add() api to add meter profile
>   instead of implementing new function
> - Use stats type indicator to determine the stats_mask for meter stats read
> 

Series applied to next-pipeline tree, thanks!

^ permalink raw reply	[flat|nested] 56+ messages in thread

end of thread, other threads:[~2018-09-28 10:40 UTC | newest]

Thread overview: 56+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-07 18:13 [dpdk-dev] [PATCH 00/10] net/softnic: implement metering and policing API Jasvinder Singh
2018-09-07 18:13 ` [dpdk-dev] [PATCH 01/10] net/softnic: add metering and policing support Jasvinder Singh
2018-09-12 16:41   ` [dpdk-dev] [PATCH v2 00/10] net/softnic: implement metering and policing API Jasvinder Singh
2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 01/10] net/softnic: add metering and policing support Jasvinder Singh
2018-09-14 17:45       ` [dpdk-dev] [PATCH v3 00/10] net/softnic: implement metering and policing API Jasvinder Singh
2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 01/10] net/softnic: add metering and policing support Jasvinder Singh
2018-09-18 16:58           ` [dpdk-dev] [PATCH v4 00/10] net/softnic: implement metering and policing API Jasvinder Singh
2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 01/10] net/softnic: add metering and policing support Jasvinder Singh
2018-09-26 13:08               ` [dpdk-dev] [PATCH v5 00/10] net/softnic: implement metering and policing API Jasvinder Singh
2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 01/10] net/softnic: add metering and policing support Jasvinder Singh
2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 02/10] net/softnic: add meter profile Jasvinder Singh
2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 03/10] net/softnic: delete " Jasvinder Singh
2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 04/10] net/softnic: create meter object Jasvinder Singh
2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 05/10] net/softnic: destroy " Jasvinder Singh
2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 06/10] net/softnic: update meter profile Jasvinder Singh
2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 07/10] net/softnic: update dscp table Jasvinder Singh
2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 08/10] net/softnic: update policer actions Jasvinder Singh
2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 09/10] net/softnic: meter stats read Jasvinder Singh
2018-09-26 13:08                 ` [dpdk-dev] [PATCH v5 10/10] net/softnic: enable flow rule with meter action Jasvinder Singh
2018-09-28 10:36                 ` [dpdk-dev] [PATCH v5 00/10] net/softnic: implement metering and policing API Dumitrescu, Cristian
2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 02/10] net/softnic: add meter profile Jasvinder Singh
2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 03/10] net/softnic: delete " Jasvinder Singh
2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 04/10] net/softnic: create meter object Jasvinder Singh
2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 05/10] net/softnic: destroy " Jasvinder Singh
2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 06/10] net/softnic: update meter profile Jasvinder Singh
2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 07/10] net/softnic: update dscp table Jasvinder Singh
2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 08/10] net/softnic: update policer actions Jasvinder Singh
2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 09/10] net/softnic: meter stats read Jasvinder Singh
2018-09-18 16:58             ` [dpdk-dev] [PATCH v4 10/10] net/softnic: enable flow rule with meter action Jasvinder Singh
2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 02/10] net/softnic: add meter profile Jasvinder Singh
2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 03/10] net/softnic: delete " Jasvinder Singh
2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 04/10] net/softnic: create meter object Jasvinder Singh
2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 05/10] net/softnic: destroy " Jasvinder Singh
2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 06/10] net/softnic: update meter profile Jasvinder Singh
2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 07/10] net/softnic: update dscp table Jasvinder Singh
2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 08/10] net/softnic: update policer actions Jasvinder Singh
2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 09/10] net/softnic: meter stats read Jasvinder Singh
2018-09-14 17:45         ` [dpdk-dev] [PATCH v3 10/10] net/softnic: enable flow rule with meter action Jasvinder Singh
2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 02/10] net/softnic: add meter profile Jasvinder Singh
2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 03/10] net/softnic: delete " Jasvinder Singh
2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 04/10] net/softnic: create meter object Jasvinder Singh
2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 05/10] net/softnic: destroy " Jasvinder Singh
2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 06/10] net/softnic: update meter profile Jasvinder Singh
2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 07/10] net/softnic: update dscp table Jasvinder Singh
2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 08/10] net/softnic: update policer actions Jasvinder Singh
2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 09/10] net/softnic: meter stats read Jasvinder Singh
2018-09-12 16:41     ` [dpdk-dev] [PATCH v2 10/10] net/softnic: enable flow rule with meter action Jasvinder Singh
2018-09-07 18:13 ` [dpdk-dev] [PATCH 02/10] net/softnic: add meter profile Jasvinder Singh
2018-09-07 18:13 ` [dpdk-dev] [PATCH 03/10] net/softnic: delete " Jasvinder Singh
2018-09-07 18:13 ` [dpdk-dev] [PATCH 04/10] net/softnic: create meter object Jasvinder Singh
2018-09-07 18:13 ` [dpdk-dev] [PATCH 05/10] net/softnic: destroy " Jasvinder Singh
2018-09-07 18:13 ` [dpdk-dev] [PATCH 06/10] net/softnic: update meter profile Jasvinder Singh
2018-09-07 18:13 ` [dpdk-dev] [PATCH 07/10] net/softnic: update dscp table Jasvinder Singh
2018-09-07 18:13 ` [dpdk-dev] [PATCH 08/10] net/softnic: update policer actions Jasvinder Singh
2018-09-07 18:13 ` [dpdk-dev] [PATCH 09/10] net/softnic: meter stats read Jasvinder Singh
2018-09-07 18:13 ` [dpdk-dev] [PATCH 10/10] net/softnic: enable meter action using flow rule Jasvinder Singh

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).