DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 0/4] support DR/DV flows over shared IB context
@ 2019-04-02  6:22 Viacheslav Ovsiienko
  2019-04-02  6:22 ` Viacheslav Ovsiienko
                   ` (5 more replies)
  0 siblings, 6 replies; 28+ messages in thread
From: Viacheslav Ovsiienko @ 2019-04-02  6:22 UTC (permalink / raw)
  To: dev; +Cc: shahafs

The Direct Rules/Direct Verbs flows support is going
to be added [1]. The master/representor over multiport
IB device is added [2]. This patchset adds support for
DR/DV flows with shared IB context over multiport IB
device.

The DV/DR flows applied to the master/representors on the
same IB device share the following entinies:
  - rx/tx namespaces
  - rx/tx flow tables
  - matchers
  - encap/decap action resources
  - flow tags (MARK actions)
  - modify action resources
  - jump tables

[1] "net/mlx5: Add Direct Rule support"
    http://patches.dpdk.org/cover/51856/
    
[2] "net/mlx5: add support for multiport IB devices"
    http://patches.dpdk.org/cover/51800/

Viacheslav Ovsiienko (4):
  net/mlx5: add DV/DR flow data alloc/free routines
  net/mlx5: add reference counter for DV/DR structures
  net/mlx5: share DV/DR flow related structures
  net/mlx5: add mutex for shared DV/DR structures

 drivers/net/mlx5/mlx5.c         | 118 ++++++++++++++++++++++++++----
 drivers/net/mlx5/mlx5.h         |  45 ++++++------
 drivers/net/mlx5/mlx5_flow_dv.c | 155 +++++++++++++++++++++++++++++++++-------
 3 files changed, 258 insertions(+), 60 deletions(-)

-- 
1.8.3.1

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

* [dpdk-dev] [PATCH 0/4] support DR/DV flows over shared IB context
  2019-04-02  6:22 [dpdk-dev] [PATCH 0/4] support DR/DV flows over shared IB context Viacheslav Ovsiienko
@ 2019-04-02  6:22 ` Viacheslav Ovsiienko
  2019-04-02  6:22 ` [dpdk-dev] [PATCH 1/4] net/mlx5: add DV/DR flow data alloc/free routines Viacheslav Ovsiienko
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 28+ messages in thread
From: Viacheslav Ovsiienko @ 2019-04-02  6:22 UTC (permalink / raw)
  To: dev; +Cc: shahafs

The Direct Rules/Direct Verbs flows support is going
to be added [1]. The master/representor over multiport
IB device is added [2]. This patchset adds support for
DR/DV flows with shared IB context over multiport IB
device.

The DV/DR flows applied to the master/representors on the
same IB device share the following entinies:
  - rx/tx namespaces
  - rx/tx flow tables
  - matchers
  - encap/decap action resources
  - flow tags (MARK actions)
  - modify action resources
  - jump tables

[1] "net/mlx5: Add Direct Rule support"
    http://patches.dpdk.org/cover/51856/
    
[2] "net/mlx5: add support for multiport IB devices"
    http://patches.dpdk.org/cover/51800/

Viacheslav Ovsiienko (4):
  net/mlx5: add DV/DR flow data alloc/free routines
  net/mlx5: add reference counter for DV/DR structures
  net/mlx5: share DV/DR flow related structures
  net/mlx5: add mutex for shared DV/DR structures

 drivers/net/mlx5/mlx5.c         | 118 ++++++++++++++++++++++++++----
 drivers/net/mlx5/mlx5.h         |  45 ++++++------
 drivers/net/mlx5/mlx5_flow_dv.c | 155 +++++++++++++++++++++++++++++++++-------
 3 files changed, 258 insertions(+), 60 deletions(-)

-- 
1.8.3.1


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

* [dpdk-dev] [PATCH 1/4] net/mlx5: add DV/DR flow data alloc/free routines
  2019-04-02  6:22 [dpdk-dev] [PATCH 0/4] support DR/DV flows over shared IB context Viacheslav Ovsiienko
  2019-04-02  6:22 ` Viacheslav Ovsiienko
@ 2019-04-02  6:22 ` Viacheslav Ovsiienko
  2019-04-02  6:22   ` Viacheslav Ovsiienko
  2019-04-02 19:09   ` Shahaf Shuler
  2019-04-02  6:22 ` [dpdk-dev] [PATCH 2/4] net/mlx5: add reference counter for DV/DR structures Viacheslav Ovsiienko
                   ` (3 subsequent siblings)
  5 siblings, 2 replies; 28+ messages in thread
From: Viacheslav Ovsiienko @ 2019-04-02  6:22 UTC (permalink / raw)
  To: dev; +Cc: shahafs

We are going to share the DR/DV flow device data structures
between master and representors in the E-Switch configurations
over multiport IB device.

The code of initializing and destroying these data is
moved to dedicated routines, this is just a preparation
step for actual data sharing.

Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
---
 drivers/net/mlx5/mlx5.c | 90 ++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 77 insertions(+), 13 deletions(-)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index b59fc58..9de122d 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -296,6 +296,73 @@ struct mlx5_dev_spawn_data {
 	pthread_mutex_unlock(&mlx5_ibv_list_mutex);
 }
 
+#ifdef HAVE_MLX5DV_DR
+/**
+ * Initialize DV/DR related data within private structure.
+ * This is preparation step for the data sharing.
+ *
+ * @param[in] priv
+ *   Pointer to the private device data structure.
+ *
+ * @return
+ *   Zero on success, positive error code otherwise.
+ */
+static int
+mlx5_alloc_shared_dv(struct mlx5_priv *priv)
+{
+	struct mlx5_ibv_shared *sh = priv->sh;
+	int err = 0;
+	void *ns;
+
+	ns = mlx5dv_dr_create_ns(sh->ctx, MLX5DV_DR_NS_DOMAIN_INGRESS_BYPASS);
+	if (!ns) {
+		DRV_LOG(ERR, "ingress mlx5dv_dr_create_ns failed");
+		err = errno;
+		goto error;
+	}
+	priv->rx_ns = ns;
+	ns = mlx5dv_dr_create_ns(sh->ctx, MLX5DV_DR_NS_DOMAIN_EGRESS_BYPASS);
+	if (!ns) {
+		DRV_LOG(ERR, "egress mlx5dv_dr_create_ns failed");
+		err = errno;
+		goto error;
+	}
+	priv->tx_ns = ns;
+	return 0;
+
+error:
+       /* Rollback the created objects. */
+	if (priv->rx_ns) {
+		mlx5dv_dr_destroy_ns(priv->rx_ns);
+		priv->rx_ns = NULL;
+	}
+	if (priv->tx_ns) {
+		mlx5dv_dr_destroy_ns(priv->tx_ns);
+		priv->tx_ns = NULL;
+	}
+	return err;
+}
+
+/**
+ * Destroy DV/DR related structures within private structure.
+ *
+ * @param[in] priv
+ *   Pointer to the private device data structure.
+ */
+static void
+mlx5_free_shared_dv(struct mlx5_priv *priv)
+{
+	if (priv->rx_ns) {
+		mlx5dv_dr_destroy_ns(priv->rx_ns);
+		priv->rx_ns = NULL;
+	}
+	if (priv->tx_ns) {
+		mlx5dv_dr_destroy_ns(priv->tx_ns);
+		priv->tx_ns = NULL;
+	}
+}
+#endif
+
 /**
  * Prepare shared data between primary and secondary process.
  */
@@ -446,6 +513,9 @@ struct mlx5_dev_spawn_data {
 	mlx5_mprq_free_mp(dev);
 	mlx5_mr_release(dev);
 	assert(priv->sh);
+#ifdef HAVE_MLX5DV_DR
+	mlx5_free_shared_dv(priv);
+#endif
 	if (priv->sh)
 		mlx5_free_shared_ibctx(priv->sh);
 	priv->sh = NULL;
@@ -1363,20 +1433,11 @@ struct mlx5_dev_spawn_data {
 		}
 	}
 #ifdef HAVE_MLX5DV_DR
-		priv->rx_ns = mlx5dv_dr_create_ns
-			(sh->ctx, MLX5DV_DR_NS_DOMAIN_INGRESS_BYPASS);
-		if (priv->rx_ns == NULL) {
-			DRV_LOG(ERR, "mlx5dv_dr_create_ns failed");
-			err = errno;
-			goto error;
-		}
-		priv->tx_ns = mlx5dv_dr_create_ns(sh->ctx,
-					 MLX5DV_DR_NS_DOMAIN_EGRESS_BYPASS);
-		if (priv->tx_ns == NULL) {
-			DRV_LOG(ERR, "mlx5dv_dr_create_ns failed");
-			err = errno;
+	if (config.dv_flow_en) {
+		err = mlx5_alloc_shared_dv(priv);
+		if (err)
 			goto error;
-		}
+	}
 #endif
 	TAILQ_INIT(&priv->flows);
 	TAILQ_INIT(&priv->ctrl_flows);
