]> git.droids-corp.org - dpdk.git/commitdiff
common/mlx5: share DevX SQ creation
authorMichael Baum <michaelba@nvidia.com>
Wed, 6 Jan 2021 08:19:34 +0000 (08:19 +0000)
committerFerruh Yigit <ferruh.yigit@intel.com>
Thu, 14 Jan 2021 09:12:36 +0000 (10:12 +0100)
The SQ object in DevX is created in several places and in several
different drivers.
In all places almost all the details are the same, and in particular the
allocations of the required resources.

Add a structure that contains all the resources, and provide creation
and release functions for it.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
drivers/common/mlx5/mlx5_common_devx.c
drivers/common/mlx5/mlx5_common_devx.h
drivers/common/mlx5/rte_common_mlx5_exports.def
drivers/common/mlx5/version.map

index 3ec0dd515a563f32f3d6e66c9c8ee8e5a5cb63fc..58b75c318e456c26ee321607b0a4c09f5b702a81 100644 (file)
@@ -153,3 +153,122 @@ error:
        rte_errno = ret;
        return -rte_errno;
 }
+
+/**
+ * Destroy DevX Send Queue.
+ *
+ * @param[in] sq
+ *   DevX SQ to destroy.
+ */
+void
+mlx5_devx_sq_destroy(struct mlx5_devx_sq *sq)
+{
+       if (sq->sq)
+               claim_zero(mlx5_devx_cmd_destroy(sq->sq));
+       if (sq->umem_obj)
+               claim_zero(mlx5_os_umem_dereg(sq->umem_obj));
+       if (sq->umem_buf)
+               mlx5_free((void *)(uintptr_t)sq->umem_buf);
+}
+
+/**
+ * Create Send Queue using DevX API.
+ *
+ * Get a pointer to partially initialized attributes structure, and updates the
+ * following fields:
+ *   wq_type
+ *   wq_umem_valid
+ *   wq_umem_id
+ *   wq_umem_offset
+ *   dbr_umem_valid
+ *   dbr_umem_id
+ *   dbr_addr
+ *   log_wq_stride
+ *   log_wq_sz
+ *   log_wq_pg_sz
+ * All other fields are updated by caller.
+ *
+ * @param[in] ctx
+ *   Context returned from mlx5 open_device() glue function.
+ * @param[in/out] sq_obj
+ *   Pointer to SQ to create.
+ * @param[in] log_wqbb_n
+ *   Log of number of WQBBs in queue.
+ * @param[in] attr
+ *   Pointer to SQ attributes structure.
+ * @param[in] socket
+ *   Socket to use for allocation.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_devx_sq_create(void *ctx, struct mlx5_devx_sq *sq_obj, uint16_t log_wqbb_n,
+                   struct mlx5_devx_create_sq_attr *attr, int socket)
+{
+       struct mlx5_devx_obj *sq = NULL;
+       struct mlx5dv_devx_umem *umem_obj = NULL;
+       void *umem_buf = NULL;
+       size_t alignment = MLX5_WQE_BUF_ALIGNMENT;
+       uint32_t umem_size, umem_dbrec;
+       uint16_t sq_size = 1 << log_wqbb_n;
+       int ret;
+
+       if (alignment == (size_t)-1) {
+               DRV_LOG(ERR, "Failed to get WQE buf alignment.");
+               rte_errno = ENOMEM;
+               return -rte_errno;
+       }
+       /* Allocate memory buffer for WQEs and doorbell record. */
+       umem_size = MLX5_WQE_SIZE * sq_size;
+       umem_dbrec = RTE_ALIGN(umem_size, MLX5_DBR_SIZE);
+       umem_size += MLX5_DBR_SIZE;
+       umem_buf = mlx5_malloc(MLX5_MEM_RTE | MLX5_MEM_ZERO, umem_size,
+                              alignment, socket);
+       if (!umem_buf) {
+               DRV_LOG(ERR, "Failed to allocate memory for SQ.");
+               rte_errno = ENOMEM;
+               return -rte_errno;
+       }
+       /* Register allocated buffer in user space with DevX. */
+       umem_obj = mlx5_os_umem_reg(ctx, (void *)(uintptr_t)umem_buf, umem_size,
+                                   IBV_ACCESS_LOCAL_WRITE);
+       if (!umem_obj) {
+               DRV_LOG(ERR, "Failed to register umem for SQ.");
+               rte_errno = errno;
+               goto error;
+       }
+       /* Fill attributes for SQ object creation. */
+       attr->wq_attr.wq_type = MLX5_WQ_TYPE_CYCLIC;
+       attr->wq_attr.wq_umem_valid = 1;
+       attr->wq_attr.wq_umem_id = mlx5_os_get_umem_id(umem_obj);
+       attr->wq_attr.wq_umem_offset = 0;
+       attr->wq_attr.dbr_umem_valid = 1;
+       attr->wq_attr.dbr_umem_id = attr->wq_attr.wq_umem_id;
+       attr->wq_attr.dbr_addr = umem_dbrec;
+       attr->wq_attr.log_wq_stride = rte_log2_u32(MLX5_WQE_SIZE);
+       attr->wq_attr.log_wq_sz = log_wqbb_n;
+       attr->wq_attr.log_wq_pg_sz = MLX5_LOG_PAGE_SIZE;
+       /* Create send queue object with DevX. */
+       sq = mlx5_devx_cmd_create_sq(ctx, attr);
+       if (!sq) {
+               DRV_LOG(ERR, "Can't create DevX SQ object.");
+               rte_errno = ENOMEM;
+               goto error;
+       }
+       sq_obj->umem_buf = umem_buf;
+       sq_obj->umem_obj = umem_obj;
+       sq_obj->sq = sq;
+       sq_obj->db_rec = RTE_PTR_ADD(sq_obj->umem_buf, umem_dbrec);
+       return 0;
+error:
+       ret = rte_errno;
+       if (umem_obj)
+               claim_zero(mlx5_os_umem_dereg(umem_obj));
+       if (umem_buf)
+               mlx5_free((void *)(uintptr_t)umem_buf);
+       rte_errno = ret;
+       return -rte_errno;
+}
+
+
index 20d5da092589492479e197a086ec72800196e0f7..6b078b2863d2c2a240f780618b1bcad088879f4d 100644 (file)
@@ -7,6 +7,9 @@
 
 #include "mlx5_devx_cmds.h"
 
