get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 64956,
    "url": "http://patches.dpdk.org/api/patches/64956/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1579539790-3882-22-git-send-email-matan@mellanox.com/",
    "project": {
        "id": 1,
        "url": "http://patches.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": "<1579539790-3882-22-git-send-email-matan@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1579539790-3882-22-git-send-email-matan@mellanox.com",
    "date": "2020-01-20T17:02:53",
    "name": "[v1,21/38] vdpa/mlx5: handle completions",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "1f8d9c85f7fcd1ba21c29e6334f318d2df4a023f",
    "submitter": {
        "id": 796,
        "url": "http://patches.dpdk.org/api/people/796/?format=api",
        "name": "Matan Azrad",
        "email": "matan@mellanox.com"
    },
    "delegate": {
        "id": 2642,
        "url": "http://patches.dpdk.org/api/users/2642/?format=api",
        "username": "mcoquelin",
        "first_name": "Maxime",
        "last_name": "Coquelin",
        "email": "maxime.coquelin@redhat.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1579539790-3882-22-git-send-email-matan@mellanox.com/mbox/",
    "series": [
        {
            "id": 8223,
            "url": "http://patches.dpdk.org/api/series/8223/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=8223",
            "date": "2020-01-20T17:02:37",
            "name": "Introduce mlx5 vDPA driver",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/8223/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/64956/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/64956/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 B5A56A0526;\n\tMon, 20 Jan 2020 18:06:37 +0100 (CET)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 3500E1C024;\n\tMon, 20 Jan 2020 18:03:51 +0100 (CET)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n by dpdk.org (Postfix) with ESMTP id 674471BFA6\n for <dev@dpdk.org>; Mon, 20 Jan 2020 18:03:14 +0100 (CET)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n asafp@mellanox.com)\n with ESMTPS (AES256-SHA encrypted); 20 Jan 2020 19:03:13 +0200",
            "from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx\n [10.210.16.112])\n by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00KH3BGe024424;\n Mon, 20 Jan 2020 19:03:13 +0200"
        ],
        "From": "Matan Azrad <matan@mellanox.com>",
        "To": "dev@dpdk.org",
        "Cc": "Maxime Coquelin <maxime.coquelin@redhat.com>,\n Thomas Monjalon <thomas@monjalon.net>",
        "Date": "Mon, 20 Jan 2020 17:02:53 +0000",
        "Message-Id": "<1579539790-3882-22-git-send-email-matan@mellanox.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1579539790-3882-1-git-send-email-matan@mellanox.com>",
        "References": "<1579539790-3882-1-git-send-email-matan@mellanox.com>",
        "Subject": "[dpdk-dev] [PATCH v1 21/38] vdpa/mlx5: handle completions",
        "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": "In order to free resources in the CQ and to allow to the HW to send\npackets from the guest, the CQ should be polled.\n\nIn order to poll the CQ we need to trigger an interrupt for each new\nCQE posted by the HW.\n\nRegister interrupt handler to poll and arm a CQ when completion event\nwas raised by the HW.\n\nSigned-off-by: Matan Azrad <matan@mellanox.com>\n---\n drivers/common/mlx5/mlx5_prm.h   |   4 ++\n drivers/vdpa/mlx5/mlx5_vdpa.h    |  24 ++++++++\n drivers/vdpa/mlx5/mlx5_vdpa_cq.c | 129 +++++++++++++++++++++++++++++++++++++++\n 3 files changed, 157 insertions(+)",
    "diff": "diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h\nindex 6db89bb..2c0e023 100644\n--- a/drivers/common/mlx5/mlx5_prm.h\n+++ b/drivers/common/mlx5/mlx5_prm.h\n@@ -392,6 +392,10 @@ struct mlx5_cqe {\n /* CQE format value. */\n #define MLX5_COMPRESSED 0x3\n \n+/* CQ doorbell cmd types. */\n+#define MLX5_CQ_DBR_CMD_SOL_ONLY (1 << 24)\n+#define MLX5_CQ_DBR_CMD_ALL (0 << 24)\n+\n /* Action type of header modification. */\n enum {\n \tMLX5_MODIFICATION_TYPE_SET = 0x1,\ndiff --git a/drivers/vdpa/mlx5/mlx5_vdpa.h b/drivers/vdpa/mlx5/mlx5_vdpa.h\nindex 6008e3f..617f57a 100644\n--- a/drivers/vdpa/mlx5/mlx5_vdpa.h\n+++ b/drivers/vdpa/mlx5/mlx5_vdpa.h\n@@ -10,12 +10,16 @@\n #include <rte_vdpa.h>\n #include <rte_vhost.h>\n #include <rte_spinlock.h>\n+#include <rte_interrupts.h>\n \n #include <mlx5_glue.h>\n #include <mlx5_devx_cmds.h>\n #include <mlx5_prm.h>\n \n \n+#define MLX5_VDPA_INTR_RETRIES 256\n+#define MLX5_VDPA_INTR_RETRIES_USEC 1000\n+\n struct mlx5_vdpa_cq {\n \tuint16_t log_desc_n;\n \tuint32_t cq_ci:24;\n@@ -55,6 +59,7 @@ struct mlx5_vdpa_priv {\n \tuint32_t eqn;\n \tstruct mlx5dv_devx_event_channel *eventc;\n \tstruct mlx5dv_devx_uar *uar;\n+\tstruct rte_intr_handle intr_handle;\n \tSLIST_HEAD(mr_list, mlx5_vdpa_query_mr) mr_list;\n };\n \n@@ -113,4 +118,23 @@ int mlx5_vdpa_cq_create(struct mlx5_vdpa_priv *priv, uint16_t desc_n,\n  */\n void mlx5_vdpa_cq_global_release(struct mlx5_vdpa_priv *priv);\n \n+/**\n+ * Setup CQE event.\n+ *\n+ * @param[in] priv\n+ *   The vdpa driver private structure.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_errno is set.\n+ */\n+int mlx5_vdpa_cqe_event_setup(struct mlx5_vdpa_priv *priv);\n+\n+/**\n+ * Unset CQE event .\n+ *\n+ * @param[in] priv\n+ *   The vdpa driver private structure.\n+ */\n+void mlx5_vdpa_cqe_event_unset(struct mlx5_vdpa_priv *priv);\n+\n #endif /* RTE_PMD_MLX5_VDPA_H_ */\ndiff --git a/drivers/vdpa/mlx5/mlx5_vdpa_cq.c b/drivers/vdpa/mlx5/mlx5_vdpa_cq.c\nindex 563277f..d64c097 100644\n--- a/drivers/vdpa/mlx5/mlx5_vdpa_cq.c\n+++ b/drivers/vdpa/mlx5/mlx5_vdpa_cq.c\n@@ -4,10 +4,15 @@\n #include <unistd.h>\n #include <stdint.h>\n #include <assert.h>\n+#include <fcntl.h>\n \n #include <rte_malloc.h>\n #include <rte_errno.h>\n #include <rte_lcore.h>\n+#include <rte_atomic.h>\n+#include <rte_common.h>\n+\n+#include <mlx5_common.h>\n \n #include \"mlx5_vdpa_utils.h\"\n #include \"mlx5_vdpa.h\"\n@@ -78,6 +83,30 @@\n \tmemset(cq, 0, sizeof(*cq));\n }\n \n+static inline void\n+mlx5_vdpa_cq_arm(struct mlx5_vdpa_priv *priv, struct mlx5_vdpa_cq *cq)\n+{\n+\tconst unsigned int cqe_mask = (1 << cq->log_desc_n) - 1;\n+\tuint32_t arm_sn = cq->arm_sn << MLX5_CQ_SQN_OFFSET;\n+\tuint32_t cq_ci = cq->cq_ci & MLX5_CI_MASK & cqe_mask;\n+\tuint32_t doorbell_hi = arm_sn | MLX5_CQ_DBR_CMD_ALL | cq_ci;\n+\tuint64_t doorbell = ((uint64_t)doorbell_hi << 32) | cq->cq->id;\n+\tuint64_t db_be = rte_cpu_to_be_64(doorbell);\n+\tuint32_t *addr = RTE_PTR_ADD(priv->uar->base_addr, MLX5_CQ_DOORBELL);\n+\n+\trte_io_wmb();\n+\tcq->db_rec[MLX5_CQ_ARM_DB] = rte_cpu_to_be_32(doorbell_hi);\n+\trte_wmb();\n+#ifdef RTE_ARCH_64\n+\t*(uint64_t *)addr = db_be;\n+#else\n+\t*(uint32_t *)addr = db_be;\n+\trte_io_wmb();\n+\t*((uint32_t *)addr + 1) = db_be >> 32;\n+#endif\n+\tcq->arm_sn++;\n+}\n+\n int\n mlx5_vdpa_cq_create(struct mlx5_vdpa_priv *priv, uint16_t desc_n, int callfd,\n \t\t    struct mlx5_vdpa_cq *cq)\n@@ -147,8 +176,108 @@\n \t\t\tgoto error;\n \t\t}\n \t}\n+\t/* First arming. */\n+\tmlx5_vdpa_cq_arm(priv, cq);\n \treturn 0;\n error:\n \tmlx5_vdpa_cq_destroy(cq);\n \treturn -1;\n }\n+\n+static inline void __rte_unused\n+mlx5_vdpa_cq_poll(struct mlx5_vdpa_priv *priv __rte_unused,\n+\t\t  struct mlx5_vdpa_cq *cq)\n+{\n+\tconst unsigned int cqe_mask = (1 << cq->log_desc_n) - 1;\n+\tint ret;\n+\n+\tdo {\n+\t\tvolatile struct mlx5_cqe *cqe = cq->cqes + (cq->cq_ci &\n+\t\t\t\t\t\t\t    cqe_mask);\n+\n+\t\tret = check_cqe(cqe, cqe_mask + 1, cq->cq_ci);\n+\t\tswitch (ret) {\n+\t\tcase MLX5_CQE_STATUS_ERR:\n+\t\t\tcq->errors++;\n+\t\t\t/*fall-through*/\n+\t\tcase MLX5_CQE_STATUS_SW_OWN:\n+\t\t\tcq->cq_ci++;\n+\t\t\tbreak;\n+\t\tcase MLX5_CQE_STATUS_HW_OWN:\n+\t\tdefault:\n+\t\t\tbreak;\n+\t\t}\n+\t} while (ret != MLX5_CQE_STATUS_HW_OWN);\n+\trte_io_wmb();\n+\tcq->db_rec[0] = rte_cpu_to_be_32(cq->cq_ci);\n+}\n+\n+static void\n+mlx5_vdpa_interrupt_handler(void *cb_arg)\n+{\n+#ifndef HAVE_IBV_DEVX_EVENT\n+\t(void)cb_arg;\n+\treturn;\n+#else\n+\tstruct mlx5_vdpa_priv *priv = cb_arg;\n+\tunion {\n+\t\tstruct mlx5dv_devx_async_event_hdr event_resp;\n+\t\tuint8_t buf[sizeof(struct mlx5dv_devx_async_event_hdr) + 128];\n+\t} out;\n+\n+\twhile (mlx5_glue->devx_get_event(priv->eventc, &out.event_resp,\n+\t\t\t\t\t sizeof(out.buf)) >=\n+\t\t\t\t       (ssize_t)sizeof(out.event_resp.cookie)) {\n+\t\tstruct mlx5_vdpa_cq *cq = (struct mlx5_vdpa_cq *)\n+\t\t\t\t\t       (uintptr_t)out.event_resp.cookie;\n+\t\trte_spinlock_lock(&cq->sl);\n+\t\tmlx5_vdpa_cq_poll(priv, cq);\n+\t\tmlx5_vdpa_cq_arm(priv, cq);\n+\t\trte_spinlock_unlock(&cq->sl);\n+\t\tDRV_LOG(DEBUG, \"CQ %p event: new cq_ci = %u.\", cq, cq->cq_ci);\n+\t}\n+#endif /* HAVE_IBV_DEVX_ASYNC */\n+}\n+\n+int\n+mlx5_vdpa_cqe_event_setup(struct mlx5_vdpa_priv *priv)\n+{\n+\tint flags = fcntl(priv->eventc->fd, F_GETFL);\n+\tint ret = fcntl(priv->eventc->fd, F_SETFL, flags | O_NONBLOCK);\n+\tif (ret) {\n+\t\tDRV_LOG(ERR, \"Failed to change event channel FD.\");\n+\t\trte_errno = errno;\n+\t\treturn -rte_errno;\n+\t}\n+\tpriv->intr_handle.fd = priv->eventc->fd;\n+\tpriv->intr_handle.type = RTE_INTR_HANDLE_EXT;\n+\tif (rte_intr_callback_register(&priv->intr_handle,\n+\t\t\t\t       mlx5_vdpa_interrupt_handler, priv)) {\n+\t\tpriv->intr_handle.fd = 0;\n+\t\tDRV_LOG(ERR, \"Failed to register CQE interrupt %d.\", rte_errno);\n+\t\treturn -rte_errno;\n+\t}\n+\treturn 0;\n+}\n+\n+void\n+mlx5_vdpa_cqe_event_unset(struct mlx5_vdpa_priv *priv)\n+{\n+\tint retries = MLX5_VDPA_INTR_RETRIES;\n+\tint ret = -EAGAIN;\n+\n+\tif (priv->intr_handle.fd) {\n+\t\twhile (retries-- && ret == -EAGAIN) {\n+\t\t\tret = rte_intr_callback_unregister(&priv->intr_handle,\n+\t\t\t\t\t\t    mlx5_vdpa_interrupt_handler,\n+\t\t\t\t\t\t    priv);\n+\t\t\tif (ret == -EAGAIN) {\n+\t\t\t\tDRV_LOG(DEBUG, \"Try again to unregister fd %d \"\n+\t\t\t\t\t\"of CQ interrupt, retries = %d.\",\n+\t\t\t\t\tpriv->intr_handle.fd, retries);\n+\t\t\t\tusleep(MLX5_VDPA_INTR_RETRIES_USEC);\n+\t\t\t}\n+\t\t}\n+\t\tmemset(&priv->intr_handle, 0, sizeof(priv->intr_handle));\n+\t}\n+}\n",
    "prefixes": [
        "v1",
        "21/38"
    ]
}