@@ -1429,6 +1490,9 @@ struct mlx5_dev_spawn_data {
 	return eth_dev;
 error:
 	if (priv) {
+#ifdef HAVE_MLX5DV_DR
+		mlx5_free_shared_dv(priv);
+#endif
 		if (priv->nl_socket_route >= 0)
 			close(priv->nl_socket_route);
 		if (priv->nl_socket_rdma >= 0)
-- 
1.8.3.1

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

* [dpdk-dev] [PATCH 1/4] net/mlx5: add DV/DR flow data alloc/free routines
  2019-04-02  6:22 ` [dpdk-dev] [PATCH 1/4] net/mlx5: add DV/DR flow data alloc/free routines Viacheslav Ovsiienko
@ 2019-04-02  6:22   ` Viacheslav Ovsiienko
  2019-04-02 19:09   ` Shahaf Shuler
  1 sibling, 0 replies; 28+ messages in thread
From: Viacheslav Ovsiienko @ 2019-04-02  6:22 UTC (permalink / raw)
  To: dev; +Cc: shahafs

We are going to share the DR/DV flow device data structures
between master and representors in the E-Switch configurations
over multiport IB device.

The code of initializing and destroying these data is
moved to dedicated routines, this is just a preparation
step for actual data sharing.

Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
---
 drivers/net/mlx5/mlx5.c | 90 ++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 77 insertions(+), 13 deletions(-)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index b59fc58..9de122d 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -296,6 +296,73 @@ struct mlx5_dev_spawn_data {
 	pthread_mutex_unlock(&mlx5_ibv_list_mutex);
 }
 
+#ifdef HAVE_MLX5DV_DR
+/**
+ * Initialize DV/DR related data within private structure.
+ * This is preparation step for the data sharing.
+ *
+ * @param[in] priv
+ *   Pointer to the private device data structure.
+ *
+ * @return
+ *   Zero on success, positive error code otherwise.
+ */
+static int
+mlx5_alloc_shared_dv(struct mlx5_priv *priv)
+{
+	struct mlx5_ibv_shared *sh = priv->sh;
+	int err = 0;
+	void *ns;
+
+	ns = mlx5dv_dr_create_ns(sh->ctx, MLX5DV_DR_NS_DOMAIN_INGRESS_BYPASS);
+	if (!ns) {
+		DRV_LOG(ERR, "ingress mlx5dv_dr_create_ns failed");
+		err = errno;
+		goto error;
+	}
+	priv->rx_ns = ns;
+	ns = mlx5dv_dr_create_ns(sh->ctx, MLX5DV_DR_NS_DOMAIN_EGRESS_BYPASS);
+	if (!ns) {
+		DRV_LOG(ERR, "egress mlx5dv_dr_create_ns failed");
+		err = errno;
+		goto error;
+	}
+	priv->tx_ns = ns;
+	return 0;
+
+error:
+       /* Rollback the created objects. */
+	if (priv->rx_ns) {
+		mlx5dv_dr_destroy_ns(priv->rx_ns);
+		priv->rx_ns = NULL;
+	}
+	if (priv->tx_ns) {
+		mlx5dv_dr_destroy_ns(priv->tx_ns);
+		priv->tx_ns = NULL;
+	}
+	return err;
+}
+
+/**
+ * Destroy DV/DR related structures within private structure.
+ *
+ * @param[in] priv
+ *   Pointer to the private device data structure.
+ */
+static void
+mlx5_free_shared_dv(struct mlx5_priv *priv)
+{
+	if (priv->rx_ns) {
+		mlx5dv_dr_destroy_ns(priv->rx_ns);
+		priv->rx_ns = NULL;
+	}
+	if (priv->tx_ns) {
+		mlx5dv_dr_destroy_ns(priv->tx_ns);
+		priv->tx_ns = NULL;
+	}
+}
+#endif
+
 /**
  * Prepare shared data between primary and secondary process.
  */
@@ -446,6 +513,9 @@ struct mlx5_dev_spawn_data {
 	mlx5_mprq_free_mp(dev);
 	mlx5_mr_release(dev);
 	assert(priv->sh);
+#ifdef HAVE_MLX5DV_DR
+	mlx5_free_shared_dv(priv);
+#endif
 	if (priv->sh)
 		mlx5_free_shared_ibctx(priv->sh);
 	priv->sh = NULL;
@@ -1363,20 +1433,11 @@ struct mlx5_dev_spawn_data {
 		}
 	}
 #ifdef HAVE_MLX5DV_DR
-		priv->rx_ns = mlx5dv_dr_create_ns
-			(sh->ctx, MLX5DV_DR_NS_DOMAIN_INGRESS_BYPASS);
-		if (priv->rx_ns == NULL) {
-			DRV_LOG(ERR, "mlx5dv_dr_create_ns failed");
-			err = errno;
-			goto error;
-		}
-		priv->tx_ns = mlx5dv_dr_create_ns(sh->ctx,
-					 MLX5DV_DR_NS_DOMAIN_EGRESS_BYPASS);
-		if (priv->tx_ns == NULL) {
-			DRV_LOG(ERR, "mlx5dv_dr_create_ns failed");
-			err = errno;
+	if (config.dv_flow_en) {
+		err = mlx5_alloc_shared_dv(priv);
+		if (err)
 			goto error;
-		}
+	}
 #endif
 	TAILQ_INIT(&priv->flows);
 	TAILQ_INIT(&priv->ctrl_flows);
@@ -1429,6 +1490,9 @@ struct mlx5_dev_spawn_data {
 	return eth_dev;
 error:
 	if (priv) {
+#ifdef HAVE_MLX5DV_DR
+		mlx5_free_shared_dv(priv);
+#endif
 		if (priv->nl_socket_route >= 0)
 			close(priv->nl_socket_route);
 		if (priv->nl_socket_rdma >= 0)
-- 
1.8.3.1


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

* [dpdk-dev] [PATCH 2/4] net/mlx5: add reference counter for DV/DR structures
  2019-04-02  6:22 [dpdk-dev] [PATCH 0/4] support DR/DV flows over shared IB context Viacheslav Ovsiienko
  2019-04-02  6:22 ` Viacheslav Ovsiienko
  2019-04-02  6:22 ` [dpdk-dev] [PATCH 1/4] net/mlx5: add DV/DR flow data alloc/free routines Viacheslav Ovsiienko
@ 2019-04-02  6:22 ` Viacheslav Ovsiienko
  2019-04-02  6:22   ` Viacheslav Ovsiienko
  2019-04-02 19:09   ` Shahaf Shuler
  2019-04-02  6:22 ` [dpdk-dev] [PATCH 3/4] net/mlx5: share DV/DR flow related structures Viacheslav Ovsiienko
                   ` (2 subsequent siblings)
  5 siblings, 2 replies; 28+ messages in thread
From: Viacheslav Ovsiienko @ 2019-04-02  6:22 UTC (permalink / raw)
  To: dev; +Cc: shahafs

This patch introduces the reference counter for DV/DR
flow engine structure, which we are going to share
between master and representors in E-Switch configurations
over multiport Infiniband device.

Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
---
 drivers/net/mlx5/mlx5.c | 26 ++++++++++++++++++++++++--
 drivers/net/mlx5/mlx5.h |  4 ++++
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 9de122d..79e0c17 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -299,7 +299,8 @@ struct mlx5_dev_spawn_data {
 #ifdef HAVE_MLX5DV_DR
 /**
  * Initialize DV/DR related data within private structure.
- * This is preparation step for the data sharing.
+ * Routine checks the reference counter and does actual
+ * resources creation/iniialization only if counter is zero.
  *
  * @param[in] priv
  *   Pointer to the private device data structure.
@@ -314,6 +315,14 @@ struct mlx5_dev_spawn_data {
 	int err = 0;
 	void *ns;
 
+	assert(sh);
+	if (sh->dv_refcnt) {
+		/* Shared DV/DR structures is already initialized. */
+		sh->dv_refcnt++;
+		priv->dv_shared = 1;
+		return 0;
+	}
+	/* Reference counter is zero, we should initialize structures. */
 	ns = mlx5dv_dr_create_ns(sh->ctx, MLX5DV_DR_NS_DOMAIN_INGRESS_BYPASS);
 	if (!ns) {
 		DRV_LOG(ERR, "ingress mlx5dv_dr_create_ns failed");
@@ -328,6 +337,8 @@ struct mlx5_dev_spawn_data {
 		goto error;
 	}
 	priv->tx_ns = ns;
+	sh->dv_refcnt++;
+	priv->dv_shared = 1;
 	return 0;
 
 error:
@@ -352,6 +363,16 @@ struct mlx5_dev_spawn_data {
 static void
 mlx5_free_shared_dv(struct mlx5_priv *priv)
 {
+	struct mlx5_ibv_shared *sh;
+
+	if (!priv->dv_shared)
+		return;
+	priv->dv_shared = 0;
+	sh = priv->sh;
+	assert(sh);
+	assert(sh->dv_refcnt);
+	if (sh->dv_refcnt && --sh->dv_refcnt)
+		return;
 	if (priv->rx_ns) {
 		mlx5dv_dr_destroy_ns(priv->rx_ns);
 		priv->rx_ns = NULL;
@@ -1491,7 +1512,8 @@ struct mlx5_dev_spawn_data {
 error:
 	if (priv) {
 #ifdef HAVE_MLX5DV_DR
-		mlx5_free_shared_dv(priv);
+		if (priv->sh)
+			mlx5_free_shared_dv(priv);
 #endif
 		if (priv->nl_socket_route >= 0)
 			close(priv->nl_socket_route);
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index a3d5f8e..56a2c61 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -213,6 +213,9 @@ struct mlx5_ibv_shared {
 	char ibdev_name[IBV_SYSFS_NAME_MAX]; /* IB device name. */
 	char ibdev_path[IBV_SYSFS_PATH_MAX]; /* IB device path for secondary */
 	struct ibv_device_attr_ex device_attr; /* Device properties. */
+	/* Shared DV/DR flow data section. */
+	uint32_t dv_refcnt; /* DV/DR data reference counter. */
+	/* Shared interrupt handler section. */
 	pthread_mutex_t intr_mutex; /* Interrupt config mutex. */
 	uint32_t intr_cnt; /* Interrupt handler reference counter. */
 	struct rte_intr_handle intr_handle; /* Interrupt handler for device. */
@@ -244,6 +247,7 @@ struct mlx5_priv {
 	unsigned int isolated:1; /* Whether isolated mode is enabled. */
 	unsigned int representor:1; /* Device is a port representor. */
 	unsigned int master:1; /* Device is a E-Switch master. */
+	unsigned int dv_shared:1; /* DV/DR data is shared. */
 	uint16_t domain_id; /* Switch domain identifier. */
 	uint16_t vport_id; /* Associated VF vport index (if any). */
 	int32_t representor_id; /* Port representor identifier. */
-- 
1.8.3.1

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

* [dpdk-dev] [PATCH 2/4] net/mlx5: add reference counter for DV/DR structures
  2019-04-02  6:22 ` [dpdk-dev] [PATCH 2/4] net/mlx5: add reference counter for DV/DR structures Viacheslav Ovsiienko
@ 2019-04-02  6:22   ` Viacheslav Ovsiienko
  2019-04-02 19:09   ` Shahaf Shuler
  1 sibling, 0 replies; 28+ messages in thread
From: Viacheslav Ovsiienko @ 2019-04-02  6:22 UTC (permalink / raw)
  To: dev; +Cc: shahafs

This patch introduces the reference counter for DV/DR
flow engine structure, which we are going to share
between master and representors in E-Switch configurations
over multiport Infiniband device.

Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
---
 drivers/net/mlx5/mlx5.c | 26 ++++++++++++++++++++++++--
 drivers/net/mlx5/mlx5.h |  4 ++++
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 9de122d..79e0c17 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -299,7 +299,8 @@ struct mlx5_dev_spawn_data {
 #ifdef HAVE_MLX5DV_DR
 /**
  * Initialize DV/DR related data within private structure.
- * This is preparation step for the data sharing.
+ * Routine checks the reference counter and does actual
+ * resources creation/iniialization only if counter is zero.
  *
  * @param[in] priv
  *   Pointer to the private device data structure.
@@ -314,6 +315,14 @@ struct mlx5_dev_spawn_data {
 	int err = 0;
 	void *ns;
 
+	assert(sh);
+	if (sh->dv_refcnt) {
+		/* Shared DV/DR structures is already initialized. */
+		sh->dv_refcnt++;
+		priv->dv_shared = 1;
+		return 0;
+	}
+	/* Reference counter is zero, we should initialize structures. */
 	ns = mlx5dv_dr_create_ns(sh->ctx, MLX5DV_DR_NS_DOMAIN_INGRESS_BYPASS);
 	if (!ns) {
 		DRV_LOG(ERR, "ingress mlx5dv_dr_create_ns failed");
@@ -328,6 +337,8 @@ struct mlx5_dev_spawn_data {
 		goto error;
 	}
 	priv->tx_ns = ns;
+	sh->dv_refcnt++;
+	priv->dv_shared = 1;
 	return 0;
 
 error:
@@ -352,6 +363,16 @@ struct mlx5_dev_spawn_data {
 static void
 mlx5_free_shared_dv(struct mlx5_priv *priv)
 {
+	struct mlx5_ibv_shared *sh;
+
+	if (!priv->dv_shared)
+		return;
+	priv->dv_shared = 0;
+	sh = priv->sh;
+	assert(sh);
+	assert(sh->dv_refcnt);
+	if (sh->dv_refcnt && --sh->dv_refcnt)
+		return;
 	if (priv->rx_ns) {
 		mlx5dv_dr_destroy_ns(priv->rx_ns);
 		priv->rx_ns = NULL;
@@ -1491,7 +1512,8 @@ struct mlx5_dev_spawn_data {
 error:
 	if (priv) {
 #ifdef HAVE_MLX5DV_DR
-		mlx5_free_shared_dv(priv);
+		if (priv->sh)
+			mlx5_free_shared_dv(priv);
 #endif
 		if (priv->nl_socket_route >= 0)
 			close(priv->nl_socket_route);
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index a3d5f8e..56a2c61 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -213,6 +213,9 @@ struct mlx5_ibv_shared {
 	char ibdev_name[IBV_SYSFS_NAME_MAX]; /* IB device name. */
 	char ibdev_path[IBV_SYSFS_PATH_MAX]; /* IB device path for secondary */
 	struct ibv_device_attr_ex device_attr; /* Device properties. */
+	/* Shared DV/DR flow data section. */
+	uint32_t dv_refcnt; /* DV/DR data reference counter. */
+	/* Shared interrupt handler section. */
 	pthread_mutex_t intr_mutex; /* Interrupt config mutex. */
 	uint32_t intr_cnt; /* Interrupt handler reference counter. */
 	struct rte_intr_handle intr_handle; /* Interrupt handler for device. */
@@ -244,6 +247,7 @@ struct mlx5_priv {
 	unsigned int isolated:1; /* Whether isolated mode is enabled. */
 	unsigned int representor:1; /* Device is a port representor. */
 	unsigned int master:1; /* Device is a E-Switch master. */
+	unsigned int dv_shared:1; /* DV/DR data is shared. */
 	uint16_t domain_id; /* Switch domain identifier. */
 	uint16_t vport_id; /* Associated VF vport index (if any). */
 	int32_t representor_id; /* Port representor identifier. */
-- 
1.8.3.1


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

* [dpdk-dev] [PATCH 3/4] net/mlx5: share DV/DR flow related structures
  2019-04-02  6:22 [dpdk-dev] [PATCH 0/4] support DR/DV flows over shared IB context Viacheslav Ovsiienko
                   ` (2 preceding siblings ...)
  2019-04-02  6:22 ` [dpdk-dev] [PATCH 2/4] net/mlx5: add reference counter for DV/DR structures Viacheslav Ovsiienko
@ 2019-04-02  6:22 ` Viacheslav Ovsiienko
  2019-04-02  6:22   ` Viacheslav Ovsiienko
  2019-04-02 19:09   ` Shahaf Shuler
  2019-04-02  6:22 ` [dpdk-dev] [PATCH 4/4] net/mlx5: add mutex for shared DV/DR structures Viacheslav Ovsiienko
  2019-04-04 13:04 ` [dpdk-dev] [PATCH v2 0/2] support Direct Rules flows over shared IB context Viacheslav Ovsiienko
  5 siblings, 2 replies; 28+ messages in thread
From: Viacheslav Ovsiienko @ 2019-04-02  6:22 UTC (permalink / raw)
  To: dev; +Cc: shahafs

DV/DR related structures are moved to the shared context:
  - rx/tx namespaces, shared by master and representors
  - rx/tx flow tables
  - matchers
  - encap/decap action resources
  - flow tags (MARK actions)
  - modify action resources
  - jump tables

Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
---
 drivers/net/mlx5/mlx5.c         | 28 +++++++++++-----------
 drivers/net/mlx5/mlx5.h         | 40 +++++++++++++++----------------
 drivers/net/mlx5/mlx5_flow_dv.c | 52 +++++++++++++++++++++++------------------
 3 files changed, 63 insertions(+), 57 deletions(-)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 79e0c17..369b698 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -329,27 +329,27 @@ struct mlx5_dev_spawn_data {
 		err = errno;
 		goto error;
 	}
-	priv->rx_ns = ns;
+	sh->rx_ns = ns;
 	ns = mlx5dv_dr_create_ns(sh->ctx, MLX5DV_DR_NS_DOMAIN_EGRESS_BYPASS);
 	if (!ns) {
 		DRV_LOG(ERR, "egress mlx5dv_dr_create_ns failed");
 		err = errno;
 		goto error;
 	}
-	priv->tx_ns = ns;
+	sh->tx_ns = ns;
 	sh->dv_refcnt++;
 	priv->dv_shared = 1;
 	return 0;
 
 error:
        /* Rollback the created objects. */
-	if (priv->rx_ns) {
-		mlx5dv_dr_destroy_ns(priv->rx_ns);
-		priv->rx_ns = NULL;
+	if (sh->rx_ns) {
+		mlx5dv_dr_destroy_ns(sh->rx_ns);
+		sh->rx_ns = NULL;
 	}
-	if (priv->tx_ns) {
-		mlx5dv_dr_destroy_ns(priv->tx_ns);
-		priv->tx_ns = NULL;
+	if (sh->tx_ns) {
+		mlx5dv_dr_destroy_ns(sh->tx_ns);
+		sh->tx_ns = NULL;
 	}
 	return err;
 }
@@ -373,13 +373,13 @@ struct mlx5_dev_spawn_data {
 	assert(sh->dv_refcnt);
 	if (sh->dv_refcnt && --sh->dv_refcnt)
 		return;
-	if (priv->rx_ns) {
-		mlx5dv_dr_destroy_ns(priv->rx_ns);
-		priv->rx_ns = NULL;
+	if (sh->rx_ns) {
+		mlx5dv_dr_destroy_ns(sh->rx_ns);
+		sh->rx_ns = NULL;
 	}
-	if (priv->tx_ns) {
-		mlx5dv_dr_destroy_ns(priv->tx_ns);
-		priv->tx_ns = NULL;
+	if (sh->tx_ns) {
+		mlx5dv_dr_destroy_ns(sh->tx_ns);
+		sh->tx_ns = NULL;
 	}
 }
 #endif
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 56a2c61..e67227f 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -199,6 +199,15 @@ struct mlx5_ibv_shared_port {
 	 */
 };
 
+/* Table structure. */
+struct mlx5_flow_tbl_resource {
+	void *obj; /**< Pointer to DR table object. */
+	rte_atomic32_t refcnt; /**< Reference counter. */
+};
+
+#define MLX5_MAX_TABLES 1024
+#define MLX5_GROUP_FACTOR 1
+
 /*
  * Shared Infiniband device context for Master/Representors
  * which belong to same IB device with multiple IB ports.
@@ -215,6 +224,17 @@ struct mlx5_ibv_shared {
 	struct ibv_device_attr_ex device_attr; /* Device properties. */
 	/* Shared DV/DR flow data section. */
 	uint32_t dv_refcnt; /* DV/DR data reference counter. */
+	void *rx_ns; /* RX Direct Rules name space handle. */
+	struct mlx5_flow_tbl_resource rx_tbl[MLX5_MAX_TABLES];
+	/* RX Direct Rules tables. */
+	void *tx_ns; /* TX Direct Rules name space handle. */
+	struct mlx5_flow_tbl_resource tx_tbl[MLX5_MAX_TABLES];
+	/* TX Direct Rules tables/ */
+	LIST_HEAD(matchers, mlx5_flow_dv_matcher) matchers;
+	LIST_HEAD(encap_decap, mlx5_flow_dv_encap_decap_resource) encaps_decaps;
+	LIST_HEAD(modify_cmd, mlx5_flow_dv_modify_hdr_resource) modify_cmds;
+	LIST_HEAD(tag, mlx5_flow_dv_tag_resource) tags;
+	LIST_HEAD(jump, mlx5_flow_dv_jump_tbl_resource) jump_tbl;
 	/* Shared interrupt handler section. */
 	pthread_mutex_t intr_mutex; /* Interrupt config mutex. */
 	uint32_t intr_cnt; /* Interrupt handler reference counter. */
@@ -222,15 +242,6 @@ struct mlx5_ibv_shared {
 	struct mlx5_ibv_shared_port port[]; /* per device port data array. */
 };
 
-/* Table structure. */
-struct mlx5_flow_tbl_resource {
-	void *obj; /**< Pointer to DR table object. */
-	rte_atomic32_t refcnt; /**< Reference counter. */
-};
-
-#define MLX5_MAX_TABLES 1024
-#define MLX5_GROUP_FACTOR 1
-
 struct mlx5_priv {
 	LIST_ENTRY(mlx5_priv) mem_event_cb;
 	/**< Called by memory event callback. */
@@ -279,11 +290,6 @@ struct mlx5_priv {
 	LIST_HEAD(txqibv, mlx5_txq_ibv) txqsibv; /* Verbs Tx queues. */
 	/* Verbs Indirection tables. */
 	LIST_HEAD(ind_tables, mlx5_ind_table_ibv) ind_tbls;
-	LIST_HEAD(matchers, mlx5_flow_dv_matcher) matchers;
-	LIST_HEAD(encap_decap, mlx5_flow_dv_encap_decap_resource) encaps_decaps;
-	LIST_HEAD(modify_cmd, mlx5_flow_dv_modify_hdr_resource) modify_cmds;
-	LIST_HEAD(tag, mlx5_flow_dv_tag_resource) tags;
-	LIST_HEAD(jump, mlx5_flow_dv_jump_tbl_resource) jump_tbl;
 	/* Pointer to next element. */
 	rte_atomic32_t refcnt; /**< Reference counter. */
 	struct ibv_flow_action *verbs_action;
@@ -308,12 +314,6 @@ struct mlx5_priv {
 	/* UAR same-page access control required in 32bit implementations. */
 #endif
 	struct mlx5_flow_tcf_context *tcf_context; /* TC flower context. */
-	void *rx_ns; /* RX Direct Rules name space handle. */
-	struct mlx5_flow_tbl_resource rx_tbl[MLX5_MAX_TABLES];
-	/* RX Direct Rules tables. */
-	void *tx_ns; /* TX Direct Rules name space handle. */
-	struct mlx5_flow_tbl_resource tx_tbl[MLX5_MAX_TABLES];
-	/* TX Direct Rules tables/ */
 };
 
 #define PORT_ID(priv) ((priv)->dev_data->port_id)
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index f1dd00a..4912fc8 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -804,18 +804,19 @@ struct field_modify_info modify_tcp[] = {
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_dv_encap_decap_resource *cache_resource;
 	struct rte_flow *flow = dev_flow->flow;
 	struct mlx5dv_dr_ns *ns;
 
 	resource->flags = flow->group ? 0 : 1;
 	if (flow->ingress)
-		ns = priv->rx_ns;
+		ns = sh->rx_ns;
 	else
-		ns = priv->tx_ns;
+		ns = sh->tx_ns;
 
 	/* Lookup a matching resource from cache. */
-	LIST_FOREACH(cache_resource, &priv->encaps_decaps, next) {
+	LIST_FOREACH(cache_resource, &sh->encaps_decaps, next) {
 		if (resource->reformat_type == cache_resource->reformat_type &&
 		    resource->ft_type == cache_resource->ft_type &&
 		    resource->flags == cache_resource->flags &&
@@ -840,7 +841,7 @@ struct field_modify_info modify_tcp[] = {
 	*cache_resource = *resource;
 	cache_resource->verbs_action =
 		mlx5_glue->dv_create_flow_action_packet_reformat
-			(priv->sh->ctx, cache_resource->reformat_type,
+			(sh->ctx, cache_resource->reformat_type,
 			 cache_resource->ft_type, ns, cache_resource->flags,
 			 cache_resource->size,
 			 (cache_resource->size ? cache_resource->buf : NULL));
@@ -852,7 +853,7 @@ struct field_modify_info modify_tcp[] = {
 	}
 	rte_atomic32_init(&cache_resource->refcnt);
 	rte_atomic32_inc(&cache_resource->refcnt);
-	LIST_INSERT_HEAD(&priv->encaps_decaps, cache_resource, next);
+	LIST_INSERT_HEAD(&sh->encaps_decaps, cache_resource, next);
 	dev_flow->dv.encap_decap = cache_resource;
 	DRV_LOG(DEBUG, "new encap/decap resource %p: refcnt %d++",
 		(void *)cache_resource,
@@ -883,10 +884,11 @@ struct field_modify_info modify_tcp[] = {
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_dv_jump_tbl_resource *cache_resource;
 
 	/* Lookup a matching resource from cache. */
-	LIST_FOREACH(cache_resource, &priv->jump_tbl, next) {
+	LIST_FOREACH(cache_resource, &sh->jump_tbl, next) {
 		if (resource->tbl == cache_resource->tbl) {
 			DRV_LOG(DEBUG, "jump table resource resource %p: refcnt %d++",
 				(void *)cache_resource,
@@ -914,7 +916,7 @@ struct field_modify_info modify_tcp[] = {
 	}
 	rte_atomic32_init(&cache_resource->refcnt);
 	rte_atomic32_inc(&cache_resource->refcnt);
-	LIST_INSERT_HEAD(&priv->jump_tbl, cache_resource, next);
+	LIST_INSERT_HEAD(&sh->jump_tbl, cache_resource, next);
 	dev_flow->dv.jump = cache_resource;
 	DRV_LOG(DEBUG, "new jump table  resource %p: refcnt %d++",
 		(void *)cache_resource,
@@ -1538,14 +1540,15 @@ struct field_modify_info modify_tcp[] = {
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_dv_modify_hdr_resource *cache_resource;
 
 	struct mlx5dv_dr_ns *ns =
 		resource->ft_type == MLX5DV_FLOW_TABLE_TYPE_NIC_TX  ?
-		priv->tx_ns : priv->rx_ns;
+		sh->tx_ns : sh->rx_ns;
 
 	/* Lookup a matching resource from cache. */
-	LIST_FOREACH(cache_resource, &priv->modify_cmds, next) {
+	LIST_FOREACH(cache_resource, &sh->modify_cmds, next) {
 		if (resource->ft_type == cache_resource->ft_type &&
 		    resource->actions_num == cache_resource->actions_num &&
 		    !memcmp((const void *)resource->actions,
@@ -1569,7 +1572,7 @@ struct field_modify_info modify_tcp[] = {
 	*cache_resource = *resource;
 	cache_resource->verbs_action =
 		mlx5_glue->dv_create_flow_action_modify_header
-					(priv->sh->ctx, cache_resource->ft_type,
+					(sh->ctx, cache_resource->ft_type,
 					 ns, 0,
 					 cache_resource->actions_num *
 					 sizeof(cache_resource->actions[0]),
@@ -1582,7 +1585,7 @@ struct field_modify_info modify_tcp[] = {
 	}
 	rte_atomic32_init(&cache_resource->refcnt);
 	rte_atomic32_inc(&cache_resource->refcnt);
-	LIST_INSERT_HEAD(&priv->modify_cmds, cache_resource, next);
+	LIST_INSERT_HEAD(&sh->modify_cmds, cache_resource, next);
 	dev_flow->dv.modify_hdr = cache_resource;
 	DRV_LOG(DEBUG, "new modify-header resource %p: refcnt %d++",
 		(void *)cache_resource,
@@ -2879,18 +2882,19 @@ struct field_modify_info modify_tcp[] = {
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_tbl_resource *tbl;
 
 	if (egress) {
-		tbl = &priv->tx_tbl[table_id];
+		tbl = &sh->tx_tbl[table_id];
 		if (!tbl->obj)
 			tbl->obj = mlx5_glue->dr_create_flow_tbl
-				(priv->tx_ns, table_id);
+				(sh->tx_ns, table_id);
 	} else {
-		tbl = &priv->rx_tbl[table_id];
+		tbl = &sh->rx_tbl[table_id];
 		if (!tbl->obj)
 			tbl->obj = mlx5_glue->dr_create_flow_tbl
-				(priv->rx_ns, table_id);
+				(sh->rx_ns, table_id);
 	}
 	if (!tbl->obj) {
 		rte_flow_error_set(error, ENOMEM,
@@ -2946,6 +2950,7 @@ struct field_modify_info modify_tcp[] = {
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_dv_matcher *cache_matcher;
 	struct mlx5dv_flow_matcher_attr dv_attr = {
 		.type = IBV_FLOW_ATTR_NORMAL,
@@ -2957,7 +2962,7 @@ struct field_modify_info modify_tcp[] = {
 #endif
 
 	/* Lookup from cache. */
-	LIST_FOREACH(cache_matcher, &priv->matchers, next) {
+	LIST_FOREACH(cache_matcher, &sh->matchers, next) {
 		if (matcher->crc == cache_matcher->crc &&
 		    matcher->priority == cache_matcher->priority &&
 		    matcher->egress == cache_matcher->egress &&
@@ -3001,8 +3006,7 @@ struct field_modify_info modify_tcp[] = {
 	if (matcher->egress)
 		dv_attr.flags |= IBV_FLOW_ATTR_FLAGS_EGRESS;
 	cache_matcher->matcher_object =
-		mlx5_glue->dv_create_flow_matcher(priv->sh->ctx, &dv_attr,
-						  tbl->obj);
+		mlx5_glue->dv_create_flow_matcher(sh->ctx, &dv_attr, tbl->obj);
 	if (!cache_matcher->matcher_object) {
 		rte_free(cache_matcher);
 #ifdef HAVE_MLX5DV_DR
@@ -3013,7 +3017,7 @@ struct field_modify_info modify_tcp[] = {
 					  NULL, "cannot create matcher");
 	}
 	rte_atomic32_inc(&cache_matcher->refcnt);
-	LIST_INSERT_HEAD(&priv->matchers, cache_matcher, next);
+	LIST_INSERT_HEAD(&sh->matchers, cache_matcher, next);
 	dev_flow->dv.matcher = cache_matcher;
 	DRV_LOG(DEBUG, "priority %hd new %s matcher %p: refcnt %d",
 		cache_matcher->priority,
@@ -3069,10 +3073,11 @@ struct field_modify_info modify_tcp[] = {
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_dv_tag_resource *cache_resource;
 
 	/* Lookup a matching resource from cache. */
-	LIST_FOREACH(cache_resource, &priv->tags, next) {
+	LIST_FOREACH(cache_resource, &sh->tags, next) {
 		if (resource->tag == cache_resource->tag) {
 			DRV_LOG(DEBUG, "tag resource %p: refcnt %d++",
 				(void *)cache_resource,
@@ -3099,7 +3104,7 @@ struct field_modify_info modify_tcp[] = {
 	}
 	rte_atomic32_init(&cache_resource->refcnt);
 	rte_atomic32_inc(&cache_resource->refcnt);
-	LIST_INSERT_HEAD(&priv->tags, cache_resource, next);
+	LIST_INSERT_HEAD(&sh->tags, cache_resource, next);
 	dev_flow->flow->tag_resource = cache_resource;
 	DRV_LOG(DEBUG, "new tag resource %p: refcnt %d++",
 		(void *)cache_resource,
@@ -3676,6 +3681,7 @@ struct field_modify_info modify_tcp[] = {
 {
 	struct mlx5_flow_dv_matcher *matcher = flow->dv.matcher;
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_tbl_resource *tbl;
 
 	assert(matcher->matcher_object);
@@ -3687,9 +3693,9 @@ struct field_modify_info modify_tcp[] = {
 			   (matcher->matcher_object));
 		LIST_REMOVE(matcher, next);
 		if (matcher->egress)
-			tbl = &priv->tx_tbl[matcher->group];
+			tbl = &sh->tx_tbl[matcher->group];
 		else
-			tbl = &priv->rx_tbl[matcher->group];
+			tbl = &sh->rx_tbl[matcher->group];
 		flow_dv_tbl_resource_release(tbl);
 		rte_free(matcher);
 		DRV_LOG(DEBUG, "port %u matcher %p: removed",
-- 
1.8.3.1

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

* [dpdk-dev] [PATCH 3/4] net/mlx5: share DV/DR flow related structures
  2019-04-02  6:22 ` [dpdk-dev] [PATCH 3/4] net/mlx5: share DV/DR flow related structures Viacheslav Ovsiienko
@ 2019-04-02  6:22   ` Viacheslav Ovsiienko
  2019-04-02 19:09   ` Shahaf Shuler
  1 sibling, 0 replies; 28+ messages in thread
From: Viacheslav Ovsiienko @ 2019-04-02  6:22 UTC (permalink / raw)
  To: dev; +Cc: shahafs

DV/DR related structures are moved to the shared context:
  - rx/tx namespaces, shared by master and representors
  - rx/tx flow tables
  - matchers
  - encap/decap action resources
  - flow tags (MARK actions)
  - modify action resources
  - jump tables

Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
---
 drivers/net/mlx5/mlx5.c         | 28 +++++++++++-----------
 drivers/net/mlx5/mlx5.h         | 40 +++++++++++++++----------------
 drivers/net/mlx5/mlx5_flow_dv.c | 52 +++++++++++++++++++++++------------------
 3 files changed, 63 insertions(+), 57 deletions(-)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 79e0c17..369b698 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -329,27 +329,27 @@ struct mlx5_dev_spawn_data {
 		err = errno;
 		goto error;
 	}
-	priv->rx_ns = ns;
+	sh->rx_ns = ns;
 	ns = mlx5dv_dr_create_ns(sh->ctx, MLX5DV_DR_NS_DOMAIN_EGRESS_BYPASS);
 	if (!ns) {
 		DRV_LOG(ERR, "egress mlx5dv_dr_create_ns failed");
 		err = errno;
 		goto error;
 	}
-	priv->tx_ns = ns;
+	sh->tx_ns = ns;
 	sh->dv_refcnt++;
 	priv->dv_shared = 1;
 	return 0;
 
 error:
        /* Rollback the created objects. */
-	if (priv->rx_ns) {
-		mlx5dv_dr_destroy_ns(priv->rx_ns);
-		priv->rx_ns = NULL;
+	if (sh->rx_ns) {
+		mlx5dv_dr_destroy_ns(sh->rx_ns);
+		sh->rx_ns = NULL;
 	}
-	if (priv->tx_ns) {
-		mlx5dv_dr_destroy_ns(priv->tx_ns);
-		priv->tx_ns = NULL;
+	if (sh->tx_ns) {
+		mlx5dv_dr_destroy_ns(sh->tx_ns);
+		sh->tx_ns = NULL;
 	}
 	return err;
 }
@@ -373,13 +373,13 @@ struct mlx5_dev_spawn_data {
 	assert(sh->dv_refcnt);
 	if (sh->dv_refcnt && --sh->dv_refcnt)
 		return;
-	if (priv->rx_ns) {
-		mlx5dv_dr_destroy_ns(priv->rx_ns);
-		priv->rx_ns = NULL;
+	if (sh->rx_ns) {
+		mlx5dv_dr_destroy_ns(sh->rx_ns);
+		sh->rx_ns = NULL;
 	}
-	if (priv->tx_ns) {
-		mlx5dv_dr_destroy_ns(priv->tx_ns);
-		priv->tx_ns = NULL;
+	if (sh->tx_ns) {
+		mlx5dv_dr_destroy_ns(sh->tx_ns);
+		sh->tx_ns = NULL;
 	}
 }
 #endif
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 56a2c61..e67227f 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -199,6 +199,15 @@ struct mlx5_ibv_shared_port {
 	 */
 };
 
+/* Table structure. */
+struct mlx5_flow_tbl_resource {
+	void *obj; /**< Pointer to DR table object. */
+	rte_atomic32_t refcnt; /**< Reference counter. */
+};
+
+#define MLX5_MAX_TABLES 1024
+#define MLX5_GROUP_FACTOR 1
+
 /*
  * Shared Infiniband device context for Master/Representors
  * which belong to same IB device with multiple IB ports.
@@ -215,6 +224,17 @@ struct mlx5_ibv_shared {
 	struct ibv_device_attr_ex device_attr; /* Device properties. */
 	/* Shared DV/DR flow data section. */
 	uint32_t dv_refcnt; /* DV/DR data reference counter. */
+	void *rx_ns; /* RX Direct Rules name space handle. */
+	struct mlx5_flow_tbl_resource rx_tbl[MLX5_MAX_TABLES];
+	/* RX Direct Rules tables. */
+	void *tx_ns; /* TX Direct Rules name space handle. */
+	struct mlx5_flow_tbl_resource tx_tbl[MLX5_MAX_TABLES];
+	/* TX Direct Rules tables/ */
+	LIST_HEAD(matchers, mlx5_flow_dv_matcher) matchers;
+	LIST_HEAD(encap_decap, mlx5_flow_dv_encap_decap_resource) encaps_decaps;
+	LIST_HEAD(modify_cmd, mlx5_flow_dv_modify_hdr_resource) modify_cmds;
+	LIST_HEAD(tag, mlx5_flow_dv_tag_resource) tags;
+	LIST_HEAD(jump, mlx5_flow_dv_jump_tbl_resource) jump_tbl;
 	/* Shared interrupt handler section. */
 	pthread_mutex_t intr_mutex; /* Interrupt config mutex. */
 	uint32_t intr_cnt; /* Interrupt handler reference counter. */
@@ -222,15 +242,6 @@ struct mlx5_ibv_shared {
 	struct mlx5_ibv_shared_port port[]; /* per device port data array. */
 };
 
-/* Table structure. */
-struct mlx5_flow_tbl_resource {
-	void *obj; /**< Pointer to DR table object. */
-	rte_atomic32_t refcnt; /**< Reference counter. */
-};
-
-#define MLX5_MAX_TABLES 1024
-#define MLX5_GROUP_FACTOR 1
-
 struct mlx5_priv {
 	LIST_ENTRY(mlx5_priv) mem_event_cb;
 	/**< Called by memory event callback. */
@@ -279,11 +290,6 @@ struct mlx5_priv {
 	LIST_HEAD(txqibv, mlx5_txq_ibv) txqsibv; /* Verbs Tx queues. */
 	/* Verbs Indirection tables. */
 	LIST_HEAD(ind_tables, mlx5_ind_table_ibv) ind_tbls;
-	LIST_HEAD(matchers, mlx5_flow_dv_matcher) matchers;
-	LIST_HEAD(encap_decap, mlx5_flow_dv_encap_decap_resource) encaps_decaps;
-	LIST_HEAD(modify_cmd, mlx5_flow_dv_modify_hdr_resource) modify_cmds;
-	LIST_HEAD(tag, mlx5_flow_dv_tag_resource) tags;
-	LIST_HEAD(jump, mlx5_flow_dv_jump_tbl_resource) jump_tbl;
 	/* Pointer to next element. */
 	rte_atomic32_t refcnt; /**< Reference counter. */
 	struct ibv_flow_action *verbs_action;
@@ -308,12 +314,6 @@ struct mlx5_priv {
 	/* UAR same-page access control required in 32bit implementations. */
 #endif
 	struct mlx5_flow_tcf_context *tcf_context; /* TC flower context. */
-	void *rx_ns; /* RX Direct Rules name space handle. */
-	struct mlx5_flow_tbl_resource rx_tbl[MLX5_MAX_TABLES];
-	/* RX Direct Rules tables. */
-	void *tx_ns; /* TX Direct Rules name space handle. */
-	struct mlx5_flow_tbl_resource tx_tbl[MLX5_MAX_TABLES];
-	/* TX Direct Rules tables/ */
 };
 
 #define PORT_ID(priv) ((priv)->dev_data->port_id)
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index f1dd00a..4912fc8 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -804,18 +804,19 @@ struct field_modify_info modify_tcp[] = {
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_dv_encap_decap_resource *cache_resource;
 	struct rte_flow *flow = dev_flow->flow;
 	struct mlx5dv_dr_ns *ns;
 
 	resource->flags = flow->group ? 0 : 1;
 	if (flow->ingress)
-		ns = priv->rx_ns;
+		ns = sh->rx_ns;
 	else
-		ns = priv->tx_ns;
+		ns = sh->tx_ns;
 
 	/* Lookup a matching resource from cache. */
-	LIST_FOREACH(cache_resource, &priv->encaps_decaps, next) {
+	LIST_FOREACH(cache_resource, &sh->encaps_decaps, next) {
 		if (resource->reformat_type == cache_resource->reformat_type &&
 		    resource->ft_type == cache_resource->ft_type &&
 		    resource->flags == cache_resource->flags &&
@@ -840,7 +841,7 @@ struct field_modify_info modify_tcp[] = {
 	*cache_resource = *resource;
 	cache_resource->verbs_action =
 		mlx5_glue->dv_create_flow_action_packet_reformat
-			(priv->sh->ctx, cache_resource->reformat_type,
+			(sh->ctx, cache_resource->reformat_type,
 			 cache_resource->ft_type, ns, cache_resource->flags,
 			 cache_resource->size,
 			 (cache_resource->size ? cache_resource->buf : NULL));
@@ -852,7 +853,7 @@ struct field_modify_info modify_tcp[] = {
 	}
 	rte_atomic32_init(&cache_resource->refcnt);
 	rte_atomic32_inc(&cache_resource->refcnt);
-	LIST_INSERT_HEAD(&priv->encaps_decaps, cache_resource, next);
+	LIST_INSERT_HEAD(&sh->encaps_decaps, cache_resource, next);
 	dev_flow->dv.encap_decap = cache_resource;
 	DRV_LOG(DEBUG, "new encap/decap resource %p: refcnt %d++",
 		(void *)cache_resource,
@@ -883,10 +884,11 @@ struct field_modify_info modify_tcp[] = {
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_dv_jump_tbl_resource *cache_resource;
 
 	/* Lookup a matching resource from cache. */
-	LIST_FOREACH(cache_resource, &priv->jump_tbl, next) {
+	LIST_FOREACH(cache_resource, &sh->jump_tbl, next) {
 		if (resource->tbl == cache_resource->tbl) {
 			DRV_LOG(DEBUG, "jump table resource resource %p: refcnt %d++",
 				(void *)cache_resource,
@@ -914,7 +916,7 @@ struct field_modify_info modify_tcp[] = {
 	}
 	rte_atomic32_init(&cache_resource->refcnt);
 	rte_atomic32_inc(&cache_resource->refcnt);
-	LIST_INSERT_HEAD(&priv->jump_tbl, cache_resource, next);
+	LIST_INSERT_HEAD(&sh->jump_tbl, cache_resource, next);
 	dev_flow->dv.jump = cache_resource;
 	DRV_LOG(DEBUG, "new jump table  resource %p: refcnt %d++",
 		(void *)cache_resource,
@@ -1538,14 +1540,15 @@ struct field_modify_info modify_tcp[] = {
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_dv_modify_hdr_resource *cache_resource;
 
 	struct mlx5dv_dr_ns *ns =
 		resource->ft_type == MLX5DV_FLOW_TABLE_TYPE_NIC_TX  ?
-		priv->tx_ns : priv->rx_ns;
+		sh->tx_ns : sh->rx_ns;
 
 	/* Lookup a matching resource from cache. */
-	LIST_FOREACH(cache_resource, &priv->modify_cmds, next) {
+	LIST_FOREACH(cache_resource, &sh->modify_cmds, next) {
 		if (resource->ft_type == cache_resource->ft_type &&
 		    resource->actions_num == cache_resource->actions_num &&
 		    !memcmp((const void *)resource->actions,
@@ -1569,7 +1572,7 @@ struct field_modify_info modify_tcp[] = {
 	*cache_resource = *resource;
 	cache_resource->verbs_action =
 		mlx5_glue->dv_create_flow_action_modify_header
-					(priv->sh->ctx, cache_resource->ft_type,
+					(sh->ctx, cache_resource->ft_type,
 					 ns, 0,
 					 cache_resource->actions_num *
 					 sizeof(cache_resource->actions[0]),
@@ -1582,7 +1585,7 @@ struct field_modify_info modify_tcp[] = {
 	}
 	rte_atomic32_init(&cache_resource->refcnt);
 	rte_atomic32_inc(&cache_resource->refcnt);
-	LIST_INSERT_HEAD(&priv->modify_cmds, cache_resource, next);
+	LIST_INSERT_HEAD(&sh->modify_cmds, cache_resource, next);
 	dev_flow->dv.modify_hdr = cache_resource;
 	DRV_LOG(DEBUG, "new modify-header resource %p: refcnt %d++",
 		(void *)cache_resource,
@@ -2879,18 +2882,19 @@ struct field_modify_info modify_tcp[] = {
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_tbl_resource *tbl;
 
 	if (egress) {
-		tbl = &priv->tx_tbl[table_id];
+		tbl = &sh->tx_tbl[table_id];
 		if (!tbl->obj)
 			tbl->obj = mlx5_glue->dr_create_flow_tbl
-				(priv->tx_ns, table_id);
+				(sh->tx_ns, table_id);
 	} else {
-		tbl = &priv->rx_tbl[table_id];
+		tbl = &sh->rx_tbl[table_id];
 		if (!tbl->obj)
 			tbl->obj = mlx5_glue->dr_create_flow_tbl
-				(priv->rx_ns, table_id);
+				(sh->rx_ns, table_id);
 	}
 	if (!tbl->obj) {
 		rte_flow_error_set(error, ENOMEM,
@@ -2946,6 +2950,7 @@ struct field_modify_info modify_tcp[] = {
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_dv_matcher *cache_matcher;
 	struct mlx5dv_flow_matcher_attr dv_attr = {
 		.type = IBV_FLOW_ATTR_NORMAL,
@@ -2957,7 +2962,7 @@ struct field_modify_info modify_tcp[] = {
 #endif
 
 	/* Lookup from cache. */
-	LIST_FOREACH(cache_matcher, &priv->matchers, next) {
+	LIST_FOREACH(cache_matcher, &sh->matchers, next) {
 		if (matcher->crc == cache_matcher->crc &&
 		    matcher->priority == cache_matcher->priority &&
 		    matcher->egress == cache_matcher->egress &&
@@ -3001,8 +3006,7 @@ struct field_modify_info modify_tcp[] = {
 	if (matcher->egress)
 		dv_attr.flags |= IBV_FLOW_ATTR_FLAGS_EGRESS;
 	cache_matcher->matcher_object =
-		mlx5_glue->dv_create_flow_matcher(priv->sh->ctx, &dv_attr,
-						  tbl->obj);
+		mlx5_glue->dv_create_flow_matcher(sh->ctx, &dv_attr, tbl->obj);
 	if (!cache_matcher->matcher_object) {
 		rte_free(cache_matcher);
 #ifdef HAVE_MLX5DV_DR
@@ -3013,7 +3017,7 @@ struct field_modify_info modify_tcp[] = {
 					  NULL, "cannot create matcher");
 	}
 	rte_atomic32_inc(&cache_matcher->refcnt);
-	LIST_INSERT_HEAD(&priv->matchers, cache_matcher, next);
+	LIST_INSERT_HEAD(&sh->matchers, cache_matcher, next);
 	dev_flow->dv.matcher = cache_matcher;
 	DRV_LOG(DEBUG, "priority %hd new %s matcher %p: refcnt %d",
 		cache_matcher->priority,
@@ -3069,10 +3073,11 @@ struct field_modify_info modify_tcp[] = {
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_dv_tag_resource *cache_resource;
 
 	/* Lookup a matching resource from cache. */
-	LIST_FOREACH(cache_resource, &priv->tags, next) {
+	LIST_FOREACH(cache_resource, &sh->tags, next) {
 		if (resource->tag == cache_resource->tag) {
 			DRV_LOG(DEBUG, "tag resource %p: refcnt %d++",
 				(void *)cache_resource,
@@ -3099,7 +3104,7 @@ struct field_modify_info modify_tcp[] = {
 	}
 	rte_atomic32_init(&cache_resource->refcnt);
 	rte_atomic32_inc(&cache_resource->refcnt);
-	LIST_INSERT_HEAD(&priv->tags, cache_resource, next);
+	LIST_INSERT_HEAD(&sh->tags, cache_resource, next);
 	dev_flow->flow->tag_resource = cache_resource;
 	DRV_LOG(DEBUG, "new tag resource %p: refcnt %d++",
 		(void *)cache_resource,
@@ -3676,6 +3681,7 @@ struct field_modify_info modify_tcp[] = {
 {
 	struct mlx5_flow_dv_matcher *matcher = flow->dv.matcher;
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_tbl_resource *tbl;
 
 	assert(matcher->matcher_object);
@@ -3687,9 +3693,9 @@ struct field_modify_info modify_tcp[] = {
 			   (matcher->matcher_object));
 		LIST_REMOVE(matcher, next);
 		if (matcher->egress)
-			tbl = &priv->tx_tbl[matcher->group];
+			tbl = &sh->tx_tbl[matcher->group];
 		else
-			tbl = &priv->rx_tbl[matcher->group];
+			tbl = &sh->rx_tbl[matcher->group];
 		flow_dv_tbl_resource_release(tbl);
 		rte_free(matcher);
 		DRV_LOG(DEBUG, "port %u matcher %p: removed",
-- 
1.8.3.1


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

* [dpdk-dev] [PATCH 4/4] net/mlx5: add mutex for shared DV/DR structures
  2019-04-02  6:22 [dpdk-dev] [PATCH 0/4] support DR/DV flows over shared IB context Viacheslav Ovsiienko
                   ` (3 preceding siblings ...)
  2019-04-02  6:22 ` [dpdk-dev] [PATCH 3/4] net/mlx5: share DV/DR flow related structures Viacheslav Ovsiienko
@ 2019-04-02  6:22 ` Viacheslav Ovsiienko
  2019-04-02  6:22   ` Viacheslav Ovsiienko
  2019-04-02 19:09   ` Shahaf Shuler
  2019-04-04 13:04 ` [dpdk-dev] [PATCH v2 0/2] support Direct Rules flows over shared IB context Viacheslav Ovsiienko
  5 siblings, 2 replies; 28+ messages in thread
From: Viacheslav Ovsiienko @ 2019-04-02  6:22 UTC (permalink / raw)
  To: dev; +Cc: shahafs

This patch introduces the mutex for shared DV/DR structures.
Application may have multiple threads (but single dedicated
thread per port). Due to sharing the IB context in the
multiport IB device configurations we should synchronize access
to the shared DV/DR flow structures.

Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
---
 drivers/net/mlx5/mlx5.c         |   6 +++
 drivers/net/mlx5/mlx5.h         |   1 +
 drivers/net/mlx5/mlx5_flow_dv.c | 103 ++++++++++++++++++++++++++++++++++++++--
 3 files changed, 106 insertions(+), 4 deletions(-)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 369b698..96ad4c6 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -312,6 +312,7 @@ struct mlx5_dev_spawn_data {
 mlx5_alloc_shared_dv(struct mlx5_priv *priv)
 {
 	struct mlx5_ibv_shared *sh = priv->sh;
+	pthread_mutexattr_t mattr;
 	int err = 0;
 	void *ns;
 
@@ -336,6 +337,10 @@ struct mlx5_dev_spawn_data {
 		err = errno;
 		goto error;
 	}
+	pthread_mutexattr_init(&mattr);
+	pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE);
+	pthread_mutex_init(&sh->dv_mutex, &mattr);
+	pthread_mutexattr_destroy(&mattr);
 	sh->tx_ns = ns;
 	sh->dv_refcnt++;
 	priv->dv_shared = 1;
@@ -381,6 +386,7 @@ struct mlx5_dev_spawn_data {
 		mlx5dv_dr_destroy_ns(sh->tx_ns);
 		sh->tx_ns = NULL;
 	}
+	pthread_mutex_destroy(&sh->dv_mutex);
 }
 #endif
 
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index e67227f..4f6c1b7 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -223,6 +223,7 @@ struct mlx5_ibv_shared {
 	char ibdev_path[IBV_SYSFS_PATH_MAX]; /* IB device path for secondary */
 	struct ibv_device_attr_ex device_attr; /* Device properties. */
 	/* Shared DV/DR flow data section. */
+	pthread_mutex_t dv_mutex; /* DV context mutex. */
 	uint32_t dv_refcnt; /* DV/DR data reference counter. */
 	void *rx_ns; /* RX Direct Rules name space handle. */
 	struct mlx5_flow_tbl_resource rx_tbl[MLX5_MAX_TABLES];
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 4912fc8..737011a 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -125,6 +125,45 @@ struct field_modify_info modify_tcp[] = {
 };
 
 /**
+ * Acquire the synchronizing object to protect multithreaded access
+ * to shared dv context. Lock occurs only if context is actually
+ * shared, i.e. we have multiport IB device and representors are
+ * created.
+ *
+ * @param[in] dev
+ *   Pointer to the rte_eth_dev structure.
+ */
+static void
+flow_d_shared_lock(struct rte_eth_dev *dev)
+{
+	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
+
+	if (sh->dv_refcnt > 1) {
+		int ret;
+
+		ret = pthread_mutex_lock(&sh->dv_mutex);
+		assert(!ret);
+		(void)ret;
+	}
+}
+
+static void
+flow_d_shared_unlock(struct rte_eth_dev *dev)
+{
+	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
+
+	if (sh->dv_refcnt > 1) {
+		int ret;
+
+		ret = pthread_mutex_unlock(&sh->dv_mutex);
+		assert(!ret);
+		(void)ret;
+	}
+}
+
+/**
  * Convert modify-header action to DV specification.
  *
  * @param[in] item
@@ -3958,14 +3997,70 @@ struct field_modify_info modify_tcp[] = {
 	return ret;
 }
 
+/*
+ * Mutex-protected thunk to flow_dv_translate().
+ */
+static int
+flow_d_translate(struct rte_eth_dev *dev,
+		 struct mlx5_flow *dev_flow,
+		 const struct rte_flow_attr *attr,
+		 const struct rte_flow_item items[],
+		 const struct rte_flow_action actions[],
+		 struct rte_flow_error *error)
+{
+	int ret;
+
+	flow_d_shared_lock(dev);
+	ret = flow_dv_translate(dev, dev_flow, attr, items, actions, error);
+	flow_d_shared_unlock(dev);
+	return ret;
+}
+
+/*
+ * Mutex-protected thunk to flow_dv_apply().
+ */
+static int
+flow_d_apply(struct rte_eth_dev *dev,
+	     struct rte_flow *flow,
+	     struct rte_flow_error *error)
+{
+	int ret;
+
+	flow_d_shared_lock(dev);
+	ret = flow_dv_apply(dev, flow, error);
+	flow_d_shared_unlock(dev);
+	return ret;
+}
+
+/*
+ * Mutex-protected thunk to flow_dv_remove().
+ */
+static void
+flow_d_remove(struct rte_eth_dev *dev, struct rte_flow *flow)
+{
+	flow_d_shared_lock(dev);
+	flow_dv_remove(dev, flow);
+	flow_d_shared_unlock(dev);
+}
+
+/*
+ * Mutex-protected thunk to flow_dv_destroy().
+ */
+static void
+flow_d_destroy(struct rte_eth_dev *dev, struct rte_flow *flow)
+{
+	flow_d_shared_lock(dev);
+	flow_dv_destroy(dev, flow);
+	flow_d_shared_unlock(dev);
+}
 
 const struct mlx5_flow_driver_ops mlx5_flow_dv_drv_ops = {
 	.validate = flow_dv_validate,
 	.prepare = flow_dv_prepare,
-	.translate = flow_dv_translate,
-	.apply = flow_dv_apply,
-	.remove = flow_dv_remove,
-	.destroy = flow_dv_destroy,
+	.translate = flow_d_translate,
+	.apply = flow_d_apply,
+	.remove = flow_d_remove,
+	.destroy = flow_d_destroy,
 	.query = flow_dv_query,
 };
 
-- 
1.8.3.1

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

* [dpdk-dev] [PATCH 4/4] net/mlx5: add mutex for shared DV/DR structures
  2019-04-02  6:22 ` [dpdk-dev] [PATCH 4/4] net/mlx5: add mutex for shared DV/DR structures Viacheslav Ovsiienko
@ 2019-04-02  6:22   ` Viacheslav Ovsiienko
  2019-04-02 19:09   ` Shahaf Shuler
  1 sibling, 0 replies; 28+ messages in thread
From: Viacheslav Ovsiienko @ 2019-04-02  6:22 UTC (permalink / raw)
  To: dev; +Cc: shahafs

This patch introduces the mutex for shared DV/DR structures.
Application may have multiple threads (but single dedicated
thread per port). Due to sharing the IB context in the
multiport IB device configurations we should synchronize access
to the shared DV/DR flow structures.

Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
---
 drivers/net/mlx5/mlx5.c         |   6 +++
 drivers/net/mlx5/mlx5.h         |   1 +
 drivers/net/mlx5/mlx5_flow_dv.c | 103 ++++++++++++++++++++++++++++++++++++++--
 3 files changed, 106 insertions(+), 4 deletions(-)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 369b698..96ad4c6 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -312,6 +312,7 @@ struct mlx5_dev_spawn_data {
 mlx5_alloc_shared_dv(struct mlx5_priv *priv)
 {
 	struct mlx5_ibv_shared *sh = priv->sh;
+	pthread_mutexattr_t mattr;
 	int err = 0;
 	void *ns;
 
@@ -336,6 +337,10 @@ struct mlx5_dev_spawn_data {
 		err = errno;
 		goto error;
 	}
+	pthread_mutexattr_init(&mattr);
+	pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE);
+	pthread_mutex_init(&sh->dv_mutex, &mattr);
+	pthread_mutexattr_destroy(&mattr);
 	sh->tx_ns = ns;
 	sh->dv_refcnt++;
 	priv->dv_shared = 1;
@@ -381,6 +386,7 @@ struct mlx5_dev_spawn_data {
 		mlx5dv_dr_destroy_ns(sh->tx_ns);
 		sh->tx_ns = NULL;
 	}
+	pthread_mutex_destroy(&sh->dv_mutex);
 }
 #endif
 
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index e67227f..4f6c1b7 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -223,6 +223,7 @@ struct mlx5_ibv_shared {
 	char ibdev_path[IBV_SYSFS_PATH_MAX]; /* IB device path for secondary */
 	struct ibv_device_attr_ex device_attr; /* Device properties. */
 	/* Shared DV/DR flow data section. */
+	pthread_mutex_t dv_mutex; /* DV context mutex. */
 	uint32_t dv_refcnt; /* DV/DR data reference counter. */
 	void *rx_ns; /* RX Direct Rules name space handle. */
 	struct mlx5_flow_tbl_resource rx_tbl[MLX5_MAX_TABLES];
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 4912fc8..737011a 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -125,6 +125,45 @@ struct field_modify_info modify_tcp[] = {
 };
 
 /**
+ * Acquire the synchronizing object to protect multithreaded access
+ * to shared dv context. Lock occurs only if context is actually
+ * shared, i.e. we have multiport IB device and representors are
+ * created.
+ *
+ * @param[in] dev
+ *   Pointer to the rte_eth_dev structure.
+ */
+static void
+flow_d_shared_lock(struct rte_eth_dev *dev)
+{
+	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
+
+	if (sh->dv_refcnt > 1) {
+		int ret;
+
+		ret = pthread_mutex_lock(&sh->dv_mutex);
+		assert(!ret);
+		(void)ret;
+	}
+}
+
+static void
+flow_d_shared_unlock(struct rte_eth_dev *dev)
+{
+	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
+
+	if (sh->dv_refcnt > 1) {
+		int ret;
+
+		ret = pthread_mutex_unlock(&sh->dv_mutex);
+		assert(!ret);
+		(void)ret;
+	}
+}
+
+/**
  * Convert modify-header action to DV specification.
  *
  * @param[in] item
@@ -3958,14 +3997,70 @@ struct field_modify_info modify_tcp[] = {
 	return ret;
 }
 
+/*
+ * Mutex-protected thunk to flow_dv_translate().
+ */
+static int
+flow_d_translate(struct rte_eth_dev *dev,
+		 struct mlx5_flow *dev_flow,
+		 const struct rte_flow_attr *attr,
+		 const struct rte_flow_item items[],
+		 const struct rte_flow_action actions[],
+		 struct rte_flow_error *error)
+{
+	int ret;
+
+	flow_d_shared_lock(dev);
+	ret = flow_dv_translate(dev, dev_flow, attr, items, actions, error);
+	flow_d_shared_unlock(dev);
+	return ret;
+}
+
+/*
+ * Mutex-protected thunk to flow_dv_apply().
+ */
+static int
+flow_d_apply(struct rte_eth_dev *dev,
+	     struct rte_flow *flow,
+	     struct rte_flow_error *error)
+{
+	int ret;
+
+	flow_d_shared_lock(dev);
+	ret = flow_dv_apply(dev, flow, error);
+	flow_d_shared_unlock(dev);
+	return ret;
+}
+
+/*
+ * Mutex-protected thunk to flow_dv_remove().
+ */
+static void
+flow_d_remove(struct rte_eth_dev *dev, struct rte_flow *flow)
+{
+	flow_d_shared_lock(dev);
+	flow_dv_remove(dev, flow);
+	flow_d_shared_unlock(dev);
+}
+
+/*
+ * Mutex-protected thunk to flow_dv_destroy().
+ */
+static void
+flow_d_destroy(struct rte_eth_dev *dev, struct rte_flow *flow)
+{
+	flow_d_shared_lock(dev);
+	flow_dv_destroy(dev, flow);
+	flow_d_shared_unlock(dev);
+}
 
 const struct mlx5_flow_driver_ops mlx5_flow_dv_drv_ops = {
 	.validate = flow_dv_validate,
 	.prepare = flow_dv_prepare,
-	.translate = flow_dv_translate,
-	.apply = flow_dv_apply,
-	.remove = flow_dv_remove,
-	.destroy = flow_dv_destroy,
+	.translate = flow_d_translate,
+	.apply = flow_d_apply,
+	.remove = flow_d_remove,
+	.destroy = flow_d_destroy,
 	.query = flow_dv_query,
 };
 
-- 
1.8.3.1


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

* Re: [dpdk-dev] [PATCH 1/4] net/mlx5: add DV/DR flow data alloc/free routines
  2019-04-02  6:22 ` [dpdk-dev] [PATCH 1/4] net/mlx5: add DV/DR flow data alloc/free routines Viacheslav Ovsiienko
  2019-04-02  6:22   ` Viacheslav Ovsiienko
@ 2019-04-02 19:09   ` Shahaf Shuler
  2019-04-02 19:09     ` Shahaf Shuler
  1 sibling, 1 reply; 28+ messages in thread
From: Shahaf Shuler @ 2019-04-02 19:09 UTC (permalink / raw)
  To: Slava Ovsiienko, dev

Tuesday, April 2, 2019 9:23 AM, Viacheslav Ovsiienko:
> Subject: [PATCH 1/4] net/mlx5: add DV/DR flow data alloc/free routines

DV and DR are acronyms which are Mellanox specific. The title should be written in a way that even non-Mellanox developer will easily understand it. 

> 
> We are going to share the DR/DV flow device data structures between
> master and representors in the E-Switch configurations over multiport IB
> device.
> 
> The code of initializing and destroying these data is moved to dedicated
> routines, this is just a preparation step for actual data sharing.
> 
> Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
> ---
>  drivers/net/mlx5/mlx5.c | 90
> ++++++++++++++++++++++++++++++++++++++++++-------
>  1 file changed, 77 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index
> b59fc58..9de122d 100644
> --- a/drivers/net/mlx5/mlx5.c
> +++ b/drivers/net/mlx5/mlx5.c
> @@ -296,6 +296,73 @@ struct mlx5_dev_spawn_data {
>  	pthread_mutex_unlock(&mlx5_ibv_list_mutex);
>  }
> 
> +#ifdef HAVE_MLX5DV_DR

Function prototypes should not be under ifdef. Ifdef should be used in the function body.
It much simplify the code readability of the function which calls them. 

> +/**
> + * Initialize DV/DR related data within private structure.
> + * This is preparation step for the data sharing.

Per my understanding below those are only direct rule objects.

> + *
> + * @param[in] priv
> + *   Pointer to the private device data structure.
> + *
> + * @return
> + *   Zero on success, positive error code otherwise.
> + */
> +static int
> +mlx5_alloc_shared_dv(struct mlx5_priv *priv) {
> +	struct mlx5_ibv_shared *sh = priv->sh;
> +	int err = 0;
> +	void *ns;
> +
> +	ns = mlx5dv_dr_create_ns(sh->ctx,
> MLX5DV_DR_NS_DOMAIN_INGRESS_BYPASS);
> +	if (!ns) {
> +		DRV_LOG(ERR, "ingress mlx5dv_dr_create_ns failed");
> +		err = errno;
> +		goto error;
> +	}
> +	priv->rx_ns = ns;
> +	ns = mlx5dv_dr_create_ns(sh->ctx,
> MLX5DV_DR_NS_DOMAIN_EGRESS_BYPASS);
> +	if (!ns) {
> +		DRV_LOG(ERR, "egress mlx5dv_dr_create_ns failed");
> +		err = errno;
> +		goto error;
> +	}
> +	priv->tx_ns = ns;
> +	return 0;
> +
> +error:
> +       /* Rollback the created objects. */
> +	if (priv->rx_ns) {
> +		mlx5dv_dr_destroy_ns(priv->rx_ns);
> +		priv->rx_ns = NULL;
> +	}
> +	if (priv->tx_ns) {
> +		mlx5dv_dr_destroy_ns(priv->tx_ns);
> +		priv->tx_ns = NULL;
> +	}
> +	return err;
> +}
> +
> +/**
> + * Destroy DV/DR related structures within private structure.
> + *
> + * @param[in] priv
> + *   Pointer to the private device data structure.
> + */
> +static void
> +mlx5_free_shared_dv(struct mlx5_priv *priv) {
> +	if (priv->rx_ns) {
> +		mlx5dv_dr_destroy_ns(priv->rx_ns);
> +		priv->rx_ns = NULL;
> +	}
> +	if (priv->tx_ns) {
> +		mlx5dv_dr_destroy_ns(priv->tx_ns);
> +		priv->tx_ns = NULL;
> +	}
> +}
> +#endif
> +
>  /**
>   * Prepare shared data between primary and secondary process.
>   */
> @@ -446,6 +513,9 @@ struct mlx5_dev_spawn_data {
>  	mlx5_mprq_free_mp(dev);
>  	mlx5_mr_release(dev);
>  	assert(priv->sh);
> +#ifdef HAVE_MLX5DV_DR

Have the ifdef inside the shared_dv and remove it from here. 

> +	mlx5_free_shared_dv(priv);
> +#endif
>  	if (priv->sh)
>  		mlx5_free_shared_ibctx(priv->sh);
>  	priv->sh = NULL;
> @@ -1363,20 +1433,11 @@ struct mlx5_dev_spawn_data {
>  		}
>  	}
>  #ifdef HAVE_MLX5DV_DR
> -		priv->rx_ns = mlx5dv_dr_create_ns
> -			(sh->ctx,
> MLX5DV_DR_NS_DOMAIN_INGRESS_BYPASS);
> -		if (priv->rx_ns == NULL) {
> -			DRV_LOG(ERR, "mlx5dv_dr_create_ns failed");
> -			err = errno;
> -			goto error;
> -		}
> -		priv->tx_ns = mlx5dv_dr_create_ns(sh->ctx,
> -
> MLX5DV_DR_NS_DOMAIN_EGRESS_BYPASS);
> -		if (priv->tx_ns == NULL) {
> -			DRV_LOG(ERR, "mlx5dv_dr_create_ns failed");
> -			err = errno;
> +	if (config.dv_flow_en) {
> +		err = mlx5_alloc_shared_dv(priv);
> +		if (err)
>  			goto error;
> -		}
> +	}
>  #endif
>  	TAILQ_INIT(&priv->flows);
>  	TAILQ_INIT(&priv->ctrl_flows);
> @@ -1429,6 +1490,9 @@ struct mlx5_dev_spawn_data {
>  	return eth_dev;
>  error:
>  	if (priv) {
> +#ifdef HAVE_MLX5DV_DR
> +		mlx5_free_shared_dv(priv);
> +#endif
>  		if (priv->nl_socket_route >= 0)
>  			close(priv->nl_socket_route);
>  		if (priv->nl_socket_rdma >= 0)
> --
> 1.8.3.1

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

* Re: [dpdk-dev] [PATCH 1/4] net/mlx5: add DV/DR flow data alloc/free routines
  2019-04-02 19:09   ` Shahaf Shuler
@ 2019-04-02 19:09     ` Shahaf Shuler
  0 siblings, 0 replies; 28+ messages in thread
From: Shahaf Shuler @ 2019-04-02 19:09 UTC (permalink / raw)
  To: Slava Ovsiienko, dev

Tuesday, April 2, 2019 9:23 AM, Viacheslav Ovsiienko:
> Subject: [PATCH 1/4] net/mlx5: add DV/DR flow data alloc/free routines

DV and DR are acronyms which are Mellanox specific. The title should be written in a way that even non-Mellanox developer will easily understand it. 

> 
> We are going to share the DR/DV flow device data structures between
> master and representors in the E-Switch configurations over multiport IB
> device.
> 
> The code of initializing and destroying these data is moved to dedicated
> routines, this is just a preparation step for actual data sharing.
> 
> Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
> ---
>  drivers/net/mlx5/mlx5.c | 90
> ++++++++++++++++++++++++++++++++++++++++++-------
>  1 file changed, 77 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index
> b59fc58..9de122d 100644
> --- a/drivers/net/mlx5/mlx5.c
> +++ b/drivers/net/mlx5/mlx5.c
> @@ -296,6 +296,73 @@ struct mlx5_dev_spawn_data {
>  	pthread_mutex_unlock(&mlx5_ibv_list_mutex);
>  }
> 
> +#ifdef HAVE_MLX5DV_DR

Function prototypes should not be under ifdef. Ifdef should be used in the function body.
It much simplify the code readability of the function which calls them. 

> +/**
> + * Initialize DV/DR related data within private structure.
> + * This is preparation step for the data sharing.

Per my understanding below those are only direct rule objects.

> + *
> + * @param[in] priv
> + *   Pointer to the private device data structure.
> + *
> + * @return
> + *   Zero on success, positive error code otherwise.
> + */
> +static int
> +mlx5_alloc_shared_dv(struct mlx5_priv *priv) {
> +	struct mlx5_ibv_shared *sh = priv->sh;
> +	int err = 0;
> +	void *ns;
> +
> +	ns = mlx5dv_dr_create_ns(sh->ctx,
> MLX5DV_DR_NS_DOMAIN_INGRESS_BYPASS);
> +	if (!ns) {
> +		DRV_LOG(ERR, "ingress mlx5dv_dr_create_ns failed");
> +		err = errno;
> +		goto error;
> +	}
> +	priv->rx_ns = ns;
> +	ns = mlx5dv_dr_create_ns(sh->ctx,
> MLX5DV_DR_NS_DOMAIN_EGRESS_BYPASS);
> +	if (!ns) {
> +		DRV_LOG(ERR, "egress mlx5dv_dr_create_ns failed");
> +		err = errno;
> +		goto error;
> +	}
> +	priv->tx_ns = ns;
> +	return 0;
> +
> +error:
> +       /* Rollback the created objects. */
> +	if (priv->rx_ns) {
> +		mlx5dv_dr_destroy_ns(priv->rx_ns);
> +		priv->rx_ns = NULL;
> +	}
> +	if (priv->tx_ns) {
> +		mlx5dv_dr_destroy_ns(priv->tx_ns);
> +		priv->tx_ns = NULL;
> +	}
> +	return err;
> +}
> +
> +/**
> + * Destroy DV/DR related structures within private structure.
> + *
> + * @param[in] priv
> + *   Pointer to the private device data structure.
> + */
> +static void
> +mlx5_free_shared_dv(struct mlx5_priv *priv) {
> +	if (priv->rx_ns) {
> +		mlx5dv_dr_destroy_ns(priv->rx_ns);
> +		priv->rx_ns = NULL;
> +	}
> +	if (priv->tx_ns) {
> +		mlx5dv_dr_destroy_ns(priv->tx_ns);
> +		priv->tx_ns = NULL;
> +	}
> +}
> +#endif
> +
>  /**
>   * Prepare shared data between primary and secondary process.
>   */
> @@ -446,6 +513,9 @@ struct mlx5_dev_spawn_data {
>  	mlx5_mprq_free_mp(dev);
>  	mlx5_mr_release(dev);
>  	assert(priv->sh);
> +#ifdef HAVE_MLX5DV_DR

Have the ifdef inside the shared_dv and remove it from here. 

> +	mlx5_free_shared_dv(priv);
> +#endif
>  	if (priv->sh)
>  		mlx5_free_shared_ibctx(priv->sh);
>  	priv->sh = NULL;
> @@ -1363,20 +1433,11 @@ struct mlx5_dev_spawn_data {
>  		}
>  	}
>  #ifdef HAVE_MLX5DV_DR
> -		priv->rx_ns = mlx5dv_dr_create_ns
> -			(sh->ctx,
> MLX5DV_DR_NS_DOMAIN_INGRESS_BYPASS);
> -		if (priv->rx_ns == NULL) {
> -			DRV_LOG(ERR, "mlx5dv_dr_create_ns failed");
> -			err = errno;
> -			goto error;
> -		}
> -		priv->tx_ns = mlx5dv_dr_create_ns(sh->ctx,
> -
> MLX5DV_DR_NS_DOMAIN_EGRESS_BYPASS);
> -		if (priv->tx_ns == NULL) {
> -			DRV_LOG(ERR, "mlx5dv_dr_create_ns failed");
> -			err = errno;
> +	if (config.dv_flow_en) {
> +		err = mlx5_alloc_shared_dv(priv);
> +		if (err)
>  			goto error;
> -		}
> +	}
>  #endif
>  	TAILQ_INIT(&priv->flows);
>  	TAILQ_INIT(&priv->ctrl_flows);
> @@ -1429,6 +1490,9 @@ struct mlx5_dev_spawn_data {
>  	return eth_dev;
>  error:
>  	if (priv) {
> +#ifdef HAVE_MLX5DV_DR
> +		mlx5_free_shared_dv(priv);
> +#endif
>  		if (priv->nl_socket_route >= 0)
>  			close(priv->nl_socket_route);
>  		if (priv->nl_socket_rdma >= 0)
> --
> 1.8.3.1


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

* Re: [dpdk-dev] [PATCH 2/4] net/mlx5: add reference counter for DV/DR structures
  2019-04-02  6:22 ` [dpdk-dev] [PATCH 2/4] net/mlx5: add reference counter for DV/DR structures Viacheslav Ovsiienko
  2019-04-02  6:22   ` Viacheslav Ovsiienko
@ 2019-04-02 19:09   ` Shahaf Shuler
  2019-04-02 19:09     ` Shahaf Shuler
  2019-04-03 13:27     ` Slava Ovsiienko
  1 sibling, 2 replies; 28+ messages in thread
From: Shahaf Shuler @ 2019-04-02 19:09 UTC (permalink / raw)
  To: Slava Ovsiienko, dev

Tuesday, April 2, 2019 9:23 AM, Viacheslav Ovsiienko:
> Subject: [PATCH 2/4] net/mlx5: add reference counter for DV/DR structures

Same comment about the title. 

> 
> This patch introduces the reference counter for DV/DR flow engine
> structure, which we are going to share between master and representors in
> E-Switch configurations over multiport Infiniband device.
> 
> Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
> ---
>  drivers/net/mlx5/mlx5.c | 26 ++++++++++++++++++++++++--
> drivers/net/mlx5/mlx5.h |  4 ++++
>  2 files changed, 28 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index
> 9de122d..79e0c17 100644
> --- a/drivers/net/mlx5/mlx5.c
> +++ b/drivers/net/mlx5/mlx5.c
> @@ -299,7 +299,8 @@ struct mlx5_dev_spawn_data {  #ifdef
> HAVE_MLX5DV_DR
>  /**
>   * Initialize DV/DR related data within private structure.
> - * This is preparation step for the data sharing.
> + * Routine checks the reference counter and does actual
> + * resources creation/iniialization only if counter is zero.
>   *
>   * @param[in] priv
>   *   Pointer to the private device data structure.
> @@ -314,6 +315,14 @@ struct mlx5_dev_spawn_data {
>  	int err = 0;
>  	void *ns;
> 
> +	assert(sh);
> +	if (sh->dv_refcnt) {
> +		/* Shared DV/DR structures is already initialized. */
> +		sh->dv_refcnt++;
> +		priv->dv_shared = 1;
> +		return 0;
> +	}
> +	/* Reference counter is zero, we should initialize structures. */
>  	ns = mlx5dv_dr_create_ns(sh->ctx,
> MLX5DV_DR_NS_DOMAIN_INGRESS_BYPASS);
>  	if (!ns) {
>  		DRV_LOG(ERR, "ingress mlx5dv_dr_create_ns failed"); @@ -
> 328,6 +337,8 @@ struct mlx5_dev_spawn_data {
>  		goto error;
>  	}
>  	priv->tx_ns = ns;
> +	sh->dv_refcnt++;
> +	priv->dv_shared = 1;
>  	return 0;
> 
>  error:
> @@ -352,6 +363,16 @@ struct mlx5_dev_spawn_data {  static void
> mlx5_free_shared_dv(struct mlx5_priv *priv)  {
> +	struct mlx5_ibv_shared *sh;
> +
> +	if (!priv->dv_shared)
> +		return;
> +	priv->dv_shared = 0;
> +	sh = priv->sh;
> +	assert(sh);
> +	assert(sh->dv_refcnt);
> +	if (sh->dv_refcnt && --sh->dv_refcnt)
> +		return;
>  	if (priv->rx_ns) {
>  		mlx5dv_dr_destroy_ns(priv->rx_ns);
>  		priv->rx_ns = NULL;
> @@ -1491,7 +1512,8 @@ struct mlx5_dev_spawn_data {
>  error:
>  	if (priv) {
>  #ifdef HAVE_MLX5DV_DR
> -		mlx5_free_shared_dv(priv);
> +		if (priv->sh)
> +			mlx5_free_shared_dv(priv);
>  #endif
>  		if (priv->nl_socket_route >= 0)
>  			close(priv->nl_socket_route);
> diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index
> a3d5f8e..56a2c61 100644
> --- a/drivers/net/mlx5/mlx5.h
> +++ b/drivers/net/mlx5/mlx5.h
> @@ -213,6 +213,9 @@ struct mlx5_ibv_shared {
>  	char ibdev_name[IBV_SYSFS_NAME_MAX]; /* IB device name. */
>  	char ibdev_path[IBV_SYSFS_PATH_MAX]; /* IB device path for
> secondary */
>  	struct ibv_device_attr_ex device_attr; /* Device properties. */
> +	/* Shared DV/DR flow data section. */
> +	uint32_t dv_refcnt; /* DV/DR data reference counter. */
> +	/* Shared interrupt handler section. */
>  	pthread_mutex_t intr_mutex; /* Interrupt config mutex. */
>  	uint32_t intr_cnt; /* Interrupt handler reference counter. */
>  	struct rte_intr_handle intr_handle; /* Interrupt handler for device.
> */ @@ -244,6 +247,7 @@ struct mlx5_priv {
>  	unsigned int isolated:1; /* Whether isolated mode is enabled. */
>  	unsigned int representor:1; /* Device is a port representor. */
>  	unsigned int master:1; /* Device is a E-Switch master. */
> +	unsigned int dv_shared:1; /* DV/DR data is shared. */

Why this flags is needed? Aren't we always going to share? 


>  	uint16_t domain_id; /* Switch domain identifier. */
>  	uint16_t vport_id; /* Associated VF vport index (if any). */
>  	int32_t representor_id; /* Port representor identifier. */
> --
> 1.8.3.1

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

* Re: [dpdk-dev] [PATCH 2/4] net/mlx5: add reference counter for DV/DR structures
  2019-04-02 19:09   ` Shahaf Shuler
@ 2019-04-02 19:09     ` Shahaf Shuler
  2019-04-03 13:27     ` Slava Ovsiienko
  1 sibling, 0 replies; 28+ messages in thread
From: Shahaf Shuler @ 2019-04-02 19:09 UTC (permalink / raw)
  To: Slava Ovsiienko, dev

Tuesday, April 2, 2019 9:23 AM, Viacheslav Ovsiienko:
> Subject: [PATCH 2/4] net/mlx5: add reference counter for DV/DR structures

Same comment about the title. 

> 
> This patch introduces the reference counter for DV/DR flow engine
> structure, which we are going to share between master and representors in
> E-Switch configurations over multiport Infiniband device.
> 
> Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
> ---
>  drivers/net/mlx5/mlx5.c | 26 ++++++++++++++++++++++++--
> drivers/net/mlx5/mlx5.h |  4 ++++
>  2 files changed, 28 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index
> 9de122d..79e0c17 100644
> --- a/drivers/net/mlx5/mlx5.c
> +++ b/drivers/net/mlx5/mlx5.c
> @@ -299,7 +299,8 @@ struct mlx5_dev_spawn_data {  #ifdef
> HAVE_MLX5DV_DR
>  /**
>   * Initialize DV/DR related data within private structure.
> - * This is preparation step for the data sharing.
> + * Routine checks the reference counter and does actual
> + * resources creation/iniialization only if counter is zero.
>   *
>   * @param[in] priv
>   *   Pointer to the private device data structure.
> @@ -314,6 +315,14 @@ struct mlx5_dev_spawn_data {
>  	int err = 0;
>  	void *ns;
> 
> +	assert(sh);
> +	if (sh->dv_refcnt) {
> +		/* Shared DV/DR structures is already initialized. */
> +		sh->dv_refcnt++;
> +		priv->dv_shared = 1;
> +		return 0;
> +	}
> +	/* Reference counter is zero, we should initialize structures. */
>  	ns = mlx5dv_dr_create_ns(sh->ctx,
> MLX5DV_DR_NS_DOMAIN_INGRESS_BYPASS);
>  	if (!ns) {
>  		DRV_LOG(ERR, "ingress mlx5dv_dr_create_ns failed"); @@ -
> 328,6 +337,8 @@ struct mlx5_dev_spawn_data {
>  		goto error;
>  	}
>  	priv->tx_ns = ns;
> +	sh->dv_refcnt++;
> +	priv->dv_shared = 1;
>  	return 0;
> 
>  error:
> @@ -352,6 +363,16 @@ struct mlx5_dev_spawn_data {  static void
> mlx5_free_shared_dv(struct mlx5_priv *priv)  {
> +	struct mlx5_ibv_shared *sh;
> +
> +	if (!priv->dv_shared)
> +		return;
> +	priv->dv_shared = 0;
> +	sh = priv->sh;
> +	assert(sh);
> +	assert(sh->dv_refcnt);
> +	if (sh->dv_refcnt && --sh->dv_refcnt)
> +		return;
>  	if (priv->rx_ns) {
>  		mlx5dv_dr_destroy_ns(priv->rx_ns);
>  		priv->rx_ns = NULL;
> @@ -1491,7 +1512,8 @@ struct mlx5_dev_spawn_data {
>  error:
>  	if (priv) {
>  #ifdef HAVE_MLX5DV_DR
> -		mlx5_free_shared_dv(priv);
> +		if (priv->sh)
> +			mlx5_free_shared_dv(priv);
>  #endif
>  		if (priv->nl_socket_route >= 0)
>  			close(priv->nl_socket_route);
> diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index
> a3d5f8e..56a2c61 100644
> --- a/drivers/net/mlx5/mlx5.h
> +++ b/drivers/net/mlx5/mlx5.h
> @@ -213,6 +213,9 @@ struct mlx5_ibv_shared {
>  	char ibdev_name[IBV_SYSFS_NAME_MAX]; /* IB device name. */
>  	char ibdev_path[IBV_SYSFS_PATH_MAX]; /* IB device path for
> secondary */
>  	struct ibv_device_attr_ex device_attr; /* Device properties. */
> +	/* Shared DV/DR flow data section. */
> +	uint32_t dv_refcnt; /* DV/DR data reference counter. */
> +	/* Shared interrupt handler section. */
>  	pthread_mutex_t intr_mutex; /* Interrupt config mutex. */
>  	uint32_t intr_cnt; /* Interrupt handler reference counter. */
>  	struct rte_intr_handle intr_handle; /* Interrupt handler for device.
> */ @@ -244,6 +247,7 @@ struct mlx5_priv {
>  	unsigned int isolated:1; /* Whether isolated mode is enabled. */
>  	unsigned int representor:1; /* Device is a port representor. */
>  	unsigned int master:1; /* Device is a E-Switch master. */
> +	unsigned int dv_shared:1; /* DV/DR data is shared. */

Why this flags is needed? Aren't we always going to share? 


>  	uint16_t domain_id; /* Switch domain identifier. */
>  	uint16_t vport_id; /* Associated VF vport index (if any). */
>  	int32_t representor_id; /* Port representor identifier. */
> --
> 1.8.3.1


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

* Re: [dpdk-dev] [PATCH 3/4] net/mlx5: share DV/DR flow related structures
  2019-04-02  6:22 ` [dpdk-dev] [PATCH 3/4] net/mlx5: share DV/DR flow related structures Viacheslav Ovsiienko
  2019-04-02  6:22   ` Viacheslav Ovsiienko
@ 2019-04-02 19:09   ` Shahaf Shuler
  2019-04-02 19:09     ` Shahaf Shuler
  1 sibling, 1 reply; 28+ messages in thread
From: Shahaf Shuler @ 2019-04-02 19:09 UTC (permalink / raw)
  To: Slava Ovsiienko, dev

Tuesday, April 2, 2019 9:23 AM, Viacheslav Ovsiienko:
> Subject: [PATCH 3/4] net/mlx5: share DV/DR flow related structures

Same comment about the title. 

> 
> DV/DR related structures are moved to the shared context:
>   - rx/tx namespaces, shared by master and representors
>   - rx/tx flow tables
>   - matchers
>   - encap/decap action resources
>   - flow tags (MARK actions)
>   - modify action resources
>   - jump tables

I am OK w/ the logic.
However the next commit (4/4 net/mlx5: add mutex for shared DV/DR structures) should be squashed into this one. 
Because w/o it, the concurrent flow creation/destroy between multiple devices is broken. 

> 
> Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
> ---
>  drivers/net/mlx5/mlx5.c         | 28 +++++++++++-----------
>  drivers/net/mlx5/mlx5.h         | 40 +++++++++++++++----------------
>  drivers/net/mlx5/mlx5_flow_dv.c | 52 +++++++++++++++++++++++---------
> ---------
>  3 files changed, 63 insertions(+), 57 deletions(-)
> 
> diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index
> 79e0c17..369b698 100644
> --- a/drivers/net/mlx5/mlx5.c
> +++ b/drivers/net/mlx5/mlx5.c
> @@ -329,27 +329,27 @@ struct mlx5_dev_spawn_data {
>  		err = errno;
>  		goto error;
>  	}
> -	priv->rx_ns = ns;
> +	sh->rx_ns = ns;
>  	ns = mlx5dv_dr_create_ns(sh->ctx,
> MLX5DV_DR_NS_DOMAIN_EGRESS_BYPASS);
>  	if (!ns) {
>  		DRV_LOG(ERR, "egress mlx5dv_dr_create_ns failed");
>  		err = errno;
>  		goto error;
>  	}
> -	priv->tx_ns = ns;
> +	sh->tx_ns = ns;
>  	sh->dv_refcnt++;
>  	priv->dv_shared = 1;
>  	return 0;
> 
>  error:
>         /* Rollback the created objects. */
> -	if (priv->rx_ns) {
> -		mlx5dv_dr_destroy_ns(priv->rx_ns);
> -		priv->rx_ns = NULL;
> +	if (sh->rx_ns) {
> +		mlx5dv_dr_destroy_ns(sh->rx_ns);
> +		sh->rx_ns = NULL;
>  	}
> -	if (priv->tx_ns) {
> -		mlx5dv_dr_destroy_ns(priv->tx_ns);
> -		priv->tx_ns = NULL;
> +	if (sh->tx_ns) {
> +		mlx5dv_dr_destroy_ns(sh->tx_ns);
> +		sh->tx_ns = NULL;
>  	}
>  	return err;
>  }
> @@ -373,13 +373,13 @@ struct mlx5_dev_spawn_data {
>  	assert(sh->dv_refcnt);
>  	if (sh->dv_refcnt && --sh->dv_refcnt)
>  		return;
> -	if (priv->rx_ns) {
> -		mlx5dv_dr_destroy_ns(priv->rx_ns);
> -		priv->rx_ns = NULL;
> +	if (sh->rx_ns) {
> +		mlx5dv_dr_destroy_ns(sh->rx_ns);
> +		sh->rx_ns = NULL;
>  	}
> -	if (priv->tx_ns) {
> -		mlx5dv_dr_destroy_ns(priv->tx_ns);
> -		priv->tx_ns = NULL;
> +	if (sh->tx_ns) {
> +		mlx5dv_dr_destroy_ns(sh->tx_ns);
> +		sh->tx_ns = NULL;
>  	}
>  }
>  #endif
> diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index
> 56a2c61..e67227f 100644
> --- a/drivers/net/mlx5/mlx5.h
> +++ b/drivers/net/mlx5/mlx5.h
> @@ -199,6 +199,15 @@ struct mlx5_ibv_shared_port {
>  	 */
>  };
> 
> +/* Table structure. */
> +struct mlx5_flow_tbl_resource {
> +	void *obj; /**< Pointer to DR table object. */
> +	rte_atomic32_t refcnt; /**< Reference counter. */ };
> +
> +#define MLX5_MAX_TABLES 1024
> +#define MLX5_GROUP_FACTOR 1
> +
>  /*
>   * Shared Infiniband device context for Master/Representors
>   * which belong to same IB device with multiple IB ports.
> @@ -215,6 +224,17 @@ struct mlx5_ibv_shared {
>  	struct ibv_device_attr_ex device_attr; /* Device properties. */
>  	/* Shared DV/DR flow data section. */
>  	uint32_t dv_refcnt; /* DV/DR data reference counter. */
> +	void *rx_ns; /* RX Direct Rules name space handle. */
> +	struct mlx5_flow_tbl_resource rx_tbl[MLX5_MAX_TABLES];
> +	/* RX Direct Rules tables. */
> +	void *tx_ns; /* TX Direct Rules name space handle. */
> +	struct mlx5_flow_tbl_resource tx_tbl[MLX5_MAX_TABLES];
> +	/* TX Direct Rules tables/ */
> +	LIST_HEAD(matchers, mlx5_flow_dv_matcher) matchers;
> +	LIST_HEAD(encap_decap, mlx5_flow_dv_encap_decap_resource)
> encaps_decaps;
> +	LIST_HEAD(modify_cmd, mlx5_flow_dv_modify_hdr_resource)
> modify_cmds;
> +	LIST_HEAD(tag, mlx5_flow_dv_tag_resource) tags;
> +	LIST_HEAD(jump, mlx5_flow_dv_jump_tbl_resource) jump_tbl;
>  	/* Shared interrupt handler section. */
>  	pthread_mutex_t intr_mutex; /* Interrupt config mutex. */
>  	uint32_t intr_cnt; /* Interrupt handler reference counter. */ @@ -
> 222,15 +242,6 @@ struct mlx5_ibv_shared {
>  	struct mlx5_ibv_shared_port port[]; /* per device port data array. */
> };
> 
> -/* Table structure. */
> -struct mlx5_flow_tbl_resource {
> -	void *obj; /**< Pointer to DR table object. */
> -	rte_atomic32_t refcnt; /**< Reference counter. */
> -};
> -
> -#define MLX5_MAX_TABLES 1024
> -#define MLX5_GROUP_FACTOR 1
> -
>  struct mlx5_priv {
>  	LIST_ENTRY(mlx5_priv) mem_event_cb;
>  	/**< Called by memory event callback. */ @@ -279,11 +290,6 @@
> struct mlx5_priv {
>  	LIST_HEAD(txqibv, mlx5_txq_ibv) txqsibv; /* Verbs Tx queues. */
>  	/* Verbs Indirection tables. */
>  	LIST_HEAD(ind_tables, mlx5_ind_table_ibv) ind_tbls;
> -	LIST_HEAD(matchers, mlx5_flow_dv_matcher) matchers;
> -	LIST_HEAD(encap_decap, mlx5_flow_dv_encap_decap_resource)
> encaps_decaps;
> -	LIST_HEAD(modify_cmd, mlx5_flow_dv_modify_hdr_resource)
> modify_cmds;
> -	LIST_HEAD(tag, mlx5_flow_dv_tag_resource) tags;
> -	LIST_HEAD(jump, mlx5_flow_dv_jump_tbl_resource) jump_tbl;
>  	/* Pointer to next element. */
>  	rte_atomic32_t refcnt; /**< Reference counter. */
>  	struct ibv_flow_action *verbs_action;
> @@ -308,12 +314,6 @@ struct mlx5_priv {
>  	/* UAR same-page access control required in 32bit implementations.
> */  #endif
>  	struct mlx5_flow_tcf_context *tcf_context; /* TC flower context. */
> -	void *rx_ns; /* RX Direct Rules name space handle. */
> -	struct mlx5_flow_tbl_resource rx_tbl[MLX5_MAX_TABLES];
> -	/* RX Direct Rules tables. */
> -	void *tx_ns; /* TX Direct Rules name space handle. */
> -	struct mlx5_flow_tbl_resource tx_tbl[MLX5_MAX_TABLES];
> -	/* TX Direct Rules tables/ */
>  };
> 
>  #define PORT_ID(priv) ((priv)->dev_data->port_id) diff --git
> a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
> index f1dd00a..4912fc8 100644
> --- a/drivers/net/mlx5/mlx5_flow_dv.c
> +++ b/drivers/net/mlx5/mlx5_flow_dv.c
> @@ -804,18 +804,19 @@ struct field_modify_info modify_tcp[] = {
>  			 struct rte_flow_error *error)
>  {
>  	struct mlx5_priv *priv = dev->data->dev_private;
> +	struct mlx5_ibv_shared *sh = priv->sh;
>  	struct mlx5_flow_dv_encap_decap_resource *cache_resource;
>  	struct rte_flow *flow = dev_flow->flow;
>  	struct mlx5dv_dr_ns *ns;
> 
>  	resource->flags = flow->group ? 0 : 1;
>  	if (flow->ingress)
> -		ns = priv->rx_ns;
> +		ns = sh->rx_ns;
>  	else
> -		ns = priv->tx_ns;
> +		ns = sh->tx_ns;
> 
>  	/* Lookup a matching resource from cache. */
> -	LIST_FOREACH(cache_resource, &priv->encaps_decaps, next) {
> +	LIST_FOREACH(cache_resource, &sh->encaps_decaps, next) {
>  		if (resource->reformat_type == cache_resource-
> >reformat_type &&
>  		    resource->ft_type == cache_resource->ft_type &&
>  		    resource->flags == cache_resource->flags && @@ -840,7
> +841,7 @@ struct field_modify_info modify_tcp[] = {
>  	*cache_resource = *resource;
>  	cache_resource->verbs_action =
>  		mlx5_glue->dv_create_flow_action_packet_reformat
> -			(priv->sh->ctx, cache_resource->reformat_type,
> +			(sh->ctx, cache_resource->reformat_type,
>  			 cache_resource->ft_type, ns, cache_resource-
> >flags,
>  			 cache_resource->size,
>  			 (cache_resource->size ? cache_resource->buf :
> NULL)); @@ -852,7 +853,7 @@ struct field_modify_info modify_tcp[] = {
>  	}
>  	rte_atomic32_init(&cache_resource->refcnt);
>  	rte_atomic32_inc(&cache_resource->refcnt);
> -	LIST_INSERT_HEAD(&priv->encaps_decaps, cache_resource, next);
> +	LIST_INSERT_HEAD(&sh->encaps_decaps, cache_resource, next);
>  	dev_flow->dv.encap_decap = cache_resource;
>  	DRV_LOG(DEBUG, "new encap/decap resource %p: refcnt %d++",
>  		(void *)cache_resource,
> @@ -883,10 +884,11 @@ struct field_modify_info modify_tcp[] = {
>  			 struct rte_flow_error *error)
>  {
>  	struct mlx5_priv *priv = dev->data->dev_private;
> +	struct mlx5_ibv_shared *sh = priv->sh;
>  	struct mlx5_flow_dv_jump_tbl_resource *cache_resource;
> 
>  	/* Lookup a matching resource from cache. */
> -	LIST_FOREACH(cache_resource, &priv->jump_tbl, next) {
> +	LIST_FOREACH(cache_resource, &sh->jump_tbl, next) {
>  		if (resource->tbl == cache_resource->tbl) {
>  			DRV_LOG(DEBUG, "jump table resource resource
> %p: refcnt %d++",
>  				(void *)cache_resource,
> @@ -914,7 +916,7 @@ struct field_modify_info modify_tcp[] = {
>  	}
>  	rte_atomic32_init(&cache_resource->refcnt);
>  	rte_atomic32_inc(&cache_resource->refcnt);
> -	LIST_INSERT_HEAD(&priv->jump_tbl, cache_resource, next);
> +	LIST_INSERT_HEAD(&sh->jump_tbl, cache_resource, next);
>  	dev_flow->dv.jump = cache_resource;
>  	DRV_LOG(DEBUG, "new jump table  resource %p: refcnt %d++",
>  		(void *)cache_resource,
> @@ -1538,14 +1540,15 @@ struct field_modify_info modify_tcp[] = {
>  			 struct rte_flow_error *error)
>  {
>  	struct mlx5_priv *priv = dev->data->dev_private;
> +	struct mlx5_ibv_shared *sh = priv->sh;
>  	struct mlx5_flow_dv_modify_hdr_resource *cache_resource;
> 
>  	struct mlx5dv_dr_ns *ns =
>  		resource->ft_type == MLX5DV_FLOW_TABLE_TYPE_NIC_TX
> ?
> -		priv->tx_ns : priv->rx_ns;
> +		sh->tx_ns : sh->rx_ns;
> 
>  	/* Lookup a matching resource from cache. */
> -	LIST_FOREACH(cache_resource, &priv->modify_cmds, next) {
> +	LIST_FOREACH(cache_resource, &sh->modify_cmds, next) {
>  		if (resource->ft_type == cache_resource->ft_type &&
>  		    resource->actions_num == cache_resource->actions_num
> &&
>  		    !memcmp((const void *)resource->actions, @@ -1569,7
> +1572,7 @@ struct field_modify_info modify_tcp[] = {
>  	*cache_resource = *resource;
>  	cache_resource->verbs_action =
>  		mlx5_glue->dv_create_flow_action_modify_header
> -					(priv->sh->ctx, cache_resource-
> >ft_type,
> +					(sh->ctx, cache_resource->ft_type,
>  					 ns, 0,
>  					 cache_resource->actions_num *
>  					 sizeof(cache_resource->actions[0]),
> @@ -1582,7 +1585,7 @@ struct field_modify_info modify_tcp[] = {
>  	}
>  	rte_atomic32_init(&cache_resource->refcnt);
>  	rte_atomic32_inc(&cache_resource->refcnt);
> -	LIST_INSERT_HEAD(&priv->modify_cmds, cache_resource, next);
> +	LIST_INSERT_HEAD(&sh->modify_cmds, cache_resource, next);
>  	dev_flow->dv.modify_hdr = cache_resource;
>  	DRV_LOG(DEBUG, "new modify-header resource %p: refcnt %d++",
>  		(void *)cache_resource,
> @@ -2879,18 +2882,19 @@ struct field_modify_info modify_tcp[] = {
>  			 struct rte_flow_error *error)
>  {
>  	struct mlx5_priv *priv = dev->data->dev_private;
> +	struct mlx5_ibv_shared *sh = priv->sh;
>  	struct mlx5_flow_tbl_resource *tbl;
> 
>  	if (egress) {
> -		tbl = &priv->tx_tbl[table_id];
> +		tbl = &sh->tx_tbl[table_id];
>  		if (!tbl->obj)
>  			tbl->obj = mlx5_glue->dr_create_flow_tbl
> -				(priv->tx_ns, table_id);
> +				(sh->tx_ns, table_id);
>  	} else {
> -		tbl = &priv->rx_tbl[table_id];
> +		tbl = &sh->rx_tbl[table_id];
>  		if (!tbl->obj)
>  			tbl->obj = mlx5_glue->dr_create_flow_tbl
> -				(priv->rx_ns, table_id);
> +				(sh->rx_ns, table_id);
>  	}
>  	if (!tbl->obj) {
>  		rte_flow_error_set(error, ENOMEM,
> @@ -2946,6 +2950,7 @@ struct field_modify_info modify_tcp[] = {
>  			 struct rte_flow_error *error)
>  {
>  	struct mlx5_priv *priv = dev->data->dev_private;
> +	struct mlx5_ibv_shared *sh = priv->sh;
>  	struct mlx5_flow_dv_matcher *cache_matcher;
>  	struct mlx5dv_flow_matcher_attr dv_attr = {
>  		.type = IBV_FLOW_ATTR_NORMAL,
> @@ -2957,7 +2962,7 @@ struct field_modify_info modify_tcp[] = {  #endif
> 
>  	/* Lookup from cache. */
> -	LIST_FOREACH(cache_matcher, &priv->matchers, next) {
> +	LIST_FOREACH(cache_matcher, &sh->matchers, next) {
>  		if (matcher->crc == cache_matcher->crc &&
>  		    matcher->priority == cache_matcher->priority &&
>  		    matcher->egress == cache_matcher->egress && @@ -
> 3001,8 +3006,7 @@ struct field_modify_info modify_tcp[] = {
>  	if (matcher->egress)
>  		dv_attr.flags |= IBV_FLOW_ATTR_FLAGS_EGRESS;
>  	cache_matcher->matcher_object =
> -		mlx5_glue->dv_create_flow_matcher(priv->sh->ctx,
> &dv_attr,
> -						  tbl->obj);
> +		mlx5_glue->dv_create_flow_matcher(sh->ctx, &dv_attr, tbl-
> >obj);
>  	if (!cache_matcher->matcher_object) {
>  		rte_free(cache_matcher);
>  #ifdef HAVE_MLX5DV_DR
> @@ -3013,7 +3017,7 @@ struct field_modify_info modify_tcp[] = {
>  					  NULL, "cannot create matcher");
>  	}
>  	rte_atomic32_inc(&cache_matcher->refcnt);
> -	LIST_INSERT_HEAD(&priv->matchers, cache_matcher, next);
> +	LIST_INSERT_HEAD(&sh->matchers, cache_matcher, next);
>  	dev_flow->dv.matcher = cache_matcher;
>  	DRV_LOG(DEBUG, "priority %hd new %s matcher %p: refcnt %d",
>  		cache_matcher->priority,
> @@ -3069,10 +3073,11 @@ struct field_modify_info modify_tcp[] = {
>  			 struct rte_flow_error *error)
>  {
>  	struct mlx5_priv *priv = dev->data->dev_private;
> +	struct mlx5_ibv_shared *sh = priv->sh;
>  	struct mlx5_flow_dv_tag_resource *cache_resource;
> 
>  	/* Lookup a matching resource from cache. */
> -	LIST_FOREACH(cache_resource, &priv->tags, next) {
> +	LIST_FOREACH(cache_resource, &sh->tags, next) {
>  		if (resource->tag == cache_resource->tag) {
>  			DRV_LOG(DEBUG, "tag resource %p: refcnt %d++",
>  				(void *)cache_resource,
> @@ -3099,7 +3104,7 @@ struct field_modify_info modify_tcp[] = {
>  	}
>  	rte_atomic32_init(&cache_resource->refcnt);
>  	rte_atomic32_inc(&cache_resource->refcnt);
> -	LIST_INSERT_HEAD(&priv->tags, cache_resource, next);
> +	LIST_INSERT_HEAD(&sh->tags, cache_resource, next);
>  	dev_flow->flow->tag_resource = cache_resource;
>  	DRV_LOG(DEBUG, "new tag resource %p: refcnt %d++",
>  		(void *)cache_resource,
> @@ -3676,6 +3681,7 @@ struct field_modify_info modify_tcp[] = {  {
>  	struct mlx5_flow_dv_matcher *matcher = flow->dv.matcher;
>  	struct mlx5_priv *priv = dev->data->dev_private;
> +	struct mlx5_ibv_shared *sh = priv->sh;
>  	struct mlx5_flow_tbl_resource *tbl;
> 
>  	assert(matcher->matcher_object);
> @@ -3687,9 +3693,9 @@ struct field_modify_info modify_tcp[] = {
>  			   (matcher->matcher_object));
>  		LIST_REMOVE(matcher, next);
>  		if (matcher->egress)
> -			tbl = &priv->tx_tbl[matcher->group];
> +			tbl = &sh->tx_tbl[matcher->group];
>  		else
> -			tbl = &priv->rx_tbl[matcher->group];
> +			tbl = &sh->rx_tbl[matcher->group];
>  		flow_dv_tbl_resource_release(tbl);
>  		rte_free(matcher);
>  		DRV_LOG(DEBUG, "port %u matcher %p: removed",
> --
> 1.8.3.1

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

* Re: [dpdk-dev] [PATCH 3/4] net/mlx5: share DV/DR flow related structures
  2019-04-02 19:09   ` Shahaf Shuler
@ 2019-04-02 19:09     ` Shahaf Shuler
  0 siblings, 0 replies; 28+ messages in thread
From: Shahaf Shuler @ 2019-04-02 19:09 UTC (permalink / raw)
  To: Slava Ovsiienko, dev

Tuesday, April 2, 2019 9:23 AM, Viacheslav Ovsiienko:
> Subject: [PATCH 3/4] net/mlx5: share DV/DR flow related structures

Same comment about the title. 

> 
> DV/DR related structures are moved to the shared context:
>   - rx/tx namespaces, shared by master and representors
>   - rx/tx flow tables
>   - matchers
>   - encap/decap action resources
>   - flow tags (MARK actions)
>   - modify action resources
>   - jump tables

I am OK w/ the logic.
However the next commit (4/4 net/mlx5: add mutex for shared DV/DR structures) should be squashed into this one. 
Because w/o it, the concurrent flow creation/destroy between multiple devices is broken. 

> 
> Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
> ---
>  drivers/net/mlx5/mlx5.c         | 28 +++++++++++-----------
>  drivers/net/mlx5/mlx5.h         | 40 +++++++++++++++----------------
>  drivers/net/mlx5/mlx5_flow_dv.c | 52 +++++++++++++++++++++++---------
> ---------
>  3 files changed, 63 insertions(+), 57 deletions(-)
> 
> diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index
> 79e0c17..369b698 100644
> --- a/drivers/net/mlx5/mlx5.c
> +++ b/drivers/net/mlx5/mlx5.c
> @@ -329,27 +329,27 @@ struct mlx5_dev_spawn_data {
>  		err = errno;
>  		goto error;
>  	}
> -	priv->rx_ns = ns;
> +	sh->rx_ns = ns;
>  	ns = mlx5dv_dr_create_ns(sh->ctx,
> MLX5DV_DR_NS_DOMAIN_EGRESS_BYPASS);
>  	if (!ns) {
>  		DRV_LOG(ERR, "egress mlx5dv_dr_create_ns failed");
>  		err = errno;
>  		goto error;
>  	}
> -	priv->tx_ns = ns;
> +	sh->tx_ns = ns;
>  	sh->dv_refcnt++;
>  	priv->dv_shared = 1;
>  	return 0;
> 
>  error:
>         /* Rollback the created objects. */
> -	if (priv->rx_ns) {
> -		mlx5dv_dr_destroy_ns(priv->rx_ns);
> -		priv->rx_ns = NULL;
> +	if (sh->rx_ns) {
> +		mlx5dv_dr_destroy_ns(sh->rx_ns);
> +		sh->rx_ns = NULL;
>  	}
> -	if (priv->tx_ns) {
> -		mlx5dv_dr_destroy_ns(priv->tx_ns);
> -		priv->tx_ns = NULL;
> +	if (sh->tx_ns) {
> +		mlx5dv_dr_destroy_ns(sh->tx_ns);
> +		sh->tx_ns = NULL;
>  	}
>  	return err;
>  }
> @@ -373,13 +373,13 @@ struct mlx5_dev_spawn_data {
>  	assert(sh->dv_refcnt);
>  	if (sh->dv_refcnt && --sh->dv_refcnt)
>  		return;
> -	if (priv->rx_ns) {
> -		mlx5dv_dr_destroy_ns(priv->rx_ns);
> -		priv->rx_ns = NULL;
> +	if (sh->rx_ns) {
> +		mlx5dv_dr_destroy_ns(sh->rx_ns);
> +		sh->rx_ns = NULL;
>  	}
> -	if (priv->tx_ns) {
> -		mlx5dv_dr_destroy_ns(priv->tx_ns);
> -		priv->tx_ns = NULL;
> +	if (sh->tx_ns) {
> +		mlx5dv_dr_destroy_ns(sh->tx_ns);
> +		sh->tx_ns = NULL;
>  	}
>  }
>  #endif
> diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index
> 56a2c61..e67227f 100644
> --- a/drivers/net/mlx5/mlx5.h
> +++ b/drivers/net/mlx5/mlx5.h
> @@ -199,6 +199,15 @@ struct mlx5_ibv_shared_port {
>  	 */
>  };
> 
> +/* Table structure. */
> +struct mlx5_flow_tbl_resource {
> +	void *obj; /**< Pointer to DR table object. */
> +	rte_atomic32_t refcnt; /**< Reference counter. */ };
> +
> +#define MLX5_MAX_TABLES 1024
> +#define MLX5_GROUP_FACTOR 1
> +
>  /*
>   * Shared Infiniband device context for Master/Representors
>   * which belong to same IB device with multiple IB ports.
> @@ -215,6 +224,17 @@ struct mlx5_ibv_shared {
>  	struct ibv_device_attr_ex device_attr; /* Device properties. */
>  	/* Shared DV/DR flow data section. */
>  	uint32_t dv_refcnt; /* DV/DR data reference counter. */
> +	void *rx_ns; /* RX Direct Rules name space handle. */
> +	struct mlx5_flow_tbl_resource rx_tbl[MLX5_MAX_TABLES];
> +	/* RX Direct Rules tables. */
> +	void *tx_ns; /* TX Direct Rules name space handle. */
> +	struct mlx5_flow_tbl_resource tx_tbl[MLX5_MAX_TABLES];
> +	/* TX Direct Rules tables/ */
> +	LIST_HEAD(matchers, mlx5_flow_dv_matcher) matchers;
> +	LIST_HEAD(encap_decap, mlx5_flow_dv_encap_decap_resource)
> encaps_decaps;
> +	LIST_HEAD(modify_cmd, mlx5_flow_dv_modify_hdr_resource)
> modify_cmds;
> +	LIST_HEAD(tag, mlx5_flow_dv_tag_resource) tags;
> +	LIST_HEAD(jump, mlx5_flow_dv_jump_tbl_resource) jump_tbl;
>  	/* Shared interrupt handler section. */
>  	pthread_mutex_t intr_mutex; /* Interrupt config mutex. */
>  	uint32_t intr_cnt; /* Interrupt handler reference counter. */ @@ -
> 222,15 +242,6 @@ struct mlx5_ibv_shared {
>  	struct mlx5_ibv_shared_port port[]; /* per device port data array. */
> };
> 
> -/* Table structure. */
> -struct mlx5_flow_tbl_resource {
> -	void *obj; /**< Pointer to DR table object. */
> -	rte_atomic32_t refcnt; /**< Reference counter. */
> -};
> -
> -#define MLX5_MAX_TABLES 1024
> -#define MLX5_GROUP_FACTOR 1
> -
>  struct mlx5_priv {
>  	LIST_ENTRY(mlx5_priv) mem_event_cb;
>  	/**< Called by memory event callback. */ @@ -279,11 +290,6 @@
> struct mlx5_priv {
>  	LIST_HEAD(txqibv, mlx5_txq_ibv) txqsibv; /* Verbs Tx queues. */
>  	/* Verbs Indirection tables. */
>  	LIST_HEAD(ind_tables, mlx5_ind_table_ibv) ind_tbls;
> -	LIST_HEAD(matchers, mlx5_flow_dv_matcher) matchers;
> -	LIST_HEAD(encap_decap, mlx5_flow_dv_encap_decap_resource)
> encaps_decaps;
> -	LIST_HEAD(modify_cmd, mlx5_flow_dv_modify_hdr_resource)
> modify_cmds;
> -	LIST_HEAD(tag, mlx5_flow_dv_tag_resource) tags;
> -	LIST_HEAD(jump, mlx5_flow_dv_jump_tbl_resource) jump_tbl;
>  	/* Pointer to next element. */
>  	rte_atomic32_t refcnt; /**< Reference counter. */
>  	struct ibv_flow_action *verbs_action;
> @@ -308,12 +314,6 @@ struct mlx5_priv {
>  	/* UAR same-page access control required in 32bit implementations.
> */  #endif
>  	struct mlx5_flow_tcf_context *tcf_context; /* TC flower context. */
> -	void *rx_ns; /* RX Direct Rules name space handle. */
> -	struct mlx5_flow_tbl_resource rx_tbl[MLX5_MAX_TABLES];
> -	/* RX Direct Rules tables. */
> -	void *tx_ns; /* TX Direct Rules name space handle. */
> -	struct mlx5_flow_tbl_resource tx_tbl[MLX5_MAX_TABLES];
> -	/* TX Direct Rules tables/ */
>  };
> 
>  #define PORT_ID(priv) ((priv)->dev_data->port_id) diff --git
> a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
> index f1dd00a..4912fc8 100644
> --- a/drivers/net/mlx5/mlx5_flow_dv.c
> +++ b/drivers/net/mlx5/mlx5_flow_dv.c
> @@ -804,18 +804,19 @@ struct field_modify_info modify_tcp[] = {
>  			 struct rte_flow_error *error)
>  {
>  	struct mlx5_priv *priv = dev->data->dev_private;
> +	struct mlx5_ibv_shared *sh = priv->sh;
>  	struct mlx5_flow_dv_encap_decap_resource *cache_resource;
>  	struct rte_flow *flow = dev_flow->flow;
>  	struct mlx5dv_dr_ns *ns;
> 
>  	resource->flags = flow->group ? 0 : 1;
>  	if (flow->ingress)
> -		ns = priv->rx_ns;
> +		ns = sh->rx_ns;
>  	else
> -		ns = priv->tx_ns;
> +		ns = sh->tx_ns;
> 
>  	/* Lookup a matching resource from cache. */
> -	LIST_FOREACH(cache_resource, &priv->encaps_decaps, next) {
> +	LIST_FOREACH(cache_resource, &sh->encaps_decaps, next) {
>  		if (resource->reformat_type == cache_resource-
> >reformat_type &&
>  		    resource->ft_type == cache_resource->ft_type &&
>  		    resource->flags == cache_resource->flags && @@ -840,7
> +841,7 @@ struct field_modify_info modify_tcp[] = {
>  	*cache_resource = *resource;
>  	cache_resource->verbs_action =
>  		mlx5_glue->dv_create_flow_action_packet_reformat
> -			(priv->sh->ctx, cache_resource->reformat_type,
> +			(sh->ctx, cache_resource->reformat_type,
>  			 cache_resource->ft_type, ns, cache_resource-
> >flags,
>  			 cache_resource->size,
>  			 (cache_resource->size ? cache_resource->buf :
> NULL)); @@ -852,7 +853,7 @@ struct field_modify_info modify_tcp[] = {
>  	}
>  	rte_atomic32_init(&cache_resource->refcnt);
>  	rte_atomic32_inc(&cache_resource->refcnt);
> -	LIST_INSERT_HEAD(&priv->encaps_decaps, cache_resource, next);
> +	LIST_INSERT_HEAD(&sh->encaps_decaps, cache_resource, next);
>  	dev_flow->dv.encap_decap = cache_resource;
>  	DRV_LOG(DEBUG, "new encap/decap resource %p: refcnt %d++",
>  		(void *)cache_resource,
> @@ -883,10 +884,11 @@ struct field_modify_info modify_tcp[] = {
>  			 struct rte_flow_error *error)
>  {
>  	struct mlx5_priv *priv = dev->data->dev_private;
> +	struct mlx5_ibv_shared *sh = priv->sh;
>  	struct mlx5_flow_dv_jump_tbl_resource *cache_resource;
> 
>  	/* Lookup a matching resource from cache. */
> -	LIST_FOREACH(cache_resource, &priv->jump_tbl, next) {
> +	LIST_FOREACH(cache_resource, &sh->jump_tbl, next) {
>  		if (resource->tbl == cache_resource->tbl) {
>  			DRV_LOG(DEBUG, "jump table resource resource
> %p: refcnt %d++",
>  				(void *)cache_resource,
> @@ -914,7 +916,7 @@ struct field_modify_info modify_tcp[] = {
>  	}
>  	rte_atomic32_init(&cache_resource->refcnt);
>  	rte_atomic32_inc(&cache_resource->refcnt);
> -	LIST_INSERT_HEAD(&priv->jump_tbl, cache_resource, next);
> +	LIST_INSERT_HEAD(&sh->jump_tbl, cache_resource, next);
>  	dev_flow->dv.jump = cache_resource;
>  	DRV_LOG(DEBUG, "new jump table  resource %p: refcnt %d++",
>  		(void *)cache_resource,
> @@ -1538,14 +1540,15 @@ struct field_modify_info modify_tcp[] = {
>  			 struct rte_flow_error *error)
>  {
>  	struct mlx5_priv *priv = dev->data->dev_private;
> +	struct mlx5_ibv_shared *sh = priv->sh;
>  	struct mlx5_flow_dv_modify_hdr_resource *cache_resource;
> 
>  	struct mlx5dv_dr_ns *ns =
>  		resource->ft_type == MLX5DV_FLOW_TABLE_TYPE_NIC_TX
> ?
> -		priv->tx_ns : priv->rx_ns;
> +		sh->tx_ns : sh->rx_ns;
> 
>  	/* Lookup a matching resource from cache. */
> -	LIST_FOREACH(cache_resource, &priv->modify_cmds, next) {
> +	LIST_FOREACH(cache_resource, &sh->modify_cmds, next) {
>  		if (resource->ft_type == cache_resource->ft_type &&
>  		    resource->actions_num == cache_resource->actions_num
> &&
>  		    !memcmp((const void *)resource->actions, @@ -1569,7
> +1572,7 @@ struct field_modify_info modify_tcp[] = {
>  	*cache_resource = *resource;
>  	cache_resource->verbs_action =
>  		mlx5_glue->dv_create_flow_action_modify_header
> -					(priv->sh->ctx, cache_resource-
> >ft_type,
> +					(sh->ctx, cache_resource->ft_type,
>  					 ns, 0,
>  					 cache_resource->actions_num *
>  					 sizeof(cache_resource->actions[0]),
> @@ -1582,7 +1585,7 @@ struct field_modify_info modify_tcp[] = {
>  	}
>  	rte_atomic32_init(&cache_resource->refcnt);
>  	rte_atomic32_inc(&cache_resource->refcnt);
> -	LIST_INSERT_HEAD(&priv->modify_cmds, cache_resource, next);
> +	LIST_INSERT_HEAD(&sh->modify_cmds, cache_resource, next);
>  	dev_flow->dv.modify_hdr = cache_resource;
>  	DRV_LOG(DEBUG, "new modify-header resource %p: refcnt %d++",
>  		(void *)cache_resource,
> @@ -2879,18 +2882,19 @@ struct field_modify_info modify_tcp[] = {
>  			 struct rte_flow_error *error)
>  {
>  	struct mlx5_priv *priv = dev->data->dev_private;
> +	struct mlx5_ibv_shared *sh = priv->sh;
>  	struct mlx5_flow_tbl_resource *tbl;
> 
>  	if (egress) {
> -		tbl = &priv->tx_tbl[table_id];
> +		tbl = &sh->tx_tbl[table_id];
>  		if (!tbl->obj)
>  			tbl->obj = mlx5_glue->dr_create_flow_tbl
> -				(priv->tx_ns, table_id);
> +				(sh->tx_ns, table_id);
>  	} else {
> -		tbl = &priv->rx_tbl[table_id];
> +		tbl = &sh->rx_tbl[table_id];
>  		if (!tbl->obj)
>  			tbl->obj = mlx5_glue->dr_create_flow_tbl
> -				(priv->rx_ns, table_id);
> +				(sh->rx_ns, table_id);
>  	}
>  	if (!tbl->obj) {
>  		rte_flow_error_set(error, ENOMEM,
> @@ -2946,6 +2950,7 @@ struct field_modify_info modify_tcp[] = {
>  			 struct rte_flow_error *error)
>  {
>  	struct mlx5_priv *priv = dev->data->dev_private;
> +	struct mlx5_ibv_shared *sh = priv->sh;
>  	struct mlx5_flow_dv_matcher *cache_matcher;
>  	struct mlx5dv_flow_matcher_attr dv_attr = {
>  		.type = IBV_FLOW_ATTR_NORMAL,
> @@ -2957,7 +2962,7 @@ struct field_modify_info modify_tcp[] = {  #endif
> 
>  	/* Lookup from cache. */
> -	LIST_FOREACH(cache_matcher, &priv->matchers, next) {
> +	LIST_FOREACH(cache_matcher, &sh->matchers, next) {
>  		if (matcher->crc == cache_matcher->crc &&
>  		    matcher->priority == cache_matcher->priority &&
>  		    matcher->egress == cache_matcher->egress && @@ -
> 3001,8 +3006,7 @@ struct field_modify_info modify_tcp[] = {
>  	if (matcher->egress)
>  		dv_attr.flags |= IBV_FLOW_ATTR_FLAGS_EGRESS;
>  	cache_matcher->matcher_object =
> -		mlx5_glue->dv_create_flow_matcher(priv->sh->ctx,
> &dv_attr,
> -						  tbl->obj);
> +		mlx5_glue->dv_create_flow_matcher(sh->ctx, &dv_attr, tbl-
> >obj);
>  	if (!cache_matcher->matcher_object) {
>  		rte_free(cache_matcher);
>  #ifdef HAVE_MLX5DV_DR
> @@ -3013,7 +3017,7 @@ struct field_modify_info modify_tcp[] = {
>  					  NULL, "cannot create matcher");
>  	}
>  	rte_atomic32_inc(&cache_matcher->refcnt);
> -	LIST_INSERT_HEAD(&priv->matchers, cache_matcher, next);
> +	LIST_INSERT_HEAD(&sh->matchers, cache_matcher, next);
>  	dev_flow->dv.matcher = cache_matcher;
>  	DRV_LOG(DEBUG, "priority %hd new %s matcher %p: refcnt %d",
>  		cache_matcher->priority,
> @@ -3069,10 +3073,11 @@ struct field_modify_info modify_tcp[] = {
>  			 struct rte_flow_error *error)
>  {
>  	struct mlx5_priv *priv = dev->data->dev_private;
> +	struct mlx5_ibv_shared *sh = priv->sh;
>  	struct mlx5_flow_dv_tag_resource *cache_resource;
> 
>  	/* Lookup a matching resource from cache. */
> -	LIST_FOREACH(cache_resource, &priv->tags, next) {
> +	LIST_FOREACH(cache_resource, &sh->tags, next) {
>  		if (resource->tag == cache_resource->tag) {
>  			DRV_LOG(DEBUG, "tag resource %p: refcnt %d++",
>  				(void *)cache_resource,
> @@ -3099,7 +3104,7 @@ struct field_modify_info modify_tcp[] = {
>  	}
>  	rte_atomic32_init(&cache_resource->refcnt);
>  	rte_atomic32_inc(&cache_resource->refcnt);
> -	LIST_INSERT_HEAD(&priv->tags, cache_resource, next);
> +	LIST_INSERT_HEAD(&sh->tags, cache_resource, next);
>  	dev_flow->flow->tag_resource = cache_resource;
>  	DRV_LOG(DEBUG, "new tag resource %p: refcnt %d++",
>  		(void *)cache_resource,
> @@ -3676,6 +3681,7 @@ struct field_modify_info modify_tcp[] = {  {
>  	struct mlx5_flow_dv_matcher *matcher = flow->dv.matcher;
>  	struct mlx5_priv *priv = dev->data->dev_private;
> +	struct mlx5_ibv_shared *sh = priv->sh;
>  	struct mlx5_flow_tbl_resource *tbl;
> 
>  	assert(matcher->matcher_object);
> @@ -3687,9 +3693,9 @@ struct field_modify_info modify_tcp[] = {
>  			   (matcher->matcher_object));
>  		LIST_REMOVE(matcher, next);
>  		if (matcher->egress)
> -			tbl = &priv->tx_tbl[matcher->group];
> +			tbl = &sh->tx_tbl[matcher->group];
>  		else
> -			tbl = &priv->rx_tbl[matcher->group];
> +			tbl = &sh->rx_tbl[matcher->group];
>  		flow_dv_tbl_resource_release(tbl);
>  		rte_free(matcher);
>  		DRV_LOG(DEBUG, "port %u matcher %p: removed",
> --
> 1.8.3.1


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

* Re: [dpdk-dev] [PATCH 4/4] net/mlx5: add mutex for shared DV/DR structures
  2019-04-02  6:22 ` [dpdk-dev] [PATCH 4/4] net/mlx5: add mutex for shared DV/DR structures Viacheslav Ovsiienko
  2019-04-02  6:22   ` Viacheslav Ovsiienko
@ 2019-04-02 19:09   ` Shahaf Shuler
  2019-04-02 19:09     ` Shahaf Shuler
  1 sibling, 1 reply; 28+ messages in thread
From: Shahaf Shuler @ 2019-04-02 19:09 UTC (permalink / raw)
  To: Slava Ovsiienko, dev

Tuesday, April 2, 2019 9:23 AM, Viacheslav Ovsiienko:
> Subject: [PATCH 4/4] net/mlx5: add mutex for shared DV/DR structures

Same comment about title. 

> 
> This patch introduces the mutex for shared DV/DR structures.
> Application may have multiple threads (but single dedicated thread per port).
> Due to sharing the IB context in the multiport IB device configurations we
> should synchronize access to the shared DV/DR flow structures.
> 
> Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
> ---
>  drivers/net/mlx5/mlx5.c         |   6 +++
>  drivers/net/mlx5/mlx5.h         |   1 +
>  drivers/net/mlx5/mlx5_flow_dv.c | 103
> ++++++++++++++++++++++++++++++++++++++--
>  3 files changed, 106 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index
> 369b698..96ad4c6 100644
> --- a/drivers/net/mlx5/mlx5.c
> +++ b/drivers/net/mlx5/mlx5.c
> @@ -312,6 +312,7 @@ struct mlx5_dev_spawn_data {
> mlx5_alloc_shared_dv(struct mlx5_priv *priv)  {
>  	struct mlx5_ibv_shared *sh = priv->sh;
> +	pthread_mutexattr_t mattr;
>  	int err = 0;
>  	void *ns;
> 
> @@ -336,6 +337,10 @@ struct mlx5_dev_spawn_data {
>  		err = errno;
>  		goto error;
>  	}
> +	pthread_mutexattr_init(&mattr);
> +	pthread_mutexattr_settype(&mattr,
> PTHREAD_MUTEX_RECURSIVE);

Please add inline comment about why you use this type of mutex (so that you can use a single mutex for the entire flow engine logic). 

> +	pthread_mutex_init(&sh->dv_mutex, &mattr);
> +	pthread_mutexattr_destroy(&mattr);
>  	sh->tx_ns = ns;
>  	sh->dv_refcnt++;
>  	priv->dv_shared = 1;
> @@ -381,6 +386,7 @@ struct mlx5_dev_spawn_data {
>  		mlx5dv_dr_destroy_ns(sh->tx_ns);
>  		sh->tx_ns = NULL;
>  	}
> +	pthread_mutex_destroy(&sh->dv_mutex);
>  }
>  #endif
> 
> diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index
> e67227f..4f6c1b7 100644
> --- a/drivers/net/mlx5/mlx5.h
> +++ b/drivers/net/mlx5/mlx5.h
> @@ -223,6 +223,7 @@ struct mlx5_ibv_shared {
>  	char ibdev_path[IBV_SYSFS_PATH_MAX]; /* IB device path for
> secondary */
>  	struct ibv_device_attr_ex device_attr; /* Device properties. */
>  	/* Shared DV/DR flow data section. */
> +	pthread_mutex_t dv_mutex; /* DV context mutex. */
>  	uint32_t dv_refcnt; /* DV/DR data reference counter. */
>  	void *rx_ns; /* RX Direct Rules name space handle. */
>  	struct mlx5_flow_tbl_resource rx_tbl[MLX5_MAX_TABLES]; diff --git
> a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
> index 4912fc8..737011a 100644
> --- a/drivers/net/mlx5/mlx5_flow_dv.c
> +++ b/drivers/net/mlx5/mlx5_flow_dv.c
> @@ -125,6 +125,45 @@ struct field_modify_info modify_tcp[] = {  };
> 
>  /**
> + * Acquire the synchronizing object to protect multithreaded access
> + * to shared dv context. Lock occurs only if context is actually
> + * shared, i.e. we have multiport IB device and representors are
> + * created.
> + *
> + * @param[in] dev
> + *   Pointer to the rte_eth_dev structure.
> + */
> +static void
> +flow_d_shared_lock(struct rte_eth_dev *dev) {
> +	struct mlx5_priv *priv = dev->data->dev_private;
> +	struct mlx5_ibv_shared *sh = priv->sh;
> +
> +	if (sh->dv_refcnt > 1) {
> +		int ret;
> +
> +		ret = pthread_mutex_lock(&sh->dv_mutex);
> +		assert(!ret);
> +		(void)ret;
> +	}
> +}
> +
> +static void
> +flow_d_shared_unlock(struct rte_eth_dev *dev) {
> +	struct mlx5_priv *priv = dev->data->dev_private;
> +	struct mlx5_ibv_shared *sh = priv->sh;
> +
> +	if (sh->dv_refcnt > 1) {
> +		int ret;
> +
> +		ret = pthread_mutex_unlock(&sh->dv_mutex);
> +		assert(!ret);
> +		(void)ret;
> +	}
> +}
> +
> +/**
>   * Convert modify-header action to DV specification.
>   *
>   * @param[in] item
> @@ -3958,14 +3997,70 @@ struct field_modify_info modify_tcp[] = {
>  	return ret;
>  }
> 
> +/*
> + * Mutex-protected thunk to flow_dv_translate().
> + */
> +static int
> +flow_d_translate(struct rte_eth_dev *dev,
> +		 struct mlx5_flow *dev_flow,
> +		 const struct rte_flow_attr *attr,
> +		 const struct rte_flow_item items[],
> +		 const struct rte_flow_action actions[],
> +		 struct rte_flow_error *error)
> +{
> +	int ret;
> +
> +	flow_d_shared_lock(dev);
> +	ret = flow_dv_translate(dev, dev_flow, attr, items, actions, error);
> +	flow_d_shared_unlock(dev);
> +	return ret;
> +}
> +
> +/*
> + * Mutex-protected thunk to flow_dv_apply().
> + */
> +static int
> +flow_d_apply(struct rte_eth_dev *dev,
> +	     struct rte_flow *flow,
> +	     struct rte_flow_error *error)
> +{
> +	int ret;
> +
> +	flow_d_shared_lock(dev);
> +	ret = flow_dv_apply(dev, flow, error);
> +	flow_d_shared_unlock(dev);
> +	return ret;
> +}
> +
> +/*
> + * Mutex-protected thunk to flow_dv_remove().
> + */
> +static void
> +flow_d_remove(struct rte_eth_dev *dev, struct rte_flow *flow) {
> +	flow_d_shared_lock(dev);
> +	flow_dv_remove(dev, flow);
> +	flow_d_shared_unlock(dev);
> +}
> +
> +/*
> + * Mutex-protected thunk to flow_dv_destroy().
> + */
> +static void
> +flow_d_destroy(struct rte_eth_dev *dev, struct rte_flow *flow) {
> +	flow_d_shared_lock(dev);
> +	flow_dv_destroy(dev, flow);
> +	flow_d_shared_unlock(dev);
> +}
> 
>  const struct mlx5_flow_driver_ops mlx5_flow_dv_drv_ops = {
>  	.validate = flow_dv_validate,
>  	.prepare = flow_dv_prepare,
> -	.translate = flow_dv_translate,
> -	.apply = flow_dv_apply,
> -	.remove = flow_dv_remove,
> -	.destroy = flow_dv_destroy,
> +	.translate = flow_d_translate,
> +	.apply = flow_d_apply,
> +	.remove = flow_d_remove,
> +	.destroy = flow_d_destroy,
>  	.query = flow_dv_query,
>  };
> 
> --
> 1.8.3.1

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

* Re: [dpdk-dev] [PATCH 4/4] net/mlx5: add mutex for shared DV/DR structures
  2019-04-02 19:09   ` Shahaf Shuler
@ 2019-04-02 19:09     ` Shahaf Shuler
  0 siblings, 0 replies; 28+ messages in thread
From: Shahaf Shuler @ 2019-04-02 19:09 UTC (permalink / raw)
  To: Slava Ovsiienko, dev

Tuesday, April 2, 2019 9:23 AM, Viacheslav Ovsiienko:
> Subject: [PATCH 4/4] net/mlx5: add mutex for shared DV/DR structures

Same comment about title. 

> 
> This patch introduces the mutex for shared DV/DR structures.
> Application may have multiple threads (but single dedicated thread per port).
> Due to sharing the IB context in the multiport IB device configurations we
> should synchronize access to the shared DV/DR flow structures.
> 
> Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
> ---
>  drivers/net/mlx5/mlx5.c         |   6 +++
>  drivers/net/mlx5/mlx5.h         |   1 +
>  drivers/net/mlx5/mlx5_flow_dv.c | 103
> ++++++++++++++++++++++++++++++++++++++--
>  3 files changed, 106 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index
> 369b698..96ad4c6 100644
> --- a/drivers/net/mlx5/mlx5.c
> +++ b/drivers/net/mlx5/mlx5.c
> @@ -312,6 +312,7 @@ struct mlx5_dev_spawn_data {
> mlx5_alloc_shared_dv(struct mlx5_priv *priv)  {
>  	struct mlx5_ibv_shared *sh = priv->sh;
> +	pthread_mutexattr_t mattr;
>  	int err = 0;
>  	void *ns;
> 
> @@ -336,6 +337,10 @@ struct mlx5_dev_spawn_data {
>  		err = errno;
>  		goto error;
>  	}
> +	pthread_mutexattr_init(&mattr);
> +	pthread_mutexattr_settype(&mattr,
> PTHREAD_MUTEX_RECURSIVE);

Please add inline comment about why you use this type of mutex (so that you can use a single mutex for the entire flow engine logic). 

> +	pthread_mutex_init(&sh->dv_mutex, &mattr);
> +	pthread_mutexattr_destroy(&mattr);
>  	sh->tx_ns = ns;
>  	sh->dv_refcnt++;
>  	priv->dv_shared = 1;
> @@ -381,6 +386,7 @@ struct mlx5_dev_spawn_data {
>  		mlx5dv_dr_destroy_ns(sh->tx_ns);
>  		sh->tx_ns = NULL;
>  	}
> +	pthread_mutex_destroy(&sh->dv_mutex);
>  }
>  #endif
> 
> diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index
> e67227f..4f6c1b7 100644
> --- a/drivers/net/mlx5/mlx5.h
> +++ b/drivers/net/mlx5/mlx5.h
> @@ -223,6 +223,7 @@ struct mlx5_ibv_shared {
>  	char ibdev_path[IBV_SYSFS_PATH_MAX]; /* IB device path for
> secondary */
>  	struct ibv_device_attr_ex device_attr; /* Device properties. */
>  	/* Shared DV/DR flow data section. */
> +	pthread_mutex_t dv_mutex; /* DV context mutex. */
>  	uint32_t dv_refcnt; /* DV/DR data reference counter. */
>  	void *rx_ns; /* RX Direct Rules name space handle. */
>  	struct mlx5_flow_tbl_resource rx_tbl[MLX5_MAX_TABLES]; diff --git
> a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
> index 4912fc8..737011a 100644
> --- a/drivers/net/mlx5/mlx5_flow_dv.c
> +++ b/drivers/net/mlx5/mlx5_flow_dv.c
> @@ -125,6 +125,45 @@ struct field_modify_info modify_tcp[] = {  };
> 
>  /**
> + * Acquire the synchronizing object to protect multithreaded access
> + * to shared dv context. Lock occurs only if context is actually
> + * shared, i.e. we have multiport IB device and representors are
> + * created.
> + *
> + * @param[in] dev
> + *   Pointer to the rte_eth_dev structure.
> + */
> +static void
> +flow_d_shared_lock(struct rte_eth_dev *dev) {
> +	struct mlx5_priv *priv = dev->data->dev_private;
> +	struct mlx5_ibv_shared *sh = priv->sh;
> +
> +	if (sh->dv_refcnt > 1) {
> +		int ret;
> +
> +		ret = pthread_mutex_lock(&sh->dv_mutex);
> +		assert(!ret);
> +		(void)ret;
> +	}
> +}
> +
> +static void
> +flow_d_shared_unlock(struct rte_eth_dev *dev) {
> +	struct mlx5_priv *priv = dev->data->dev_private;
> +	struct mlx5_ibv_shared *sh = priv->sh;
> +
> +	if (sh->dv_refcnt > 1) {
> +		int ret;
> +
> +		ret = pthread_mutex_unlock(&sh->dv_mutex);
> +		assert(!ret);
> +		(void)ret;
> +	}
> +}
> +
> +/**
>   * Convert modify-header action to DV specification.
>   *
>   * @param[in] item
> @@ -3958,14 +3997,70 @@ struct field_modify_info modify_tcp[] = {
>  	return ret;
>  }
> 
> +/*
> + * Mutex-protected thunk to flow_dv_translate().
> + */
> +static int
> +flow_d_translate(struct rte_eth_dev *dev,
> +		 struct mlx5_flow *dev_flow,
> +		 const struct rte_flow_attr *attr,
> +		 const struct rte_flow_item items[],
> +		 const struct rte_flow_action actions[],
> +		 struct rte_flow_error *error)
> +{
> +	int ret;
> +
> +	flow_d_shared_lock(dev);
> +	ret = flow_dv_translate(dev, dev_flow, attr, items, actions, error);
> +	flow_d_shared_unlock(dev);
> +	return ret;
> +}
> +
> +/*
> + * Mutex-protected thunk to flow_dv_apply().
> + */
> +static int
> +flow_d_apply(struct rte_eth_dev *dev,
> +	     struct rte_flow *flow,
> +	     struct rte_flow_error *error)
> +{
> +	int ret;
> +
> +	flow_d_shared_lock(dev);
> +	ret = flow_dv_apply(dev, flow, error);
> +	flow_d_shared_unlock(dev);
> +	return ret;
> +}
> +
> +/*
> + * Mutex-protected thunk to flow_dv_remove().
> + */
> +static void
> +flow_d_remove(struct rte_eth_dev *dev, struct rte_flow *flow) {
> +	flow_d_shared_lock(dev);
> +	flow_dv_remove(dev, flow);
> +	flow_d_shared_unlock(dev);
> +}
> +
> +/*
> + * Mutex-protected thunk to flow_dv_destroy().
> + */
> +static void
> +flow_d_destroy(struct rte_eth_dev *dev, struct rte_flow *flow) {
> +	flow_d_shared_lock(dev);
> +	flow_dv_destroy(dev, flow);
> +	flow_d_shared_unlock(dev);
> +}
> 
>  const struct mlx5_flow_driver_ops mlx5_flow_dv_drv_ops = {
>  	.validate = flow_dv_validate,
>  	.prepare = flow_dv_prepare,
> -	.translate = flow_dv_translate,
> -	.apply = flow_dv_apply,
> -	.remove = flow_dv_remove,
> -	.destroy = flow_dv_destroy,
> +	.translate = flow_d_translate,
> +	.apply = flow_d_apply,
> +	.remove = flow_d_remove,
> +	.destroy = flow_d_destroy,
>  	.query = flow_dv_query,
>  };
> 
> --
> 1.8.3.1


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

* Re: [dpdk-dev] [PATCH 2/4] net/mlx5: add reference counter for DV/DR structures
  2019-04-02 19:09   ` Shahaf Shuler
  2019-04-02 19:09     ` Shahaf Shuler
@ 2019-04-03 13:27     ` Slava Ovsiienko
  2019-04-03 13:27       ` Slava Ovsiienko
  1 sibling, 1 reply; 28+ messages in thread
From: Slava Ovsiienko @ 2019-04-03 13:27 UTC (permalink / raw)
  To: Shahaf Shuler, dev

> -----Original Message-----
> From: Shahaf Shuler
> Sent: Tuesday, April 2, 2019 22:10
> To: Slava Ovsiienko <viacheslavo@mellanox.com>; dev@dpdk.org
> Subject: RE: [PATCH 2/4] net/mlx5: add reference counter for DV/DR
> structures
> 
> Tuesday, April 2, 2019 9:23 AM, Viacheslav Ovsiienko:
> > Subject: [PATCH 2/4] net/mlx5: add reference counter for DV/DR
> > structures
> 
> Same comment about the title.
> 
> >
> > This patch introduces the reference counter for DV/DR flow engine
> > structure, which we are going to share between master and representors
> > in E-Switch configurations over multiport Infiniband device.
> >
> > Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
> > ---
> >  drivers/net/mlx5/mlx5.c | 26 ++++++++++++++++++++++++--
> > drivers/net/mlx5/mlx5.h |  4 ++++
> >  2 files changed, 28 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index
> > 9de122d..79e0c17 100644
> > --- a/drivers/net/mlx5/mlx5.c
> > +++ b/drivers/net/mlx5/mlx5.c
> > @@ -299,7 +299,8 @@ struct mlx5_dev_spawn_data {  #ifdef
> > HAVE_MLX5DV_DR
> >  /**
> >   * Initialize DV/DR related data within private structure.
> > - * This is preparation step for the data sharing.
> > + * Routine checks the reference counter and does actual
> > + * resources creation/iniialization only if counter is zero.
> >   *
> >   * @param[in] priv
> >   *   Pointer to the private device data structure.
> > @@ -314,6 +315,14 @@ struct mlx5_dev_spawn_data {
> >  	int err = 0;
> >  	void *ns;
> >
> > +	assert(sh);
> > +	if (sh->dv_refcnt) {
> > +		/* Shared DV/DR structures is already initialized. */
> > +		sh->dv_refcnt++;
> > +		priv->dv_shared = 1;
> > +		return 0;
> > +	}
> > +	/* Reference counter is zero, we should initialize structures. */
> >  	ns = mlx5dv_dr_create_ns(sh->ctx,
> > MLX5DV_DR_NS_DOMAIN_INGRESS_BYPASS);
> >  	if (!ns) {
> >  		DRV_LOG(ERR, "ingress mlx5dv_dr_create_ns failed"); @@ -
> > 328,6 +337,8 @@ struct mlx5_dev_spawn_data {
> >  		goto error;
> >  	}
> >  	priv->tx_ns = ns;
> > +	sh->dv_refcnt++;
> > +	priv->dv_shared = 1;
> >  	return 0;
> >
> >  error:
> > @@ -352,6 +363,16 @@ struct mlx5_dev_spawn_data {  static void
> > mlx5_free_shared_dv(struct mlx5_priv *priv)  {
> > +	struct mlx5_ibv_shared *sh;
> > +
> > +	if (!priv->dv_shared)
> > +		return;
> > +	priv->dv_shared = 0;
> > +	sh = priv->sh;
> > +	assert(sh);
> > +	assert(sh->dv_refcnt);
> > +	if (sh->dv_refcnt && --sh->dv_refcnt)
> > +		return;
> >  	if (priv->rx_ns) {
> >  		mlx5dv_dr_destroy_ns(priv->rx_ns);
> >  		priv->rx_ns = NULL;
> > @@ -1491,7 +1512,8 @@ struct mlx5_dev_spawn_data {
> >  error:
> >  	if (priv) {
> >  #ifdef HAVE_MLX5DV_DR
> > -		mlx5_free_shared_dv(priv);
> > +		if (priv->sh)
> > +			mlx5_free_shared_dv(priv);
> >  #endif
> >  		if (priv->nl_socket_route >= 0)
> >  			close(priv->nl_socket_route);
> > diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index
> > a3d5f8e..56a2c61 100644
> > --- a/drivers/net/mlx5/mlx5.h
> > +++ b/drivers/net/mlx5/mlx5.h
> > @@ -213,6 +213,9 @@ struct mlx5_ibv_shared {
> >  	char ibdev_name[IBV_SYSFS_NAME_MAX]; /* IB device name. */
> >  	char ibdev_path[IBV_SYSFS_PATH_MAX]; /* IB device path for
> secondary
> > */
> >  	struct ibv_device_attr_ex device_attr; /* Device properties. */
> > +	/* Shared DV/DR flow data section. */
> > +	uint32_t dv_refcnt; /* DV/DR data reference counter. */
> > +	/* Shared interrupt handler section. */
> >  	pthread_mutex_t intr_mutex; /* Interrupt config mutex. */
> >  	uint32_t intr_cnt; /* Interrupt handler reference counter. */
> >  	struct rte_intr_handle intr_handle; /* Interrupt handler for device.
> > */ @@ -244,6 +247,7 @@ struct mlx5_priv {
> >  	unsigned int isolated:1; /* Whether isolated mode is enabled. */
> >  	unsigned int representor:1; /* Device is a port representor. */
> >  	unsigned int master:1; /* Device is a E-Switch master. */
> > +	unsigned int dv_shared:1; /* DV/DR data is shared. */
> 
> Why this flags is needed? Aren't we always going to share?

I think we can get rid of this flag, because it is used for correct cleanup
in device spawning routines If something goes wrong (on error exit)

> 
> 
> >  	uint16_t domain_id; /* Switch domain identifier. */
> >  	uint16_t vport_id; /* Associated VF vport index (if any). */
> >  	int32_t representor_id; /* Port representor identifier. */
> > --
> > 1.8.3.1

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

* Re: [dpdk-dev] [PATCH 2/4] net/mlx5: add reference counter for DV/DR structures
  2019-04-03 13:27     ` Slava Ovsiienko
@ 2019-04-03 13:27       ` Slava Ovsiienko
  0 siblings, 0 replies; 28+ messages in thread
From: Slava Ovsiienko @ 2019-04-03 13:27 UTC (permalink / raw)
  To: Shahaf Shuler, dev

> -----Original Message-----
> From: Shahaf Shuler
> Sent: Tuesday, April 2, 2019 22:10
> To: Slava Ovsiienko <viacheslavo@mellanox.com>; dev@dpdk.org
> Subject: RE: [PATCH 2/4] net/mlx5: add reference counter for DV/DR
> structures
> 
> Tuesday, April 2, 2019 9:23 AM, Viacheslav Ovsiienko:
> > Subject: [PATCH 2/4] net/mlx5: add reference counter for DV/DR
> > structures
> 
> Same comment about the title.
> 
> >
> > This patch introduces the reference counter for DV/DR flow engine
> > structure, which we are going to share between master and representors
> > in E-Switch configurations over multiport Infiniband device.
> >
> > Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
> > ---
> >  drivers/net/mlx5/mlx5.c | 26 ++++++++++++++++++++++++--
> > drivers/net/mlx5/mlx5.h |  4 ++++
> >  2 files changed, 28 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index
> > 9de122d..79e0c17 100644
> > --- a/drivers/net/mlx5/mlx5.c
> > +++ b/drivers/net/mlx5/mlx5.c
> > @@ -299,7 +299,8 @@ struct mlx5_dev_spawn_data {  #ifdef
> > HAVE_MLX5DV_DR
> >  /**
> >   * Initialize DV/DR related data within private structure.
> > - * This is preparation step for the data sharing.
> > + * Routine checks the reference counter and does actual
> > + * resources creation/iniialization only if counter is zero.
> >   *
> >   * @param[in] priv
> >   *   Pointer to the private device data structure.
> > @@ -314,6 +315,14 @@ struct mlx5_dev_spawn_data {
> >  	int err = 0;
> >  	void *ns;
> >
> > +	assert(sh);
> > +	if (sh->dv_refcnt) {
> > +		/* Shared DV/DR structures is already initialized. */
> > +		sh->dv_refcnt++;
> > +		priv->dv_shared = 1;
> > +		return 0;
> > +	}
> > +	/* Reference counter is zero, we should initialize structures. */
> >  	ns = mlx5dv_dr_create_ns(sh->ctx,
> > MLX5DV_DR_NS_DOMAIN_INGRESS_BYPASS);
> >  	if (!ns) {
> >  		DRV_LOG(ERR, "ingress mlx5dv_dr_create_ns failed"); @@ -
> > 328,6 +337,8 @@ struct mlx5_dev_spawn_data {
> >  		goto error;
> >  	}
> >  	priv->tx_ns = ns;
> > +	sh->dv_refcnt++;
> > +	priv->dv_shared = 1;
> >  	return 0;
> >
> >  error:
> > @@ -352,6 +363,16 @@ struct mlx5_dev_spawn_data {  static void
> > mlx5_free_shared_dv(struct mlx5_priv *priv)  {
> > +	struct mlx5_ibv_shared *sh;
> > +
> > +	if (!priv->dv_shared)
> > +		return;
> > +	priv->dv_shared = 0;
> > +	sh = priv->sh;
> > +	assert(sh);
> > +	assert(sh->dv_refcnt);
> > +	if (sh->dv_refcnt && --sh->dv_refcnt)
> > +		return;
> >  	if (priv->rx_ns) {
> >  		mlx5dv_dr_destroy_ns(priv->rx_ns);
> >  		priv->rx_ns = NULL;
> > @@ -1491,7 +1512,8 @@ struct mlx5_dev_spawn_data {
> >  error:
> >  	if (priv) {
> >  #ifdef HAVE_MLX5DV_DR
> > -		mlx5_free_shared_dv(priv);
> > +		if (priv->sh)
> > +			mlx5_free_shared_dv(priv);
> >  #endif
> >  		if (priv->nl_socket_route >= 0)
> >  			close(priv->nl_socket_route);
> > diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index
> > a3d5f8e..56a2c61 100644
> > --- a/drivers/net/mlx5/mlx5.h
> > +++ b/drivers/net/mlx5/mlx5.h
> > @@ -213,6 +213,9 @@ struct mlx5_ibv_shared {
> >  	char ibdev_name[IBV_SYSFS_NAME_MAX]; /* IB device name. */
> >  	char ibdev_path[IBV_SYSFS_PATH_MAX]; /* IB device path for
> secondary
> > */
> >  	struct ibv_device_attr_ex device_attr; /* Device properties. */
> > +	/* Shared DV/DR flow data section. */
> > +	uint32_t dv_refcnt; /* DV/DR data reference counter. */
> > +	/* Shared interrupt handler section. */
> >  	pthread_mutex_t intr_mutex; /* Interrupt config mutex. */
> >  	uint32_t intr_cnt; /* Interrupt handler reference counter. */
> >  	struct rte_intr_handle intr_handle; /* Interrupt handler for device.
> > */ @@ -244,6 +247,7 @@ struct mlx5_priv {
> >  	unsigned int isolated:1; /* Whether isolated mode is enabled. */
> >  	unsigned int representor:1; /* Device is a port representor. */
> >  	unsigned int master:1; /* Device is a E-Switch master. */
> > +	unsigned int dv_shared:1; /* DV/DR data is shared. */
> 
> Why this flags is needed? Aren't we always going to share?

I think we can get rid of this flag, because it is used for correct cleanup
in device spawning routines If something goes wrong (on error exit)

> 
> 
> >  	uint16_t domain_id; /* Switch domain identifier. */
> >  	uint16_t vport_id; /* Associated VF vport index (if any). */
> >  	int32_t representor_id; /* Port representor identifier. */
> > --
> > 1.8.3.1


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

* [dpdk-dev] [PATCH v2 0/2] support Direct Rules flows over shared IB context
  2019-04-02  6:22 [dpdk-dev] [PATCH 0/4] support DR/DV flows over shared IB context Viacheslav Ovsiienko
                   ` (4 preceding siblings ...)
  2019-04-02  6:22 ` [dpdk-dev] [PATCH 4/4] net/mlx5: add mutex for shared DV/DR structures Viacheslav Ovsiienko
@ 2019-04-04 13:04 ` Viacheslav Ovsiienko
  2019-04-04 13:04   ` Viacheslav Ovsiienko
                     ` (3 more replies)
  5 siblings, 4 replies; 28+ messages in thread
From: Viacheslav Ovsiienko @ 2019-04-04 13:04 UTC (permalink / raw)
  To: dev; +Cc: shahafs

The Direct Rules/Direct Verbs flows support is going
to be added [1]. The master/representor over multiport
IB device is added [2]. This patchset adds support for
DR/DV flows with shared IB context over multiport IB
device.

The DV/DR flows applied to the master/representors on the
same IB device share the following entinies:
  - rx/tx namespaces
  - rx/tx flow tables
  - matchers
  - encap/decap action resources
  - flow tags (MARK actions)
  - modify action resources
  - jump tables

[1] "net/mlx5: Add Direct Rule support"
    http://patches.dpdk.org/cover/51856/
    
[2] "net/mlx5: add support for multiport IB devices"
    http://patches.dpdk.org/cover/51800/

v2:
  - mutex reverted to non-counting type (because there is
    no DV flow functions intercalls and reentrances)
  - some commits are squashed to make patchset more consistent
  - conditional directives cleanup

v1:
  http://patches.dpdk.org/cover/52053/

Viacheslav Ovsiienko (2):
  net/mlx5: add Direct Rules flow data alloc/free routines
  net/mlx5: share Direct Rules/Verbs flow related structures

 drivers/net/mlx5/mlx5.c         | 119 ++++++++++++++++++++++++++----
 drivers/net/mlx5/mlx5.h         |  45 +++++++-----
 drivers/net/mlx5/mlx5_flow_dv.c | 159 ++++++++++++++++++++++++++++++++--------
 3 files changed, 259 insertions(+), 64 deletions(-)

-- 
1.8.3.1

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

* [dpdk-dev] [PATCH v2 0/2] support Direct Rules flows over shared IB context
  2019-04-04 13:04 ` [dpdk-dev] [PATCH v2 0/2] support Direct Rules flows over shared IB context Viacheslav Ovsiienko
@ 2019-04-04 13:04   ` Viacheslav Ovsiienko
  2019-04-04 13:04   ` [dpdk-dev] [PATCH v2 1/2] net/mlx5: add Direct Rules flow data alloc/free routines Viacheslav Ovsiienko
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 28+ messages in thread
From: Viacheslav Ovsiienko @ 2019-04-04 13:04 UTC (permalink / raw)
  To: dev; +Cc: shahafs

The Direct Rules/Direct Verbs flows support is going
to be added [1]. The master/representor over multiport
IB device is added [2]. This patchset adds support for
DR/DV flows with shared IB context over multiport IB
device.

The DV/DR flows applied to the master/representors on the
same IB device share the following entinies:
  - rx/tx namespaces
  - rx/tx flow tables
  - matchers
  - encap/decap action resources
  - flow tags (MARK actions)
  - modify action resources
  - jump tables

[1] "net/mlx5: Add Direct Rule support"
    http://patches.dpdk.org/cover/51856/
    
[2] "net/mlx5: add support for multiport IB devices"
    http://patches.dpdk.org/cover/51800/

v2:
  - mutex reverted to non-counting type (because there is
    no DV flow functions intercalls and reentrances)
  - some commits are squashed to make patchset more consistent
  - conditional directives cleanup

v1:
  http://patches.dpdk.org/cover/52053/

Viacheslav Ovsiienko (2):
  net/mlx5: add Direct Rules flow data alloc/free routines
  net/mlx5: share Direct Rules/Verbs flow related structures

 drivers/net/mlx5/mlx5.c         | 119 ++++++++++++++++++++++++++----
 drivers/net/mlx5/mlx5.h         |  45 +++++++-----
 drivers/net/mlx5/mlx5_flow_dv.c | 159 ++++++++++++++++++++++++++++++++--------
 3 files changed, 259 insertions(+), 64 deletions(-)

-- 
1.8.3.1


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

* [dpdk-dev] [PATCH v2 1/2] net/mlx5: add Direct Rules flow data alloc/free routines
  2019-04-04 13:04 ` [dpdk-dev] [PATCH v2 0/2] support Direct Rules flows over shared IB context Viacheslav Ovsiienko
  2019-04-04 13:04   ` Viacheslav Ovsiienko
@ 2019-04-04 13:04   ` Viacheslav Ovsiienko
  2019-04-04 13:04     ` Viacheslav Ovsiienko
  2019-04-04 13:04   ` [dpdk-dev] [PATCH v2 2/2] net/mlx5: share Direct Rules/Verbs flow related structures Viacheslav Ovsiienko
  2019-04-04 18:57   ` [dpdk-dev] [PATCH v2 0/2] support Direct Rules flows over shared IB context Shahaf Shuler
  3 siblings, 1 reply; 28+ messages in thread
From: Viacheslav Ovsiienko @ 2019-04-04 13:04 UTC (permalink / raw)
  To: dev; +Cc: shahafs

We are going to share the Direct Rules and Direct Verbs flow
device data structures between master and representors in the
E-Switch configurations over multiport IB device.

The code of initializing and destroying these data is
moved to dedicated routines, this is just a preparation
step for actual data sharing.

Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
---
 drivers/net/mlx5/mlx5.c | 117 +++++++++++++++++++++++++++++++++++++++++-------
 drivers/net/mlx5/mlx5.h |   4 ++
 2 files changed, 106 insertions(+), 15 deletions(-)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 65aa9cf..62cba00 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -303,6 +303,101 @@ struct mlx5_dev_spawn_data {
 }
 
 /**
+ * Initialize DR related data within private structure.
+ * Routine checks the reference counter and does actual
+ * resources creation/iniialization only if counter is zero.
+ *
+ * @param[in] priv
+ *   Pointer to the private device data structure.
+ *
+ * @return
+ *   Zero on success, positive error code otherwise.
+ */
+static int
+mlx5_alloc_shared_dr(struct mlx5_priv *priv)
+{
+#ifdef HAVE_MLX5DV_DR
+	struct mlx5_ibv_shared *sh = priv->sh;
+	int err = 0;
+	void *ns;
+
+	assert(sh);
+	if (sh->dv_refcnt) {
+		/* Shared DV/DR structures is already initialized. */
+		sh->dv_refcnt++;
+		priv->dr_shared = 1;
+		return 0;
+	}
+	/* Reference counter is zero, we should initialize structures. */
+	ns = mlx5dv_dr_create_ns(sh->ctx, MLX5DV_DR_NS_DOMAIN_INGRESS_BYPASS);
+	if (!ns) {
+		DRV_LOG(ERR, "ingress mlx5dv_dr_create_ns failed");
+		err = errno;
+		goto error;
+	}
+	priv->rx_ns = ns;
+	ns = mlx5dv_dr_create_ns(sh->ctx, MLX5DV_DR_NS_DOMAIN_EGRESS_BYPASS);
+	if (!ns) {
+		DRV_LOG(ERR, "egress mlx5dv_dr_create_ns failed");
+		err = errno;
+		goto error;
+	}
+	priv->tx_ns = ns;
+	sh->dv_refcnt++;
+	priv->dr_shared = 1;
+	return 0;
+
+error:
+       /* Rollback the created objects. */
+	if (priv->rx_ns) {
+		mlx5dv_dr_destroy_ns(priv->rx_ns);
+		priv->rx_ns = NULL;
+	}
+	if (priv->tx_ns) {
+		mlx5dv_dr_destroy_ns(priv->tx_ns);
+		priv->tx_ns = NULL;
+	}
+	return err;
+#else
+	(void)priv;
+	return 0;
+#endif
+}
+
+/**
+ * Destroy DR related data within private structure.
+ *
+ * @param[in] priv
+ *   Pointer to the private device data structure.
+ */
+static void
+mlx5_free_shared_dr(struct mlx5_priv *priv)
+{
+#ifdef HAVE_MLX5DV_DR
+	struct mlx5_ibv_shared *sh;
+
+	if (!priv->dr_shared)
+		return;
+	priv->dr_shared = 0;
+	sh = priv->sh;
+	assert(sh);
+	assert(sh->dv_refcnt);
+	if (sh->dv_refcnt && --sh->dv_refcnt)
+		return;
+	if (priv->rx_ns) {
+		mlx5dv_dr_destroy_ns(priv->rx_ns);
+		priv->rx_ns = NULL;
+	}
+	if (priv->tx_ns) {
+		mlx5dv_dr_destroy_ns(priv->tx_ns);
+		priv->tx_ns = NULL;
+	}
+#else
+	(void)priv;
+#endif
+}
+
+/**
  * Initialize shared data between primary and secondary process.
  *
  * A memzone is reserved by primary process and secondary processes attach to
@@ -495,6 +590,7 @@ struct mlx5_dev_spawn_data {
 	mlx5_mprq_free_mp(dev);
 	mlx5_mr_release(dev);
 	assert(priv->sh);
+	mlx5_free_shared_dr(priv);
 	if (priv->sh)
 		mlx5_free_shared_ibctx(priv->sh);
 	priv->sh = NULL;
@@ -1483,22 +1579,11 @@ struct mlx5_dev_spawn_data {
 			priv->tcf_context = NULL;
 		}
 	}
-#ifdef HAVE_MLX5DV_DR
-		priv->rx_ns = mlx5dv_dr_create_ns
-			(sh->ctx, MLX5DV_DR_NS_DOMAIN_INGRESS_BYPASS);
-		if (priv->rx_ns == NULL) {
-			DRV_LOG(ERR, "mlx5dv_dr_create_ns failed");
-			err = errno;
-			goto error;
-		}
-		priv->tx_ns = mlx5dv_dr_create_ns(sh->ctx,
-					 MLX5DV_DR_NS_DOMAIN_EGRESS_BYPASS);
-		if (priv->tx_ns == NULL) {
-			DRV_LOG(ERR, "mlx5dv_dr_create_ns failed");
-			err = errno;
+	if (config.dv_flow_en) {
+		err = mlx5_alloc_shared_dr(priv);
+		if (err)
 			goto error;
-		}
-#endif
+	}
 	TAILQ_INIT(&priv->flows);
 	TAILQ_INIT(&priv->ctrl_flows);
 	/* Hint libmlx5 to use PMD allocator for data plane resources */
@@ -1550,6 +1635,8 @@ struct mlx5_dev_spawn_data {
 	return eth_dev;
 error:
 	if (priv) {
+		if (priv->sh)
+			mlx5_free_shared_dr(priv);
 		if (priv->nl_socket_route >= 0)
 			close(priv->nl_socket_route);
 		if (priv->nl_socket_rdma >= 0)
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 5a7597e..a6f6ef4 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -253,6 +253,9 @@ struct mlx5_ibv_shared {
 	char ibdev_name[IBV_SYSFS_NAME_MAX]; /* IB device name. */
 	char ibdev_path[IBV_SYSFS_PATH_MAX]; /* IB device path for secondary */
 	struct ibv_device_attr_ex device_attr; /* Device properties. */
+	/* Shared DV/DR flow data section. */
+	uint32_t dv_refcnt; /* DV/DR data reference counter. */
+	/* Shared interrupt handler section. */
 	pthread_mutex_t intr_mutex; /* Interrupt config mutex. */
 	uint32_t intr_cnt; /* Interrupt handler reference counter. */
 	struct rte_intr_handle intr_handle; /* Interrupt handler for device. */
@@ -284,6 +287,7 @@ struct mlx5_priv {
 	unsigned int isolated:1; /* Whether isolated mode is enabled. */
 	unsigned int representor:1; /* Device is a port representor. */
 	unsigned int master:1; /* Device is a E-Switch master. */
+	unsigned int dr_shared:1; /* DV/DR data is shared. */
 	uint16_t domain_id; /* Switch domain identifier. */
 	uint16_t vport_id; /* Associated VF vport index (if any). */
 	int32_t representor_id; /* Port representor identifier. */
-- 
1.8.3.1

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

* [dpdk-dev] [PATCH v2 1/2] net/mlx5: add Direct Rules flow data alloc/free routines
  2019-04-04 13:04   ` [dpdk-dev] [PATCH v2 1/2] net/mlx5: add Direct Rules flow data alloc/free routines Viacheslav Ovsiienko
@ 2019-04-04 13:04     ` Viacheslav Ovsiienko
  0 siblings, 0 replies; 28+ messages in thread
From: Viacheslav Ovsiienko @ 2019-04-04 13:04 UTC (permalink / raw)
  To: dev; +Cc: shahafs

We are going to share the Direct Rules and Direct Verbs flow
device data structures between master and representors in the
E-Switch configurations over multiport IB device.

The code of initializing and destroying these data is
moved to dedicated routines, this is just a preparation
step for actual data sharing.

Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
---
 drivers/net/mlx5/mlx5.c | 117 +++++++++++++++++++++++++++++++++++++++++-------
 drivers/net/mlx5/mlx5.h |   4 ++
 2 files changed, 106 insertions(+), 15 deletions(-)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 65aa9cf..62cba00 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -303,6 +303,101 @@ struct mlx5_dev_spawn_data {
 }
 
 /**
+ * Initialize DR related data within private structure.
+ * Routine checks the reference counter and does actual
+ * resources creation/iniialization only if counter is zero.
+ *
+ * @param[in] priv
+ *   Pointer to the private device data structure.
+ *
+ * @return
+ *   Zero on success, positive error code otherwise.
+ */
+static int
+mlx5_alloc_shared_dr(struct mlx5_priv *priv)
+{
+#ifdef HAVE_MLX5DV_DR
+	struct mlx5_ibv_shared *sh = priv->sh;
+	int err = 0;
+	void *ns;
+
+	assert(sh);
+	if (sh->dv_refcnt) {
+		/* Shared DV/DR structures is already initialized. */
+		sh->dv_refcnt++;
+		priv->dr_shared = 1;
+		return 0;
+	}
+	/* Reference counter is zero, we should initialize structures. */
+	ns = mlx5dv_dr_create_ns(sh->ctx, MLX5DV_DR_NS_DOMAIN_INGRESS_BYPASS);
+	if (!ns) {
+		DRV_LOG(ERR, "ingress mlx5dv_dr_create_ns failed");
+		err = errno;
+		goto error;
+	}
+	priv->rx_ns = ns;
+	ns = mlx5dv_dr_create_ns(sh->ctx, MLX5DV_DR_NS_DOMAIN_EGRESS_BYPASS);
+	if (!ns) {
+		DRV_LOG(ERR, "egress mlx5dv_dr_create_ns failed");
+		err = errno;
+		goto error;
+	}
+	priv->tx_ns = ns;
+	sh->dv_refcnt++;
+	priv->dr_shared = 1;
+	return 0;
+
+error:
+       /* Rollback the created objects. */
+	if (priv->rx_ns) {
+		mlx5dv_dr_destroy_ns(priv->rx_ns);
+		priv->rx_ns = NULL;
+	}
+	if (priv->tx_ns) {
+		mlx5dv_dr_destroy_ns(priv->tx_ns);
+		priv->tx_ns = NULL;
+	}
+	return err;
+#else
+	(void)priv;
+	return 0;
+#endif
+}
+
+/**
+ * Destroy DR related data within private structure.
+ *
+ * @param[in] priv
+ *   Pointer to the private device data structure.
+ */
+static void
+mlx5_free_shared_dr(struct mlx5_priv *priv)
+{
+#ifdef HAVE_MLX5DV_DR
+	struct mlx5_ibv_shared *sh;
+
+	if (!priv->dr_shared)
+		return;
+	priv->dr_shared = 0;
+	sh = priv->sh;
+	assert(sh);
+	assert(sh->dv_refcnt);
+	if (sh->dv_refcnt && --sh->dv_refcnt)
+		return;
+	if (priv->rx_ns) {
+		mlx5dv_dr_destroy_ns(priv->rx_ns);
+		priv->rx_ns = NULL;
+	}
+	if (priv->tx_ns) {
+		mlx5dv_dr_destroy_ns(priv->tx_ns);
+		priv->tx_ns = NULL;
+	}
+#else
+	(void)priv;
+#endif
+}
+
+/**
  * Initialize shared data between primary and secondary process.
  *
  * A memzone is reserved by primary process and secondary processes attach to
@@ -495,6 +590,7 @@ struct mlx5_dev_spawn_data {
 	mlx5_mprq_free_mp(dev);
 	mlx5_mr_release(dev);
 	assert(priv->sh);
+	mlx5_free_shared_dr(priv);
 	if (priv->sh)
 		mlx5_free_shared_ibctx(priv->sh);
 	priv->sh = NULL;
@@ -1483,22 +1579,11 @@ struct mlx5_dev_spawn_data {
 			priv->tcf_context = NULL;
 		}
 	}
-#ifdef HAVE_MLX5DV_DR
-		priv->rx_ns = mlx5dv_dr_create_ns
-			(sh->ctx, MLX5DV_DR_NS_DOMAIN_INGRESS_BYPASS);
-		if (priv->rx_ns == NULL) {
-			DRV_LOG(ERR, "mlx5dv_dr_create_ns failed");
-			err = errno;
-			goto error;
-		}
-		priv->tx_ns = mlx5dv_dr_create_ns(sh->ctx,
-					 MLX5DV_DR_NS_DOMAIN_EGRESS_BYPASS);
-		if (priv->tx_ns == NULL) {
-			DRV_LOG(ERR, "mlx5dv_dr_create_ns failed");
-			err = errno;
+	if (config.dv_flow_en) {
+		err = mlx5_alloc_shared_dr(priv);
+		if (err)
 			goto error;
-		}
-#endif
+	}
 	TAILQ_INIT(&priv->flows);
 	TAILQ_INIT(&priv->ctrl_flows);
 	/* Hint libmlx5 to use PMD allocator for data plane resources */
@@ -1550,6 +1635,8 @@ struct mlx5_dev_spawn_data {
 	return eth_dev;
 error:
 	if (priv) {
+		if (priv->sh)
+			mlx5_free_shared_dr(priv);
 		if (priv->nl_socket_route >= 0)
 			close(priv->nl_socket_route);
 		if (priv->nl_socket_rdma >= 0)
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 5a7597e..a6f6ef4 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -253,6 +253,9 @@ struct mlx5_ibv_shared {
 	char ibdev_name[IBV_SYSFS_NAME_MAX]; /* IB device name. */
 	char ibdev_path[IBV_SYSFS_PATH_MAX]; /* IB device path for secondary */
 	struct ibv_device_attr_ex device_attr; /* Device properties. */
+	/* Shared DV/DR flow data section. */
+	uint32_t dv_refcnt; /* DV/DR data reference counter. */
+	/* Shared interrupt handler section. */
 	pthread_mutex_t intr_mutex; /* Interrupt config mutex. */
 	uint32_t intr_cnt; /* Interrupt handler reference counter. */
 	struct rte_intr_handle intr_handle; /* Interrupt handler for device. */
@@ -284,6 +287,7 @@ struct mlx5_priv {
 	unsigned int isolated:1; /* Whether isolated mode is enabled. */
 	unsigned int representor:1; /* Device is a port representor. */
 	unsigned int master:1; /* Device is a E-Switch master. */
+	unsigned int dr_shared:1; /* DV/DR data is shared. */
 	uint16_t domain_id; /* Switch domain identifier. */
 	uint16_t vport_id; /* Associated VF vport index (if any). */
 	int32_t representor_id; /* Port representor identifier. */
-- 
1.8.3.1


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

* [dpdk-dev] [PATCH v2 2/2] net/mlx5: share Direct Rules/Verbs flow related structures
  2019-04-04 13:04 ` [dpdk-dev] [PATCH v2 0/2] support Direct Rules flows over shared IB context Viacheslav Ovsiienko
  2019-04-04 13:04   ` Viacheslav Ovsiienko
  2019-04-04 13:04   ` [dpdk-dev] [PATCH v2 1/2] net/mlx5: add Direct Rules flow data alloc/free routines Viacheslav Ovsiienko
@ 2019-04-04 13:04   ` Viacheslav Ovsiienko
  2019-04-04 13:04     ` Viacheslav Ovsiienko
  2019-04-04 18:57   ` [dpdk-dev] [PATCH v2 0/2] support Direct Rules flows over shared IB context Shahaf Shuler
  3 siblings, 1 reply; 28+ messages in thread
From: Viacheslav Ovsiienko @ 2019-04-04 13:04 UTC (permalink / raw)
  To: dev; +Cc: shahafs

Direct Rules/Verbs related structures are moved to
the shared context:
  - rx/tx namespaces, shared by master and representors
  - rx/tx flow tables
  - matchers
  - encap/decap action resources
  - flow tags (MARK actions)
  - modify action resources
  - jump tables

Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
---
 drivers/net/mlx5/mlx5.c         |  30 ++++----
 drivers/net/mlx5/mlx5.h         |  41 ++++++-----
 drivers/net/mlx5/mlx5_flow_dv.c | 159 ++++++++++++++++++++++++++++++++--------
 3 files changed, 167 insertions(+), 63 deletions(-)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 62cba00..aea72a1 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -335,27 +335,28 @@ struct mlx5_dev_spawn_data {
 		err = errno;
 		goto error;
 	}
-	priv->rx_ns = ns;
+	sh->rx_ns = ns;
 	ns = mlx5dv_dr_create_ns(sh->ctx, MLX5DV_DR_NS_DOMAIN_EGRESS_BYPASS);
 	if (!ns) {
 		DRV_LOG(ERR, "egress mlx5dv_dr_create_ns failed");
 		err = errno;
 		goto error;
 	}
-	priv->tx_ns = ns;
+	pthread_mutex_init(&sh->dv_mutex, NULL);
+	sh->tx_ns = ns;
 	sh->dv_refcnt++;
 	priv->dr_shared = 1;
 	return 0;
 
 error:
        /* Rollback the created objects. */
-	if (priv->rx_ns) {
-		mlx5dv_dr_destroy_ns(priv->rx_ns);
-		priv->rx_ns = NULL;
+	if (sh->rx_ns) {
+		mlx5dv_dr_destroy_ns(sh->rx_ns);
+		sh->rx_ns = NULL;
 	}
-	if (priv->tx_ns) {
-		mlx5dv_dr_destroy_ns(priv->tx_ns);
-		priv->tx_ns = NULL;
+	if (sh->tx_ns) {
+		mlx5dv_dr_destroy_ns(sh->tx_ns);
+		sh->tx_ns = NULL;
 	}
 	return err;
 #else
@@ -384,14 +385,15 @@ struct mlx5_dev_spawn_data {
 	assert(sh->dv_refcnt);
 	if (sh->dv_refcnt && --sh->dv_refcnt)
 		return;
-	if (priv->rx_ns) {
-		mlx5dv_dr_destroy_ns(priv->rx_ns);
-		priv->rx_ns = NULL;
+	if (sh->rx_ns) {
+		mlx5dv_dr_destroy_ns(sh->rx_ns);
+		sh->rx_ns = NULL;
 	}
-	if (priv->tx_ns) {
-		mlx5dv_dr_destroy_ns(priv->tx_ns);
-		priv->tx_ns = NULL;
+	if (sh->tx_ns) {
+		mlx5dv_dr_destroy_ns(sh->tx_ns);
+		sh->tx_ns = NULL;
 	}
+	pthread_mutex_destroy(&sh->dv_mutex);
 #else
 	(void)priv;
 #endif
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index a6f6ef4..ef05d9f 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -239,6 +239,15 @@ struct mlx5_ibv_shared_port {
 	 */
 };
 
+/* Table structure. */
+struct mlx5_flow_tbl_resource {
+	void *obj; /**< Pointer to DR table object. */
+	rte_atomic32_t refcnt; /**< Reference counter. */
+};
+
+#define MLX5_MAX_TABLES 1024
+#define MLX5_GROUP_FACTOR 1
+
 /*
  * Shared Infiniband device context for Master/Representors
  * which belong to same IB device with multiple IB ports.
@@ -254,7 +263,19 @@ struct mlx5_ibv_shared {
 	char ibdev_path[IBV_SYSFS_PATH_MAX]; /* IB device path for secondary */
 	struct ibv_device_attr_ex device_attr; /* Device properties. */
 	/* Shared DV/DR flow data section. */
+	pthread_mutex_t dv_mutex; /* DV context mutex. */
 	uint32_t dv_refcnt; /* DV/DR data reference counter. */
+	void *rx_ns; /* RX Direct Rules name space handle. */
+	struct mlx5_flow_tbl_resource rx_tbl[MLX5_MAX_TABLES];
+	/* RX Direct Rules tables. */
+	void *tx_ns; /* TX Direct Rules name space handle. */
+	struct mlx5_flow_tbl_resource tx_tbl[MLX5_MAX_TABLES];
+	/* TX Direct Rules tables/ */
+	LIST_HEAD(matchers, mlx5_flow_dv_matcher) matchers;
+	LIST_HEAD(encap_decap, mlx5_flow_dv_encap_decap_resource) encaps_decaps;
+	LIST_HEAD(modify_cmd, mlx5_flow_dv_modify_hdr_resource) modify_cmds;
+	LIST_HEAD(tag, mlx5_flow_dv_tag_resource) tags;
+	LIST_HEAD(jump, mlx5_flow_dv_jump_tbl_resource) jump_tbl;
 	/* Shared interrupt handler section. */
 	pthread_mutex_t intr_mutex; /* Interrupt config mutex. */
 	uint32_t intr_cnt; /* Interrupt handler reference counter. */
@@ -262,15 +283,6 @@ struct mlx5_ibv_shared {
 	struct mlx5_ibv_shared_port port[]; /* per device port data array. */
 };
 
-/* Table structure. */
-struct mlx5_flow_tbl_resource {
-	void *obj; /**< Pointer to DR table object. */
-	rte_atomic32_t refcnt; /**< Reference counter. */
-};
-
-#define MLX5_MAX_TABLES 1024
-#define MLX5_GROUP_FACTOR 1
-
 struct mlx5_priv {
 	LIST_ENTRY(mlx5_priv) mem_event_cb;
 	/**< Called by memory event callback. */
@@ -319,11 +331,6 @@ struct mlx5_priv {
 	LIST_HEAD(txqibv, mlx5_txq_ibv) txqsibv; /* Verbs Tx queues. */
 	/* Verbs Indirection tables. */
 	LIST_HEAD(ind_tables, mlx5_ind_table_ibv) ind_tbls;
-	LIST_HEAD(matchers, mlx5_flow_dv_matcher) matchers;
-	LIST_HEAD(encap_decap, mlx5_flow_dv_encap_decap_resource) encaps_decaps;
-	LIST_HEAD(modify_cmd, mlx5_flow_dv_modify_hdr_resource) modify_cmds;
-	LIST_HEAD(tag, mlx5_flow_dv_tag_resource) tags;
-	LIST_HEAD(jump, mlx5_flow_dv_jump_tbl_resource) jump_tbl;
 	/* Pointer to next element. */
 	rte_atomic32_t refcnt; /**< Reference counter. */
 	struct ibv_flow_action *verbs_action;
@@ -345,12 +352,6 @@ struct mlx5_priv {
 	/* UAR same-page access control required in 32bit implementations. */
 #endif
 	struct mlx5_flow_tcf_context *tcf_context; /* TC flower context. */
-	void *rx_ns; /* RX Direct Rules name space handle. */
-	struct mlx5_flow_tbl_resource rx_tbl[MLX5_MAX_TABLES];
-	/* RX Direct Rules tables. */
-	void *tx_ns; /* TX Direct Rules name space handle. */
-	struct mlx5_flow_tbl_resource tx_tbl[MLX5_MAX_TABLES];
-	/* TX Direct Rules tables/ */
 };
 
 #define PORT_ID(priv) ((priv)->dev_data->port_id)
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 10c6eee..52be8b3 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -129,6 +129,45 @@ struct field_modify_info modify_tcp[] = {
 };
 
 /**
+ * Acquire the synchronizing object to protect multithreaded access
+ * to shared dv context. Lock occurs only if context is actually
+ * shared, i.e. we have multiport IB device and representors are
+ * created.
+ *
+ * @param[in] dev
+ *   Pointer to the rte_eth_dev structure.
+ */
+static void
+flow_d_shared_lock(struct rte_eth_dev *dev)
+{
+	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
+
+	if (sh->dv_refcnt > 1) {
+		int ret;
+
+		ret = pthread_mutex_lock(&sh->dv_mutex);
+		assert(!ret);
+		(void)ret;
+	}
+}
+
+static void
+flow_d_shared_unlock(struct rte_eth_dev *dev)
+{
+	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
+
+	if (sh->dv_refcnt > 1) {
+		int ret;
+
+		ret = pthread_mutex_unlock(&sh->dv_mutex);
+		assert(!ret);
+		(void)ret;
+	}
+}
+
+/**
  * Convert modify-header action to DV specification.
  *
  * @param[in] item
@@ -808,18 +847,19 @@ struct field_modify_info modify_tcp[] = {
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_dv_encap_decap_resource *cache_resource;
 	struct rte_flow *flow = dev_flow->flow;
 	struct mlx5dv_dr_ns *ns;
 
 	resource->flags = flow->group ? 0 : 1;
 	if (flow->ingress)
-		ns = priv->rx_ns;
+		ns = sh->rx_ns;
 	else
-		ns = priv->tx_ns;
+		ns = sh->tx_ns;
 
 	/* Lookup a matching resource from cache. */
-	LIST_FOREACH(cache_resource, &priv->encaps_decaps, next) {
+	LIST_FOREACH(cache_resource, &sh->encaps_decaps, next) {
 		if (resource->reformat_type == cache_resource->reformat_type &&
 		    resource->ft_type == cache_resource->ft_type &&
 		    resource->flags == cache_resource->flags &&
@@ -844,7 +884,7 @@ struct field_modify_info modify_tcp[] = {
 	*cache_resource = *resource;
 	cache_resource->verbs_action =
 		mlx5_glue->dv_create_flow_action_packet_reformat
-			(priv->sh->ctx, cache_resource->reformat_type,
+			(sh->ctx, cache_resource->reformat_type,
 			 cache_resource->ft_type, ns, cache_resource->flags,
 			 cache_resource->size,
 			 (cache_resource->size ? cache_resource->buf : NULL));
@@ -856,7 +896,7 @@ struct field_modify_info modify_tcp[] = {
 	}
 	rte_atomic32_init(&cache_resource->refcnt);
 	rte_atomic32_inc(&cache_resource->refcnt);
-	LIST_INSERT_HEAD(&priv->encaps_decaps, cache_resource, next);
+	LIST_INSERT_HEAD(&sh->encaps_decaps, cache_resource, next);
 	dev_flow->dv.encap_decap = cache_resource;
 	DRV_LOG(DEBUG, "new encap/decap resource %p: refcnt %d++",
 		(void *)cache_resource,
@@ -887,10 +927,11 @@ struct field_modify_info modify_tcp[] = {
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_dv_jump_tbl_resource *cache_resource;
 
 	/* Lookup a matching resource from cache. */
-	LIST_FOREACH(cache_resource, &priv->jump_tbl, next) {
+	LIST_FOREACH(cache_resource, &sh->jump_tbl, next) {
 		if (resource->tbl == cache_resource->tbl) {
 			DRV_LOG(DEBUG, "jump table resource resource %p: refcnt %d++",
 				(void *)cache_resource,
@@ -918,7 +959,7 @@ struct field_modify_info modify_tcp[] = {
 	}
 	rte_atomic32_init(&cache_resource->refcnt);
 	rte_atomic32_inc(&cache_resource->refcnt);
-	LIST_INSERT_HEAD(&priv->jump_tbl, cache_resource, next);
+	LIST_INSERT_HEAD(&sh->jump_tbl, cache_resource, next);
 	dev_flow->dv.jump = cache_resource;
 	DRV_LOG(DEBUG, "new jump table  resource %p: refcnt %d++",
 		(void *)cache_resource,
@@ -1542,14 +1583,15 @@ struct field_modify_info modify_tcp[] = {
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_dv_modify_hdr_resource *cache_resource;
 
 	struct mlx5dv_dr_ns *ns =
 		resource->ft_type == MLX5DV_FLOW_TABLE_TYPE_NIC_TX  ?
-		priv->tx_ns : priv->rx_ns;
+		sh->tx_ns : sh->rx_ns;
 
 	/* Lookup a matching resource from cache. */
-	LIST_FOREACH(cache_resource, &priv->modify_cmds, next) {
+	LIST_FOREACH(cache_resource, &sh->modify_cmds, next) {
 		if (resource->ft_type == cache_resource->ft_type &&
 		    resource->actions_num == cache_resource->actions_num &&
 		    !memcmp((const void *)resource->actions,
@@ -1573,7 +1615,7 @@ struct field_modify_info modify_tcp[] = {
 	*cache_resource = *resource;
 	cache_resource->verbs_action =
 		mlx5_glue->dv_create_flow_action_modify_header
-					(priv->sh->ctx, cache_resource->ft_type,
+					(sh->ctx, cache_resource->ft_type,
 					 ns, 0,
 					 cache_resource->actions_num *
 					 sizeof(cache_resource->actions[0]),
@@ -1586,7 +1628,7 @@ struct field_modify_info modify_tcp[] = {
 	}
 	rte_atomic32_init(&cache_resource->refcnt);
 	rte_atomic32_inc(&cache_resource->refcnt);
-	LIST_INSERT_HEAD(&priv->modify_cmds, cache_resource, next);
+	LIST_INSERT_HEAD(&sh->modify_cmds, cache_resource, next);
 	dev_flow->dv.modify_hdr = cache_resource;
 	DRV_LOG(DEBUG, "new modify-header resource %p: refcnt %d++",
 		(void *)cache_resource,
@@ -2883,19 +2925,20 @@ struct field_modify_info modify_tcp[] = {
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_tbl_resource *tbl;
 
 #ifdef HAVE_MLX5DV_DR
 	if (egress) {
-		tbl = &priv->tx_tbl[table_id];
+		tbl = &sh->tx_tbl[table_id];
 		if (!tbl->obj)
 			tbl->obj = mlx5_glue->dr_create_flow_tbl
-				(priv->tx_ns, table_id);
+				(sh->tx_ns, table_id);
 	} else {
-		tbl = &priv->rx_tbl[table_id];
+		tbl = &sh->rx_tbl[table_id];
 		if (!tbl->obj)
 			tbl->obj = mlx5_glue->dr_create_flow_tbl
-				(priv->rx_ns, table_id);
+				(sh->rx_ns, table_id);
 	}
 	if (!tbl->obj) {
 		rte_flow_error_set(error, ENOMEM,
@@ -2909,9 +2952,9 @@ struct field_modify_info modify_tcp[] = {
 	(void)error;
 	(void)tbl;
 	if (egress)
-		return &priv->tx_tbl[table_id];
+		return &sh->tx_tbl[table_id];
 	else
-		return &priv->rx_tbl[table_id];
+		return &sh->rx_tbl[table_id];
 #endif
 }
 
@@ -2959,6 +3002,7 @@ struct field_modify_info modify_tcp[] = {
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_dv_matcher *cache_matcher;
 	struct mlx5dv_flow_matcher_attr dv_attr = {
 		.type = IBV_FLOW_ATTR_NORMAL,
@@ -2967,7 +3011,7 @@ struct field_modify_info modify_tcp[] = {
 	struct mlx5_flow_tbl_resource *tbl = NULL;
 
 	/* Lookup from cache. */
-	LIST_FOREACH(cache_matcher, &priv->matchers, next) {
+	LIST_FOREACH(cache_matcher, &sh->matchers, next) {
 		if (matcher->crc == cache_matcher->crc &&
 		    matcher->priority == cache_matcher->priority &&
 		    matcher->egress == cache_matcher->egress &&
@@ -3007,8 +3051,7 @@ struct field_modify_info modify_tcp[] = {
 	if (matcher->egress)
 		dv_attr.flags |= IBV_FLOW_ATTR_FLAGS_EGRESS;
 	cache_matcher->matcher_object =
-		mlx5_glue->dv_create_flow_matcher(priv->sh->ctx, &dv_attr,
-						  tbl->obj);
+		mlx5_glue->dv_create_flow_matcher(sh->ctx, &dv_attr, tbl->obj);
 	if (!cache_matcher->matcher_object) {
 		rte_free(cache_matcher);
 #ifdef HAVE_MLX5DV_DR
@@ -3019,7 +3062,7 @@ struct field_modify_info modify_tcp[] = {
 					  NULL, "cannot create matcher");
 	}
 	rte_atomic32_inc(&cache_matcher->refcnt);
-	LIST_INSERT_HEAD(&priv->matchers, cache_matcher, next);
+	LIST_INSERT_HEAD(&sh->matchers, cache_matcher, next);
 	dev_flow->dv.matcher = cache_matcher;
 	DRV_LOG(DEBUG, "priority %hd new %s matcher %p: refcnt %d",
 		cache_matcher->priority,
@@ -3075,10 +3118,11 @@ struct field_modify_info modify_tcp[] = {
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_dv_tag_resource *cache_resource;
 
 	/* Lookup a matching resource from cache. */
-	LIST_FOREACH(cache_resource, &priv->tags, next) {
+	LIST_FOREACH(cache_resource, &sh->tags, next) {
 		if (resource->tag == cache_resource->tag) {
 			DRV_LOG(DEBUG, "tag resource %p: refcnt %d++",
 				(void *)cache_resource,
@@ -3105,7 +3149,7 @@ struct field_modify_info modify_tcp[] = {
 	}
 	rte_atomic32_init(&cache_resource->refcnt);
 	rte_atomic32_inc(&cache_resource->refcnt);
-	LIST_INSERT_HEAD(&priv->tags, cache_resource, next);
+	LIST_INSERT_HEAD(&sh->tags, cache_resource, next);
 	dev_flow->flow->tag_resource = cache_resource;
 	DRV_LOG(DEBUG, "new tag resource %p: refcnt %d++",
 		(void *)cache_resource,
@@ -3682,6 +3726,7 @@ struct field_modify_info modify_tcp[] = {
 {
 	struct mlx5_flow_dv_matcher *matcher = flow->dv.matcher;
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_tbl_resource *tbl;
 
 	assert(matcher->matcher_object);
@@ -3693,9 +3738,9 @@ struct field_modify_info modify_tcp[] = {
 			   (matcher->matcher_object));
 		LIST_REMOVE(matcher, next);
 		if (matcher->egress)
-			tbl = &priv->tx_tbl[matcher->group];
+			tbl = &sh->tx_tbl[matcher->group];
 		else
-			tbl = &priv->rx_tbl[matcher->group];
+			tbl = &sh->rx_tbl[matcher->group];
 		flow_dv_tbl_resource_release(tbl);
 		rte_free(matcher);
 		DRV_LOG(DEBUG, "port %u matcher %p: removed",
@@ -3958,14 +4003,70 @@ struct field_modify_info modify_tcp[] = {
 	return ret;
 }
 
+/*
+ * Mutex-protected thunk to flow_dv_translate().
+ */
+static int
+flow_d_translate(struct rte_eth_dev *dev,
+		 struct mlx5_flow *dev_flow,
+		 const struct rte_flow_attr *attr,
+		 const struct rte_flow_item items[],
+		 const struct rte_flow_action actions[],
+		 struct rte_flow_error *error)
+{
+	int ret;
+
+	flow_d_shared_lock(dev);
+	ret = flow_dv_translate(dev, dev_flow, attr, items, actions, error);
+	flow_d_shared_unlock(dev);
+	return ret;
+}
+
+/*
+ * Mutex-protected thunk to flow_dv_apply().
+ */
+static int
+flow_d_apply(struct rte_eth_dev *dev,
+	     struct rte_flow *flow,
+	     struct rte_flow_error *error)
+{
+	int ret;
+
+	flow_d_shared_lock(dev);
+	ret = flow_dv_apply(dev, flow, error);
+	flow_d_shared_unlock(dev);
+	return ret;
+}
+
+/*
+ * Mutex-protected thunk to flow_dv_remove().
+ */
+static void
+flow_d_remove(struct rte_eth_dev *dev, struct rte_flow *flow)
+{
+	flow_d_shared_lock(dev);
+	flow_dv_remove(dev, flow);
+	flow_d_shared_unlock(dev);
+}
+
+/*
+ * Mutex-protected thunk to flow_dv_destroy().
+ */
+static void
+flow_d_destroy(struct rte_eth_dev *dev, struct rte_flow *flow)
+{
+	flow_d_shared_lock(dev);
+	flow_dv_destroy(dev, flow);
+	flow_d_shared_unlock(dev);
+}
 
 const struct mlx5_flow_driver_ops mlx5_flow_dv_drv_ops = {
 	.validate = flow_dv_validate,
 	.prepare = flow_dv_prepare,
-	.translate = flow_dv_translate,
-	.apply = flow_dv_apply,
-	.remove = flow_dv_remove,
-	.destroy = flow_dv_destroy,
+	.translate = flow_d_translate,
+	.apply = flow_d_apply,
+	.remove = flow_d_remove,
+	.destroy = flow_d_destroy,
 	.query = flow_dv_query,
 };
 
-- 
1.8.3.1

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

* [dpdk-dev] [PATCH v2 2/2] net/mlx5: share Direct Rules/Verbs flow related structures
  2019-04-04 13:04   ` [dpdk-dev] [PATCH v2 2/2] net/mlx5: share Direct Rules/Verbs flow related structures Viacheslav Ovsiienko
@ 2019-04-04 13:04     ` Viacheslav Ovsiienko
  0 siblings, 0 replies; 28+ messages in thread
From: Viacheslav Ovsiienko @ 2019-04-04 13:04 UTC (permalink / raw)
  To: dev; +Cc: shahafs

Direct Rules/Verbs related structures are moved to
the shared context:
  - rx/tx namespaces, shared by master and representors
  - rx/tx flow tables
  - matchers
  - encap/decap action resources
  - flow tags (MARK actions)
  - modify action resources
  - jump tables

Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
---
 drivers/net/mlx5/mlx5.c         |  30 ++++----
 drivers/net/mlx5/mlx5.h         |  41 ++++++-----
 drivers/net/mlx5/mlx5_flow_dv.c | 159 ++++++++++++++++++++++++++++++++--------
 3 files changed, 167 insertions(+), 63 deletions(-)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 62cba00..aea72a1 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -335,27 +335,28 @@ struct mlx5_dev_spawn_data {
 		err = errno;
 		goto error;
 	}
-	priv->rx_ns = ns;
+	sh->rx_ns = ns;
 	ns = mlx5dv_dr_create_ns(sh->ctx, MLX5DV_DR_NS_DOMAIN_EGRESS_BYPASS);
 	if (!ns) {
 		DRV_LOG(ERR, "egress mlx5dv_dr_create_ns failed");
 		err = errno;
 		goto error;
 	}
-	priv->tx_ns = ns;
+	pthread_mutex_init(&sh->dv_mutex, NULL);
+	sh->tx_ns = ns;
 	sh->dv_refcnt++;
 	priv->dr_shared = 1;
 	return 0;
 
 error:
        /* Rollback the created objects. */
-	if (priv->rx_ns) {
-		mlx5dv_dr_destroy_ns(priv->rx_ns);
-		priv->rx_ns = NULL;
+	if (sh->rx_ns) {
+		mlx5dv_dr_destroy_ns(sh->rx_ns);
+		sh->rx_ns = NULL;
 	}
-	if (priv->tx_ns) {
-		mlx5dv_dr_destroy_ns(priv->tx_ns);
-		priv->tx_ns = NULL;
+	if (sh->tx_ns) {
+		mlx5dv_dr_destroy_ns(sh->tx_ns);
+		sh->tx_ns = NULL;
 	}
 	return err;
 #else
@@ -384,14 +385,15 @@ struct mlx5_dev_spawn_data {
 	assert(sh->dv_refcnt);
 	if (sh->dv_refcnt && --sh->dv_refcnt)
 		return;
-	if (priv->rx_ns) {
-		mlx5dv_dr_destroy_ns(priv->rx_ns);
-		priv->rx_ns = NULL;
+	if (sh->rx_ns) {
+		mlx5dv_dr_destroy_ns(sh->rx_ns);
+		sh->rx_ns = NULL;
 	}
-	if (priv->tx_ns) {
-		mlx5dv_dr_destroy_ns(priv->tx_ns);
-		priv->tx_ns = NULL;
+	if (sh->tx_ns) {
+		mlx5dv_dr_destroy_ns(sh->tx_ns);
+		sh->tx_ns = NULL;
 	}
+	pthread_mutex_destroy(&sh->dv_mutex);
 #else
 	(void)priv;
 #endif
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index a6f6ef4..ef05d9f 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -239,6 +239,15 @@ struct mlx5_ibv_shared_port {
 	 */
 };
 
+/* Table structure. */
+struct mlx5_flow_tbl_resource {
+	void *obj; /**< Pointer to DR table object. */
+	rte_atomic32_t refcnt; /**< Reference counter. */
+};
+
+#define MLX5_MAX_TABLES 1024
+#define MLX5_GROUP_FACTOR 1
+
 /*
  * Shared Infiniband device context for Master/Representors
  * which belong to same IB device with multiple IB ports.
@@ -254,7 +263,19 @@ struct mlx5_ibv_shared {
 	char ibdev_path[IBV_SYSFS_PATH_MAX]; /* IB device path for secondary */
 	struct ibv_device_attr_ex device_attr; /* Device properties. */
 	/* Shared DV/DR flow data section. */
+	pthread_mutex_t dv_mutex; /* DV context mutex. */
 	uint32_t dv_refcnt; /* DV/DR data reference counter. */
+	void *rx_ns; /* RX Direct Rules name space handle. */
+	struct mlx5_flow_tbl_resource rx_tbl[MLX5_MAX_TABLES];
+	/* RX Direct Rules tables. */
+	void *tx_ns; /* TX Direct Rules name space handle. */
+	struct mlx5_flow_tbl_resource tx_tbl[MLX5_MAX_TABLES];
+	/* TX Direct Rules tables/ */
+	LIST_HEAD(matchers, mlx5_flow_dv_matcher) matchers;
+	LIST_HEAD(encap_decap, mlx5_flow_dv_encap_decap_resource) encaps_decaps;
+	LIST_HEAD(modify_cmd, mlx5_flow_dv_modify_hdr_resource) modify_cmds;
+	LIST_HEAD(tag, mlx5_flow_dv_tag_resource) tags;
+	LIST_HEAD(jump, mlx5_flow_dv_jump_tbl_resource) jump_tbl;
 	/* Shared interrupt handler section. */
 	pthread_mutex_t intr_mutex; /* Interrupt config mutex. */
 	uint32_t intr_cnt; /* Interrupt handler reference counter. */
@@ -262,15 +283,6 @@ struct mlx5_ibv_shared {
 	struct mlx5_ibv_shared_port port[]; /* per device port data array. */
 };
 
-/* Table structure. */
-struct mlx5_flow_tbl_resource {
-	void *obj; /**< Pointer to DR table object. */
-	rte_atomic32_t refcnt; /**< Reference counter. */
-};
-
-#define MLX5_MAX_TABLES 1024
-#define MLX5_GROUP_FACTOR 1
-
 struct mlx5_priv {
 	LIST_ENTRY(mlx5_priv) mem_event_cb;
 	/**< Called by memory event callback. */
@@ -319,11 +331,6 @@ struct mlx5_priv {
 	LIST_HEAD(txqibv, mlx5_txq_ibv) txqsibv; /* Verbs Tx queues. */
 	/* Verbs Indirection tables. */
 	LIST_HEAD(ind_tables, mlx5_ind_table_ibv) ind_tbls;
-	LIST_HEAD(matchers, mlx5_flow_dv_matcher) matchers;
-	LIST_HEAD(encap_decap, mlx5_flow_dv_encap_decap_resource) encaps_decaps;
-	LIST_HEAD(modify_cmd, mlx5_flow_dv_modify_hdr_resource) modify_cmds;
-	LIST_HEAD(tag, mlx5_flow_dv_tag_resource) tags;
-	LIST_HEAD(jump, mlx5_flow_dv_jump_tbl_resource) jump_tbl;
 	/* Pointer to next element. */
 	rte_atomic32_t refcnt; /**< Reference counter. */
 	struct ibv_flow_action *verbs_action;
@@ -345,12 +352,6 @@ struct mlx5_priv {
 	/* UAR same-page access control required in 32bit implementations. */
 #endif
 	struct mlx5_flow_tcf_context *tcf_context; /* TC flower context. */
-	void *rx_ns; /* RX Direct Rules name space handle. */
-	struct mlx5_flow_tbl_resource rx_tbl[MLX5_MAX_TABLES];
-	/* RX Direct Rules tables. */
-	void *tx_ns; /* TX Direct Rules name space handle. */
-	struct mlx5_flow_tbl_resource tx_tbl[MLX5_MAX_TABLES];
-	/* TX Direct Rules tables/ */
 };
 
 #define PORT_ID(priv) ((priv)->dev_data->port_id)
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 10c6eee..52be8b3 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -129,6 +129,45 @@ struct field_modify_info modify_tcp[] = {
 };
 
 /**
+ * Acquire the synchronizing object to protect multithreaded access
+ * to shared dv context. Lock occurs only if context is actually
+ * shared, i.e. we have multiport IB device and representors are
+ * created.
+ *
+ * @param[in] dev
+ *   Pointer to the rte_eth_dev structure.
+ */
+static void
+flow_d_shared_lock(struct rte_eth_dev *dev)
+{
+	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
+
+	if (sh->dv_refcnt > 1) {
+		int ret;
+
+		ret = pthread_mutex_lock(&sh->dv_mutex);
+		assert(!ret);
+		(void)ret;
+	}
+}
+
+static void
+flow_d_shared_unlock(struct rte_eth_dev *dev)
+{
+	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
+
+	if (sh->dv_refcnt > 1) {
+		int ret;
+
+		ret = pthread_mutex_unlock(&sh->dv_mutex);
+		assert(!ret);
+		(void)ret;
+	}
+}
+
+/**
  * Convert modify-header action to DV specification.
  *
  * @param[in] item
@@ -808,18 +847,19 @@ struct field_modify_info modify_tcp[] = {
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_dv_encap_decap_resource *cache_resource;
 	struct rte_flow *flow = dev_flow->flow;
 	struct mlx5dv_dr_ns *ns;
 
 	resource->flags = flow->group ? 0 : 1;
 	if (flow->ingress)
-		ns = priv->rx_ns;
+		ns = sh->rx_ns;
 	else
-		ns = priv->tx_ns;
+		ns = sh->tx_ns;
 
 	/* Lookup a matching resource from cache. */
-	LIST_FOREACH(cache_resource, &priv->encaps_decaps, next) {
+	LIST_FOREACH(cache_resource, &sh->encaps_decaps, next) {
 		if (resource->reformat_type == cache_resource->reformat_type &&
 		    resource->ft_type == cache_resource->ft_type &&
 		    resource->flags == cache_resource->flags &&
@@ -844,7 +884,7 @@ struct field_modify_info modify_tcp[] = {
 	*cache_resource = *resource;
 	cache_resource->verbs_action =
 		mlx5_glue->dv_create_flow_action_packet_reformat
-			(priv->sh->ctx, cache_resource->reformat_type,
+			(sh->ctx, cache_resource->reformat_type,
 			 cache_resource->ft_type, ns, cache_resource->flags,
 			 cache_resource->size,
 			 (cache_resource->size ? cache_resource->buf : NULL));
@@ -856,7 +896,7 @@ struct field_modify_info modify_tcp[] = {
 	}
 	rte_atomic32_init(&cache_resource->refcnt);
 	rte_atomic32_inc(&cache_resource->refcnt);
-	LIST_INSERT_HEAD(&priv->encaps_decaps, cache_resource, next);
+	LIST_INSERT_HEAD(&sh->encaps_decaps, cache_resource, next);
 	dev_flow->dv.encap_decap = cache_resource;
 	DRV_LOG(DEBUG, "new encap/decap resource %p: refcnt %d++",
 		(void *)cache_resource,
@@ -887,10 +927,11 @@ struct field_modify_info modify_tcp[] = {
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_dv_jump_tbl_resource *cache_resource;
 
 	/* Lookup a matching resource from cache. */
-	LIST_FOREACH(cache_resource, &priv->jump_tbl, next) {
+	LIST_FOREACH(cache_resource, &sh->jump_tbl, next) {
 		if (resource->tbl == cache_resource->tbl) {
 			DRV_LOG(DEBUG, "jump table resource resource %p: refcnt %d++",
 				(void *)cache_resource,
@@ -918,7 +959,7 @@ struct field_modify_info modify_tcp[] = {
 	}
 	rte_atomic32_init(&cache_resource->refcnt);
 	rte_atomic32_inc(&cache_resource->refcnt);
-	LIST_INSERT_HEAD(&priv->jump_tbl, cache_resource, next);
+	LIST_INSERT_HEAD(&sh->jump_tbl, cache_resource, next);
 	dev_flow->dv.jump = cache_resource;
 	DRV_LOG(DEBUG, "new jump table  resource %p: refcnt %d++",
 		(void *)cache_resource,
@@ -1542,14 +1583,15 @@ struct field_modify_info modify_tcp[] = {
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_dv_modify_hdr_resource *cache_resource;
 
 	struct mlx5dv_dr_ns *ns =
 		resource->ft_type == MLX5DV_FLOW_TABLE_TYPE_NIC_TX  ?
-		priv->tx_ns : priv->rx_ns;
+		sh->tx_ns : sh->rx_ns;
 
 	/* Lookup a matching resource from cache. */
-	LIST_FOREACH(cache_resource, &priv->modify_cmds, next) {
+	LIST_FOREACH(cache_resource, &sh->modify_cmds, next) {
 		if (resource->ft_type == cache_resource->ft_type &&
 		    resource->actions_num == cache_resource->actions_num &&
 		    !memcmp((const void *)resource->actions,
@@ -1573,7 +1615,7 @@ struct field_modify_info modify_tcp[] = {
 	*cache_resource = *resource;
 	cache_resource->verbs_action =
 		mlx5_glue->dv_create_flow_action_modify_header
-					(priv->sh->ctx, cache_resource->ft_type,
+					(sh->ctx, cache_resource->ft_type,
 					 ns, 0,
 					 cache_resource->actions_num *
 					 sizeof(cache_resource->actions[0]),
@@ -1586,7 +1628,7 @@ struct field_modify_info modify_tcp[] = {
 	}
 	rte_atomic32_init(&cache_resource->refcnt);
 	rte_atomic32_inc(&cache_resource->refcnt);
-	LIST_INSERT_HEAD(&priv->modify_cmds, cache_resource, next);
+	LIST_INSERT_HEAD(&sh->modify_cmds, cache_resource, next);
 	dev_flow->dv.modify_hdr = cache_resource;
 	DRV_LOG(DEBUG, "new modify-header resource %p: refcnt %d++",
 		(void *)cache_resource,
@@ -2883,19 +2925,20 @@ struct field_modify_info modify_tcp[] = {
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_tbl_resource *tbl;
 
 #ifdef HAVE_MLX5DV_DR
 	if (egress) {
-		tbl = &priv->tx_tbl[table_id];
+		tbl = &sh->tx_tbl[table_id];
 		if (!tbl->obj)
 			tbl->obj = mlx5_glue->dr_create_flow_tbl
-				(priv->tx_ns, table_id);
+				(sh->tx_ns, table_id);
 	} else {
-		tbl = &priv->rx_tbl[table_id];
+		tbl = &sh->rx_tbl[table_id];
 		if (!tbl->obj)
 			tbl->obj = mlx5_glue->dr_create_flow_tbl
-				(priv->rx_ns, table_id);
+				(sh->rx_ns, table_id);
 	}
 	if (!tbl->obj) {
 		rte_flow_error_set(error, ENOMEM,
@@ -2909,9 +2952,9 @@ struct field_modify_info modify_tcp[] = {
 	(void)error;
 	(void)tbl;
 	if (egress)
-		return &priv->tx_tbl[table_id];
+		return &sh->tx_tbl[table_id];
 	else
-		return &priv->rx_tbl[table_id];
+		return &sh->rx_tbl[table_id];
 #endif
 }
 
@@ -2959,6 +3002,7 @@ struct field_modify_info modify_tcp[] = {
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_dv_matcher *cache_matcher;
 	struct mlx5dv_flow_matcher_attr dv_attr = {
 		.type = IBV_FLOW_ATTR_NORMAL,
@@ -2967,7 +3011,7 @@ struct field_modify_info modify_tcp[] = {
 	struct mlx5_flow_tbl_resource *tbl = NULL;
 
 	/* Lookup from cache. */
-	LIST_FOREACH(cache_matcher, &priv->matchers, next) {
+	LIST_FOREACH(cache_matcher, &sh->matchers, next) {
 		if (matcher->crc == cache_matcher->crc &&
 		    matcher->priority == cache_matcher->priority &&
 		    matcher->egress == cache_matcher->egress &&
@@ -3007,8 +3051,7 @@ struct field_modify_info modify_tcp[] = {
 	if (matcher->egress)
 		dv_attr.flags |= IBV_FLOW_ATTR_FLAGS_EGRESS;
 	cache_matcher->matcher_object =
-		mlx5_glue->dv_create_flow_matcher(priv->sh->ctx, &dv_attr,
-						  tbl->obj);
+		mlx5_glue->dv_create_flow_matcher(sh->ctx, &dv_attr, tbl->obj);
 	if (!cache_matcher->matcher_object) {
 		rte_free(cache_matcher);
 #ifdef HAVE_MLX5DV_DR
@@ -3019,7 +3062,7 @@ struct field_modify_info modify_tcp[] = {
 					  NULL, "cannot create matcher");
 	}
 	rte_atomic32_inc(&cache_matcher->refcnt);
-	LIST_INSERT_HEAD(&priv->matchers, cache_matcher, next);
+	LIST_INSERT_HEAD(&sh->matchers, cache_matcher, next);
 	dev_flow->dv.matcher = cache_matcher;
 	DRV_LOG(DEBUG, "priority %hd new %s matcher %p: refcnt %d",
 		cache_matcher->priority,
@@ -3075,10 +3118,11 @@ struct field_modify_info modify_tcp[] = {
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_dv_tag_resource *cache_resource;
 
 	/* Lookup a matching resource from cache. */
-	LIST_FOREACH(cache_resource, &priv->tags, next) {
+	LIST_FOREACH(cache_resource, &sh->tags, next) {
 		if (resource->tag == cache_resource->tag) {
 			DRV_LOG(DEBUG, "tag resource %p: refcnt %d++",
 				(void *)cache_resource,
@@ -3105,7 +3149,7 @@ struct field_modify_info modify_tcp[] = {
 	}
 	rte_atomic32_init(&cache_resource->refcnt);
 	rte_atomic32_inc(&cache_resource->refcnt);
-	LIST_INSERT_HEAD(&priv->tags, cache_resource, next);
+	LIST_INSERT_HEAD(&sh->tags, cache_resource, next);
 	dev_flow->flow->tag_resource = cache_resource;
 	DRV_LOG(DEBUG, "new tag resource %p: refcnt %d++",
 		(void *)cache_resource,
@@ -3682,6 +3726,7 @@ struct field_modify_info modify_tcp[] = {
 {
 	struct mlx5_flow_dv_matcher *matcher = flow->dv.matcher;
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_tbl_resource *tbl;
 
 	assert(matcher->matcher_object);
@@ -3693,9 +3738,9 @@ struct field_modify_info modify_tcp[] = {
 			   (matcher->matcher_object));
 		LIST_REMOVE(matcher, next);
 		if (matcher->egress)
-			tbl = &priv->tx_tbl[matcher->group];
+			tbl = &sh->tx_tbl[matcher->group];
 		else
-			tbl = &priv->rx_tbl[matcher->group];
+			tbl = &sh->rx_tbl[matcher->group];
 		flow_dv_tbl_resource_release(tbl);
 		rte_free(matcher);
 		DRV_LOG(DEBUG, "port %u matcher %p: removed",
@@ -3958,14 +4003,70 @@ struct field_modify_info modify_tcp[] = {
 	return ret;
 }
 
+/*
+ * Mutex-protected thunk to flow_dv_translate().
+ */
+static int
+flow_d_translate(struct rte_eth_dev *dev,
+		 struct mlx5_flow *dev_flow,
+		 const struct rte_flow_attr *attr,
+		 const struct rte_flow_item items[],
+		 const struct rte_flow_action actions[],
+		 struct rte_flow_error *error)
+{
+	int ret;
+
+	flow_d_shared_lock(dev);
+	ret = flow_dv_translate(dev, dev_flow, attr, items, actions, error);
+	flow_d_shared_unlock(dev);
+	return ret;
+}
+
+/*
+ * Mutex-protected thunk to flow_dv_apply().
+ */
+static int
+flow_d_apply(struct rte_eth_dev *dev,
+	     struct rte_flow *flow,
+	     struct rte_flow_error *error)
+{
+	int ret;
+
+	flow_d_shared_lock(dev);
+	ret = flow_dv_apply(dev, flow, error);
+	flow_d_shared_unlock(dev);
+	return ret;
+}
+
+/*
+ * Mutex-protected thunk to flow_dv_remove().
+ */
+static void
+flow_d_remove(struct rte_eth_dev *dev, struct rte_flow *flow)
+{
+	flow_d_shared_lock(dev);
+	flow_dv_remove(dev, flow);
+	flow_d_shared_unlock(dev);
+}
+
+/*
+ * Mutex-protected thunk to flow_dv_destroy().
+ */
+static void
+flow_d_destroy(struct rte_eth_dev *dev, struct rte_flow *flow)
+{
+	flow_d_shared_lock(dev);
+	flow_dv_destroy(dev, flow);
+	flow_d_shared_unlock(dev);
+}
 
 const struct mlx5_flow_driver_ops mlx5_flow_dv_drv_ops = {
 	.validate = flow_dv_validate,
 	.prepare = flow_dv_prepare,
-	.translate = flow_dv_translate,
-	.apply = flow_dv_apply,
-	.remove = flow_dv_remove,
-	.destroy = flow_dv_destroy,
+	.translate = flow_d_translate,
+	.apply = flow_d_apply,
+	.remove = flow_d_remove,
+	.destroy = flow_d_destroy,
 	.query = flow_dv_query,
 };
 
-- 
1.8.3.1


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

* Re: [dpdk-dev] [PATCH v2 0/2] support Direct Rules flows over shared IB context
  2019-04-04 13:04 ` [dpdk-dev] [PATCH v2 0/2] support Direct Rules flows over shared IB context Viacheslav Ovsiienko
                     ` (2 preceding siblings ...)
  2019-04-04 13:04   ` [dpdk-dev] [PATCH v2 2/2] net/mlx5: share Direct Rules/Verbs flow related structures Viacheslav Ovsiienko
@ 2019-04-04 18:57   ` Shahaf Shuler
  2019-04-04 18:57     ` Shahaf Shuler
  3 siblings, 1 reply; 28+ messages in thread
From: Shahaf Shuler @ 2019-04-04 18:57 UTC (permalink / raw)
  To: Slava Ovsiienko, dev

Thursday, April 4, 2019 4:04 PM, Viacheslav Ovsiienko:
> Subject: [dpdk-dev] [PATCH v2 0/2] support Direct Rules flows over shared IB
> context
> 
> The Direct Rules/Direct Verbs flows support is going to be added [1]. The
> master/representor over multiport IB device is added [2]. This patchset adds
> support for DR/DV flows with shared IB context over multiport IB device.
> 
> The DV/DR flows applied to the master/representors on the same IB device
> share the following entinies:
>   - rx/tx namespaces
>   - rx/tx flow tables
>   - matchers
>   - encap/decap action resources
>   - flow tags (MARK actions)
>   - modify action resources
>   - jump tables

Series applied to next-net-mlx, thanks!

> 
> [1] "net/mlx5: Add Direct Rule support"
> 
> https://eur03.safelinks.protection.outlook.com/?url=http%3A%2F%2Fpatch
> es.dpdk.org%2Fcover%2F51856%2F&amp;data=02%7C01%7Cshahafs%40mel
> lanox.com%7Cabc5776f51794b8f53dd08d6b8fe43c7%7Ca652971c7d2e4d9ba6
> a4d149256f461b%7C0%7C0%7C636899799527209089&amp;sdata=EugeCEbt76
> LO%2F84BPRWYqvlx2e9imLeuW0OgFk82ICQ%3D&amp;reserved=0
> 
> [2] "net/mlx5: add support for multiport IB devices"
> 
> https://eur03.safelinks.protection.outlook.com/?url=http%3A%2F%2Fpatch
> es.dpdk.org%2Fcover%2F51800%2F&amp;data=02%7C01%7Cshahafs%40mel
> lanox.com%7Cabc5776f51794b8f53dd08d6b8fe43c7%7Ca652971c7d2e4d9ba6
> a4d149256f461b%7C0%7C0%7C636899799527209089&amp;sdata=Qds0%2BG
> 5fUGneYAPimMLkgpy41w10aTPuXmH47NENSjc%3D&amp;reserved=0
> 
> v2:
>   - mutex reverted to non-counting type (because there is
>     no DV flow functions intercalls and reentrances)
>   - some commits are squashed to make patchset more consistent
>   - conditional directives cleanup
> 
> v1:
> 
> https://eur03.safelinks.protection.outlook.com/?url=http%3A%2F%2Fpatch
> es.dpdk.org%2Fcover%2F52053%2F&amp;data=02%7C01%7Cshahafs%40mel
> lanox.com%7Cabc5776f51794b8f53dd08d6b8fe43c7%7Ca652971c7d2e4d9ba6
> a4d149256f461b%7C0%7C0%7C636899799527209089&amp;sdata=OvGIaSfZoT
> Ch9wjpeUkzCra76Ft7zZzF6QL2edTxEHM%3D&amp;reserved=0
> 
> Viacheslav Ovsiienko (2):
>   net/mlx5: add Direct Rules flow data alloc/free routines
>   net/mlx5: share Direct Rules/Verbs flow related structures
> 
>  drivers/net/mlx5/mlx5.c         | 119 ++++++++++++++++++++++++++----
>  drivers/net/mlx5/mlx5.h         |  45 +++++++-----
>  drivers/net/mlx5/mlx5_flow_dv.c | 159
> ++++++++++++++++++++++++++++++++--------
>  3 files changed, 259 insertions(+), 64 deletions(-)
> 
> --
> 1.8.3.1

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

* Re: [dpdk-dev] [PATCH v2 0/2] support Direct Rules flows over shared IB context
  2019-04-04 18:57   ` [dpdk-dev] [PATCH v2 0/2] support Direct Rules flows over shared IB context Shahaf Shuler
@ 2019-04-04 18:57     ` Shahaf Shuler
  0 siblings, 0 replies; 28+ messages in thread
From: Shahaf Shuler @ 2019-04-04 18:57 UTC (permalink / raw)
  To: Slava Ovsiienko, dev

Thursday, April 4, 2019 4:04 PM, Viacheslav Ovsiienko:
> Subject: [dpdk-dev] [PATCH v2 0/2] support Direct Rules flows over shared IB
> context
> 
> The Direct Rules/Direct Verbs flows support is going to be added [1]. The
> master/representor over multiport IB device is added [2]. This patchset adds
> support for DR/DV flows with shared IB context over multiport IB device.
> 
> The DV/DR flows applied to the master/representors on the same IB device
> share the following entinies:
>   - rx/tx namespaces
>   - rx/tx flow tables
>   - matchers
>   - encap/decap action resources
>   - flow tags (MARK actions)
>   - modify action resources
>   - jump tables

Series applied to next-net-mlx, thanks!

> 
> [1] "net/mlx5: Add Direct Rule support"
> 
> https://eur03.safelinks.protection.outlook.com/?url=http%3A%2F%2Fpatch
> es.dpdk.org%2Fcover%2F51856%2F&amp;data=02%7C01%7Cshahafs%40mel
> lanox.com%7Cabc5776f51794b8f53dd08d6b8fe43c7%7Ca652971c7d2e4d9ba6
> a4d149256f461b%7C0%7C0%7C636899799527209089&amp;sdata=EugeCEbt76
> LO%2F84BPRWYqvlx2e9imLeuW0OgFk82ICQ%3D&amp;reserved=0
> 
> [2] "net/mlx5: add support for multiport IB devices"
> 
> https://eur03.safelinks.protection.outlook.com/?url=http%3A%2F%2Fpatch
> es.dpdk.org%2Fcover%2F51800%2F&amp;data=02%7C01%7Cshahafs%40mel
> lanox.com%7Cabc5776f51794b8f53dd08d6b8fe43c7%7Ca652971c7d2e4d9ba6
> a4d149256f461b%7C0%7C0%7C636899799527209089&amp;sdata=Qds0%2BG
> 5fUGneYAPimMLkgpy41w10aTPuXmH47NENSjc%3D&amp;reserved=0
> 
> v2:
>   - mutex reverted to non-counting type (because there is
>     no DV flow functions intercalls and reentrances)
>   - some commits are squashed to make patchset more consistent
>   - conditional directives cleanup
> 
> v1:
> 
> https://eur03.safelinks.protection.outlook.com/?url=http%3A%2F%2Fpatch
> es.dpdk.org%2Fcover%2F52053%2F&amp;data=02%7C01%7Cshahafs%40mel
> lanox.com%7Cabc5776f51794b8f53dd08d6b8fe43c7%7Ca652971c7d2e4d9ba6
> a4d149256f461b%7C0%7C0%7C636899799527209089&amp;sdata=OvGIaSfZoT
> Ch9wjpeUkzCra76Ft7zZzF6QL2edTxEHM%3D&amp;reserved=0
> 
> Viacheslav Ovsiienko (2):
>   net/mlx5: add Direct Rules flow data alloc/free routines
>   net/mlx5: share Direct Rules/Verbs flow related structures
> 
>  drivers/net/mlx5/mlx5.c         | 119 ++++++++++++++++++++++++++----
>  drivers/net/mlx5/mlx5.h         |  45 +++++++-----
>  drivers/net/mlx5/mlx5_flow_dv.c | 159
> ++++++++++++++++++++++++++++++++--------
>  3 files changed, 259 insertions(+), 64 deletions(-)
> 
> --
> 1.8.3.1


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

end of thread, other threads:[~2019-04-04 18:57 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-02  6:22 [dpdk-dev] [PATCH 0/4] support DR/DV flows over shared IB context Viacheslav Ovsiienko
2019-04-02  6:22 ` Viacheslav Ovsiienko
2019-04-02  6:22 ` [dpdk-dev] [PATCH 1/4] net/mlx5: add DV/DR flow data alloc/free routines Viacheslav Ovsiienko
2019-04-02  6:22   ` Viacheslav Ovsiienko
2019-04-02 19:09   ` Shahaf Shuler
2019-04-02 19:09     ` Shahaf Shuler
2019-04-02  6:22 ` [dpdk-dev] [PATCH 2/4] net/mlx5: add reference counter for DV/DR structures Viacheslav Ovsiienko
2019-04-02  6:22   ` Viacheslav Ovsiienko
2019-04-02 19:09   ` Shahaf Shuler
2019-04-02 19:09     ` Shahaf Shuler
2019-04-03 13:27     ` Slava Ovsiienko
2019-04-03 13:27       ` Slava Ovsiienko
2019-04-02  6:22 ` [dpdk-dev] [PATCH 3/4] net/mlx5: share DV/DR flow related structures Viacheslav Ovsiienko
2019-04-02  6:22   ` Viacheslav Ovsiienko
2019-04-02 19:09   ` Shahaf Shuler
2019-04-02 19:09     ` Shahaf Shuler
2019-04-02  6:22 ` [dpdk-dev] [PATCH 4/4] net/mlx5: add mutex for shared DV/DR structures Viacheslav Ovsiienko
2019-04-02  6:22   ` Viacheslav Ovsiienko
2019-04-02 19:09   ` Shahaf Shuler
2019-04-02 19:09     ` Shahaf Shuler
2019-04-04 13:04 ` [dpdk-dev] [PATCH v2 0/2] support Direct Rules flows over shared IB context Viacheslav Ovsiienko
2019-04-04 13:04   ` Viacheslav Ovsiienko
2019-04-04 13:04   ` [dpdk-dev] [PATCH v2 1/2] net/mlx5: add Direct Rules flow data alloc/free routines Viacheslav Ovsiienko
2019-04-04 13:04     ` Viacheslav Ovsiienko
2019-04-04 13:04   ` [dpdk-dev] [PATCH v2 2/2] net/mlx5: share Direct Rules/Verbs flow related structures Viacheslav Ovsiienko
2019-04-04 13:04     ` Viacheslav Ovsiienko
2019-04-04 18:57   ` [dpdk-dev] [PATCH v2 0/2] support Direct Rules flows over shared IB context Shahaf Shuler
2019-04-04 18:57     ` Shahaf Shuler

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).