get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/74436/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 74436,
    "url": "http://patchwork.dpdk.org/api/patches/74436/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/a113822415c4ee0ea2b6e92dc16b890b0993c9b7.1595152873.git.dekelp@mellanox.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<a113822415c4ee0ea2b6e92dc16b890b0993c9b7.1595152873.git.dekelp@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/a113822415c4ee0ea2b6e92dc16b890b0993c9b7.1595152873.git.dekelp@mellanox.com",
    "date": "2020-07-19T11:13:06",
    "name": "net/mlx5: implement CQ for RxQ using DevX API",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "0f78fa32892f269d72e2edd7ea203daa7ea80c88",
    "submitter": {
        "id": 1082,
        "url": "http://patchwork.dpdk.org/api/people/1082/?format=api",
        "name": "Dekel Peled",
        "email": "dekelp@mellanox.com"
    },
    "delegate": {
        "id": 3268,
        "url": "http://patchwork.dpdk.org/api/users/3268/?format=api",
        "username": "rasland",
        "first_name": "Raslan",
        "last_name": "Darawsheh",
        "email": "rasland@nvidia.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/a113822415c4ee0ea2b6e92dc16b890b0993c9b7.1595152873.git.dekelp@mellanox.com/mbox/",
    "series": [
        {
            "id": 11148,
            "url": "http://patchwork.dpdk.org/api/series/11148/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=11148",
            "date": "2020-07-19T11:13:06",
            "name": "net/mlx5: implement CQ for RxQ using DevX API",
            "version": 1,
            "mbox": "http://patchwork.dpdk.org/series/11148/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/74436/comments/",
    "check": "fail",
    "checks": "http://patchwork.dpdk.org/api/patches/74436/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 04207A0540;\n\tSun, 19 Jul 2020 13:14:58 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id C33FA1BFBA;\n\tSun, 19 Jul 2020 13:14:57 +0200 (CEST)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n by dpdk.org (Postfix) with ESMTP id E9A9B1BFAD\n for <dev@dpdk.org>; Sun, 19 Jul 2020 13:14:55 +0200 (CEST)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n dekelp@mellanox.com) with SMTP; 19 Jul 2020 14:14:51 +0300",
            "from mtl-vdi-280.wap.labs.mlnx. (mtl-vdi-280.wap.labs.mlnx\n [10.228.134.250])\n by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 06JBEpmW005827;\n Sun, 19 Jul 2020 14:14:51 +0300"
        ],
        "From": "Dekel Peled <dekelp@mellanox.com>",
        "To": "matan@mellanox.com, viacheslavo@mellanox.com, rasland@mellanox.com",
        "Cc": "dev@dpdk.org",
        "Date": "Sun, 19 Jul 2020 14:13:06 +0300",
        "Message-Id": "\n <a113822415c4ee0ea2b6e92dc16b890b0993c9b7.1595152873.git.dekelp@mellanox.com>",
        "X-Mailer": "git-send-email 1.7.1",
        "Subject": "[dpdk-dev] [PATCH] net/mlx5: implement CQ for RxQ using DevX API",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "This patch continues the work to use DevX API for different objects\ncreation and management.\nOn Rx control path, the RQ, RQT, and TIR objects can already be\ncreated using DevX API.\nThis patch adds the support to create CQ for RxQ using DevX API.\nThe corresponding event channel is also created and utilized using\nDevX API.\n\nSigned-off-by: Dekel Peled <dekelp@mellanox.com>\nAcked-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>\n---\n drivers/net/mlx5/linux/mlx5_os.c |  21 ++\n drivers/net/mlx5/mlx5.c          |  10 +\n drivers/net/mlx5/mlx5.h          |   2 +\n drivers/net/mlx5/mlx5_rxq.c      | 422 +++++++++++++++++++++++++++++----------\n drivers/net/mlx5/mlx5_rxtx.h     |  29 ++-\n 5 files changed, 375 insertions(+), 109 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c\nindex bf1c750..8af9756 100644\n--- a/drivers/net/mlx5/linux/mlx5_os.c\n+++ b/drivers/net/mlx5/linux/mlx5_os.c\n@@ -68,6 +68,27 @@\n #endif\n \n /**\n+ * Set the completion channel file descriptor interrupt as non-blocking.\n+ *\n+ * @param[in] rxq_obj\n+ *   Pointer to RQ channel object, which includes the channel fd\n+ *\n+ * @param[out] fd\n+ *   The file descriptor (representing the intetrrupt) used in this channel.\n+ *\n+ * @return\n+ *   0 on successfully setting the fd to non-blocking, non-zero otherwise.\n+ */\n+int\n+mlx5_os_set_nonblock_channel_fd(int fd)\n+{\n+\tint flags;\n+\n+\tflags = fcntl(fd, F_GETFL);\n+\treturn fcntl(fd, F_SETFL, flags | O_NONBLOCK);\n+}\n+\n+/**\n  * Get mlx5 device attributes. The glue function query_device_ex() is called\n  * with out parameter of type 'struct ibv_device_attr_ex *'. Then fill in mlx5\n  * device attributes from the glue out parameter.\ndiff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c\nindex 517fbb4..25ce4f0 100644\n--- a/drivers/net/mlx5/mlx5.c\n+++ b/drivers/net/mlx5/mlx5.c\n@@ -827,6 +827,12 @@ struct mlx5_dev_ctx_shared *\n \t\t\terr = ENOMEM;\n \t\t\tgoto error;\n \t\t}\n+\t\tsh->devx_rx_uar = mlx5_glue->devx_alloc_uar(sh->ctx, 0);\n+\t\tif (!sh->devx_rx_uar) {\n+\t\t\tDRV_LOG(ERR, \"Failed to allocate Rx DevX UAR.\");\n+\t\t\terr = ENOMEM;\n+\t\t\tgoto error;\n+\t\t}\n \t}\n \tsh->flow_id_pool = mlx5_flow_id_pool_alloc\n \t\t\t\t\t((1 << HAIRPIN_FLOW_ID_BITS) - 1);\n@@ -894,6 +900,8 @@ struct mlx5_dev_ctx_shared *\n \t\tclaim_zero(mlx5_devx_cmd_destroy(sh->tis));\n \tif (sh->td)\n \t\tclaim_zero(mlx5_devx_cmd_destroy(sh->td));\n+\tif (sh->devx_rx_uar)\n+\t\tmlx5_glue->devx_free_uar(sh->devx_rx_uar);\n \tif (sh->pd)\n \t\tclaim_zero(mlx5_glue->dealloc_pd(sh->pd));\n \tif (sh->ctx)\n@@ -965,6 +973,8 @@ struct mlx5_dev_ctx_shared *\n \t\tclaim_zero(mlx5_devx_cmd_destroy(sh->tis));\n \tif (sh->td)\n \t\tclaim_zero(mlx5_devx_cmd_destroy(sh->td));\n+\tif (sh->devx_rx_uar)\n+\t\tmlx5_glue->devx_free_uar(sh->devx_rx_uar);\n \tif (sh->ctx)\n \t\tclaim_zero(mlx5_glue->close_device(sh->ctx));\n \tif (sh->flow_id_pool)\ndiff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h\nindex 78ebd19..c5f6552 100644\n--- a/drivers/net/mlx5/mlx5.h\n+++ b/drivers/net/mlx5/mlx5.h\n@@ -665,6 +665,7 @@ struct mlx5_dev_ctx_shared {\n \tstruct mlx5dv_devx_uar *tx_uar; /* Tx/packer pacing shared UAR. */\n \tstruct mlx5_flex_parser_profiles fp[MLX5_FLEX_PARSER_MAX];\n \t/* Flex parser profiles information. */\n+\tstruct mlx5dv_devx_uar *devx_rx_uar; /* DevX UAR for Rx. */\n \tstruct mlx5_dev_shared_port port[]; /* per device port data array. */\n };\n \n@@ -1025,6 +1026,7 @@ int mlx5_os_read_dev_stat(struct mlx5_priv *priv,\n void mlx5_os_stats_init(struct rte_eth_dev *dev);\n void mlx5_os_set_reg_mr_cb(mlx5_reg_mr_t *reg_mr_cb,\n \t\t\t   mlx5_dereg_mr_t *dereg_mr_cb);\n+int mlx5_os_set_nonblock_channel_fd(int fd);\n \n /* mlx5_txpp.c */\n \ndiff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c\nindex 67d996c..0d6f02d 100644\n--- a/drivers/net/mlx5/mlx5_rxq.c\n+++ b/drivers/net/mlx5/mlx5_rxq.c\n@@ -28,6 +28,7 @@\n #include <rte_interrupts.h>\n #include <rte_debug.h>\n #include <rte_io.h>\n+#include <rte_eal_paging.h>\n \n #include <mlx5_glue.h>\n #include <mlx5_devx_cmds.h>\n@@ -638,7 +639,7 @@\n  *   DevX Rx queue object.\n  */\n static void\n-rxq_release_rq_resources(struct mlx5_rxq_ctrl *rxq_ctrl)\n+rxq_release_devx_rq_resources(struct mlx5_rxq_ctrl *rxq_ctrl)\n {\n \tif (rxq_ctrl->rxq.wqes) {\n \t\tmlx5_free((void *)(uintptr_t)rxq_ctrl->rxq.wqes);\n@@ -651,6 +652,25 @@\n }\n \n /**\n+ * Release the resources allocated for the Rx CQ DevX object.\n+ *\n+ * @param rxq_ctrl\n+ *   DevX Rx queue object.\n+ */\n+static void\n+rxq_release_devx_cq_resources(struct mlx5_rxq_ctrl *rxq_ctrl)\n+{\n+\tif (rxq_ctrl->rxq.cqes) {\n+\t\trte_free((void *)(uintptr_t)rxq_ctrl->rxq.cqes);\n+\t\trxq_ctrl->rxq.cqes = NULL;\n+\t}\n+\tif (rxq_ctrl->cq_umem) {\n+\t\tmlx5_glue->devx_umem_dereg(rxq_ctrl->cq_umem);\n+\t\trxq_ctrl->cq_umem = NULL;\n+\t}\n+}\n+\n+/**\n  * Release an Rx hairpin related resources.\n  *\n  * @param rxq_obj\n@@ -685,27 +705,31 @@\n \t\tswitch (rxq_obj->type) {\n \t\tcase MLX5_RXQ_OBJ_TYPE_IBV:\n \t\t\tMLX5_ASSERT(rxq_obj->wq);\n-\t\t\tMLX5_ASSERT(rxq_obj->cq);\n+\t\t\tMLX5_ASSERT(rxq_obj->ibv_cq);\n \t\t\trxq_free_elts(rxq_obj->rxq_ctrl);\n \t\t\tclaim_zero(mlx5_glue->destroy_wq(rxq_obj->wq));\n-\t\t\tclaim_zero(mlx5_glue->destroy_cq(rxq_obj->cq));\n+\t\t\tclaim_zero(mlx5_glue->destroy_cq(rxq_obj->ibv_cq));\n+\t\t\tif (rxq_obj->ibv_channel)\n+\t\t\t\tclaim_zero(mlx5_glue->destroy_comp_channel\n+\t\t\t\t\t   (rxq_obj->ibv_channel));\n \t\t\tbreak;\n \t\tcase MLX5_RXQ_OBJ_TYPE_DEVX_RQ:\n-\t\t\tMLX5_ASSERT(rxq_obj->cq);\n \t\t\tMLX5_ASSERT(rxq_obj->rq);\n+\t\t\tMLX5_ASSERT(rxq_obj->devx_cq);\n \t\t\trxq_free_elts(rxq_obj->rxq_ctrl);\n \t\t\tclaim_zero(mlx5_devx_cmd_destroy(rxq_obj->rq));\n-\t\t\trxq_release_rq_resources(rxq_obj->rxq_ctrl);\n-\t\t\tclaim_zero(mlx5_glue->destroy_cq(rxq_obj->cq));\n+\t\t\tclaim_zero(mlx5_devx_cmd_destroy(rxq_obj->devx_cq));\n+\t\t\tif (rxq_obj->devx_channel)\n+\t\t\t\tmlx5_glue->devx_destroy_event_channel\n+\t\t\t\t\t\t\t(rxq_obj->devx_channel);\n+\t\t\trxq_release_devx_rq_resources(rxq_obj->rxq_ctrl);\n+\t\t\trxq_release_devx_cq_resources(rxq_obj->rxq_ctrl);\n \t\t\tbreak;\n \t\tcase MLX5_RXQ_OBJ_TYPE_DEVX_HAIRPIN:\n \t\t\tMLX5_ASSERT(rxq_obj->rq);\n \t\t\trxq_obj_hairpin_release(rxq_obj);\n \t\t\tbreak;\n \t\t}\n-\t\tif (rxq_obj->channel)\n-\t\t\tclaim_zero(mlx5_glue->destroy_comp_channel\n-\t\t\t\t   (rxq_obj->channel));\n \t\tLIST_REMOVE(rxq_obj, next);\n \t\tmlx5_free(rxq_obj);\n \t\treturn 0;\n@@ -750,12 +774,11 @@\n \tfor (i = 0; i != n; ++i) {\n \t\t/* This rxq obj must not be released in this function. */\n \t\tstruct mlx5_rxq_obj *rxq_obj = mlx5_rxq_obj_get(dev, i);\n-\t\tint fd;\n-\t\tint flags;\n \t\tint rc;\n \n \t\t/* Skip queues that cannot request interrupts. */\n-\t\tif (!rxq_obj || !rxq_obj->channel) {\n+\t\tif (!rxq_obj || (!rxq_obj->ibv_channel &&\n+\t\t\t\t !rxq_obj->devx_channel)) {\n \t\t\t/* Use invalid intr_vec[] index to disable entry. */\n \t\t\tintr_handle->intr_vec[i] =\n \t\t\t\tRTE_INTR_VEC_RXTX_OFFSET +\n@@ -772,21 +795,19 @@\n \t\t\trte_errno = ENOMEM;\n \t\t\treturn -rte_errno;\n \t\t}\n-\t\tfd = rxq_obj->channel->fd;\n-\t\tflags = fcntl(fd, F_GETFL);\n-\t\trc = fcntl(fd, F_SETFL, flags | O_NONBLOCK);\n+\t\trc = mlx5_os_set_nonblock_channel_fd(rxq_obj->fd);\n \t\tif (rc < 0) {\n \t\t\trte_errno = errno;\n \t\t\tDRV_LOG(ERR,\n \t\t\t\t\"port %u failed to make Rx interrupt file\"\n \t\t\t\t\" descriptor %d non-blocking for queue index\"\n \t\t\t\t\" %d\",\n-\t\t\t\tdev->data->port_id, fd, i);\n+\t\t\t\tdev->data->port_id, rxq_obj->fd, i);\n \t\t\tmlx5_rx_intr_vec_disable(dev);\n \t\t\treturn -rte_errno;\n \t\t}\n \t\tintr_handle->intr_vec[i] = RTE_INTR_VEC_RXTX_OFFSET + count;\n-\t\tintr_handle->efds[count] = fd;\n+\t\tintr_handle->efds[count] = rxq_obj->fd;\n \t\tcount++;\n \t}\n \tif (!count)\n@@ -858,7 +879,7 @@\n \tsq_n = sq_n_rxq & MLX5_CQ_SQN_MASK;\n \tdoorbell_hi = sq_n << MLX5_CQ_SQN_OFFSET | (rxq->cq_ci & MLX5_CI_MASK);\n \tdoorbell = (uint64_t)doorbell_hi << 32;\n-\tdoorbell |=  rxq->cqn;\n+\tdoorbell |= rxq->cqn;\n \trxq->cq_db[MLX5_CQ_ARM_DB] = rte_cpu_to_be_32(doorbell_hi);\n \tmlx5_uar_write64(rte_cpu_to_be_64(doorbell),\n \t\t\t cq_db_reg, rxq->uar_lock_cq);\n@@ -937,13 +958,29 @@\n \t\trte_errno = EINVAL;\n \t\treturn -rte_errno;\n \t}\n-\tret = mlx5_glue->get_cq_event(rxq_obj->channel, &ev_cq, &ev_ctx);\n-\tif (ret || ev_cq != rxq_obj->cq) {\n-\t\trte_errno = EINVAL;\n-\t\tgoto exit;\n+\tif (rxq_obj->type == MLX5_RXQ_OBJ_TYPE_IBV) {\n+\t\tret = mlx5_glue->get_cq_event(rxq_obj->ibv_channel, &ev_cq,\n+\t\t\t\t\t      &ev_ctx);\n+\t\tif (ret || ev_cq != rxq_obj->ibv_cq) {\n+\t\t\trte_errno = EINVAL;\n+\t\t\tgoto exit;\n+\t\t}\n+\t\tmlx5_glue->ack_cq_events(rxq_obj->ibv_cq, 1);\n+\t} else if (rxq_obj->type == MLX5_RXQ_OBJ_TYPE_DEVX_RQ) {\n+#ifdef HAVE_IBV_DEVX_EVENT\n+\t\tstruct mlx5dv_devx_async_event_hdr *event_data = NULL;\n+\n+\t\tret = mlx5_glue->devx_get_event\n+\t\t\t\t(rxq_obj->devx_channel, event_data,\n+\t\t\t\t sizeof(struct mlx5dv_devx_async_event_hdr));\n+\t\tif (ret <= 0 || event_data->cookie !=\n+\t\t\t\t(uint64_t)(uintptr_t)rxq_obj->devx_cq) {\n+\t\t\trte_errno = EINVAL;\n+\t\t\tgoto exit;\n+\t\t}\n+#endif /* HAVE_IBV_DEVX_EVENT */\n \t}\n \trxq_data->cq_arm_sn++;\n-\tmlx5_glue->ack_cq_events(rxq_obj->cq, 1);\n \tmlx5_rxq_obj_release(rxq_obj);\n \treturn 0;\n exit:\n@@ -985,7 +1022,7 @@\n \n \tcq_attr.ibv = (struct ibv_cq_init_attr_ex){\n \t\t.cqe = cqe_n,\n-\t\t.channel = rxq_obj->channel,\n+\t\t.channel = rxq_obj->ibv_channel,\n \t\t.comp_mask = 0,\n \t};\n \tcq_attr.mlx5 = (struct mlx5dv_cq_init_attr){\n@@ -1069,7 +1106,7 @@\n \t\t/* Max number of scatter/gather elements in a WR. */\n \t\t.max_sge = 1 << rxq_data->sges_n,\n \t\t.pd = priv->sh->pd,\n-\t\t.cq = rxq_obj->cq,\n+\t\t.cq = rxq_obj->ibv_cq,\n \t\t.comp_mask = IBV_WQ_FLAGS_CVLAN_STRIPPING | 0,\n \t\t.create_flags = (rxq_data->vlan_strip ?\n \t\t\t\t IBV_WQ_FLAGS_CVLAN_STRIPPING : 0),\n@@ -1168,8 +1205,8 @@\n \t\t\t\t\tMLX5_WQ_END_PAD_MODE_ALIGN :\n \t\t\t\t\tMLX5_WQ_END_PAD_MODE_NONE;\n \twq_attr->pd = priv->sh->pdn;\n-\twq_attr->dbr_addr = rxq_ctrl->dbr_offset;\n-\twq_attr->dbr_umem_id = rxq_ctrl->dbr_umem_id;\n+\twq_attr->dbr_addr = rxq_ctrl->rq_dbr_offset;\n+\twq_attr->dbr_umem_id = rxq_ctrl->rq_dbr_umem_id;\n \twq_attr->dbr_umem_valid = 1;\n \twq_attr->wq_umem_id = rxq_ctrl->wq_umem->umem_id;\n \twq_attr->wq_umem_valid = 1;\n@@ -1195,7 +1232,7 @@\n \tstruct mlx5_rxq_data *rxq_data = (*priv->rxqs)[idx];\n \tstruct mlx5_rxq_ctrl *rxq_ctrl =\n \t\tcontainer_of(rxq_data, struct mlx5_rxq_ctrl, rxq);\n-\tstruct mlx5_devx_create_rq_attr rq_attr;\n+\tstruct mlx5_devx_create_rq_attr rq_attr = { 0 };\n \tuint32_t wqe_n = 1 << (rxq_data->elts_n - rxq_data->sges_n);\n \tuint32_t wq_size = 0;\n \tuint32_t wqe_size = 0;\n@@ -1203,7 +1240,6 @@\n \tvoid *buf = NULL;\n \tstruct mlx5_devx_obj *rq;\n \n-\tmemset(&rq_attr, 0, sizeof(rq_attr));\n \t/* Fill RQ attributes. */\n \trq_attr.mem_rq_type = MLX5_RQC_MEM_RQ_TYPE_MEMORY_RQ_INLINE;\n \trq_attr.flush_in_error_en = 1;\n@@ -1247,11 +1283,136 @@\n \tmlx5_devx_wq_attr_fill(priv, rxq_ctrl, &rq_attr.wq_attr);\n \trq = mlx5_devx_cmd_create_rq(priv->sh->ctx, &rq_attr, rxq_ctrl->socket);\n \tif (!rq)\n-\t\trxq_release_rq_resources(rxq_ctrl);\n+\t\trxq_release_devx_rq_resources(rxq_ctrl);\n \treturn rq;\n }\n \n /**\n+ * Create a DevX CQ object for an Rx queue.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device.\n+ * @param cqe_n\n+ *   Number of CQEs in CQ.\n+ * @param idx\n+ *   Queue index in DPDK Rx queue array\n+ * @param rxq_obj\n+ *   Pointer to Rx queue object data.\n+ *\n+ * @return\n+ *   The DevX object initialised, NULL otherwise and rte_errno is set.\n+ */\n+static struct mlx5_devx_obj *\n+mlx5_devx_cq_new(struct rte_eth_dev *dev, unsigned int cqe_n, uint16_t idx,\n+\t\t struct mlx5_rxq_obj *rxq_obj)\n+{\n+\tstruct mlx5_devx_obj *cq_obj = 0;\n+\tstruct mlx5_devx_cq_attr cq_attr = { 0 };\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct mlx5_rxq_data *rxq_data = (*priv->rxqs)[idx];\n+\tstruct mlx5_rxq_ctrl *rxq_ctrl =\n+\t\tcontainer_of(rxq_data, struct mlx5_rxq_ctrl, rxq);\n+\tsize_t page_size = rte_mem_page_size();\n+\tuint32_t lcore = (uint32_t)rte_lcore_to_cpu_id(-1);\n+\tuint32_t eqn = 0;\n+\tvoid *buf = NULL;\n+\tuint16_t event_nums[1] = {0};\n+\tuint32_t log_cqe_n;\n+\tuint32_t cq_size;\n+\tint ret = 0;\n+\n+\tif (page_size == (size_t)-1) {\n+\t\tDRV_LOG(ERR, \"Failed to get page_size.\");\n+\t\tgoto error;\n+\t}\n+\tif (priv->config.cqe_comp && !rxq_data->hw_timestamp &&\n+\t    !rxq_data->lro) {\n+\t\tcq_attr.cqe_comp_en = MLX5DV_CQ_INIT_ATTR_MASK_COMPRESSED_CQE;\n+#ifdef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT\n+\t\tcq_attr.mini_cqe_res_format =\n+\t\t\t\tmlx5_rxq_mprq_enabled(rxq_data) ?\n+\t\t\t\tMLX5DV_CQE_RES_FORMAT_CSUM_STRIDX :\n+\t\t\t\tMLX5DV_CQE_RES_FORMAT_HASH;\n+#else\n+\t\tcq_attr.mini_cqe_res_format = MLX5DV_CQE_RES_FORMAT_HASH;\n+#endif\n+\t\t/*\n+\t\t * For vectorized Rx, it must not be doubled in order to\n+\t\t * make cq_ci and rq_ci aligned.\n+\t\t */\n+\t\tif (mlx5_rxq_check_vec_support(rxq_data) < 0)\n+\t\t\tcqe_n *= 2;\n+\t} else if (priv->config.cqe_comp && rxq_data->hw_timestamp) {\n+\t\tDRV_LOG(DEBUG,\n+\t\t\t\"port %u Rx CQE compression is disabled for HW\"\n+\t\t\t\" timestamp\",\n+\t\t\tdev->data->port_id);\n+\t} else if (priv->config.cqe_comp && rxq_data->lro) {\n+\t\tDRV_LOG(DEBUG,\n+\t\t\t\"port %u Rx CQE compression is disabled for LRO\",\n+\t\t\tdev->data->port_id);\n+\t}\n+#ifdef HAVE_IBV_MLX5_MOD_CQE_128B_PAD\n+\tif (priv->config.cqe_pad)\n+\t\tcq_attr.cqe_size = MLX5DV_CQ_INIT_ATTR_FLAGS_CQE_PAD;\n+#endif\n+\tlog_cqe_n = log2above(cqe_n);\n+\tcq_size = sizeof(struct mlx5_cqe) * (1 << log_cqe_n);\n+\t/* Query the EQN for this core. */\n+\tif (mlx5_glue->devx_query_eqn(priv->sh->ctx, lcore, &eqn)) {\n+\t\tDRV_LOG(ERR, \"Failed to query EQN for CQ.\");\n+\t\tgoto error;\n+\t}\n+\tcq_attr.eqn = eqn;\n+\tbuf = rte_calloc_socket(__func__, 1, cq_size, page_size,\n+\t\t\t\trxq_ctrl->socket);\n+\tif (!buf) {\n+\t\tDRV_LOG(ERR, \"Failed to allocate memory for CQ.\");\n+\t\tgoto error;\n+\t}\n+\trxq_data->cqes = (volatile struct mlx5_cqe (*)[])(uintptr_t)buf;\n+\trxq_ctrl->cq_umem = mlx5_glue->devx_umem_reg(priv->sh->ctx, buf,\n+\t\t\t\t\t\t     cq_size,\n+\t\t\t\t\t\t     IBV_ACCESS_LOCAL_WRITE);\n+\tif (!rxq_ctrl->cq_umem) {\n+\t\tDRV_LOG(ERR, \"Failed to register umem for CQ.\");\n+\t\tgoto error;\n+\t}\n+\tcq_attr.uar_page_id = priv->sh->devx_rx_uar->page_id;\n+\tcq_attr.q_umem_id = rxq_ctrl->cq_umem->umem_id;\n+\tcq_attr.q_umem_valid = 1;\n+\tcq_attr.log_cq_size = log_cqe_n;\n+\tcq_attr.log_page_size = rte_log2_u32(page_size);\n+\tcq_attr.db_umem_offset = rxq_ctrl->cq_dbr_offset;\n+\tcq_attr.db_umem_id = rxq_ctrl->cq_dbr_umem_id;\n+\tcq_attr.db_umem_valid = rxq_ctrl->cq_dbr_umem_id_valid;\n+\tcq_obj = mlx5_devx_cmd_create_cq(priv->sh->ctx, &cq_attr);\n+\tif (!cq_obj)\n+\t\tgoto error;\n+\trxq_data->cqe_n = log_cqe_n;\n+\trxq_data->cqn = cq_obj->id;\n+\tif (rxq_obj->devx_channel) {\n+\t\tret = mlx5_glue->devx_subscribe_devx_event\n+\t\t\t\t\t\t(rxq_obj->devx_channel,\n+\t\t\t\t\t\t cq_obj->obj,\n+\t\t\t\t\t\t sizeof(event_nums),\n+\t\t\t\t\t\t event_nums,\n+\t\t\t\t\t\t (uint64_t)(uintptr_t)cq_obj);\n+\t\tif (ret) {\n+\t\t\tDRV_LOG(ERR, \"Fail to subscribe CQ to event channel.\");\n+\t\t\trte_errno = errno;\n+\t\t\tgoto error;\n+\t\t}\n+\t}\n+\t/* Initialise CQ to 1's to mark HW ownership for all CQEs. */\n+\tmemset((void *)(uintptr_t)rxq_data->cqes, 0xFF, cq_size);\n+\treturn cq_obj;\n+error:\n+\trxq_release_devx_cq_resources(rxq_ctrl);\n+\treturn NULL;\n+}\n+\n+/**\n  * Create the Rx hairpin queue object.\n  *\n  * @param dev\n@@ -1366,7 +1527,7 @@ struct mlx5_rxq_obj *\n \t\t\t   rxq_ctrl->socket);\n \tif (!tmpl) {\n \t\tDRV_LOG(ERR,\n-\t\t\t\"port %u Rx queue %u cannot allocate verbs resources\",\n+\t\t\t\"port %u Rx queue %u cannot allocate resources\",\n \t\t\tdev->data->port_id, rxq_data->idx);\n \t\trte_errno = ENOMEM;\n \t\tgoto error;\n@@ -1374,60 +1535,75 @@ struct mlx5_rxq_obj *\n \ttmpl->type = type;\n \ttmpl->rxq_ctrl = rxq_ctrl;\n \tif (rxq_ctrl->irq) {\n-\t\ttmpl->channel = mlx5_glue->create_comp_channel(priv->sh->ctx);\n-\t\tif (!tmpl->channel) {\n-\t\t\tDRV_LOG(ERR, \"port %u: comp channel creation failure\",\n-\t\t\t\tdev->data->port_id);\n-\t\t\trte_errno = ENOMEM;\n-\t\t\tgoto error;\n+\t\tif (tmpl->type == MLX5_RXQ_OBJ_TYPE_IBV) {\n+\t\t\ttmpl->ibv_channel =\n+\t\t\t\tmlx5_glue->create_comp_channel(priv->sh->ctx);\n+\t\t\tif (!tmpl->ibv_channel) {\n+\t\t\t\tDRV_LOG(ERR, \"port %u: comp channel creation \"\n+\t\t\t\t\t\"failure\", dev->data->port_id);\n+\t\t\t\trte_errno = ENOMEM;\n+\t\t\t\tgoto error;\n+\t\t\t}\n+\t\t\ttmpl->fd = tmpl->ibv_channel->fd;\n+\t\t} else if (tmpl->type == MLX5_RXQ_OBJ_TYPE_DEVX_RQ) {\n+\t\t\tint devx_ev_flag =\n+\t\t\t  MLX5DV_DEVX_CREATE_EVENT_CHANNEL_FLAGS_OMIT_EV_DATA;\n+\n+\t\t\ttmpl->devx_channel =\n+\t\t\t\tmlx5_glue->devx_create_event_channel\n+\t\t\t\t\t\t\t\t(priv->sh->ctx,\n+\t\t\t\t\t\t\t\t devx_ev_flag);\n+\t\t\tif (!tmpl->devx_channel) {\n+\t\t\t\trte_errno = errno;\n+\t\t\t\tDRV_LOG(ERR,\n+\t\t\t\t\t\"Failed to create event channel %d.\",\n+\t\t\t\t\trte_errno);\n+\t\t\t\tgoto error;\n+\t\t\t}\n+\t\t\ttmpl->fd = tmpl->devx_channel->fd;\n \t\t}\n \t}\n \tif (mlx5_rxq_mprq_enabled(rxq_data))\n \t\tcqe_n = wqe_n * (1 << rxq_data->strd_num_n) - 1;\n \telse\n-\t\tcqe_n = wqe_n  - 1;\n-\ttmpl->cq = mlx5_ibv_cq_new(dev, priv, rxq_data, cqe_n, tmpl);\n-\tif (!tmpl->cq) {\n-\t\tDRV_LOG(ERR, \"port %u Rx queue %u CQ creation failure\",\n-\t\t\tdev->data->port_id, idx);\n-\t\trte_errno = ENOMEM;\n-\t\tgoto error;\n-\t}\n-\tobj.cq.in = tmpl->cq;\n-\tobj.cq.out = &cq_info;\n-\tret = mlx5_glue->dv_init_obj(&obj, MLX5DV_OBJ_CQ);\n-\tif (ret) {\n-\t\trte_errno = ret;\n-\t\tgoto error;\n-\t}\n-\tif (cq_info.cqe_size != RTE_CACHE_LINE_SIZE) {\n-\t\tDRV_LOG(ERR,\n-\t\t\t\"port %u wrong MLX5_CQE_SIZE environment variable\"\n-\t\t\t\" value: it should be set to %u\",\n-\t\t\tdev->data->port_id, RTE_CACHE_LINE_SIZE);\n-\t\trte_errno = EINVAL;\n-\t\tgoto error;\n-\t}\n+\t\tcqe_n = wqe_n - 1;\n \tDRV_LOG(DEBUG, \"port %u device_attr.max_qp_wr is %d\",\n \t\tdev->data->port_id, priv->sh->device_attr.max_qp_wr);\n \tDRV_LOG(DEBUG, \"port %u device_attr.max_sge is %d\",\n \t\tdev->data->port_id, priv->sh->device_attr.max_sge);\n-\t/* Allocate door-bell for types created with DevX. */\n-\tif (tmpl->type != MLX5_RXQ_OBJ_TYPE_IBV) {\n-\t\tstruct mlx5_devx_dbr_page *dbr_page;\n-\t\tint64_t dbr_offset;\n-\n-\t\tdbr_offset = mlx5_get_dbr(priv->sh->ctx, &priv->dbrpgs,\n-\t\t\t\t\t  &dbr_page);\n-\t\tif (dbr_offset < 0)\n-\t\t\tgoto error;\n-\t\trxq_ctrl->dbr_offset = dbr_offset;\n-\t\trxq_ctrl->dbr_umem_id = mlx5_os_get_umem_id(dbr_page->umem);\n-\t\trxq_ctrl->dbr_umem_id_valid = 1;\n-\t\trxq_data->rq_db = (uint32_t *)((uintptr_t)dbr_page->dbrs +\n-\t\t\t\t\t       (uintptr_t)rxq_ctrl->dbr_offset);\n-\t}\n \tif (tmpl->type == MLX5_RXQ_OBJ_TYPE_IBV) {\n+\t\t/* Create CQ using Verbs API. */\n+\t\ttmpl->ibv_cq = mlx5_ibv_cq_new(dev, priv, rxq_data, cqe_n,\n+\t\t\t\t\t       tmpl);\n+\t\tif (!tmpl->ibv_cq) {\n+\t\t\tDRV_LOG(ERR, \"port %u Rx queue %u CQ creation failure\",\n+\t\t\t\tdev->data->port_id, idx);\n+\t\t\trte_errno = ENOMEM;\n+\t\t\tgoto error;\n+\t\t}\n+\t\tobj.cq.in = tmpl->ibv_cq;\n+\t\tobj.cq.out = &cq_info;\n+\t\tret = mlx5_glue->dv_init_obj(&obj, MLX5DV_OBJ_CQ);\n+\t\tif (ret) {\n+\t\t\trte_errno = ret;\n+\t\t\tgoto error;\n+\t\t}\n+\t\tif (cq_info.cqe_size != RTE_CACHE_LINE_SIZE) {\n+\t\t\tDRV_LOG(ERR,\n+\t\t\t\t\"port %u wrong MLX5_CQE_SIZE environment \"\n+\t\t\t\t\"variable value: it should be set to %u\",\n+\t\t\t\tdev->data->port_id, RTE_CACHE_LINE_SIZE);\n+\t\t\trte_errno = EINVAL;\n+\t\t\tgoto error;\n+\t\t}\n+\t\t/* Fill the rings. */\n+\t\trxq_data->cqe_n = log2above(cq_info.cqe_cnt);\n+\t\trxq_data->cq_db = cq_info.dbrec;\n+\t\trxq_data->cqes =\n+\t\t\t(volatile struct mlx5_cqe (*)[])(uintptr_t)cq_info.buf;\n+\t\trxq_data->cq_uar = cq_info.cq_uar;\n+\t\trxq_data->cqn = cq_info.cqn;\n+\t\t/* Create WQ (RQ) using Verbs API. */\n \t\ttmpl->wq = mlx5_ibv_wq_new(dev, priv, rxq_data, idx, wqe_n,\n \t\t\t\t\t   tmpl);\n \t\tif (!tmpl->wq) {\n@@ -1459,10 +1635,45 @@ struct mlx5_rxq_obj *\n \t\trxq_data->wqes = rwq.buf;\n \t\trxq_data->rq_db = rwq.dbrec;\n \t} else if (tmpl->type == MLX5_RXQ_OBJ_TYPE_DEVX_RQ) {\n-\t\tstruct mlx5_devx_modify_rq_attr rq_attr;\n+\t\tstruct mlx5_devx_modify_rq_attr rq_attr = { 0 };\n+\t\tstruct mlx5_devx_dbr_page *dbr_page;\n+\t\tint64_t dbr_offset;\n \n-\t\tmemset(&rq_attr, 0, sizeof(rq_attr));\n-\t\ttmpl->rq = mlx5_devx_rq_new(dev, idx, cq_info.cqn);\n+\t\t/* Allocate CQ door-bell. */\n+\t\tdbr_offset = mlx5_get_dbr(priv->sh->ctx, &priv->dbrpgs,\n+\t\t\t\t\t  &dbr_page);\n+\t\tif (dbr_offset < 0) {\n+\t\t\tDRV_LOG(ERR, \"Failed to allocate CQ door-bell.\");\n+\t\t\tgoto error;\n+\t\t}\n+\t\trxq_ctrl->cq_dbr_offset = dbr_offset;\n+\t\trxq_ctrl->cq_dbr_umem_id = mlx5_os_get_umem_id(dbr_page->umem);\n+\t\trxq_ctrl->cq_dbr_umem_id_valid = 1;\n+\t\trxq_data->cq_db =\n+\t\t\t(uint32_t *)((uintptr_t)dbr_page->dbrs +\n+\t\t\t\t     (uintptr_t)rxq_ctrl->cq_dbr_offset);\n+\t\trxq_data->cq_uar = priv->sh->devx_rx_uar->base_addr;\n+\t\t/* Create CQ using DevX API. */\n+\t\ttmpl->devx_cq = mlx5_devx_cq_new(dev, cqe_n, idx, tmpl);\n+\t\tif (!tmpl->devx_cq) {\n+\t\t\tDRV_LOG(ERR, \"Failed to create CQ.\");\n+\t\t\tgoto error;\n+\t\t}\n+\t\t/* Allocate RQ door-bell. */\n+\t\tdbr_offset = mlx5_get_dbr(priv->sh->ctx, &priv->dbrpgs,\n+\t\t\t\t\t  &dbr_page);\n+\t\tif (dbr_offset < 0) {\n+\t\t\tDRV_LOG(ERR, \"Failed to allocate RQ door-bell.\");\n+\t\t\tgoto error;\n+\t\t}\n+\t\trxq_ctrl->rq_dbr_offset = dbr_offset;\n+\t\trxq_ctrl->rq_dbr_umem_id = mlx5_os_get_umem_id(dbr_page->umem);\n+\t\trxq_ctrl->rq_dbr_umem_id_valid = 1;\n+\t\trxq_data->rq_db =\n+\t\t\t(uint32_t *)((uintptr_t)dbr_page->dbrs +\n+\t\t\t\t     (uintptr_t)rxq_ctrl->rq_dbr_offset);\n+\t\t/* Create RQ using DevX API. */\n+\t\ttmpl->rq = mlx5_devx_rq_new(dev, idx, tmpl->devx_cq->id);\n \t\tif (!tmpl->rq) {\n \t\t\tDRV_LOG(ERR, \"port %u Rx queue %u RQ creation failure\",\n \t\t\t\tdev->data->port_id, idx);\n@@ -1476,12 +1687,6 @@ struct mlx5_rxq_obj *\n \t\tif (ret)\n \t\t\tgoto error;\n \t}\n-\t/* Fill the rings. */\n-\trxq_data->cqe_n = log2above(cq_info.cqe_cnt);\n-\trxq_data->cq_db = cq_info.dbrec;\n-\trxq_data->cqes = (volatile struct mlx5_cqe (*)[])(uintptr_t)cq_info.buf;\n-\trxq_data->cq_uar = cq_info.cq_uar;\n-\trxq_data->cqn = cq_info.cqn;\n \trxq_data->cq_arm_sn = 0;\n \tmlx5_rxq_initialize(rxq_data);\n \trxq_data->cq_ci = 0;\n@@ -1494,20 +1699,31 @@ struct mlx5_rxq_obj *\n error:\n \tif (tmpl) {\n \t\tret = rte_errno; /* Save rte_errno before cleanup. */\n-\t\tif (tmpl->type == MLX5_RXQ_OBJ_TYPE_IBV && tmpl->wq)\n-\t\t\tclaim_zero(mlx5_glue->destroy_wq(tmpl->wq));\n-\t\telse if (tmpl->type == MLX5_RXQ_OBJ_TYPE_DEVX_RQ && tmpl->rq)\n-\t\t\tclaim_zero(mlx5_devx_cmd_destroy(tmpl->rq));\n-\t\tif (tmpl->cq)\n-\t\t\tclaim_zero(mlx5_glue->destroy_cq(tmpl->cq));\n-\t\tif (tmpl->channel)\n-\t\t\tclaim_zero(mlx5_glue->destroy_comp_channel\n-\t\t\t\t\t\t\t(tmpl->channel));\n+\t\tif (tmpl->type == MLX5_RXQ_OBJ_TYPE_IBV) {\n+\t\t\tif (tmpl->wq)\n+\t\t\t\tclaim_zero(mlx5_glue->destroy_wq(tmpl->wq));\n+\t\t\tif (tmpl->ibv_cq)\n+\t\t\t\tclaim_zero(mlx5_glue->destroy_cq(tmpl->ibv_cq));\n+\t\t\tif (tmpl->ibv_channel)\n+\t\t\t\tclaim_zero(mlx5_glue->destroy_comp_channel\n+\t\t\t\t\t\t\t(tmpl->ibv_channel));\n+\t\t} else if (tmpl->type == MLX5_RXQ_OBJ_TYPE_DEVX_RQ) {\n+\t\t\tif (tmpl->rq)\n+\t\t\t\tclaim_zero(mlx5_devx_cmd_destroy(tmpl->rq));\n+\t\t\tif (tmpl->devx_cq)\n+\t\t\t\tclaim_zero(mlx5_devx_cmd_destroy\n+\t\t\t\t\t\t\t(tmpl->devx_cq));\n+\t\t\tif (tmpl->devx_channel)\n+\t\t\t\tmlx5_glue->devx_destroy_event_channel\n+\t\t\t\t\t\t\t(tmpl->devx_channel);\n+\t\t}\n \t\tmlx5_free(tmpl);\n \t\trte_errno = ret; /* Restore rte_errno. */\n \t}\n-\tif (type == MLX5_RXQ_OBJ_TYPE_DEVX_RQ)\n-\t\trxq_release_rq_resources(rxq_ctrl);\n+\tif (type == MLX5_RXQ_OBJ_TYPE_DEVX_RQ) {\n+\t\trxq_release_devx_rq_resources(rxq_ctrl);\n+\t\trxq_release_devx_cq_resources(rxq_ctrl);\n+\t}\n \tpriv->verbs_alloc_ctx.type = MLX5_VERBS_ALLOC_TYPE_NONE;\n \treturn NULL;\n }\n@@ -2104,10 +2320,14 @@ struct mlx5_rxq_ctrl *\n \tif (rxq_ctrl->obj && !mlx5_rxq_obj_release(rxq_ctrl->obj))\n \t\trxq_ctrl->obj = NULL;\n \tif (rte_atomic32_dec_and_test(&rxq_ctrl->refcnt)) {\n-\t\tif (rxq_ctrl->dbr_umem_id_valid)\n+\t\tif (rxq_ctrl->rq_dbr_umem_id_valid)\n+\t\t\tclaim_zero(mlx5_release_dbr(&priv->dbrpgs,\n+\t\t\t\t\t\t    rxq_ctrl->rq_dbr_umem_id,\n+\t\t\t\t\t\t    rxq_ctrl->rq_dbr_offset));\n+\t\tif (rxq_ctrl->cq_dbr_umem_id_valid)\n \t\t\tclaim_zero(mlx5_release_dbr(&priv->dbrpgs,\n-\t\t\t\t\t\t    rxq_ctrl->dbr_umem_id,\n-\t\t\t\t\t\t    rxq_ctrl->dbr_offset));\n+\t\t\t\t\t\t    rxq_ctrl->cq_dbr_umem_id,\n+\t\t\t\t\t\t    rxq_ctrl->cq_dbr_offset));\n \t\tif (rxq_ctrl->type == MLX5_RXQ_TYPE_STANDARD)\n \t\t\tmlx5_mr_btree_free(&rxq_ctrl->rxq.mr_ctrl.cache_bh);\n \t\tLIST_REMOVE(rxq_ctrl, next);\n@@ -2771,7 +2991,7 @@ enum mlx5_rxq_type\n \t\trte_errno = ENOMEM;\n \t\tgoto error;\n \t}\n-\trxq->cq = cq;\n+\trxq->ibv_cq = cq;\n \trxq->wq = wq;\n \tpriv->drop_queue.rxq = rxq;\n \treturn rxq;\n@@ -2800,8 +3020,8 @@ enum mlx5_rxq_type\n \n \tif (rxq->wq)\n \t\tclaim_zero(mlx5_glue->destroy_wq(rxq->wq));\n-\tif (rxq->cq)\n-\t\tclaim_zero(mlx5_glue->destroy_cq(rxq->cq));\n+\tif (rxq->ibv_cq)\n+\t\tclaim_zero(mlx5_glue->destroy_cq(rxq->ibv_cq));\n \tmlx5_free(rxq);\n \tpriv->drop_queue.rxq = NULL;\n }\ndiff --git a/drivers/net/mlx5/mlx5_rxtx.h b/drivers/net/mlx5/mlx5_rxtx.h\nindex 5116a15..39fa1fb 100644\n--- a/drivers/net/mlx5/mlx5_rxtx.h\n+++ b/drivers/net/mlx5/mlx5_rxtx.h\n@@ -154,7 +154,7 @@ struct mlx5_rxq_data {\n \tstruct mlx5_rxq_stats stats;\n \trte_xmm_t mbuf_initializer; /* Default rearm/flags for vectorized Rx. */\n \tstruct rte_mbuf fake_mbuf; /* elts padding for vectorized Rx. */\n-\tvoid *cq_uar; /* CQ user access region. */\n+\tvoid *cq_uar; /* Verbs CQ user access region. */\n \tuint32_t cqn; /* CQ number. */\n \tuint8_t cq_arm_sn; /* CQ arm seq number. */\n #ifndef RTE_ARCH_64\n@@ -184,14 +184,21 @@ struct mlx5_rxq_obj {\n \tLIST_ENTRY(mlx5_rxq_obj) next; /* Pointer to the next element. */\n \trte_atomic32_t refcnt; /* Reference counter. */\n \tstruct mlx5_rxq_ctrl *rxq_ctrl; /* Back pointer to parent. */\n-\tstruct ibv_cq *cq; /* Completion Queue. */\n \tenum mlx5_rxq_obj_type type;\n+\tint fd; /* File descriptor for event channel */\n \tRTE_STD_C11\n \tunion {\n-\t\tstruct ibv_wq *wq; /* Work Queue. */\n-\t\tstruct mlx5_devx_obj *rq; /* DevX object for Rx Queue. */\n+\t\tstruct {\n+\t\t\tstruct ibv_wq *wq; /* Work Queue. */\n+\t\t\tstruct ibv_cq *ibv_cq; /* Completion Queue. */\n+\t\t\tstruct ibv_comp_channel *ibv_channel;\n+\t\t};\n+\t\tstruct {\n+\t\t\tstruct mlx5_devx_obj *rq; /* DevX Rx Queue object. */\n+\t\t\tstruct mlx5_devx_obj *devx_cq; /* DevX CQ object. */\n+\t\t\tstruct mlx5dv_devx_event_channel *devx_channel;\n+\t\t};\n \t};\n-\tstruct ibv_comp_channel *channel;\n };\n \n /* RX queue control descriptor. */\n@@ -204,14 +211,20 @@ struct mlx5_rxq_ctrl {\n \tenum mlx5_rxq_type type; /* Rxq type. */\n \tunsigned int socket; /* CPU socket ID for allocations. */\n \tunsigned int irq:1; /* Whether IRQ is enabled. */\n-\tunsigned int dbr_umem_id_valid:1; /* dbr_umem_id holds a valid value. */\n+\tunsigned int rq_dbr_umem_id_valid:1;\n+\tunsigned int cq_dbr_umem_id_valid:1;\n \tuint32_t flow_mark_n; /* Number of Mark/Flag flows using this Queue. */\n \tuint32_t flow_tunnels_n[MLX5_FLOW_TUNNEL]; /* Tunnels counters. */\n \tuint32_t wqn; /* WQ number. */\n \tuint16_t dump_file_n; /* Number of dump files. */\n-\tuint32_t dbr_umem_id; /* Storing door-bell information, */\n-\tuint64_t dbr_offset;  /* needed when freeing door-bell. */\n+\tuint32_t rq_dbr_umem_id;\n+\tuint64_t rq_dbr_offset;\n+\t/* Storing RQ door-bell information, needed when freeing door-bell. */\n+\tuint32_t cq_dbr_umem_id;\n+\tuint64_t cq_dbr_offset;\n+\t/* Storing CQ door-bell information, needed when freeing door-bell. */\n \tstruct mlx5dv_devx_umem *wq_umem; /* WQ buffer registration info. */\n+\tstruct mlx5dv_devx_umem *cq_umem; /* CQ buffer registration info. */\n \tstruct rte_eth_hairpin_conf hairpin_conf; /* Hairpin configuration. */\n };\n \n",
    "prefixes": []
}