* Create Completion Queue using DevX API. * * Get a pointer to partially initialized attributes structure, and updates the * following fields: * q_umem_valid * q_umem_id * q_umem_offset * db_umem_valid * db_umem_id * db_umem_offset * eqn * log_cq_size * log_page_size * All other fields are updated by caller. * * @param[in] ctx * Context returned from mlx5 open_d
| 78 | * 0 on success, a negative errno value otherwise and rte_errno is set. |
| 79 | */ |
| 80 | int |
| 81 | mlx5_devx_cq_create(void *ctx, struct mlx5_devx_cq *cq_obj, uint16_t log_desc_n, |
| 82 | struct mlx5_devx_cq_attr *attr, int socket) |
| 83 | { |
| 84 | struct mlx5_devx_obj *cq = NULL; |
| 85 | struct mlx5dv_devx_umem *umem_obj = NULL; |
| 86 | void *umem_buf = NULL; |
| 87 | size_t page_size = rte_mem_page_size(); |
| 88 | size_t alignment = MLX5_CQE_BUF_ALIGNMENT; |
| 89 | uint32_t umem_size, umem_dbrec; |
| 90 | uint32_t eqn; |
| 91 | uint32_t num_of_cqes = RTE_BIT32(log_desc_n); |
| 92 | int ret; |
| 93 | |
| 94 | if (page_size == (size_t)-1 || alignment == (size_t)-1) { |
| 95 | DRV_LOG(ERR, "Failed to get page_size."); |
| 96 | rte_errno = ENOMEM; |
| 97 | return -rte_errno; |
| 98 | } |
| 99 | /* Query first EQN. */ |
| 100 | ret = mlx5_glue->devx_query_eqn(ctx, 0, &eqn); |
| 101 | if (ret) { |
| 102 | rte_errno = errno; |
| 103 | DRV_LOG(ERR, "Failed to query event queue number."); |
| 104 | return -rte_errno; |
| 105 | } |
| 106 | /* Allocate memory buffer for CQEs and doorbell record. */ |
| 107 | umem_size = sizeof(struct mlx5_cqe) * num_of_cqes; |
| 108 | umem_dbrec = RTE_ALIGN(umem_size, MLX5_DBR_SIZE); |
| 109 | umem_size += MLX5_DBR_SIZE; |
| 110 | umem_buf = mlx5_malloc(MLX5_MEM_RTE | MLX5_MEM_ZERO, umem_size, |
| 111 | alignment, socket); |
| 112 | if (!umem_buf) { |
| 113 | DRV_LOG(ERR, "Failed to allocate memory for CQ."); |
| 114 | rte_errno = ENOMEM; |
| 115 | return -rte_errno; |
| 116 | } |
| 117 | /* Register allocated buffer in user space with DevX. */ |
| 118 | umem_obj = mlx5_os_umem_reg(ctx, (void *)(uintptr_t)umem_buf, umem_size, |
| 119 | IBV_ACCESS_LOCAL_WRITE); |
| 120 | if (!umem_obj) { |
| 121 | DRV_LOG(ERR, "Failed to register umem for CQ."); |
| 122 | rte_errno = errno; |
| 123 | goto error; |
| 124 | } |
| 125 | /* Fill attributes for CQ object creation. */ |
| 126 | attr->q_umem_valid = 1; |
| 127 | attr->q_umem_id = mlx5_os_get_umem_id(umem_obj); |
| 128 | attr->q_umem_offset = 0; |
| 129 | attr->db_umem_valid = 1; |
| 130 | attr->db_umem_id = attr->q_umem_id; |
| 131 | attr->db_umem_offset = umem_dbrec; |
| 132 | attr->eqn = eqn; |
| 133 | attr->log_cq_size = log_desc_n; |
| 134 | attr->log_page_size = rte_log2_u32(page_size); |
| 135 | /* Create completion queue object with DevX. */ |
| 136 | cq = mlx5_devx_cmd_create_cq(ctx, attr); |
| 137 | if (!cq) { |
no test coverage detected