get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 102785,
    "url": "https://patches.dpdk.org/api/patches/102785/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20211025142712.1273-2-david.marchand@redhat.com/",
    "project": {
        "id": 1,
        "url": "https://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": "<20211025142712.1273-2-david.marchand@redhat.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20211025142712.1273-2-david.marchand@redhat.com",
    "date": "2021-10-25T14:27:04",
    "name": "[v8,1/9] interrupts: add allocator and accessors",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "a49c40ea07f2dbb5b9ac6e600101a4a8563b88f2",
    "submitter": {
        "id": 1173,
        "url": "https://patches.dpdk.org/api/people/1173/?format=api",
        "name": "David Marchand",
        "email": "david.marchand@redhat.com"
    },
    "delegate": {
        "id": 24651,
        "url": "https://patches.dpdk.org/api/users/24651/?format=api",
        "username": "dmarchand",
        "first_name": "David",
        "last_name": "Marchand",
        "email": "david.marchand@redhat.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20211025142712.1273-2-david.marchand@redhat.com/mbox/",
    "series": [
        {
            "id": 19959,
            "url": "https://patches.dpdk.org/api/series/19959/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=19959",
            "date": "2021-10-25T14:27:03",
            "name": "make rte_intr_handle internal",
            "version": 8,
            "mbox": "https://patches.dpdk.org/series/19959/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/102785/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/102785/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 mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 83B42A0C4E;\n\tMon, 25 Oct 2021 16:27:43 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 84A8E41144;\n\tMon, 25 Oct 2021 16:27:38 +0200 (CEST)",
            "from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [216.205.24.124])\n by mails.dpdk.org (Postfix) with ESMTP id 961404111B\n for <dev@dpdk.org>; Mon, 25 Oct 2021 16:27:37 +0200 (CEST)",
            "from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com\n [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id\n us-mta-531-1wKiWaKPN_qYplaFXg81pg-1; Mon, 25 Oct 2021 10:27:33 -0400",
            "from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com\n [10.5.11.23])\n (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n (No client certificate requested)\n by mimecast-mx01.redhat.com (Postfix) with ESMTPS id C3EAA18125C2;\n Mon, 25 Oct 2021 14:27:31 +0000 (UTC)",
            "from dmarchan.remote.csb (unknown [10.40.192.64])\n by smtp.corp.redhat.com (Postfix) with ESMTP id A037C19D9D;\n Mon, 25 Oct 2021 14:27:28 +0000 (UTC)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1635172057;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=iK0/pkOOvyi1b+S+aC32WHgBnl0bCutAFV5ezJ82eJw=;\n b=IOImdZIk0e2XrqUdB8Rbd+HLXV+efYAg3lWfQLL9AsbJhecKV/IKB83LWwks4K7dEC7zCy\n IYc5L1LR51NWv6xSVLt9EjXeNBBgTk7y4u4AmlCGQRjEq3+jauY/xbtQyPuNNqCddOI2Sa\n 8dZRpggTiRt0gi1oE0IJOgMDfyCyMOg=",
        "X-MC-Unique": "1wKiWaKPN_qYplaFXg81pg-1",
        "From": "David Marchand <david.marchand@redhat.com>",
        "To": "hkalra@marvell.com,\n\tdev@dpdk.org",
        "Cc": "dmitry.kozliuk@gmail.com, rasland@nvidia.com, thomas@monjalon.net,\n Ray Kinsella <mdr@ashroe.eu>",
        "Date": "Mon, 25 Oct 2021 16:27:04 +0200",
        "Message-Id": "<20211025142712.1273-2-david.marchand@redhat.com>",
        "In-Reply-To": "<20211025142712.1273-1-david.marchand@redhat.com>",
        "References": "<20211022204934.132186-1-hkalra@marvell.com>\n <20211025142712.1273-1-david.marchand@redhat.com>",
        "MIME-Version": "1.0",
        "X-Scanned-By": "MIMEDefang 2.84 on 10.5.11.23",
        "Authentication-Results": "relay.mimecast.com;\n auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=david.marchand@redhat.com",
        "X-Mimecast-Spam-Score": "0",
        "X-Mimecast-Originator": "redhat.com",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain; charset=\"US-ASCII\"",
        "Subject": "[dpdk-dev] [PATCH v8 1/9] interrupts: add allocator and accessors",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "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": "From: Harman Kalra <hkalra@marvell.com>\n\nPrototype/Implement get set APIs for interrupt handle fields.\nUser won't be able to access any of the interrupt handle fields\ndirectly while should use these get/set APIs to access/manipulate\nthem.\n\nInternal interrupt header i.e. rte_eal_interrupt.h is rearranged,\nas APIs defined are moved to rte_interrupts.h and epoll specific\ndefinitions are moved to a new header rte_epoll.h.\nLater in the series rte_eal_interrupt.h will be removed.\n\nSigned-off-by: Harman Kalra <hkalra@marvell.com>\nAcked-by: Ray Kinsella <mdr@ashroe.eu>\nAcked-by: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>\nSigned-off-by: David Marchand <david.marchand@redhat.com>\n---\nChanges since v7:\n- lowered checks log level to DEBUG,\n- removed asserts on vector list size, and fixed check on list size\n  for drivers like mlx5 who expects list is not initialized,\n\nChanges since v5:\n- renamed RTE_INTR_INSTANCE_F_UNSHARED as RTE_INTR_INSTANCE_F_PRIVATE,\n- used a single bit to mark instance as shared (default is private),\n- removed rte_intr_instance_copy / rte_intr_instance_alloc_flag_get\n  with a single rte_intr_instance_dup helper,\n- made rte_intr_vec_list_alloc alloc_flags-aware,\n- exported all symbols for Windows,\n\n---\n MAINTAINERS                            |   1 +\n lib/eal/common/eal_common_interrupts.c | 407 ++++++++++++++++\n lib/eal/common/meson.build             |   1 +\n lib/eal/include/meson.build            |   1 +\n lib/eal/include/rte_eal_interrupts.h   | 207 +-------\n lib/eal/include/rte_epoll.h            | 118 +++++\n lib/eal/include/rte_interrupts.h       | 627 +++++++++++++++++++++++++\n lib/eal/version.map                    |  45 +-\n 8 files changed, 1197 insertions(+), 210 deletions(-)\n create mode 100644 lib/eal/common/eal_common_interrupts.c\n create mode 100644 lib/eal/include/rte_epoll.h",
    "diff": "diff --git a/MAINTAINERS b/MAINTAINERS\nindex 587632dce0..097a57f7f6 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -211,6 +211,7 @@ F: app/test/test_memzone.c\n \n Interrupt Subsystem\n M: Harman Kalra <hkalra@marvell.com>\n+F: lib/eal/include/rte_epoll.h\n F: lib/eal/*/*interrupts.*\n F: app/test/test_interrupts.c\n \ndiff --git a/lib/eal/common/eal_common_interrupts.c b/lib/eal/common/eal_common_interrupts.c\nnew file mode 100644\nindex 0000000000..46064870f4\n--- /dev/null\n+++ b/lib/eal/common/eal_common_interrupts.c\n@@ -0,0 +1,407 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(C) 2021 Marvell.\n+ */\n+\n+#include <stdlib.h>\n+#include <string.h>\n+\n+#include <rte_errno.h>\n+#include <rte_interrupts.h>\n+#include <rte_log.h>\n+#include <rte_malloc.h>\n+\n+/* Macros to check for valid interrupt handle */\n+#define CHECK_VALID_INTR_HANDLE(intr_handle) do { \\\n+\tif (intr_handle == NULL) { \\\n+\t\tRTE_LOG(DEBUG, EAL, \"Interrupt instance unallocated\\n\"); \\\n+\t\trte_errno = EINVAL; \\\n+\t\tgoto fail; \\\n+\t} \\\n+} while (0)\n+\n+#define RTE_INTR_INSTANCE_KNOWN_FLAGS (RTE_INTR_INSTANCE_F_PRIVATE \\\n+\t| RTE_INTR_INSTANCE_F_SHARED \\\n+\t)\n+\n+#define RTE_INTR_INSTANCE_USES_RTE_MEMORY(flags) \\\n+\t!!(flags & RTE_INTR_INSTANCE_F_SHARED)\n+\n+struct rte_intr_handle *rte_intr_instance_alloc(uint32_t flags)\n+{\n+\tstruct rte_intr_handle *intr_handle;\n+\tbool uses_rte_memory;\n+\n+\t/* Check the flag passed by user, it should be part of the\n+\t * defined flags.\n+\t */\n+\tif ((flags & ~RTE_INTR_INSTANCE_KNOWN_FLAGS) != 0) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Invalid alloc flag passed 0x%x\\n\", flags);\n+\t\trte_errno = EINVAL;\n+\t\treturn NULL;\n+\t}\n+\n+\tuses_rte_memory = RTE_INTR_INSTANCE_USES_RTE_MEMORY(flags);\n+\tif (uses_rte_memory)\n+\t\tintr_handle = rte_zmalloc(NULL, sizeof(*intr_handle), 0);\n+\telse\n+\t\tintr_handle = calloc(1, sizeof(*intr_handle));\n+\tif (intr_handle == NULL) {\n+\t\tRTE_LOG(ERR, EAL, \"Failed to allocate intr_handle\\n\");\n+\t\trte_errno = ENOMEM;\n+\t\treturn NULL;\n+\t}\n+\n+\tintr_handle->alloc_flags = flags;\n+\tintr_handle->nb_intr = RTE_MAX_RXTX_INTR_VEC_ID;\n+\n+\treturn intr_handle;\n+}\n+\n+struct rte_intr_handle *rte_intr_instance_dup(const struct rte_intr_handle *src)\n+{\n+\tstruct rte_intr_handle *intr_handle;\n+\n+\tif (src == NULL) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Source interrupt instance unallocated\\n\");\n+\t\trte_errno = EINVAL;\n+\t\treturn NULL;\n+\t}\n+\n+\tintr_handle = rte_intr_instance_alloc(src->alloc_flags);\n+\n+\tintr_handle->fd = src->fd;\n+\tintr_handle->vfio_dev_fd = src->vfio_dev_fd;\n+\tintr_handle->type = src->type;\n+\tintr_handle->max_intr = src->max_intr;\n+\tintr_handle->nb_efd = src->nb_efd;\n+\tintr_handle->efd_counter_size = src->efd_counter_size;\n+\tmemcpy(intr_handle->efds, src->efds, src->nb_intr);\n+\tmemcpy(intr_handle->elist, src->elist, src->nb_intr);\n+\n+\treturn intr_handle;\n+}\n+\n+void rte_intr_instance_free(struct rte_intr_handle *intr_handle)\n+{\n+\tif (intr_handle == NULL)\n+\t\treturn;\n+\tif (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags))\n+\t\trte_free(intr_handle);\n+\telse\n+\t\tfree(intr_handle);\n+}\n+\n+int rte_intr_fd_set(struct rte_intr_handle *intr_handle, int fd)\n+{\n+\tCHECK_VALID_INTR_HANDLE(intr_handle);\n+\n+\tintr_handle->fd = fd;\n+\n+\treturn 0;\n+fail:\n+\treturn -rte_errno;\n+}\n+\n+int rte_intr_fd_get(const struct rte_intr_handle *intr_handle)\n+{\n+\tCHECK_VALID_INTR_HANDLE(intr_handle);\n+\n+\treturn intr_handle->fd;\n+fail:\n+\treturn -1;\n+}\n+\n+int rte_intr_type_set(struct rte_intr_handle *intr_handle,\n+\tenum rte_intr_handle_type type)\n+{\n+\tCHECK_VALID_INTR_HANDLE(intr_handle);\n+\n+\tintr_handle->type = type;\n+\n+\treturn 0;\n+fail:\n+\treturn -rte_errno;\n+}\n+\n+enum rte_intr_handle_type rte_intr_type_get(\n+\tconst struct rte_intr_handle *intr_handle)\n+{\n+\tCHECK_VALID_INTR_HANDLE(intr_handle);\n+\n+\treturn intr_handle->type;\n+fail:\n+\treturn RTE_INTR_HANDLE_UNKNOWN;\n+}\n+\n+int rte_intr_dev_fd_set(struct rte_intr_handle *intr_handle, int fd)\n+{\n+\tCHECK_VALID_INTR_HANDLE(intr_handle);\n+\n+\tintr_handle->vfio_dev_fd = fd;\n+\n+\treturn 0;\n+fail:\n+\treturn -rte_errno;\n+}\n+\n+int rte_intr_dev_fd_get(const struct rte_intr_handle *intr_handle)\n+{\n+\tCHECK_VALID_INTR_HANDLE(intr_handle);\n+\n+\treturn intr_handle->vfio_dev_fd;\n+fail:\n+\treturn -1;\n+}\n+\n+int rte_intr_max_intr_set(struct rte_intr_handle *intr_handle,\n+\t\t\t\t int max_intr)\n+{\n+\tCHECK_VALID_INTR_HANDLE(intr_handle);\n+\n+\tif (max_intr > intr_handle->nb_intr) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Maximum interrupt vector ID (%d) exceeds \"\n+\t\t\t\"the number of available events (%d)\\n\", max_intr,\n+\t\t\tintr_handle->nb_intr);\n+\t\trte_errno = ERANGE;\n+\t\tgoto fail;\n+\t}\n+\n+\tintr_handle->max_intr = max_intr;\n+\n+\treturn 0;\n+fail:\n+\treturn -rte_errno;\n+}\n+\n+int rte_intr_max_intr_get(const struct rte_intr_handle *intr_handle)\n+{\n+\tCHECK_VALID_INTR_HANDLE(intr_handle);\n+\n+\treturn intr_handle->max_intr;\n+fail:\n+\treturn -rte_errno;\n+}\n+\n+int rte_intr_nb_efd_set(struct rte_intr_handle *intr_handle, int nb_efd)\n+{\n+\tCHECK_VALID_INTR_HANDLE(intr_handle);\n+\n+\tintr_handle->nb_efd = nb_efd;\n+\n+\treturn 0;\n+fail:\n+\treturn -rte_errno;\n+}\n+\n+int rte_intr_nb_efd_get(const struct rte_intr_handle *intr_handle)\n+{\n+\tCHECK_VALID_INTR_HANDLE(intr_handle);\n+\n+\treturn intr_handle->nb_efd;\n+fail:\n+\treturn -rte_errno;\n+}\n+\n+int rte_intr_nb_intr_get(const struct rte_intr_handle *intr_handle)\n+{\n+\tCHECK_VALID_INTR_HANDLE(intr_handle);\n+\n+\treturn intr_handle->nb_intr;\n+fail:\n+\treturn -rte_errno;\n+}\n+\n+int rte_intr_efd_counter_size_set(struct rte_intr_handle *intr_handle,\n+\tuint8_t efd_counter_size)\n+{\n+\tCHECK_VALID_INTR_HANDLE(intr_handle);\n+\n+\tintr_handle->efd_counter_size = efd_counter_size;\n+\n+\treturn 0;\n+fail:\n+\treturn -rte_errno;\n+}\n+\n+int rte_intr_efd_counter_size_get(const struct rte_intr_handle *intr_handle)\n+{\n+\tCHECK_VALID_INTR_HANDLE(intr_handle);\n+\n+\treturn intr_handle->efd_counter_size;\n+fail:\n+\treturn -rte_errno;\n+}\n+\n+int rte_intr_efds_index_get(const struct rte_intr_handle *intr_handle,\n+\tint index)\n+{\n+\tCHECK_VALID_INTR_HANDLE(intr_handle);\n+\n+\tif (index >= intr_handle->nb_intr) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Invalid index %d, max limit %d\\n\", index,\n+\t\t\tintr_handle->nb_intr);\n+\t\trte_errno = EINVAL;\n+\t\tgoto fail;\n+\t}\n+\n+\treturn intr_handle->efds[index];\n+fail:\n+\treturn -rte_errno;\n+}\n+\n+int rte_intr_efds_index_set(struct rte_intr_handle *intr_handle,\n+\tint index, int fd)\n+{\n+\tCHECK_VALID_INTR_HANDLE(intr_handle);\n+\n+\tif (index >= intr_handle->nb_intr) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Invalid index %d, max limit %d\\n\", index,\n+\t\t\tintr_handle->nb_intr);\n+\t\trte_errno = ERANGE;\n+\t\tgoto fail;\n+\t}\n+\n+\tintr_handle->efds[index] = fd;\n+\n+\treturn 0;\n+fail:\n+\treturn -rte_errno;\n+}\n+\n+struct rte_epoll_event *rte_intr_elist_index_get(\n+\tstruct rte_intr_handle *intr_handle, int index)\n+{\n+\tCHECK_VALID_INTR_HANDLE(intr_handle);\n+\n+\tif (index >= intr_handle->nb_intr) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Invalid index %d, max limit %d\\n\", index,\n+\t\t\tintr_handle->nb_intr);\n+\t\trte_errno = ERANGE;\n+\t\tgoto fail;\n+\t}\n+\n+\treturn &intr_handle->elist[index];\n+fail:\n+\treturn NULL;\n+}\n+\n+int rte_intr_elist_index_set(struct rte_intr_handle *intr_handle,\n+\tint index, struct rte_epoll_event elist)\n+{\n+\tCHECK_VALID_INTR_HANDLE(intr_handle);\n+\n+\tif (index >= intr_handle->nb_intr) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Invalid index %d, max limit %d\\n\", index,\n+\t\t\tintr_handle->nb_intr);\n+\t\trte_errno = ERANGE;\n+\t\tgoto fail;\n+\t}\n+\n+\tintr_handle->elist[index] = elist;\n+\n+\treturn 0;\n+fail:\n+\treturn -rte_errno;\n+}\n+\n+int rte_intr_vec_list_alloc(struct rte_intr_handle *intr_handle,\n+\tconst char *name, int size)\n+{\n+\tCHECK_VALID_INTR_HANDLE(intr_handle);\n+\n+\t/* Vector list already allocated */\n+\tif (intr_handle->intr_vec != NULL)\n+\t\treturn 0;\n+\n+\tif (size > intr_handle->nb_intr) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Invalid size %d, max limit %d\\n\", size,\n+\t\t\tintr_handle->nb_intr);\n+\t\trte_errno = ERANGE;\n+\t\tgoto fail;\n+\t}\n+\n+\tif (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags))\n+\t\tintr_handle->intr_vec = rte_zmalloc(name, size * sizeof(int), 0);\n+\telse\n+\t\tintr_handle->intr_vec = calloc(size, sizeof(int));\n+\tif (intr_handle->intr_vec == NULL) {\n+\t\tRTE_LOG(ERR, EAL, \"Failed to allocate %d intr_vec\\n\", size);\n+\t\trte_errno = ENOMEM;\n+\t\tgoto fail;\n+\t}\n+\n+\tintr_handle->vec_list_size = size;\n+\n+\treturn 0;\n+fail:\n+\treturn -rte_errno;\n+}\n+\n+int rte_intr_vec_list_index_get(const struct rte_intr_handle *intr_handle,\n+\t\t\t\tint index)\n+{\n+\tCHECK_VALID_INTR_HANDLE(intr_handle);\n+\n+\tif (index >= intr_handle->vec_list_size) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Index %d greater than vec list size %d\\n\",\n+\t\t\tindex, intr_handle->vec_list_size);\n+\t\trte_errno = ERANGE;\n+\t\tgoto fail;\n+\t}\n+\n+\treturn intr_handle->intr_vec[index];\n+fail:\n+\treturn -rte_errno;\n+}\n+\n+int rte_intr_vec_list_index_set(struct rte_intr_handle *intr_handle,\n+\t\t\t\tint index, int vec)\n+{\n+\tCHECK_VALID_INTR_HANDLE(intr_handle);\n+\n+\tif (index >= intr_handle->vec_list_size) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Index %d greater than vec list size %d\\n\",\n+\t\t\tindex, intr_handle->vec_list_size);\n+\t\trte_errno = ERANGE;\n+\t\tgoto fail;\n+\t}\n+\n+\tintr_handle->intr_vec[index] = vec;\n+\n+\treturn 0;\n+fail:\n+\treturn -rte_errno;\n+}\n+\n+void rte_intr_vec_list_free(struct rte_intr_handle *intr_handle)\n+{\n+\tif (intr_handle == NULL)\n+\t\treturn;\n+\tif (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags))\n+\t\trte_free(intr_handle->intr_vec);\n+\telse\n+\t\tfree(intr_handle->intr_vec);\n+\tintr_handle->intr_vec = NULL;\n+\tintr_handle->vec_list_size = 0;\n+}\n+\n+void *rte_intr_instance_windows_handle_get(struct rte_intr_handle *intr_handle)\n+{\n+\tCHECK_VALID_INTR_HANDLE(intr_handle);\n+\n+\treturn intr_handle->windows_handle;\n+fail:\n+\treturn NULL;\n+}\n+\n+int rte_intr_instance_windows_handle_set(struct rte_intr_handle *intr_handle,\n+\tvoid *windows_handle)\n+{\n+\tCHECK_VALID_INTR_HANDLE(intr_handle);\n+\n+\tintr_handle->windows_handle = windows_handle;\n+\n+\treturn 0;\n+fail:\n+\treturn -rte_errno;\n+}\ndiff --git a/lib/eal/common/meson.build b/lib/eal/common/meson.build\nindex 6d01b0f072..917758cc65 100644\n--- a/lib/eal/common/meson.build\n+++ b/lib/eal/common/meson.build\n@@ -15,6 +15,7 @@ sources += files(\n         'eal_common_errno.c',\n         'eal_common_fbarray.c',\n         'eal_common_hexdump.c',\n+        'eal_common_interrupts.c',\n         'eal_common_launch.c',\n         'eal_common_lcore.c',\n         'eal_common_log.c',\ndiff --git a/lib/eal/include/meson.build b/lib/eal/include/meson.build\nindex 88a9eba12f..8e258607b8 100644\n--- a/lib/eal/include/meson.build\n+++ b/lib/eal/include/meson.build\n@@ -19,6 +19,7 @@ headers += files(\n         'rte_eal_memconfig.h',\n         'rte_eal_trace.h',\n         'rte_errno.h',\n+        'rte_epoll.h',\n         'rte_fbarray.h',\n         'rte_hexdump.h',\n         'rte_hypervisor.h',\ndiff --git a/lib/eal/include/rte_eal_interrupts.h b/lib/eal/include/rte_eal_interrupts.h\nindex 00bcc19b6d..60bb60ca59 100644\n--- a/lib/eal/include/rte_eal_interrupts.h\n+++ b/lib/eal/include/rte_eal_interrupts.h\n@@ -39,32 +39,6 @@ enum rte_intr_handle_type {\n \tRTE_INTR_HANDLE_MAX           /**< count of elements */\n };\n \n-#define RTE_INTR_EVENT_ADD            1UL\n-#define RTE_INTR_EVENT_DEL            2UL\n-\n-typedef void (*rte_intr_event_cb_t)(int fd, void *arg);\n-\n-struct rte_epoll_data {\n-\tuint32_t event;               /**< event type */\n-\tvoid *data;                   /**< User data */\n-\trte_intr_event_cb_t cb_fun;   /**< IN: callback fun */\n-\tvoid *cb_arg;\t              /**< IN: callback arg */\n-};\n-\n-enum {\n-\tRTE_EPOLL_INVALID = 0,\n-\tRTE_EPOLL_VALID,\n-\tRTE_EPOLL_EXEC,\n-};\n-\n-/** interrupt epoll event obj, taken by epoll_event.ptr */\n-struct rte_epoll_event {\n-\tuint32_t status;           /**< OUT: event status */\n-\tint fd;                    /**< OUT: event fd */\n-\tint epfd;       /**< OUT: epoll instance the ev associated with */\n-\tstruct rte_epoll_data epdata;\n-};\n-\n /** Handle for interrupts. */\n struct rte_intr_handle {\n \tRTE_STD_C11\n@@ -79,191 +53,20 @@ struct rte_intr_handle {\n \t\t\t};\n \t\t\tint fd;\t/**< interrupt event file descriptor */\n \t\t};\n-\t\tvoid *handle; /**< device driver handle (Windows) */\n+\t\tvoid *windows_handle; /**< device driver handle */\n \t};\n+\tuint32_t alloc_flags;\t/**< flags passed at allocation */\n \tenum rte_intr_handle_type type;  /**< handle type */\n \tuint32_t max_intr;             /**< max interrupt requested */\n \tuint32_t nb_efd;               /**< number of available efd(event fd) */\n \tuint8_t efd_counter_size;      /**< size of efd counter, used for vdev */\n+\tuint16_t nb_intr;\n+\t\t/**< Max vector count, default RTE_MAX_RXTX_INTR_VEC_ID */\n \tint efds[RTE_MAX_RXTX_INTR_VEC_ID];  /**< intr vectors/efds mapping */\n \tstruct rte_epoll_event elist[RTE_MAX_RXTX_INTR_VEC_ID];\n \t\t\t\t       /**< intr vector epoll event */\n+\tuint16_t vec_list_size;\n \tint *intr_vec;                 /**< intr vector number array */\n };\n \n-#define RTE_EPOLL_PER_THREAD        -1  /**< to hint using per thread epfd */\n-\n-/**\n- * It waits for events on the epoll instance.\n- * Retries if signal received.\n- *\n- * @param epfd\n- *   Epoll instance fd on which the caller wait for events.\n- * @param events\n- *   Memory area contains the events that will be available for the caller.\n- * @param maxevents\n- *   Up to maxevents are returned, must greater than zero.\n- * @param timeout\n- *   Specifying a timeout of -1 causes a block indefinitely.\n- *   Specifying a timeout equal to zero cause to return immediately.\n- * @return\n- *   - On success, returns the number of available event.\n- *   - On failure, a negative value.\n- */\n-int\n-rte_epoll_wait(int epfd, struct rte_epoll_event *events,\n-\t       int maxevents, int timeout);\n-\n-/**\n- * It waits for events on the epoll instance.\n- * Does not retry if signal received.\n- *\n- * @param epfd\n- *   Epoll instance fd on which the caller wait for events.\n- * @param events\n- *   Memory area contains the events that will be available for the caller.\n- * @param maxevents\n- *   Up to maxevents are returned, must greater than zero.\n- * @param timeout\n- *   Specifying a timeout of -1 causes a block indefinitely.\n- *   Specifying a timeout equal to zero cause to return immediately.\n- * @return\n- *   - On success, returns the number of available event.\n- *   - On failure, a negative value.\n- */\n-__rte_experimental\n-int\n-rte_epoll_wait_interruptible(int epfd, struct rte_epoll_event *events,\n-\t       int maxevents, int timeout);\n-\n-/**\n- * It performs control operations on epoll instance referred by the epfd.\n- * It requests that the operation op be performed for the target fd.\n- *\n- * @param epfd\n- *   Epoll instance fd on which the caller perform control operations.\n- * @param op\n- *   The operation be performed for the target fd.\n- * @param fd\n- *   The target fd on which the control ops perform.\n- * @param event\n- *   Describes the object linked to the fd.\n- *   Note: The caller must take care the object deletion after CTL_DEL.\n- * @return\n- *   - On success, zero.\n- *   - On failure, a negative value.\n- */\n-int\n-rte_epoll_ctl(int epfd, int op, int fd,\n-\t      struct rte_epoll_event *event);\n-\n-/**\n- * The function returns the per thread epoll instance.\n- *\n- * @return\n- *   epfd the epoll instance referred to.\n- */\n-int\n-rte_intr_tls_epfd(void);\n-\n-/**\n- * @param intr_handle\n- *   Pointer to the interrupt handle.\n- * @param epfd\n- *   Epoll instance fd which the intr vector associated to.\n- * @param op\n- *   The operation be performed for the vector.\n- *   Operation type of {ADD, DEL}.\n- * @param vec\n- *   RX intr vector number added to the epoll instance wait list.\n- * @param data\n- *   User raw data.\n- * @return\n- *   - On success, zero.\n- *   - On failure, a negative value.\n- */\n-int\n-rte_intr_rx_ctl(struct rte_intr_handle *intr_handle,\n-\t\tint epfd, int op, unsigned int vec, void *data);\n-\n-/**\n- * It deletes registered eventfds.\n- *\n- * @param intr_handle\n- *   Pointer to the interrupt handle.\n- */\n-void\n-rte_intr_free_epoll_fd(struct rte_intr_handle *intr_handle);\n-\n-/**\n- * It enables the packet I/O interrupt event if it's necessary.\n- * It creates event fd for each interrupt vector when MSIX is used,\n- * otherwise it multiplexes a single event fd.\n- *\n- * @param intr_handle\n- *   Pointer to the interrupt handle.\n- * @param nb_efd\n- *   Number of interrupt vector trying to enable.\n- *   The value 0 is not allowed.\n- * @return\n- *   - On success, zero.\n- *   - On failure, a negative value.\n- */\n-int\n-rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd);\n-\n-/**\n- * It disables the packet I/O interrupt event.\n- * It deletes registered eventfds and closes the open fds.\n- *\n- * @param intr_handle\n- *   Pointer to the interrupt handle.\n- */\n-void\n-rte_intr_efd_disable(struct rte_intr_handle *intr_handle);\n-\n-/**\n- * The packet I/O interrupt on datapath is enabled or not.\n- *\n- * @param intr_handle\n- *   Pointer to the interrupt handle.\n- */\n-int\n-rte_intr_dp_is_en(struct rte_intr_handle *intr_handle);\n-\n-/**\n- * The interrupt handle instance allows other causes or not.\n- * Other causes stand for any none packet I/O interrupts.\n- *\n- * @param intr_handle\n- *   Pointer to the interrupt handle.\n- */\n-int\n-rte_intr_allow_others(struct rte_intr_handle *intr_handle);\n-\n-/**\n- * The multiple interrupt vector capability of interrupt handle instance.\n- * It returns zero if no multiple interrupt vector support.\n- *\n- * @param intr_handle\n- *   Pointer to the interrupt handle.\n- */\n-int\n-rte_intr_cap_multiple(struct rte_intr_handle *intr_handle);\n-\n-/**\n- * @warning\n- * @b EXPERIMENTAL: this API may change without prior notice\n- *\n- * @internal\n- * Check if currently executing in interrupt context\n- *\n- * @return\n- *  - non zero in case of interrupt context\n- *  - zero in case of process context\n- */\n-__rte_experimental\n-int\n-rte_thread_is_intr(void);\n-\n #endif /* _RTE_EAL_INTERRUPTS_H_ */\ndiff --git a/lib/eal/include/rte_epoll.h b/lib/eal/include/rte_epoll.h\nnew file mode 100644\nindex 0000000000..56b7b6bad6\n--- /dev/null\n+++ b/lib/eal/include/rte_epoll.h\n@@ -0,0 +1,118 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(C) 2021 Marvell International Ltd.\n+ */\n+\n+#ifndef __RTE_EPOLL_H__\n+#define __RTE_EPOLL_H__\n+\n+/**\n+ * @file\n+ * The rte_epoll provides interfaces functions to add delete events,\n+ * wait poll for an event.\n+ */\n+\n+#include <stdint.h>\n+\n+#include <rte_compat.h>\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+\n+#define RTE_INTR_EVENT_ADD            1UL\n+#define RTE_INTR_EVENT_DEL            2UL\n+\n+typedef void (*rte_intr_event_cb_t)(int fd, void *arg);\n+\n+struct rte_epoll_data {\n+\tuint32_t event;               /**< event type */\n+\tvoid *data;                   /**< User data */\n+\trte_intr_event_cb_t cb_fun;   /**< IN: callback fun */\n+\tvoid *cb_arg;\t              /**< IN: callback arg */\n+};\n+\n+enum {\n+\tRTE_EPOLL_INVALID = 0,\n+\tRTE_EPOLL_VALID,\n+\tRTE_EPOLL_EXEC,\n+};\n+\n+/** interrupt epoll event obj, taken by epoll_event.ptr */\n+struct rte_epoll_event {\n+\tuint32_t status;           /**< OUT: event status */\n+\tint fd;                    /**< OUT: event fd */\n+\tint epfd;       /**< OUT: epoll instance the ev associated with */\n+\tstruct rte_epoll_data epdata;\n+};\n+\n+#define RTE_EPOLL_PER_THREAD        -1  /**< to hint using per thread epfd */\n+\n+/**\n+ * It waits for events on the epoll instance.\n+ * Retries if signal received.\n+ *\n+ * @param epfd\n+ *   Epoll instance fd on which the caller wait for events.\n+ * @param events\n+ *   Memory area contains the events that will be available for the caller.\n+ * @param maxevents\n+ *   Up to maxevents are returned, must greater than zero.\n+ * @param timeout\n+ *   Specifying a timeout of -1 causes a block indefinitely.\n+ *   Specifying a timeout equal to zero cause to return immediately.\n+ * @return\n+ *   - On success, returns the number of available event.\n+ *   - On failure, a negative value.\n+ */\n+int\n+rte_epoll_wait(int epfd, struct rte_epoll_event *events,\n+\t       int maxevents, int timeout);\n+\n+/**\n+ * It waits for events on the epoll instance.\n+ * Does not retry if signal received.\n+ *\n+ * @param epfd\n+ *   Epoll instance fd on which the caller wait for events.\n+ * @param events\n+ *   Memory area contains the events that will be available for the caller.\n+ * @param maxevents\n+ *   Up to maxevents are returned, must greater than zero.\n+ * @param timeout\n+ *   Specifying a timeout of -1 causes a block indefinitely.\n+ *   Specifying a timeout equal to zero cause to return immediately.\n+ * @return\n+ *   - On success, returns the number of available event.\n+ *   - On failure, a negative value.\n+ */\n+__rte_experimental\n+int\n+rte_epoll_wait_interruptible(int epfd, struct rte_epoll_event *events,\n+\t       int maxevents, int timeout);\n+\n+/**\n+ * It performs control operations on epoll instance referred by the epfd.\n+ * It requests that the operation op be performed for the target fd.\n+ *\n+ * @param epfd\n+ *   Epoll instance fd on which the caller perform control operations.\n+ * @param op\n+ *   The operation be performed for the target fd.\n+ * @param fd\n+ *   The target fd on which the control ops perform.\n+ * @param event\n+ *   Describes the object linked to the fd.\n+ *   Note: The caller must take care the object deletion after CTL_DEL.\n+ * @return\n+ *   - On success, zero.\n+ *   - On failure, a negative value.\n+ */\n+int\n+rte_epoll_ctl(int epfd, int op, int fd,\n+\t      struct rte_epoll_event *event);\n+\n+#ifdef __cplusplus\n+}\n+#endif\n+\n+#endif /* __RTE_EPOLL_H__ */\ndiff --git a/lib/eal/include/rte_interrupts.h b/lib/eal/include/rte_interrupts.h\nindex cc3bf45d8c..a515a8c073 100644\n--- a/lib/eal/include/rte_interrupts.h\n+++ b/lib/eal/include/rte_interrupts.h\n@@ -5,8 +5,12 @@\n #ifndef _RTE_INTERRUPTS_H_\n #define _RTE_INTERRUPTS_H_\n \n+#include <stdbool.h>\n+\n+#include <rte_bitops.h>\n #include <rte_common.h>\n #include <rte_compat.h>\n+#include <rte_epoll.h>\n \n /**\n  * @file\n@@ -22,6 +26,15 @@ extern \"C\" {\n /** Interrupt handle */\n struct rte_intr_handle;\n \n+/** Interrupt instance allocation flags\n+ * @see rte_intr_instance_alloc\n+ */\n+\n+/** Interrupt instance will not be shared between primary and secondary processes. */\n+#define RTE_INTR_INSTANCE_F_PRIVATE     UINT32_C(0)\n+/** Interrupt instance will be shared between primary and secondary processes. */\n+#define RTE_INTR_INSTANCE_F_SHARED      RTE_BIT32(0)\n+\n /** Function to be registered for the specific interrupt */\n typedef void (*rte_intr_callback_fn)(void *cb_arg);\n \n@@ -163,6 +176,620 @@ int rte_intr_disable(const struct rte_intr_handle *intr_handle);\n __rte_experimental\n int rte_intr_ack(const struct rte_intr_handle *intr_handle);\n \n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice\n+ *\n+ * Check if currently executing in interrupt context\n+ *\n+ * @return\n+ *  - non zero in case of interrupt context\n+ *  - zero in case of process context\n+ */\n+__rte_experimental\n+int\n+rte_thread_is_intr(void);\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice\n+ *\n+ * It allocates memory for interrupt instance. API takes flag as an argument\n+ * which define from where memory should be allocated i.e. using DPDK memory\n+ * management library APIs or normal heap allocation.\n+ * Default memory allocation for event fds and event list array is done which\n+ * can be realloced later based on size of MSIX interrupts supported by a PCI\n+ * device.\n+ *\n+ * This function should be called from application or driver, before calling\n+ * any of the interrupt APIs.\n+ *\n+ * @param flags\n+ *  See RTE_INTR_INSTANCE_F_* flags definitions.\n+ *\n+ * @return\n+ *  - On success, address of interrupt handle.\n+ *  - On failure, NULL.\n+ */\n+__rte_experimental\n+struct rte_intr_handle *\n+rte_intr_instance_alloc(uint32_t flags);\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice\n+ *\n+ * This API is used to free the memory allocated for interrupt handle\n+ * resources.\n+ *\n+ * @param intr_handle\n+ *  Interrupt handle address.\n+ *\n+ */\n+__rte_experimental\n+void\n+rte_intr_instance_free(struct rte_intr_handle *intr_handle);\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice\n+ *\n+ * This API is used to set the fd field of interrupt handle with user provided\n+ * file descriptor.\n+ *\n+ * @param intr_handle\n+ *  pointer to the interrupt handle.\n+ * @param fd\n+ *  file descriptor value provided by user.\n+ *\n+ * @return\n+ *  - On success, zero.\n+ *  - On failure, a negative value and rte_errno is set.\n+ */\n+__rte_experimental\n+int\n+rte_intr_fd_set(struct rte_intr_handle *intr_handle, int fd);\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice\n+ *\n+ * Returns the fd field of the given interrupt handle instance.\n+ *\n+ * @param intr_handle\n+ *  pointer to the interrupt handle.\n+ *\n+ * @return\n+ *  - On success, fd field.\n+ *  - On failure, a negative value.\n+ */\n+__rte_experimental\n+int\n+rte_intr_fd_get(const struct rte_intr_handle *intr_handle);\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice\n+ *\n+ * This API is used to set the type field of interrupt handle with user provided\n+ * interrupt type.\n+ *\n+ * @param intr_handle\n+ *  pointer to the interrupt handle.\n+ * @param type\n+ *  interrupt type\n+ *\n+ * @return\n+ *  - On success, zero.\n+ *  - On failure, a negative value and rte_errno is set.\n+ */\n+__rte_experimental\n+int\n+rte_intr_type_set(struct rte_intr_handle *intr_handle,\n+\t\t  enum rte_intr_handle_type type);\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice\n+ *\n+ * Returns the type field of the given interrupt handle instance.\n+ *\n+ * @param intr_handle\n+ *  pointer to the interrupt handle.\n+ *\n+ * @return\n+ *  - On success, interrupt type\n+ *  - On failure, RTE_INTR_HANDLE_UNKNOWN.\n+ */\n+__rte_experimental\n+enum rte_intr_handle_type\n+rte_intr_type_get(const struct rte_intr_handle *intr_handle);\n+\n+/**\n+ * @internal\n+ * The function returns the per thread epoll instance.\n+ *\n+ * @return\n+ *   epfd the epoll instance referred to.\n+ */\n+__rte_internal\n+int\n+rte_intr_tls_epfd(void);\n+\n+/**\n+ * @internal\n+ * @param intr_handle\n+ *   Pointer to the interrupt handle.\n+ * @param epfd\n+ *   Epoll instance fd which the intr vector associated to.\n+ * @param op\n+ *   The operation be performed for the vector.\n+ *   Operation type of {ADD, DEL}.\n+ * @param vec\n+ *   RX intr vector number added to the epoll instance wait list.\n+ * @param data\n+ *   User raw data.\n+ * @return\n+ *   - On success, zero.\n+ *   - On failure, a negative value.\n+ */\n+__rte_internal\n+int\n+rte_intr_rx_ctl(struct rte_intr_handle *intr_handle,\n+\t\tint epfd, int op, unsigned int vec, void *data);\n+\n+/**\n+ * @internal\n+ * It deletes registered eventfds.\n+ *\n+ * @param intr_handle\n+ *   Pointer to the interrupt handle.\n+ */\n+__rte_internal\n+void\n+rte_intr_free_epoll_fd(struct rte_intr_handle *intr_handle);\n+\n+/**\n+ * @internal\n+ * It enables the packet I/O interrupt event if it's necessary.\n+ * It creates event fd for each interrupt vector when MSIX is used,\n+ * otherwise it multiplexes a single event fd.\n+ *\n+ * @param intr_handle\n+ *   Pointer to the interrupt handle.\n+ * @param nb_efd\n+ *   Number of interrupt vector trying to enable.\n+ *   The value 0 is not allowed.\n+ * @return\n+ *   - On success, zero.\n+ *   - On failure, a negative value.\n+ */\n+__rte_internal\n+int\n+rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd);\n+\n+/**\n+ * @internal\n+ * It disables the packet I/O interrupt event.\n+ * It deletes registered eventfds and closes the open fds.\n+ *\n+ * @param intr_handle\n+ *   Pointer to the interrupt handle.\n+ */\n+__rte_internal\n+void\n+rte_intr_efd_disable(struct rte_intr_handle *intr_handle);\n+\n+/**\n+ * @internal\n+ * The packet I/O interrupt on datapath is enabled or not.\n+ *\n+ * @param intr_handle\n+ *   Pointer to the interrupt handle.\n+ */\n+__rte_internal\n+int\n+rte_intr_dp_is_en(struct rte_intr_handle *intr_handle);\n+\n+/**\n+ * @internal\n+ * The interrupt handle instance allows other causes or not.\n+ * Other causes stand for any none packet I/O interrupts.\n+ *\n+ * @param intr_handle\n+ *   Pointer to the interrupt handle.\n+ */\n+__rte_internal\n+int\n+rte_intr_allow_others(struct rte_intr_handle *intr_handle);\n+\n+/**\n+ * @internal\n+ * The multiple interrupt vector capability of interrupt handle instance.\n+ * It returns zero if no multiple interrupt vector support.\n+ *\n+ * @param intr_handle\n+ *   Pointer to the interrupt handle.\n+ */\n+__rte_internal\n+int\n+rte_intr_cap_multiple(struct rte_intr_handle *intr_handle);\n+\n+/**\n+ * @internal\n+ * Creates a clone of src by allocating a new handle and copying src content.\n+ *\n+ * @param src\n+ *  Source interrupt handle to be cloned.\n+ *\n+ * @return\n+ *  - On success, address of interrupt handle.\n+ *  - On failure, NULL.\n+ */\n+__rte_internal\n+struct rte_intr_handle *\n+rte_intr_instance_dup(const struct rte_intr_handle *src);\n+\n+/**\n+ * @internal\n+ * This API is used to set the device fd field of interrupt handle with user\n+ * provided dev fd. Device fd corresponds to VFIO device fd or UIO config fd.\n+ *\n+ * @param intr_handle\n+ *  pointer to the interrupt handle.\n+ * @param fd\n+ *  interrupt type\n+ *\n+ * @return\n+ *  - On success, zero.\n+ *  - On failure, a negative value and rte_errno is set.\n+ */\n+__rte_internal\n+int\n+rte_intr_dev_fd_set(struct rte_intr_handle *intr_handle, int fd);\n+\n+/**\n+ * @internal\n+ * Returns the device fd field of the given interrupt handle instance.\n+ *\n+ * @param intr_handle\n+ *  pointer to the interrupt handle.\n+ *\n+ * @return\n+ *  - On success, dev fd.\n+ *  - On failure, a negative value and rte_errno is set.\n+ */\n+__rte_internal\n+int\n+rte_intr_dev_fd_get(const struct rte_intr_handle *intr_handle);\n+\n+/**\n+ * @internal\n+ * This API is used to set the max intr field of interrupt handle with user\n+ * provided max intr value.\n+ *\n+ * @param intr_handle\n+ *  pointer to the interrupt handle.\n+ * @param max_intr\n+ *  interrupt type\n+ *\n+ * @return\n+ *  - On success, zero.\n+ *  - On failure, a negative value and rte_errno is set.\n+ */\n+__rte_internal\n+int\n+rte_intr_max_intr_set(struct rte_intr_handle *intr_handle, int max_intr);\n+\n+/**\n+ * @internal\n+ * Returns the max intr field of the given interrupt handle instance.\n+ *\n+ * @param intr_handle\n+ *  pointer to the interrupt handle.\n+ *\n+ * @return\n+ *  - On success, max intr.\n+ *  - On failure, a negative value and rte_errno is set.\n+ */\n+__rte_internal\n+int\n+rte_intr_max_intr_get(const struct rte_intr_handle *intr_handle);\n+\n+/**\n+ * @internal\n+ * This API is used to set the number of event fd field of interrupt handle\n+ * with user provided available event file descriptor value.\n+ *\n+ * @param intr_handle\n+ *  pointer to the interrupt handle.\n+ * @param nb_efd\n+ *  Available event fd\n+ *\n+ * @return\n+ *  - On success, zero.\n+ *  - On failure, a negative value and rte_errno is set.\n+ */\n+__rte_internal\n+int\n+rte_intr_nb_efd_set(struct rte_intr_handle *intr_handle, int nb_efd);\n+\n+/**\n+ * @internal\n+ * Returns the number of available event fd field of the given interrupt handle\n+ * instance.\n+ *\n+ * @param intr_handle\n+ *  pointer to the interrupt handle.\n+ *\n+ * @return\n+ *  - On success, nb_efd\n+ *  - On failure, a negative value and rte_errno is set.\n+ */\n+__rte_internal\n+int\n+rte_intr_nb_efd_get(const struct rte_intr_handle *intr_handle);\n+\n+/**\n+ * @internal\n+ * Returns the number of interrupt vector field of the given interrupt handle\n+ * instance. This field is to configured on device probe time, and based on\n+ * this value efds and elist arrays are dynamically allocated. By default\n+ * this value is set to RTE_MAX_RXTX_INTR_VEC_ID.\n+ * For eg. in case of PCI device, its msix size is queried and efds/elist\n+ * arrays are allocated accordingly.\n+ *\n+ * @param intr_handle\n+ *  pointer to the interrupt handle.\n+ *\n+ * @return\n+ *  - On success, nb_intr\n+ *  - On failure, a negative value and rte_errno is set.\n+ */\n+__rte_internal\n+int\n+rte_intr_nb_intr_get(const struct rte_intr_handle *intr_handle);\n+\n+/**\n+ * @internal\n+ * This API is used to set the event fd counter size field of interrupt handle\n+ * with user provided efd counter size.\n+ *\n+ * @param intr_handle\n+ *  pointer to the interrupt handle.\n+ * @param efd_counter_size\n+ *  size of efd counter.\n+ *\n+ * @return\n+ *  - On success, zero.\n+ *  - On failure, a negative value and rte_errno is set.\n+ */\n+__rte_internal\n+int\n+rte_intr_efd_counter_size_set(struct rte_intr_handle *intr_handle,\n+\t\t\t      uint8_t efd_counter_size);\n+\n+/**\n+ * @internal\n+ * Returns the event fd counter size field of the given interrupt handle\n+ * instance.\n+ *\n+ * @param intr_handle\n+ *  pointer to the interrupt handle.\n+ *\n+ * @return\n+ *  - On success, efd_counter_size\n+ *  - On failure, a negative value and rte_errno is set.\n+ */\n+__rte_internal\n+int\n+rte_intr_efd_counter_size_get(const struct rte_intr_handle *intr_handle);\n+\n+/**\n+ * @internal\n+ * This API is used to set the event fd array index with the given fd.\n+ *\n+ * @param intr_handle\n+ *  pointer to the interrupt handle.\n+ * @param index\n+ *  efds array index to be set\n+ * @param fd\n+ *  event fd\n+ *\n+ * @return\n+ *  - On success, zero.\n+ *  - On failure, a negative value and rte_errno is set.\n+ */\n+__rte_internal\n+int\n+rte_intr_efds_index_set(struct rte_intr_handle *intr_handle, int index, int fd);\n+\n+/**\n+ * @internal\n+ * Returns the fd value of event fds array at a given index.\n+ *\n+ * @param intr_handle\n+ *  pointer to the interrupt handle.\n+ * @param index\n+ *  efds array index to be returned\n+ *\n+ * @return\n+ *  - On success, fd\n+ *  - On failure, a negative value and rte_errno is set.\n+ */\n+__rte_internal\n+int\n+rte_intr_efds_index_get(const struct rte_intr_handle *intr_handle, int index);\n+\n+/**\n+ * @internal\n+ * This API is used to set the epoll event object array index with the given\n+ * elist instance.\n+ *\n+ * @param intr_handle\n+ *  pointer to the interrupt handle.\n+ * @param index\n+ *  elist array index to be set\n+ * @param elist\n+ *  epoll event instance of struct rte_epoll_event\n+ *\n+ * @return\n+ *  - On success, zero.\n+ *  - On failure, a negative value and rte_errno is set.\n+ */\n+__rte_internal\n+int\n+rte_intr_elist_index_set(struct rte_intr_handle *intr_handle, int index,\n+\t\t\t struct rte_epoll_event elist);\n+\n+/**\n+ * @internal\n+ * Returns the address of epoll event instance from elist array at a given\n+ * index.\n+ *\n+ * @param intr_handle\n+ *  pointer to the interrupt handle.\n+ * @param index\n+ *  elist array index to be returned\n+ *\n+ * @return\n+ *  - On success, elist\n+ *  - On failure, a negative value and rte_errno is set.\n+ */\n+__rte_internal\n+struct rte_epoll_event *\n+rte_intr_elist_index_get(struct rte_intr_handle *intr_handle, int index);\n+\n+/**\n+ * @internal\n+ * Allocates the memory of interrupt vector list array, with size defining the\n+ * number of elements required in the array.\n+ *\n+ * @param intr_handle\n+ *  pointer to the interrupt handle.\n+ * @param name\n+ *  Name assigned to the allocation, or NULL.\n+ * @param size\n+ *  Number of element required in the array.\n+ *\n+ * @return\n+ *  - On success, zero\n+ *  - On failure, a negative value and rte_errno is set.\n+ */\n+__rte_internal\n+int\n+rte_intr_vec_list_alloc(struct rte_intr_handle *intr_handle, const char *name,\n+\t\t\tint size);\n+\n+/**\n+ * @internal\n+ * Sets the vector value at given index of interrupt vector list field of given\n+ * interrupt handle.\n+ *\n+ * @param intr_handle\n+ *  pointer to the interrupt handle.\n+ * @param index\n+ *  intr_vec array index to be set\n+ * @param vec\n+ *  Interrupt vector value.\n+ *\n+ * @return\n+ *  - On success, zero\n+ *  - On failure, a negative value and rte_errno is set.\n+ */\n+__rte_internal\n+int\n+rte_intr_vec_list_index_set(struct rte_intr_handle *intr_handle, int index,\n+\t\t\t    int vec);\n+\n+/**\n+ * @internal\n+ * Returns the vector value at the given index of interrupt vector list array.\n+ *\n+ * @param intr_handle\n+ *  pointer to the interrupt handle.\n+ * @param index\n+ *  intr_vec array index to be returned\n+ *\n+ * @return\n+ *  - On success, interrupt vector\n+ *  - On failure, a negative value and rte_errno is set.\n+ */\n+__rte_internal\n+int\n+rte_intr_vec_list_index_get(const struct rte_intr_handle *intr_handle,\n+\t\t\t    int index);\n+\n+/**\n+ * @internal\n+ * Frees the memory allocated for interrupt vector list array.\n+ *\n+ * @param intr_handle\n+ *  pointer to the interrupt handle.\n+ *\n+ * @return\n+ *  - On success, zero\n+ *  - On failure, a negative value and rte_errno is set.\n+ */\n+__rte_internal\n+void\n+rte_intr_vec_list_free(struct rte_intr_handle *intr_handle);\n+\n+/**\n+ * @internal\n+ * Reallocates the size efds and elist array based on size provided by user.\n+ * By default efds and elist array are allocated with default size\n+ * RTE_MAX_RXTX_INTR_VEC_ID on interrupt handle array creation. Later on device\n+ * probe, device may have capability of more interrupts than\n+ * RTE_MAX_RXTX_INTR_VEC_ID. Using this API, PMDs can reallocate the arrays as\n+ * per the max interrupts capability of device.\n+ *\n+ * @param intr_handle\n+ *  pointer to the interrupt handle.\n+ * @param size\n+ *  efds and elist array size.\n+ *\n+ * @return\n+ *  - On success, zero\n+ *  - On failure, a negative value and rte_errno is set.\n+ */\n+__rte_internal\n+int\n+rte_intr_event_list_update(struct rte_intr_handle *intr_handle, int size);\n+\n+/**\n+ * @internal\n+ * This API returns the Windows handle of the given interrupt instance.\n+ *\n+ * @param intr_handle\n+ *  pointer to the interrupt handle.\n+ *\n+ * @return\n+ *  - On success, Windows handle.\n+ *  - On failure, NULL.\n+ */\n+__rte_internal\n+void *\n+rte_intr_instance_windows_handle_get(struct rte_intr_handle *intr_handle);\n+\n+/**\n+ * @internal\n+ * This API set the Windows handle for the given interrupt instance.\n+ *\n+ * @param intr_handle\n+ *  pointer to the interrupt handle.\n+ * @param windows_handle\n+ *  Windows handle to be set.\n+ *\n+ * @return\n+ *  - On success, zero\n+ *  - On failure, a negative value and rte_errno is set.\n+ */\n+__rte_internal\n+int\n+rte_intr_instance_windows_handle_set(struct rte_intr_handle *intr_handle,\n+\t\t\t\t     void *windows_handle);\n+\n #ifdef __cplusplus\n }\n #endif\ndiff --git a/lib/eal/version.map b/lib/eal/version.map\nindex 38f7de83e1..9d43655b66 100644\n--- a/lib/eal/version.map\n+++ b/lib/eal/version.map\n@@ -109,18 +109,10 @@ DPDK_22 {\n \trte_hexdump;\n \trte_hypervisor_get;\n \trte_hypervisor_get_name; # WINDOWS_NO_EXPORT\n-\trte_intr_allow_others;\n \trte_intr_callback_register;\n \trte_intr_callback_unregister;\n-\trte_intr_cap_multiple;\n \trte_intr_disable;\n-\trte_intr_dp_is_en;\n-\trte_intr_efd_disable;\n-\trte_intr_efd_enable;\n \trte_intr_enable;\n-\trte_intr_free_epoll_fd;\n-\trte_intr_rx_ctl;\n-\trte_intr_tls_epfd;\n \trte_keepalive_create; # WINDOWS_NO_EXPORT\n \trte_keepalive_dispatch_pings; # WINDOWS_NO_EXPORT\n \trte_keepalive_mark_alive; # WINDOWS_NO_EXPORT\n@@ -420,12 +412,49 @@ EXPERIMENTAL {\n \n \t# added in 21.08\n \trte_power_monitor_multi; # WINDOWS_NO_EXPORT\n+\n+\t# added in 21.11\n+\trte_intr_fd_get;\n+\trte_intr_fd_set;\n+\trte_intr_instance_alloc;\n+\trte_intr_instance_free;\n+\trte_intr_type_get;\n+\trte_intr_type_set;\n };\n \n INTERNAL {\n \tglobal:\n \n \trte_firmware_read;\n+\trte_intr_allow_others;\n+\trte_intr_cap_multiple;\n+\trte_intr_dev_fd_get;\n+\trte_intr_dev_fd_set;\n+\trte_intr_dp_is_en;\n+\trte_intr_efd_counter_size_set;\n+\trte_intr_efd_counter_size_get;\n+\trte_intr_efd_disable;\n+\trte_intr_efd_enable;\n+\trte_intr_efds_index_get;\n+\trte_intr_efds_index_set;\n+\trte_intr_elist_index_get;\n+\trte_intr_elist_index_set;\n+\trte_intr_event_list_update;\n+\trte_intr_free_epoll_fd;\n+\trte_intr_instance_dup;\n+\trte_intr_instance_windows_handle_get;\n+\trte_intr_instance_windows_handle_set;\n+\trte_intr_max_intr_get;\n+\trte_intr_max_intr_set;\n+\trte_intr_nb_efd_get;\n+\trte_intr_nb_efd_set;\n+\trte_intr_nb_intr_get;\n+\trte_intr_rx_ctl;\n+\trte_intr_tls_epfd;\n+\trte_intr_vec_list_alloc;\n+\trte_intr_vec_list_free;\n+\trte_intr_vec_list_index_get;\n+\trte_intr_vec_list_index_set;\n \trte_mem_lock;\n \trte_mem_map;\n \trte_mem_page_size;\n",
    "prefixes": [
        "v8",
        "1/9"
    ]
}