+/* The standard page size */
+#define MLX5_LOG_PAGE_SIZE 12
+
 /* DevX Completion Queue structure. */
 struct mlx5_devx_cq {
        struct mlx5_devx_obj *cq; /* The CQ DevX object. */
@@ -18,6 +21,18 @@ struct mlx5_devx_cq {
        volatile uint32_t *db_rec; /* The CQ doorbell record. */
 };
 
+/* DevX Send Queue structure. */
+struct mlx5_devx_sq {
+       struct mlx5_devx_obj *sq; /* The SQ DevX object. */
+       void *umem_obj; /* The SQ umem object. */
+       union {
+               volatile void *umem_buf;
+               volatile struct mlx5_wqe *wqes; /* The SQ ring buffer. */
+       };
+       volatile uint32_t *db_rec; /* The SQ doorbell record. */
+};
+
+
 /* mlx5_common_devx.c */
 
 __rte_internal
@@ -25,7 +40,15 @@ void mlx5_devx_cq_destroy(struct mlx5_devx_cq *cq);
 
 __rte_internal
 int mlx5_devx_cq_create(void *ctx, struct mlx5_devx_cq *cq_obj,
-                       uint16_t log_desc_n, struct mlx5_devx_cq_attr *attr,
-                       int socket);
+                       uint16_t log_desc_n,
+                       struct mlx5_devx_cq_attr *attr, int socket);
+
+__rte_internal
+void mlx5_devx_sq_destroy(struct mlx5_devx_sq *sq);
+
+__rte_internal
+int mlx5_devx_sq_create(void *ctx, struct mlx5_devx_sq *sq_obj,
+                       uint16_t log_wqbb_n,
+                       struct mlx5_devx_create_sq_attr *attr, int socket);
 
 #endif /* RTE_PMD_MLX5_COMMON_DEVX_H_ */
index 613799170f0d98f34cab34ae81aabbe571f890a2..68073c909732f3a6bdb2020e50b76d1a2b5c0b65 100644 (file)
@@ -37,6 +37,8 @@ EXPORTS
 
        mlx5_devx_cq_create
        mlx5_devx_cq_destroy
+       mlx5_devx_sq_create
+       mlx5_devx_sq_destroy
 
        mlx5_get_dbr
        mlx5_glue
index 4a07fb5071d02e9178a511449e162cd32e77b60f..ea628ebff0a5849ffbf400e8d6c1de91f969558c 100644 (file)
@@ -45,6 +45,8 @@ INTERNAL {
 
        mlx5_devx_cq_create;
        mlx5_devx_cq_destroy;
+       mlx5_devx_sq_create;
+       mlx5_devx_sq_destroy;
 
        mlx5_get_ifname_sysfs;
        mlx5_get_dbr;