Skip to contentSkip to conversation

mlx5: some UAR fixes

PATCH Applied [email protected] 2 participants 8 messages Nov 3, 2021 – Nov 7, 2021

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

cover mlx5: some UAR fixes

From: Michael Baum <[email protected]>

Some different fixes around User Access Memory object.

Michael Baum (6):
crypto/mlx5: fix invalid memory access in probing common/mlx5: fix redundant code in UAR allocation common/mlx5: fix UAR allocation diagnostics messages common/mlx5: fix doorbell mapping configuration net/mlx5: remove duplicated reference of the TxQ doorbell common/mlx5: fix post doorbell barrier

 drivers/common/mlx5/mlx5_common.c        | 101 ++++++++----
 drivers/common/mlx5/mlx5_common.h        |  91 ++++++++++-
 drivers/common/mlx5/mlx5_common_defs.h   |   8 +
 drivers/common/mlx5/version.map          |   5 +-
 drivers/compress/mlx5/mlx5_compress.c    |  69 ++------
 drivers/crypto/mlx5/mlx5_crypto.c        |  72 ++-------
 drivers/crypto/mlx5/mlx5_crypto.h        |   6 +-
 drivers/net/mlx5/linux/mlx5_verbs.c      |  48 +++++-
 drivers/net/mlx5/mlx5.c                  | 195 +++++------------------
 drivers/net/mlx5/mlx5.h                  |  12 +-
 drivers/net/mlx5/mlx5_defs.h             |   8 -
 drivers/net/mlx5/mlx5_devx.c             |  24 +--
 drivers/net/mlx5/mlx5_flow_aso.c         |  81 +++++-----
 drivers/net/mlx5/mlx5_rx.h               |   6 +-
 drivers/net/mlx5/mlx5_rxq.c              |  11 +-
 drivers/net/mlx5/mlx5_tx.h               | 103 ++----------
 drivers/net/mlx5/mlx5_txpp.c             |  36 ++---
 drivers/net/mlx5/mlx5_txq.c              |  79 ++-------
 drivers/regex/mlx5/mlx5_regex.c          |  17 +-
 drivers/regex/mlx5/mlx5_regex.h          |   2 +-
 drivers/regex/mlx5/mlx5_regex_control.c  |   4 +-
 drivers/regex/mlx5/mlx5_regex_fastpath.c |  26 ++-
 drivers/vdpa/mlx5/mlx5_vdpa.h            |   2 +-
 drivers/vdpa/mlx5/mlx5_vdpa_event.c      |  33 +---
 24 files changed, 390 insertions(+), 649 deletions(-)
Signature · 1 line
2.25.1
#1 lore raw

PATCH 1/6 crypto/mlx5: fix invalid memory access in probing

From: Michael Baum <[email protected]>

The probe function creates DevX object named login and saves pointer to it in priv structure.

The remove function releases first the priv structure and then releases the login object.
However, the pointer to login object is field of priv structure, which is invalid.

Release the login object and then release the priv structure.

Fixes debb27ea3442 ("crypto/mlx5: create login object using DevX")
---
 drivers/crypto/mlx5/mlx5_crypto.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)
drivers/crypto/mlx5/mlx5_crypto.c +10 -8
index f430d8cde0..f9fd0d498e 100644
@@ -878,12 +878,6 @@ mlx5_crypto_dev_probe(struct mlx5_common_device *cdev)
 		DRV_LOG(ERR, "Failed to parse devargs.");
 		return -rte_errno;
 	}
-	login = mlx5_devx_cmd_create_crypto_login_obj(cdev->ctx,
-						      &devarg_prms.login_attr);
-	if (login == NULL) {
-		DRV_LOG(ERR, "Failed to configure login.");
-		return -rte_errno;
-	}
 	crypto_dev = rte_cryptodev_pmd_create(ibdev_name, cdev->dev,
 					      &init_params);
 	if (crypto_dev == NULL) {
@@ -899,12 +893,20 @@ mlx5_crypto_dev_probe(struct mlx5_common_device *cdev)
 	crypto_dev->driver_id = mlx5_crypto_driver_id;
 	priv = crypto_dev->data->dev_private;
 	priv->cdev = cdev;
-	priv->login_obj = login;
 	priv->crypto_dev = crypto_dev;
 	if (mlx5_crypto_uar_prepare(priv) != 0) {
 		rte_cryptodev_pmd_destroy(priv->crypto_dev);
 		return -1;
 	}
+	login = mlx5_devx_cmd_create_crypto_login_obj(cdev->ctx,
+						      &devarg_prms.login_attr);
+	if (login == NULL) {
+		DRV_LOG(ERR, "Failed to configure login.");
+		mlx5_crypto_uar_release(priv);
+		rte_cryptodev_pmd_destroy(priv->crypto_dev);
+		return -rte_errno;
+	}
+	priv->login_obj = login;
 	priv->keytag = rte_cpu_to_be_64(devarg_prms.keytag);
 	priv->max_segs_num = devarg_prms.max_segs_num;
 	priv->umr_wqe_size = sizeof(struct mlx5_wqe_umr_bsf_seg) +
@@ -940,9 +942,9 @@ mlx5_crypto_dev_remove(struct mlx5_common_device *cdev)
 		TAILQ_REMOVE(&mlx5_crypto_priv_list, priv, next);
 	pthread_mutex_unlock(&priv_list_lock);
 	if (priv) {
+		claim_zero(mlx5_devx_cmd_destroy(priv->login_obj));
 		mlx5_crypto_uar_release(priv);
 		rte_cryptodev_pmd_destroy(priv->crypto_dev);
-		claim_zero(mlx5_devx_cmd_destroy(priv->login_obj));
 	}
 	return 0;
 }
Signature · 1 line
2.25.1
#2 lore raw

PATCH 2/6 common/mlx5: fix redundant code in UAR allocation

In reply to [email protected]

From: Michael Baum <[email protected]>

The User Access Region (UAR) provides access to the hardware resources like Doorbell Register from userspace.
It means the resources should be mapped by the kernel to some virtual address range. There two types of memory mapping are supported by mlx5 kernel driver:

MLX5DV_UAR_ALLOC_TYPE_NC - non-cached, all writes promoted directly to
hardware.
MLX5DV_UAR_ALLOC_TYPE_BF - "BlueFlame", all writes might be cached by
CPU, and will be flushed to hardware explicitly with memory barriers.

The supported mapping types depend on the platform (x86/ARM/etc), kernel version, driver version, virtualization environment (hypervisor), etc.

In UAR allocation, if the system supports the allocation with non-cached mapping, the first attempt is performed with MLX5DV_UAR_ALLOC_TYPE_NC. Then, if this fails, the next attempt is done with MLX5DV_UAR_ALLOC_TYPE_BF.

However, the function adds a condition for the case where the first attempt was performed with MLX5DV_UAR_ALLOC_TYPE_BF, a condition that is unattainable since the first attempt was always performed with MLX5DV_UAR_ALLOC_TYPE_NC.

Remove the unreachable code.

Fixes 9cc0e99c81ab0 ("common/mlx5: share UAR allocation routine")
---
 drivers/common/mlx5/mlx5_common.c | 22 ++++------------------
 1 file changed, 4 insertions(+), 18 deletions(-)
drivers/common/mlx5/mlx5_common.c +4 -18
index e6ff045c95..a0076510ac 100644
@@ -942,11 +942,11 @@ RTE_INIT_PRIO(mlx5_is_haswell_broadwell_cpu, LOG)
  *				attributes (if supported by the host), the
  *				writes to the UAR registers must be followed
  *				by write memory barrier.
- *   MLX5DV_UAR_ALLOC_TYPE_NC - allocate as non-cached nenory, all writes are
+ *   MLX5DV_UAR_ALLOC_TYPE_NC - allocate as non-cached memory, all writes are
  *				promoted to the registers immediately, no
  *				memory barriers needed.
- *   mapping < 0 - the first attempt is performed with MLX5DV_UAR_ALLOC_TYPE_BF,
- *		   if this fails the next attempt with MLX5DV_UAR_ALLOC_TYPE_NC
+ *   mapping < 0 - the first attempt is performed with MLX5DV_UAR_ALLOC_TYPE_NC,
+ *		   if this fails the next attempt with MLX5DV_UAR_ALLOC_TYPE_BF
  *		   is performed. The drivers specifying negative values should
  *		   always provide the write memory barrier operation after UAR
  *		   register writings.
@@ -978,21 +978,7 @@ mlx5_devx_alloc_uar(void *ctx, int mapping)
 #endif
 		uar = mlx5_glue->devx_alloc_uar(ctx, uar_mapping);
 #ifdef MLX5DV_UAR_ALLOC_TYPE_NC
