* Create Queue Pair using DevX API. * * Get a pointer to partially initialized attributes structure, and updates the * following fields: * wq_umem_id * wq_umem_offset * dbr_umem_valid * dbr_umem_id * dbr_address * log_page_size * All other fields are updated by caller. * * @param[in] ctx * Context returned from mlx5 open_device() glue function. * @param[in/out] qp_obj
| 351 | * 0 on success, a negative errno value otherwise and rte_errno is set. |
| 352 | */ |
| 353 | int |
| 354 | mlx5_devx_qp_create(void *ctx, struct mlx5_devx_qp *qp_obj, uint32_t queue_size, |
| 355 | struct mlx5_devx_qp_attr *attr, int socket) |
| 356 | { |
| 357 | struct mlx5_devx_obj *qp = NULL; |
| 358 | struct mlx5dv_devx_umem *umem_obj = NULL; |
| 359 | void *umem_buf = NULL; |
| 360 | size_t alignment = MLX5_WQE_BUF_ALIGNMENT; |
| 361 | uint32_t umem_size, umem_dbrec; |
| 362 | int ret; |
| 363 | |
| 364 | if (alignment == (size_t)-1) { |
| 365 | DRV_LOG(ERR, "Failed to get WQE buf alignment."); |
| 366 | rte_errno = ENOMEM; |
| 367 | return -rte_errno; |
| 368 | } |
| 369 | /* Allocate memory buffer for WQEs and doorbell record. */ |
| 370 | umem_size = queue_size; |
| 371 | umem_dbrec = RTE_ALIGN(umem_size, MLX5_DBR_SIZE); |
| 372 | umem_size += MLX5_DBR_SIZE; |
| 373 | umem_buf = mlx5_malloc(MLX5_MEM_RTE | MLX5_MEM_ZERO, umem_size, |
| 374 | alignment, socket); |
| 375 | if (!umem_buf) { |
| 376 | DRV_LOG(ERR, "Failed to allocate memory for QP."); |
| 377 | rte_errno = ENOMEM; |
| 378 | return -rte_errno; |
| 379 | } |
| 380 | /* Register allocated buffer in user space with DevX. */ |
| 381 | umem_obj = mlx5_os_umem_reg(ctx, (void *)(uintptr_t)umem_buf, umem_size, |
| 382 | IBV_ACCESS_LOCAL_WRITE); |
| 383 | if (!umem_obj) { |
| 384 | DRV_LOG(ERR, "Failed to register umem for QP."); |
| 385 | rte_errno = errno; |
| 386 | goto error; |
| 387 | } |
| 388 | /* Fill attributes for SQ object creation. */ |
| 389 | attr->wq_umem_id = mlx5_os_get_umem_id(umem_obj); |
| 390 | attr->wq_umem_offset = 0; |
| 391 | attr->dbr_umem_valid = 1; |
| 392 | attr->dbr_umem_id = attr->wq_umem_id; |
| 393 | attr->dbr_address = umem_dbrec; |
| 394 | attr->log_page_size = MLX5_LOG_PAGE_SIZE; |
| 395 | /* Create send queue object with DevX. */ |
| 396 | qp = mlx5_devx_cmd_create_qp(ctx, attr); |
| 397 | if (!qp) { |
| 398 | DRV_LOG(ERR, "Can't create DevX QP object."); |
| 399 | rte_errno = ENOMEM; |
| 400 | goto error; |
| 401 | } |
| 402 | qp_obj->umem_buf = umem_buf; |
| 403 | qp_obj->umem_obj = umem_obj; |
| 404 | qp_obj->qp = qp; |
| 405 | qp_obj->db_rec = RTE_PTR_ADD(qp_obj->umem_buf, umem_dbrec); |
| 406 | return 0; |
| 407 | error: |
| 408 | ret = rte_errno; |
| 409 | if (umem_obj) |
| 410 | claim_zero(mlx5_os_umem_dereg(umem_obj)); |
no test coverage detected