-		if (!uar &&
-		    mapping < 0 &&
-		    uar_mapping == MLX5DV_UAR_ALLOC_TYPE_BF) {
-			/*
-			 * In some environments like virtual machine the
-			 * Write Combining mapped might be not supported and
-			 * UAR allocation fails. We tried "Non-Cached" mapping
-			 * for the case.
-			 */
-			DRV_LOG(WARNING, "Failed to allocate DevX UAR (BF)");
-			uar_mapping = MLX5DV_UAR_ALLOC_TYPE_NC;
-			uar = mlx5_glue->devx_alloc_uar(ctx, uar_mapping);
-		} else if (!uar &&
-			   mapping < 0 &&
-			   uar_mapping == MLX5DV_UAR_ALLOC_TYPE_NC) {
+		if (!uar && mapping < 0) {
 			/*
 			 * If Verbs/kernel does not support "Non-Cached"
 			 * try the "Write-Combining".
Signature · 1 line
2.25.1
#3 lore raw

PATCH 3/6 common/mlx5: fix UAR allocation diagnostics messages

In reply to [email protected]

From: Michael Baum <[email protected]>

Depending on kernel capabilities and rdma-core version the mapping of UAR (User Access Region) of desired memory caching type (non-cached or write combining) might fail. The PMD implements the flexible strategy of UAR mapping, alternating the type of caching to succeed.

During this process the failure diagnostics messages are emitted. These messages are merely diagnostics ones and the logging level should be adjusted to DEBUG.

Fixes 9cc0e99c81ab0 ("common/mlx5: share UAR allocation routine")
---
 drivers/common/mlx5/mlx5_common.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/common/mlx5/mlx5_common.c +2 -2
index a0076510ac..7f92e3b2cc 100644
@@ -983,7 +983,7 @@ mlx5_devx_alloc_uar(void *ctx, int mapping)
 			 * If Verbs/kernel does not support "Non-Cached"
 			 * try the "Write-Combining".
 			 */
-			DRV_LOG(WARNING, "Failed to allocate DevX UAR (NC)");
+			DRV_LOG(DEBUG, "Failed to allocate DevX UAR (NC)");
 			uar_mapping = MLX5DV_UAR_ALLOC_TYPE_BF;
 			uar = mlx5_glue->devx_alloc_uar(ctx, uar_mapping);
 		}
@@ -1001,7 +1001,7 @@ mlx5_devx_alloc_uar(void *ctx, int mapping)
 		 * IB device context, on context closure all UARs
 		 * will be freed, should be no memory/object leakage.
 		 */
-		DRV_LOG(WARNING, "Retrying to allocate DevX UAR");
+		DRV_LOG(DEBUG, "Retrying to allocate DevX UAR");
 		uar = NULL;
 	}
 	/* Check whether we finally succeeded with valid UAR allocation. */
Signature · 1 line
2.25.1
#4 lore raw

PATCH 4/6 common/mlx5: fix doorbell mapping configuration

In reply to [email protected]

From: Michael Baum <[email protected]>

UAR mapping type can be affected by the devarg tx_db_nc, which can cause setting the environment variable MLX5_SHUT_UP_BF.
So, the MLX5_SHUT_UP_BF value and the UAR mapping parameter affect the UAR cache mode.

Wrongly, the devarg was considered for the MLX5_SHUT_UP_BF but not for the UAR mapping parameter in all the drivers except the net.

Take the tx_db_nc devarg into account for all the drivers.

Fixes ca1418ce3910 ("common/mlx5: share device context object")
---
 drivers/common/mlx5/mlx5_common.c     | 52 ++++++++++++++-------------
 drivers/common/mlx5/mlx5_common.h     |  5 +--
 drivers/compress/mlx5/mlx5_compress.c |  2 +-
 drivers/crypto/mlx5/mlx5_crypto.c     |  2 +-
 drivers/regex/mlx5/mlx5_regex.c       |  2 +-
 drivers/vdpa/mlx5/mlx5_vdpa_event.c   |  2 +-
 6 files changed, 35 insertions(+), 30 deletions(-)
drivers/common/mlx5/mlx5_common.c +28 -24
index 7f92e3b2cc..7bdc550b36 100644
@@ -934,30 +934,25 @@ RTE_INIT_PRIO(mlx5_is_haswell_broadwell_cpu, LOG)
 
 /**
  * Allocate the User Access Region with DevX on specified device.
+ * This routine handles the following UAR allocation issues:
  *
- * @param [in] ctx
- *   Infiniband device context to perform allocation on.
- * @param [in] mapping
- *   MLX5DV_UAR_ALLOC_TYPE_BF - allocate as cached memory with write-combining
- *				attributes (if supported by the host), the
- *				writes to the UAR registers must be followed
- *				by write memory barrier.
- *   MLX5DV_UAR_ALLOC_TYPE_NC - allocate as non-cached memory, all writes are
- *				promoted to the registers immediately, no
- *				memory barriers needed.
- *   mapping < 0 - the first attempt is performed with MLX5DV_UAR_ALLOC_TYPE_NC,
- *		   if this fails the next attempt with MLX5DV_UAR_ALLOC_TYPE_BF
- *		   is performed. The drivers specifying negative values should
- *		   always provide the write memory barrier operation after UAR
- *		   register writings.
- * If there is no definitions for the MLX5DV_UAR_ALLOC_TYPE_xx (older rdma
- * library headers), the caller can specify 0.
+ *  - tries to allocate the UAR with the most appropriate memory mapping
+ *    type from the ones supported by the host.
+ *
+ *  - tries to allocate the UAR with non-NULL base address OFED 5.0.x and
+ *    Upstream rdma_core before v29 returned the NULL as UAR base address
+ *    if UAR was not the first object in the UAR page.
+ *    It caused the PMD failure and we should try to get another UAR till
+ *    we get the first one with non-NULL base address returned.
+ *
+ * @param [in] cdev
+ *   Pointer to mlx5 device structure to perform allocation on its context.
  *
  * @return
  *   UAR object pointer on success, NULL otherwise and rte_errno is set.
  */
 void *
-mlx5_devx_alloc_uar(void *ctx, int mapping)
+mlx5_devx_alloc_uar(struct mlx5_common_device *cdev)
 {
 	void *uar;
 	uint32_t retry, uar_mapping;
@@ -966,26 +961,35 @@ mlx5_devx_alloc_uar(void *ctx, int mapping)
 	for (retry = 0; retry < MLX5_ALLOC_UAR_RETRY; ++retry) {
 #ifdef MLX5DV_UAR_ALLOC_TYPE_NC
 		/* Control the mapping type according to the settings. */
-		uar_mapping = (mapping < 0) ?
-			      MLX5DV_UAR_ALLOC_TYPE_NC : mapping;
+		uar_mapping = (cdev->config.dbnc == MLX5_TXDB_NCACHED) ?
+			    MLX5DV_UAR_ALLOC_TYPE_NC : MLX5DV_UAR_ALLOC_TYPE_BF;
 #else
 		/*
 		 * It seems we have no way to control the memory mapping type
 		 * for the UAR, the default "Write-Combining" type is supposed.
 		 */
 		uar_mapping = 0;
-		RTE_SET_USED(mapping);
 #endif
-		uar = mlx5_glue->devx_alloc_uar(ctx, uar_mapping);
+		uar = mlx5_glue->devx_alloc_uar(cdev->ctx, uar_mapping);
 #ifdef MLX5DV_UAR_ALLOC_TYPE_NC
-		if (!uar && mapping < 0) {
+		if (!uar && uar_mapping == MLX5DV_UAR_ALLOC_TYPE_BF) {
+			/*
+			 * In some environments like virtual machine the
+			 * Write Combining mapped might be not supported and
+			 * UAR allocation fails. We tried "Non-Cached" mapping
+			 * for the case.
+			 */
+			DRV_LOG(DEBUG, "Failed to allocate DevX UAR (BF)");
+			uar_mapping = MLX5DV_UAR_ALLOC_TYPE_NC;
+			uar = mlx5_glue->devx_alloc_uar(cdev->ctx, uar_mapping);
+		} else if (!uar && uar_mapping == MLX5DV_UAR_ALLOC_TYPE_NC) {
 			/*
 			 * If Verbs/kernel does not support "Non-Cached"
 			 * try the "Write-Combining".
 			 */
 			DRV_LOG(DEBUG, "Failed to allocate DevX UAR (NC)");
 			uar_mapping = MLX5DV_UAR_ALLOC_TYPE_BF;
-			uar = mlx5_glue->devx_alloc_uar(ctx, uar_mapping);
+			uar = mlx5_glue->devx_alloc_uar(cdev->ctx, uar_mapping);
 		}
 #endif
 		if (!uar) {
drivers/common/mlx5/mlx5_common.h +3 -2
index 744c6a72b3..7febae9cdf 100644
@@ -284,8 +284,6 @@ __rte_internal
 void mlx5_translate_port_name(const char *port_name_in,
 			      struct mlx5_switch_info *port_info_out);
 void mlx5_glue_constructor(void);
-__rte_internal
-void *mlx5_devx_alloc_uar(void *ctx, int mapping);
 extern uint8_t haswell_broadwell_cpu;
 
 __rte_internal
@@ -417,6 +415,9 @@ void
 mlx5_dev_mempool_unregister(struct mlx5_common_device *cdev,
 			    struct rte_mempool *mp);
 
+__rte_internal
+void *mlx5_devx_alloc_uar(struct mlx5_common_device *cdev);
+
 /* mlx5_common_mr.c */
 
 __rte_internal
drivers/compress/mlx5/mlx5_compress.c +1 -1
index c4081c5f7d..df60b05ab3 100644
@@ -690,7 +690,7 @@ mlx5_compress_uar_release(struct mlx5_compress_priv *priv)
 static int
 mlx5_compress_uar_prepare(struct mlx5_compress_priv *priv)
 {
-	priv->uar = mlx5_devx_alloc_uar(priv->cdev->ctx, -1);
+	priv->uar = mlx5_devx_alloc_uar(priv->cdev);
 	if (priv->uar == NULL || mlx5_os_get_devx_uar_reg_addr(priv->uar) ==
 	    NULL) {
 		rte_errno = errno;
drivers/crypto/mlx5/mlx5_crypto.c +1 -1
index f9fd0d498e..33d797a6a0 100644
@@ -731,7 +731,7 @@ mlx5_crypto_uar_release(struct mlx5_crypto_priv *priv)
 static int
 mlx5_crypto_uar_prepare(struct mlx5_crypto_priv *priv)
 {
-	priv->uar = mlx5_devx_alloc_uar(priv->cdev->ctx, -1);
+	priv->uar = mlx5_devx_alloc_uar(priv->cdev);
 	if (priv->uar)
 		priv->uar_addr = mlx5_os_get_devx_uar_reg_addr(priv->uar);
 	if (priv->uar == NULL || priv->uar_addr == NULL) {
drivers/regex/mlx5/mlx5_regex.c +1 -1
index b8a513e1fa..d632252794 100644
@@ -138,7 +138,7 @@ mlx5_regex_dev_probe(struct mlx5_common_device *cdev)
 	 * registers writings, it is safe to allocate UAR with any
 	 * memory mapping type.
 	 */
-	priv->uar = mlx5_devx_alloc_uar(priv->cdev->ctx, -1);
+	priv->uar = mlx5_devx_alloc_uar(priv->cdev);
 	if (!priv->uar) {
 		DRV_LOG(ERR, "can't allocate uar.");
 		rte_errno = ENOMEM;
drivers/vdpa/mlx5/mlx5_vdpa_event.c +1 -1
index 042d22777f..21738bdfff 100644
@@ -61,7 +61,7 @@ mlx5_vdpa_event_qp_global_prepare(struct mlx5_vdpa_priv *priv)
 	 * registers writings, it is safe to allocate UAR with any
 	 * memory mapping type.
 	 */
-	priv->uar = mlx5_devx_alloc_uar(priv->cdev->ctx, -1);
+	priv->uar = mlx5_devx_alloc_uar(priv->cdev);
 	if (!priv->uar) {
 		rte_errno = errno;
 		DRV_LOG(ERR, "Failed to allocate UAR.");
Signature · 1 line
2.25.1
#5 lore raw

PATCH 5/6 net/mlx5: remove duplicated reference of the TxQ doorbell

In reply to [email protected]

From: Michael Baum <[email protected]>

The Tx doorbell has different virtual addresses per process. The secondary process takes the UAR physical page ID of the primary and mmap it to its own virtual address.
The primary doorbell references were saved in two shared memory
locations: the TxQ structure and a dedicated doorbell array.

Remove the doorbell reference from the TxQ structure and move the primary processes to take the UAR information from the primary doorbell array.

---
 drivers/net/mlx5/linux/mlx5_verbs.c |  6 ++----
 drivers/net/mlx5/mlx5.c             |  2 ++
 drivers/net/mlx5/mlx5.h             |  2 +-
 drivers/net/mlx5/mlx5_devx.c        |  8 ++------
 drivers/net/mlx5/mlx5_tx.h          |  3 +--
 drivers/net/mlx5/mlx5_txq.c         | 15 ++++++++-------
 6 files changed, 16 insertions(+), 20 deletions(-)
drivers/net/mlx5/linux/mlx5_verbs.c +2 -4
index 4779b37aa6..eef8391c12 100644
@@ -990,20 +990,18 @@ mlx5_txq_ibv_obj_new(struct rte_eth_dev *dev, uint16_t idx)
 		}
 	}
 #endif
-	txq_ctrl->bf_reg = qp.bf.reg;
 	if (qp.comp_mask & MLX5DV_QP_MASK_UAR_MMAP_OFFSET) {
 		txq_ctrl->uar_mmap_offset = qp.uar_mmap_offset;
 		DRV_LOG(DEBUG, "Port %u: uar_mmap_offset 0x%" PRIx64 ".",
 			dev->data->port_id, txq_ctrl->uar_mmap_offset);
 	} else {
 		DRV_LOG(ERR,
-			"Port %u failed to retrieve UAR info, invalid"
-			" libmlx5.so",
+			"Port %u failed to retrieve UAR info, invalid libmlx5.so",
 			dev->data->port_id);
 		rte_errno = EINVAL;
 		goto error;
 	}
-	txq_uar_init(txq_ctrl);
+	txq_uar_init(txq_ctrl, qp.bf.reg);
 	dev->data->tx_queue_state[idx] = RTE_ETH_QUEUE_STATE_STARTED;
 	return 0;
 error:
drivers/net/mlx5/mlx5.c +2 -0
index 4fe7e34578..39158a5dde 100644
@@ -1616,6 +1616,8 @@ mlx5_proc_priv_init(struct rte_eth_dev *dev)
 	}
 	ppriv->uar_table_sz = priv->txqs_n;
 	dev->process_private = ppriv;
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		priv->sh->pppriv = ppriv;
 	return 0;
 }
 
drivers/net/mlx5/mlx5.h +1 -1
index 5768b82935..3b04f9d4e3 100644
@@ -1167,6 +1167,7 @@ struct mlx5_dev_ctx_shared {
 	struct mlx5_devx_obj *td; /* Transport domain. */
 	struct mlx5_lag lag; /* LAG attributes */
 	void *tx_uar; /* Tx/packet pacing shared UAR. */
+	struct mlx5_proc_priv *pppriv; /* Pointer to primary private process. */
 	struct mlx5_flex_parser_profiles fp[MLX5_FLEX_PARSER_MAX];
 	/* Flex parser profiles information. */
 	void *devx_rx_uar; /* DevX UAR for Rx. */
@@ -1479,7 +1480,6 @@ void mlx5_set_metadata_mask(struct rte_eth_dev *dev);
 int mlx5_dev_check_sibling_config(struct mlx5_priv *priv,
 				  struct mlx5_dev_config *config,
 				  struct rte_device *dpdk_dev);
-int mlx5_dev_configure(struct rte_eth_dev *dev);
 int mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info);
 int mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size);
 int mlx5_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu);
drivers/net/mlx5/mlx5_devx.c +2 -6
index 7ed774e804..dc391529c2 100644
@@ -1074,7 +1074,6 @@ mlx5_txq_devx_obj_new(struct rte_eth_dev *dev, uint16_t idx)
 	struct mlx5_devx_cq_attr cq_attr = {
 		.uar_page_id = mlx5_os_get_devx_uar_page_id(sh->tx_uar),
 	};
-	void *reg_addr;
 	uint32_t cqe_n, log_desc_n;
 	uint32_t wqe_n, wqe_size;
 	int ret = 0;
@@ -1171,13 +1170,10 @@ mlx5_txq_devx_obj_new(struct rte_eth_dev *dev, uint16_t idx)
 	if (!priv->sh->tdn)
 		priv->sh->tdn = priv->sh->td->id;
 #endif
-	MLX5_ASSERT(sh->tx_uar);
-	reg_addr = mlx5_os_get_devx_uar_reg_addr(sh->tx_uar);
-	MLX5_ASSERT(reg_addr);
-	txq_ctrl->bf_reg = reg_addr;
+	MLX5_ASSERT(sh->tx_uar && mlx5_os_get_devx_uar_reg_addr(sh->tx_uar));
 	txq_ctrl->uar_mmap_offset =
 				mlx5_os_get_devx_uar_mmap_offset(sh->tx_uar);
-	txq_uar_init(txq_ctrl);
+	txq_uar_init(txq_ctrl, mlx5_os_get_devx_uar_reg_addr(sh->tx_uar));
 	dev->data->tx_queue_state[idx] = RTE_ETH_QUEUE_STATE_STARTED;
 	return 0;
 error:
drivers/net/mlx5/mlx5_tx.h +1 -2
index ea20213a40..24a312b58b 100644
@@ -184,7 +184,6 @@ struct mlx5_txq_ctrl {
 	struct mlx5_txq_obj *obj; /* Verbs/DevX queue object. */
 	struct mlx5_priv *priv; /* Back pointer to private data. */
 	off_t uar_mmap_offset; /* UAR mmap offset for non-primary process. */
-	void *bf_reg; /* BlueFlame register from Verbs. */
 	uint16_t dump_file_n; /* Number of dump files. */
 	struct rte_eth_hairpin_conf hairpin_conf; /* Hairpin configuration. */
 	uint32_t hairpin_status; /* Hairpin binding status. */
@@ -204,7 +203,7 @@ int mlx5_tx_hairpin_queue_setup
 	(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	 const struct rte_eth_hairpin_conf *hairpin_conf);
 void mlx5_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid);
-void txq_uar_init(struct mlx5_txq_ctrl *txq_ctrl);
+void txq_uar_init(struct mlx5_txq_ctrl *txq_ctrl, void *bf_reg);
 int mlx5_tx_uar_init_secondary(struct rte_eth_dev *dev, int fd);
 void mlx5_tx_uar_uninit_secondary(struct rte_eth_dev *dev);
 int mlx5_txq_obj_verify(struct rte_eth_dev *dev);
drivers/net/mlx5/mlx5_txq.c +8 -7
index e2a38d980a..5fa43d63f1 100644
@@ -523,9 +523,11 @@ txq_uar_ncattr_init(struct mlx5_txq_ctrl *txq_ctrl, size_t page_size)
  *
  * @param txq_ctrl
  *   Pointer to Tx queue control structure.
+ * @param bf_reg
+ *   BlueFlame register from Verbs UAR.
  */
 void
-txq_uar_init(struct mlx5_txq_ctrl *txq_ctrl)
+txq_uar_init(struct mlx5_txq_ctrl *txq_ctrl, void *bf_reg)
 {
 	struct mlx5_priv *priv = txq_ctrl->priv;
 	struct mlx5_proc_priv *ppriv = MLX5_PROC_PRIV(PORT_ID(priv));
@@ -542,7 +544,7 @@ txq_uar_init(struct mlx5_txq_ctrl *txq_ctrl)
 		return;
 	MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY);
 	MLX5_ASSERT(ppriv);
-	ppriv->uar_table[txq_ctrl->txq.idx] = txq_ctrl->bf_reg;
+	ppriv->uar_table[txq_ctrl->txq.idx] = bf_reg;
 	txq_uar_ncattr_init(txq_ctrl, page_size);
 #ifndef RTE_ARCH_64
 	/* Assign an UAR lock according to UAR page number */
@@ -571,6 +573,7 @@ txq_uar_init_secondary(struct mlx5_txq_ctrl *txq_ctrl, int fd)
 {
 	struct mlx5_priv *priv = txq_ctrl->priv;
 	struct mlx5_proc_priv *ppriv = MLX5_PROC_PRIV(PORT_ID(priv));
+	struct mlx5_proc_priv *primary_ppriv = priv->sh->pppriv;
 	struct mlx5_txq_data *txq = &txq_ctrl->txq;
 	void *addr;
 	uintptr_t uar_va;
@@ -589,20 +592,18 @@ txq_uar_init_secondary(struct mlx5_txq_ctrl *txq_ctrl, int fd)
 	 * As rdma-core, UARs are mapped in size of OS page
 	 * size. Ref to libmlx5 function: mlx5_init_context()
 	 */
-	uar_va = (uintptr_t)txq_ctrl->bf_reg;
+	uar_va = (uintptr_t)primary_ppriv->uar_table[txq->idx];
 	offset = uar_va & (page_size - 1); /* Offset in page. */
 	addr = rte_mem_map(NULL, page_size, RTE_PROT_WRITE, RTE_MAP_SHARED,
-			    fd, txq_ctrl->uar_mmap_offset);
+			   fd, txq_ctrl->uar_mmap_offset);
 	if (!addr) {
-		DRV_LOG(ERR,
-			"port %u mmap failed for BF reg of txq %u",
+		DRV_LOG(ERR, "Port %u mmap failed for BF reg of txq %u.",
 			txq->port_id, txq->idx);
 		rte_errno = ENXIO;
 		return -rte_errno;
 	}
 	addr = RTE_PTR_ADD(addr, offset);
 	ppriv->uar_table[txq->idx] = addr;
-	txq_uar_ncattr_init(txq_ctrl, page_size);
 	return 0;
 }
 
Signature · 1 line
2.25.1
#6 lore raw

PATCH 6/6 common/mlx5: fix post doorbell barrier

In reply to [email protected]

From: Michael Baum <[email protected]>

The rdma core library can map doorbell register in two ways, depending on the environment variable "MLX5_SHUT_UP_BF":

- as regular cached memory, the variable is either missing or set to zero. This type of mapping may cause the significant doorbell register writing latency and requires an explicit memory write barrier to mitigate this issue and prevent write combining.

- as non-cached memory, the variable is present and set to not "0" value. This type of mapping may cause performance impact under heavy loading conditions but the explicit write memory barrier is not required and it may improve core performance.

The UAR creation function maps a doorbell in one of the above ways according to the system. In run time, it always adds an explicit memory barrier after writing to.
In cases where the doorbell was mapped as non-cached memory, the explicit memory barrier is unnecessary and may impair performance.

The commit [1] solved this problem for a Tx queue. In run time, it checks the mapping type and provides the memory barrier after writing to a Tx doorbell register if it is needed. The mapping type is extracted directly from the uar_mmap_offset field in the queue properties.

This patch shares this code between the drivers and extends the above solution for each of them.

[1] commit 8409a28573d3
("net/mlx5: control transmit doorbell register mapping")

Fixes f8c97babc9f4 ("compress/mlx5: add data-path functions")
Fixes 8e196c08ab53 ("crypto/mlx5: support enqueue/dequeue operations")
Fixes 4d4e245ad637 ("regex/mlx5: support enqueue")
---
 drivers/common/mlx5/mlx5_common.c        |  49 +++++-
 drivers/common/mlx5/mlx5_common.h        |  88 ++++++++++-
 drivers/common/mlx5/mlx5_common_defs.h   |   8 +
 drivers/common/mlx5/version.map          |   5 +-
 drivers/compress/mlx5/mlx5_compress.c    |  69 ++------
 drivers/crypto/mlx5/mlx5_crypto.c        |  56 +------
 drivers/crypto/mlx5/mlx5_crypto.h        |   6 +-
 drivers/net/mlx5/linux/mlx5_verbs.c      |  44 +++++-
 drivers/net/mlx5/mlx5.c                  | 193 +++++------------------
 drivers/net/mlx5/mlx5.h                  |  10 +-
 drivers/net/mlx5/mlx5_defs.h             |   8 -
 drivers/net/mlx5/mlx5_devx.c             |  20 ++-
 drivers/net/mlx5/mlx5_flow_aso.c         |  81 +++++-----
 drivers/net/mlx5/mlx5_rx.h               |   6 +-
 drivers/net/mlx5/mlx5_rxq.c              |  11 +-
 drivers/net/mlx5/mlx5_tx.h               | 102 ++----------
 drivers/net/mlx5/mlx5_txpp.c             |  36 ++---
 drivers/net/mlx5/mlx5_txq.c              |  74 ++-------
 drivers/regex/mlx5/mlx5_regex.c          |  17 +-
 drivers/regex/mlx5/mlx5_regex.h          |   2 +-
 drivers/regex/mlx5/mlx5_regex_control.c  |   4 +-
 drivers/regex/mlx5/mlx5_regex_fastpath.c |  26 ++-
 drivers/vdpa/mlx5/mlx5_vdpa.h            |   2 +-
 drivers/vdpa/mlx5/mlx5_vdpa_event.c      |  33 +---
 24 files changed, 351 insertions(+), 599 deletions(-)
drivers/common/mlx5/mlx5_common.c +46 -3
index 7bdc550b36..c81c7115a4 100644
@@ -10,6 +10,7 @@
 #include <rte_mempool.h>
 #include <rte_class.h>
 #include <rte_malloc.h>
+#include <rte_eal_paging.h>
 
 #include "mlx5_common.h"
 #include "mlx5_common_os.h"
@@ -936,10 +937,10 @@ RTE_INIT_PRIO(mlx5_is_haswell_broadwell_cpu, LOG)
  * Allocate the User Access Region with DevX on specified device.
  * This routine handles the following UAR allocation issues:
  *
- *  - tries to allocate the UAR with the most appropriate memory mapping
+ *  - Try to allocate the UAR with the most appropriate memory mapping
  *    type from the ones supported by the host.
  *
- *  - tries to allocate the UAR with non-NULL base address OFED 5.0.x and
+ *  - Try to allocate the UAR with non-NULL base address OFED 5.0.x and
  *    Upstream rdma_core before v29 returned the NULL as UAR base address
  *    if UAR was not the first object in the UAR page.
  *    It caused the PMD failure and we should try to get another UAR till
@@ -951,7 +952,7 @@ RTE_INIT_PRIO(mlx5_is_haswell_broadwell_cpu, LOG)
  * @return
  *   UAR object pointer on success, NULL otherwise and rte_errno is set.
  */
-void *
+static void *
 mlx5_devx_alloc_uar(struct mlx5_common_device *cdev)
 {
 	void *uar;
@@ -1021,4 +1022,46 @@ mlx5_devx_alloc_uar(struct mlx5_common_device *cdev)
 	return uar;
 }
 
+void
+mlx5_devx_uar_release(struct mlx5_uar *uar)
+{
+	if (uar->obj != NULL)
+		mlx5_glue->devx_free_uar(uar->obj);
+	memset(uar, 0, sizeof(*uar));
+}
+
+int
+mlx5_devx_uar_prepare(struct mlx5_common_device *cdev, struct mlx5_uar *uar)
+{
+	off_t uar_mmap_offset;
+	const size_t page_size = rte_mem_page_size();
+	void *base_addr;
+	void *uar_obj;
+
+	if (page_size == (size_t)-1) {
+		DRV_LOG(ERR, "Failed to get mem page size");
+		rte_errno = ENOMEM;
+		return -1;
+	}
+	uar_obj = mlx5_devx_alloc_uar(cdev);
+	if (uar_obj == NULL || mlx5_os_get_devx_uar_reg_addr(uar_obj) == NULL) {
+		rte_errno = errno;
+		DRV_LOG(ERR, "Failed to allocate UAR.");
+		return -1;
+	}
+	uar->obj = uar_obj;
+	uar_mmap_offset = mlx5_os_get_devx_uar_mmap_offset(uar_obj);
+	base_addr = mlx5_os_get_devx_uar_base_addr(uar_obj);
+	uar->dbnc = mlx5_db_map_type_get(uar_mmap_offset, page_size);
+	uar->bf_db.db = mlx5_os_get_devx_uar_reg_addr(uar_obj);
+	uar->cq_db.db = RTE_PTR_ADD(base_addr, MLX5_CQ_DOORBELL);
+#ifndef RTE_ARCH_64
+	rte_spinlock_init(&uar->bf_sl);
+	rte_spinlock_init(&uar->cq_sl);
+	uar->bf_db.sl_p = &uar->bf_sl;
+	uar->cq_db.sl_p = &uar->cq_sl;
+#endif /* RTE_ARCH_64 */
+	return 0;
+}
+
 RTE_PMD_EXPORT_NAME(mlx5_common_driver, __COUNTER__);
drivers/common/mlx5/mlx5_common.h +87 -1

100 lines not on this page · raw message

drivers/common/mlx5/mlx5_common_defs.h +8 -0
index 8f43b8e8ad..ca80cd8d29 100644
@@ -39,6 +39,14 @@
 #define MLX5_TXDB_NCACHED 1
 #define MLX5_TXDB_HEURISTIC 2
 
+/* Fields of memory mapping type in offset parameter of mmap() */
+#define MLX5_UAR_MMAP_CMD_SHIFT 8
+#define MLX5_UAR_MMAP_CMD_MASK 0xff
+
+#ifndef HAVE_MLX5DV_MMAP_GET_NC_PAGES_CMD
+#define MLX5_MMAP_GET_NC_PAGES_CMD 3
+#endif
+
 #define MLX5_VDPA_MAX_RETRIES 20
 #define MLX5_VDPA_USEC 1000
 
drivers/common/mlx5/version.map +3 -2
index 0ea8325f9a..0f3192e58d 100644
@@ -16,8 +16,6 @@ INTERNAL {
 	mlx5_dev_mempool_unregister;
 	mlx5_dev_mempool_subscribe;
 
-	mlx5_devx_alloc_uar; # WINDOWS_NO_EXPORT
-
 	mlx5_devx_cmd_alloc_pd;
 	mlx5_devx_cmd_create_conn_track_offload_obj;
 	mlx5_devx_cmd_create_cq;
@@ -75,6 +73,9 @@ INTERNAL {
 	mlx5_devx_sq_create;
 	mlx5_devx_sq_destroy;
 
+	mlx5_devx_uar_prepare;
+	mlx5_devx_uar_release;
+
 	mlx5_free;
 
 	mlx5_get_ifname_sysfs; # WINDOWS_NO_EXPORT
drivers/compress/mlx5/mlx5_compress.c +9 -60

125 lines not on this page · raw message

drivers/crypto/mlx5/mlx5_crypto.c +8 -48

104 lines not on this page · raw message

drivers/crypto/mlx5/mlx5_crypto.h +1 -5
index 69cef81d77..135cd78212 100644
@@ -21,8 +21,7 @@ struct mlx5_crypto_priv {
 	TAILQ_ENTRY(mlx5_crypto_priv) next;
 	struct mlx5_common_device *cdev; /* Backend mlx5 device. */
 	struct rte_cryptodev *crypto_dev;
-	void *uar; /* User Access Region. */
-	volatile uint64_t *uar_addr;
+	struct mlx5_uar uar; /* User Access Region. */
 	uint32_t max_segs_num; /* Maximum supported data segs. */
 	struct mlx5_hlist *dek_hlist; /* Dek hash list. */
 	struct rte_cryptodev_config dev_config;
@@ -32,9 +31,6 @@ struct mlx5_crypto_priv {
 	uint16_t umr_wqe_size;
 	uint16_t umr_wqe_stride;
 	uint16_t max_rdmar_ds;
-#ifndef RTE_ARCH_64
-	rte_spinlock_t uar32_sl;
-#endif /* RTE_ARCH_64 */
 };
 
 struct mlx5_crypto_qp {
drivers/net/mlx5/linux/mlx5_verbs.c +42 -2

68 lines not on this page · raw message

drivers/net/mlx5/mlx5.c +37 -156

243 lines not on this page · raw message

drivers/net/mlx5/mlx5.h +5 -5
index 3b04f9d4e3..7be0e88233 100644
@@ -518,7 +518,6 @@ struct mlx5_aso_sq {
 	rte_spinlock_t sqsl;
 	struct mlx5_aso_cq cq;
 	struct mlx5_devx_sq sq_obj;
-	volatile uint64_t *uar_addr;
 	struct mlx5_pmd_mr mr;
 	uint16_t pi;
 	uint32_t head;
@@ -1138,7 +1137,7 @@ struct mlx5_dev_ctx_shared {
 	void *rx_domain; /* RX Direct Rules name space handle. */
 	void *tx_domain; /* TX Direct Rules name space handle. */
 #ifndef RTE_ARCH_64
-	rte_spinlock_t uar_lock_cq; /* CQs share a common distinct UAR */
+	rte_spinlock_t uar_lock_cq; /* CQs share a common distinct UAR. */
 	rte_spinlock_t uar_lock[MLX5_UAR_PAGE_NUM_MAX];
 	/* UAR same-page access control required in 32bit implementations. */
 #endif
@@ -1166,11 +1165,11 @@ struct mlx5_dev_ctx_shared {
 	struct mlx5_devx_obj *tis[16]; /* TIS object. */
 	struct mlx5_devx_obj *td; /* Transport domain. */
 	struct mlx5_lag lag; /* LAG attributes */
-	void *tx_uar; /* Tx/packet pacing shared UAR. */
+	struct mlx5_uar tx_uar; /* DevX UAR for Tx and Txpp and ASO SQs. */
+	struct mlx5_uar rx_uar; /* DevX UAR for Rx. */
 	struct mlx5_proc_priv *pppriv; /* Pointer to primary private process. */
 	struct mlx5_flex_parser_profiles fp[MLX5_FLEX_PARSER_MAX];
 	/* Flex parser profiles information. */
-	void *devx_rx_uar; /* DevX UAR for Rx. */
 	struct mlx5_aso_age_mng *aso_age_mng;
 	/* Management data for aging mechanism using ASO Flow Hit. */
 	struct mlx5_geneve_tlv_option_resource *geneve_tlv_option_resource;
@@ -1191,7 +1190,7 @@ struct mlx5_dev_ctx_shared {
 struct mlx5_proc_priv {
 	size_t uar_table_sz;
 	/* Size of UAR register table. */
-	void *uar_table[];
+	struct mlx5_uar_data uar_table[];
 	/* Table of UAR registers for each process. */
 };
 
@@ -1741,6 +1740,7 @@ int mlx5_flow_meter_flush(struct rte_eth_dev *dev,
 void mlx5_flow_meter_rxq_flush(struct rte_eth_dev *dev);
 
 /* mlx5_os.c */
+
 struct rte_pci_driver;
 int mlx5_os_get_dev_attr(struct mlx5_common_device *dev,
 			 struct mlx5_dev_attr *dev_attr);
drivers/net/mlx5/mlx5_defs.h +0 -8
index d36c13c38e..258475ed2c 100644
@@ -112,14 +112,6 @@
 #define MLX5_UAR_PAGE_NUM_MAX 64
 #define MLX5_UAR_PAGE_NUM_MASK ((MLX5_UAR_PAGE_NUM_MAX) - 1)
 
-/* Fields of memory mapping type in offset parameter of mmap() */
-#define MLX5_UAR_MMAP_CMD_SHIFT 8
-#define MLX5_UAR_MMAP_CMD_MASK 0xff
-
-#ifndef HAVE_MLX5DV_MMAP_GET_NC_PAGES_CMD
-#define MLX5_MMAP_GET_NC_PAGES_CMD 3
-#endif
-
 /* Log 2 of the default number of strides per WQE for Multi-Packet RQ. */
 #define MLX5_MPRQ_STRIDE_NUM_N 6U
 
drivers/net/mlx5/mlx5_devx.c +12 -8
index dc391529c2..591a4d55c5 100644
@@ -363,7 +363,7 @@ mlx5_rxq_create_devx_cq_resources(struct rte_eth_dev *dev, uint16_t idx)
 			"Port %u Rx CQE compression is disabled for LRO.",
 			dev->data->port_id);
 	}
-	cq_attr.uar_page_id = mlx5_os_get_devx_uar_page_id(sh->devx_rx_uar);
+	cq_attr.uar_page_id = mlx5_os_get_devx_uar_page_id(sh->rx_uar.obj);
 	log_cqe_n = log2above(cqe_n);
 	/* Create CQ using DevX API. */
 	ret = mlx5_devx_cq_create(sh->cdev->ctx, &rxq_ctrl->obj->cq_obj,
@@ -374,7 +374,7 @@ mlx5_rxq_create_devx_cq_resources(struct rte_eth_dev *dev, uint16_t idx)
 	rxq_data->cqes = (volatile struct mlx5_cqe (*)[])
 							(uintptr_t)cq_obj->cqes;
 	rxq_data->cq_db = cq_obj->db_rec;
-	rxq_data->cq_uar = mlx5_os_get_devx_uar_base_addr(sh->devx_rx_uar);
+	rxq_data->uar_data = sh->rx_uar.cq_db;
 	rxq_data->cqe_n = log_cqe_n;
 	rxq_data->cqn = cq_obj->cq->id;
 	if (rxq_ctrl->obj->devx_channel) {
@@ -1015,6 +1015,7 @@ mlx5_txq_create_devx_sq_resources(struct rte_eth_dev *dev, uint16_t idx,
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5_common_device *cdev = priv->sh->cdev;
+	struct mlx5_uar *uar = &priv->sh->tx_uar;
 	struct mlx5_txq_data *txq_data = (*priv->txqs)[idx];
 	struct mlx5_txq_ctrl *txq_ctrl =
 			container_of(txq_data, struct mlx5_txq_ctrl, txq);
@@ -1028,8 +1029,7 @@ mlx5_txq_create_devx_sq_resources(struct rte_eth_dev *dev, uint16_t idx,
 		.tis_lst_sz = 1,
 		.wq_attr = (struct mlx5_devx_wq_attr){
 			.pd = cdev->pdn,
-			.uar_page =
-				 mlx5_os_get_devx_uar_page_id(priv->sh->tx_uar),
+			.uar_page = mlx5_os_get_devx_uar_page_id(uar->obj),
 		},
 		.ts_format =
 			mlx5_ts_format_conv(cdev->config.hca_attr.sq_ts_format),
@@ -1069,10 +1069,11 @@ mlx5_txq_devx_obj_new(struct rte_eth_dev *dev, uint16_t idx)
 	rte_errno = ENOMEM;
 	return -rte_errno;
 #else
+	struct mlx5_proc_priv *ppriv = MLX5_PROC_PRIV(PORT_ID(priv));
 	struct mlx5_dev_ctx_shared *sh = priv->sh;
 	struct mlx5_txq_obj *txq_obj = txq_ctrl->obj;
 	struct mlx5_devx_cq_attr cq_attr = {
-		.uar_page_id = mlx5_os_get_devx_uar_page_id(sh->tx_uar),
+		.uar_page_id = mlx5_os_get_devx_uar_page_id(sh->tx_uar.obj),
 	};
 	uint32_t cqe_n, log_desc_n;
 	uint32_t wqe_n, wqe_size;
@@ -1080,6 +1081,8 @@ mlx5_txq_devx_obj_new(struct rte_eth_dev *dev, uint16_t idx)
 
 	MLX5_ASSERT(txq_data);
 	MLX5_ASSERT(txq_obj);
+	MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY);
+	MLX5_ASSERT(ppriv);
 	txq_obj->txq_ctrl = txq_ctrl;
 	txq_obj->dev = dev;
 	cqe_n = (1UL << txq_data->elts_n) / MLX5_TX_COMP_THRESH +
@@ -1152,6 +1155,8 @@ mlx5_txq_devx_obj_new(struct rte_eth_dev *dev, uint16_t idx)
 	txq_data->qp_db = &txq_obj->sq_obj.db_rec[MLX5_SND_DBR];
 	*txq_data->qp_db = 0;
 	txq_data->qp_num_8s = txq_obj->sq_obj.sq->id << 8;
+	txq_data->db_heu = sh->cdev->config.dbnc == MLX5_TXDB_HEURISTIC;
+	txq_data->db_nc = sh->tx_uar.dbnc;
 	/* Change Send Queue state to Ready-to-Send. */
 	ret = mlx5_txq_devx_modify(txq_obj, MLX5_TXQ_MOD_RST2RDY, 0);
 	if (ret) {
@@ -1170,10 +1175,9 @@ mlx5_txq_devx_obj_new(struct rte_eth_dev *dev, uint16_t idx)
 	if (!priv->sh->tdn)
 		priv->sh->tdn = priv->sh->td->id;
 #endif
-	MLX5_ASSERT(sh->tx_uar && mlx5_os_get_devx_uar_reg_addr(sh->tx_uar));
 	txq_ctrl->uar_mmap_offset =
-				mlx5_os_get_devx_uar_mmap_offset(sh->tx_uar);
-	txq_uar_init(txq_ctrl, mlx5_os_get_devx_uar_reg_addr(sh->tx_uar));
+			mlx5_os_get_devx_uar_mmap_offset(sh->tx_uar.obj);
+	ppriv->uar_table[txq_data->idx] = sh->tx_uar.bf_db;
 	dev->data->tx_queue_state[idx] = RTE_ETH_QUEUE_STATE_STARTED;
 	return 0;
 error:
drivers/net/mlx5/mlx5_flow_aso.c +36 -45

214 lines not on this page · raw message

drivers/net/mlx5/mlx5_rx.h +1 -5
index 4952fe1455..6d2e79ebaf 100644
@@ -121,13 +121,9 @@ struct mlx5_rxq_data {
 	struct mlx5_rxq_stats stats;
 	rte_xmm_t mbuf_initializer; /* Default rearm/flags for vectorized Rx. */
 	struct rte_mbuf fake_mbuf; /* elts padding for vectorized Rx. */
-	void *cq_uar; /* Verbs CQ user access region. */
+	struct mlx5_uar_data uar_data; /* CQ doorbell. */
 	uint32_t cqn; /* CQ number. */
 	uint8_t cq_arm_sn; /* CQ arm seq number. */
-#ifndef RTE_ARCH_64
-	rte_spinlock_t *uar_lock_cq;
-	/* CQ (UAR) access lock required for 32bit implementations */
-#endif
 	uint32_t tunnel; /* Tunnel information. */
 	int timestamp_offset; /* Dynamic mbuf field for timestamp. */
 	uint64_t timestamp_rx_flag; /* Dynamic mbuf flag for timestamp. */
drivers/net/mlx5/mlx5_rxq.c +3 -8
index 4f02fe02b9..fdb8a51d02 100644
@@ -21,11 +21,11 @@
 
 #include <mlx5_glue.h>
 #include <mlx5_malloc.h>
+#include <mlx5_common.h>
 #include <mlx5_common_mr.h>
 
 #include "mlx5_defs.h"
 #include "mlx5.h"
-#include "mlx5_tx.h"
 #include "mlx5_rx.h"
 #include "mlx5_utils.h"
 #include "mlx5_autoconf.h"
@@ -952,15 +952,13 @@ mlx5_arm_cq(struct mlx5_rxq_data *rxq, int sq_n_rxq)
 	int sq_n = 0;
 	uint32_t doorbell_hi;
 	uint64_t doorbell;
-	void *cq_db_reg = (char *)rxq->cq_uar + MLX5_CQ_DOORBELL;
 
 	sq_n = sq_n_rxq & MLX5_CQ_SQN_MASK;
 	doorbell_hi = sq_n << MLX5_CQ_SQN_OFFSET | (rxq->cq_ci & MLX5_CI_MASK);
 	doorbell = (uint64_t)doorbell_hi << 32;
 	doorbell |= rxq->cqn;
-	rxq->cq_db[MLX5_CQ_ARM_DB] = rte_cpu_to_be_32(doorbell_hi);
-	mlx5_uar_write64(rte_cpu_to_be_64(doorbell),
-			 cq_db_reg, rxq->uar_lock_cq);
+	mlx5_doorbell_ring(&rxq->uar_data, rte_cpu_to_be_64(doorbell),
+			   doorbell_hi, &rxq->cq_db[MLX5_CQ_ARM_DB], 0);
 }
 
 /**
@@ -1621,9 +1619,6 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		(struct rte_mbuf *(*)[desc_n])(tmpl + 1);
 	tmpl->rxq.mprq_bufs =
 		(struct mlx5_mprq_buf *(*)[desc])(*tmpl->rxq.elts + desc_n);
-#ifndef RTE_ARCH_64
-	tmpl->rxq.uar_lock_cq = &priv->sh->uar_lock_cq;
-#endif
 	tmpl->rxq.idx = idx;
 	__atomic_fetch_add(&tmpl->refcnt, 1, __ATOMIC_RELAXED);
 	LIST_INSERT_HEAD(&priv->rxqsctrl, tmpl, next);
drivers/net/mlx5/mlx5_tx.h +10 -92

148 lines not on this page · raw message

drivers/net/mlx5/mlx5_txpp.c +9 -27
index 34f92faa67..927c327284 100644
@@ -164,21 +164,14 @@ mlx5_txpp_doorbell_rearm_queue(struct mlx5_dev_ctx_shared *sh, uint16_t ci)
 		uint32_t w32[2];
 		uint64_t w64;
 	} cs;
-	void *reg_addr;
 
 	wq->sq_ci = ci + 1;
 	cs.w32[0] = rte_cpu_to_be_32(rte_be_to_cpu_32
 			(wqe[ci & (wq->sq_size - 1)].ctrl[0]) | (ci - 1) << 8);
 	cs.w32[1] = wqe[ci & (wq->sq_size - 1)].ctrl[1];
 	/* Update SQ doorbell record with new SQ ci. */
-	rte_compiler_barrier();
-	*wq->sq_obj.db_rec = rte_cpu_to_be_32(wq->sq_ci);
-	/* Make sure the doorbell record is updated. */
-	rte_wmb();
-	/* Write to doorbel register to start processing. */
-	reg_addr = mlx5_os_get_devx_uar_reg_addr(sh->tx_uar);
-	__mlx5_uar_write64_relaxed(cs.w64, reg_addr, NULL);
-	rte_wmb();
+	mlx5_doorbell_ring(&sh->tx_uar.bf_db, cs.w64, wq->sq_ci,
+			   wq->sq_obj.db_rec, !sh->tx_uar.dbnc);
 }
 
 static void
@@ -233,14 +226,15 @@ mlx5_txpp_create_rearm_queue(struct mlx5_dev_ctx_shared *sh)
 		.tis_num = sh->tis[0]->id,
 		.wq_attr = (struct mlx5_devx_wq_attr){
 			.pd = sh->cdev->pdn,
-			.uar_page = mlx5_os_get_devx_uar_page_id(sh->tx_uar),
+			.uar_page =
+				mlx5_os_get_devx_uar_page_id(sh->tx_uar.obj),
 		},
 		.ts_format = mlx5_ts_format_conv
 				       (sh->cdev->config.hca_attr.sq_ts_format),
 	};
 	struct mlx5_devx_modify_sq_attr msq_attr = { 0 };
 	struct mlx5_devx_cq_attr cq_attr = {
-		.uar_page_id = mlx5_os_get_devx_uar_page_id(sh->tx_uar),
+		.uar_page_id = mlx5_os_get_devx_uar_page_id(sh->tx_uar.obj),
 	};
 	struct mlx5_txpp_wq *wq = &sh->txpp.rearm_queue;
 	int ret;
@@ -394,7 +388,7 @@ mlx5_txpp_create_clock_queue(struct mlx5_dev_ctx_shared *sh)
 	struct mlx5_devx_cq_attr cq_attr = {
 		.use_first_only = 1,
 		.overrun_ignore = 1,
-		.uar_page_id = mlx5_os_get_devx_uar_page_id(sh->tx_uar),
+		.uar_page_id = mlx5_os_get_devx_uar_page_id(sh->tx_uar.obj),
 	};
 	struct mlx5_txpp_wq *wq = &sh->txpp.clock_queue;
 	int ret;
@@ -444,7 +438,7 @@ mlx5_txpp_create_clock_queue(struct mlx5_dev_ctx_shared *sh)
 	sq_attr.cqn = wq->cq_obj.cq->id;
 	sq_attr.packet_pacing_rate_limit_index = sh->txpp.pp_id;
 	sq_attr.wq_attr.cd_slave = 1;
-	sq_attr.wq_attr.uar_page = mlx5_os_get_devx_uar_page_id(sh->tx_uar);
+	sq_attr.wq_attr.uar_page = mlx5_os_get_devx_uar_page_id(sh->tx_uar.obj);
 	sq_attr.wq_attr.pd = sh->cdev->pdn;
 	sq_attr.ts_format =
 		mlx5_ts_format_conv(sh->cdev->config.hca_attr.sq_ts_format);
@@ -479,26 +473,14 @@ mlx5_txpp_create_clock_queue(struct mlx5_dev_ctx_shared *sh)
 static inline void
 mlx5_txpp_cq_arm(struct mlx5_dev_ctx_shared *sh)
 {
-	void *base_addr;
-
 	struct mlx5_txpp_wq *aq = &sh->txpp.rearm_queue;
 	uint32_t arm_sn = aq->arm_sn << MLX5_CQ_SQN_OFFSET;
 	uint32_t db_hi = arm_sn | MLX5_CQ_DBR_CMD_ALL | aq->cq_ci;
 	uint64_t db_be =
 		rte_cpu_to_be_64(((uint64_t)db_hi << 32) | aq->cq_obj.cq->id);
-	base_addr = mlx5_os_get_devx_uar_base_addr(sh->tx_uar);
-	uint32_t *addr = RTE_PTR_ADD(base_addr, MLX5_CQ_DOORBELL);
 
-	rte_compiler_barrier();
-	aq->cq_obj.db_rec[MLX5_CQ_ARM_DB] = rte_cpu_to_be_32(db_hi);
-	rte_wmb();
-#ifdef RTE_ARCH_64
-	*(uint64_t *)addr = db_be;
-#else
-	*(uint32_t *)addr = db_be;
-	rte_io_wmb();
-	*((uint32_t *)addr + 1) = db_be >> 32;
-#endif
+	mlx5_doorbell_ring(&sh->tx_uar.cq_db, db_be, db_hi,
+			   &aq->cq_obj.db_rec[MLX5_CQ_ARM_DB], 0);
 	aq->arm_sn++;
 }
 
drivers/net/mlx5/mlx5_txq.c +9 -65

105 lines not on this page · raw message

drivers/regex/mlx5/mlx5_regex.c +3 -14
index d632252794..71c42eab25 100644
@@ -133,17 +133,9 @@ mlx5_regex_dev_probe(struct mlx5_common_device *cdev)
 		rte_errno = rte_errno ? rte_errno : EINVAL;
 		goto dev_error;
 	}
-	/*
-	 * This PMD always claims the write memory barrier on UAR
-	 * registers writings, it is safe to allocate UAR with any
-	 * memory mapping type.
-	 */
-	priv->uar = mlx5_devx_alloc_uar(priv->cdev);
-	if (!priv->uar) {
-		DRV_LOG(ERR, "can't allocate uar.");
-		rte_errno = ENOMEM;
+	ret = mlx5_devx_uar_prepare(cdev, &priv->uar);
+	if (ret)
 		goto error;
-	}
 	priv->regexdev->dev_ops = &mlx5_regexdev_ops;
 	priv->regexdev->enqueue = mlx5_regexdev_enqueue;
 #ifdef HAVE_MLX5_UMR_IMKEY
@@ -162,8 +154,6 @@ mlx5_regex_dev_probe(struct mlx5_common_device *cdev)
 	return 0;
 
 error:
-	if (priv->uar)
-		mlx5_glue->devx_free_uar(priv->uar);
 	if (priv->regexdev)
 		rte_regexdev_unregister(priv->regexdev);
 dev_error:
@@ -185,8 +175,7 @@ mlx5_regex_dev_remove(struct mlx5_common_device *cdev)
 		return 0;
 	priv = dev->data->dev_private;
 	if (priv) {
-		if (priv->uar)
-			mlx5_glue->devx_free_uar(priv->uar);
+		mlx5_devx_uar_release(&priv->uar);
 		if (priv->regexdev)
 			rte_regexdev_unregister(priv->regexdev);
 		rte_free(priv);
drivers/regex/mlx5/mlx5_regex.h +1 -1
index eb59cc38a6..fa17b46f6f 100644
@@ -67,7 +67,7 @@ struct mlx5_regex_priv {
 	struct mlx5_regex_db db[MLX5_RXP_MAX_ENGINES +
 				MLX5_RXP_EM_COUNT];
 	uint32_t nb_engines; /* Number of RegEx engines. */
-	struct mlx5dv_devx_uar *uar; /* UAR object. */
+	struct mlx5_uar uar; /* UAR object. */
 	uint8_t is_bf2; /* The device is BF2 device. */
 	uint8_t has_umr; /* The device supports UMR. */
 	uint32_t mmo_regex_qp_cap:1;
drivers/regex/mlx5/mlx5_regex_control.c +2 -2
index 50c966a022..9354673251 100644
@@ -78,7 +78,7 @@ static int
 regex_ctrl_create_cq(struct mlx5_regex_priv *priv, struct mlx5_regex_cq *cq)
 {
 	struct mlx5_devx_cq_attr attr = {
-		.uar_page_id = priv->uar->page_id,
+		.uar_page_id = mlx5_os_get_devx_uar_page_id(priv->uar.obj),
 	};
 	int ret;
 
@@ -137,7 +137,7 @@ regex_ctrl_create_hw_qp(struct mlx5_regex_priv *priv, struct mlx5_regex_qp *qp,
 #ifdef HAVE_IBV_FLOW_DV_SUPPORT
 	struct mlx5_devx_qp_attr attr = {
 		.cqn = qp->cq.cq_obj.cq->id,
-		.uar_index = priv->uar->page_id,
+		.uar_index = mlx5_os_get_devx_uar_page_id(priv->uar.obj),
 		.pd = priv->cdev->pdn,
 		.ts_format = mlx5_ts_format_conv
 				     (priv->cdev->config.hca_attr.qp_ts_format),
drivers/regex/mlx5/mlx5_regex_fastpath.c +11 -15
index adb5343a46..18bbda6340 100644
@@ -188,24 +188,20 @@ prep_one(struct mlx5_regex_priv *priv, struct mlx5_regex_qp *qp,
 }
 
 static inline void
-send_doorbell(struct mlx5_regex_priv *priv, struct mlx5_regex_hw_qp *qp_obj)
+send_doorbell(struct mlx5_regex_priv *priv, struct mlx5_regex_hw_qp *qp)
 {
-	struct mlx5dv_devx_uar *uar = priv->uar;
-	size_t wqe_offset = (qp_obj->db_pi & (qp_size_get(qp_obj) - 1)) *
-		(MLX5_SEND_WQE_BB << (priv->has_umr ? 2 : 0)) +
-		(priv->has_umr ? MLX5_REGEX_UMR_WQE_SIZE : 0);
-	uint8_t *wqe = (uint8_t *)(uintptr_t)qp_obj->qp_obj.wqes + wqe_offset;
+	size_t wqe_offset = (qp->db_pi & (qp_size_get(qp) - 1)) *
+			    (MLX5_SEND_WQE_BB << (priv->has_umr ? 2 : 0)) +
+			    (priv->has_umr ? MLX5_REGEX_UMR_WQE_SIZE : 0);
+	uint8_t *wqe = (uint8_t *)(uintptr_t)qp->qp_obj.wqes + wqe_offset;
+	uint32_t actual_pi = (priv->has_umr ? (qp->db_pi * 4 + 3) : qp->db_pi) &
+			     MLX5_REGEX_MAX_WQE_INDEX;
+
 	/* Or the fm_ce_se instead of set, avoid the fence be cleared. */
 	((struct mlx5_wqe_ctrl_seg *)wqe)->fm_ce_se |= MLX5_WQE_CTRL_CQ_UPDATE;
-	uint64_t *doorbell_addr =
-		(uint64_t *)((uint8_t *)uar->base_addr + 0x800);
-	rte_io_wmb();
-	qp_obj->qp_obj.db_rec[MLX5_SND_DBR] = rte_cpu_to_be_32((priv->has_umr ?
-					(qp_obj->db_pi * 4 + 3) : qp_obj->db_pi)
-					& MLX5_REGEX_MAX_WQE_INDEX);
-	rte_wmb();
-	*doorbell_addr = *(volatile uint64_t *)wqe;
-	rte_wmb();
+	mlx5_doorbell_ring(&priv->uar.bf_db, *(volatile uint64_t *)wqe,
+			   actual_pi, &qp->qp_obj.db_rec[MLX5_SND_DBR],
+			   !priv->uar.dbnc);
 }
 
 static inline int
drivers/vdpa/mlx5/mlx5_vdpa.h +1 -1
index cf4f384fa4..312473e00c 100644
@@ -136,7 +136,7 @@ struct mlx5_vdpa_priv {
 	struct rte_vhost_memory *vmem;
 	struct mlx5dv_devx_event_channel *eventc;
 	struct mlx5dv_devx_event_channel *err_chnl;
-	struct mlx5dv_devx_uar *uar;
+	struct mlx5_uar uar;
 	struct rte_intr_handle *err_intr_handle;
 	struct mlx5_devx_obj *td;
 	struct mlx5_devx_obj *tiss[16]; /* TIS list for each LAG port. */
drivers/vdpa/mlx5/mlx5_vdpa_event.c +7 -26
index 21738bdfff..9cc71714a2 100644
@@ -30,10 +30,7 @@
 void
 mlx5_vdpa_event_qp_global_release(struct mlx5_vdpa_priv *priv)
 {
-	if (priv->uar) {
-		mlx5_glue->devx_free_uar(priv->uar);
-		priv->uar = NULL;
-	}
+	mlx5_devx_uar_release(&priv->uar);
 #ifdef HAVE_IBV_DEVX_EVENT
 	if (priv->eventc) {
 		mlx5_os_devx_destroy_event_channel(priv->eventc);
@@ -56,14 +53,7 @@ mlx5_vdpa_event_qp_global_prepare(struct mlx5_vdpa_priv *priv)
 			rte_errno);
 		goto error;
 	}
-	/*
-	 * This PMD always claims the write memory barrier on UAR
-	 * registers writings, it is safe to allocate UAR with any
-	 * memory mapping type.
-	 */
-	priv->uar = mlx5_devx_alloc_uar(priv->cdev);
-	if (!priv->uar) {
-		rte_errno = errno;
+	if (mlx5_devx_uar_prepare(priv->cdev, &priv->uar) != 0) {
 		DRV_LOG(ERR, "Failed to allocate UAR.");
 		goto error;
 	}
@@ -88,18 +78,9 @@ mlx5_vdpa_cq_arm(struct mlx5_vdpa_priv *priv, struct mlx5_vdpa_cq *cq)
 	uint32_t doorbell_hi = arm_sn | MLX5_CQ_DBR_CMD_ALL | cq_ci;
 	uint64_t doorbell = ((uint64_t)doorbell_hi << 32) | cq->cq_obj.cq->id;
 	uint64_t db_be = rte_cpu_to_be_64(doorbell);
-	uint32_t *addr = RTE_PTR_ADD(priv->uar->base_addr, MLX5_CQ_DOORBELL);
-
-	rte_io_wmb();
-	cq->cq_obj.db_rec[MLX5_CQ_ARM_DB] = rte_cpu_to_be_32(doorbell_hi);
-	rte_wmb();
-#ifdef RTE_ARCH_64
-	*(uint64_t *)addr = db_be;
-#else
-	*(uint32_t *)addr = db_be;
-	rte_io_wmb();
-	*((uint32_t *)addr + 1) = db_be >> 32;
-#endif
+
+	mlx5_doorbell_ring(&priv->uar.cq_db, db_be, doorbell_hi,
+			   &cq->cq_obj.db_rec[MLX5_CQ_ARM_DB], 0);
 	cq->arm_sn++;
 	cq->armed = 1;
 }
@@ -110,7 +91,7 @@ mlx5_vdpa_cq_create(struct mlx5_vdpa_priv *priv, uint16_t log_desc_n,
 {
 	struct mlx5_devx_cq_attr attr = {
 		.use_first_only = 1,
-		.uar_page_id = priv->uar->page_id,
+		.uar_page_id = mlx5_os_get_devx_uar_page_id(priv->uar.obj),
 	};
 	uint16_t event_nums[1] = {0};
 	int ret;
@@ -606,7 +587,7 @@ mlx5_vdpa_event_qp_create(struct mlx5_vdpa_priv *priv, uint16_t desc_n,
 		DRV_LOG(ERR, "Failed to create FW QP(%u).", rte_errno);
 		goto error;
 	}
-	attr.uar_index = priv->uar->page_id;
+	attr.uar_index = mlx5_os_get_devx_uar_page_id(priv->uar.obj);
 	attr.cqn = eqp->cq.cq_obj.cq->id;
 	attr.rq_size = RTE_BIT32(log_desc_n);
 	attr.log_rq_stride = rte_log2_u32(MLX5_WSEG_SIZE);
Signature · 1 line
2.25.1
#7 lore raw
In reply to [email protected]
Quoted 7 lines

Michael Baum (6):
crypto/mlx5: fix invalid memory access in probing common/mlx5: fix redundant code in UAR allocation common/mlx5: fix UAR allocation diagnostics messages common/mlx5: fix doorbell mapping configuration net/mlx5: remove duplicated reference of the TxQ doorbell common/mlx5: fix post doorbell barrier

Applied, thanks.