get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 132658,
    "url": "https://patches.dpdk.org/api/patches/132658/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20231016205715.970999-3-sivaprasad.tummala@amd.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": "<20231016205715.970999-3-sivaprasad.tummala@amd.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20231016205715.970999-3-sivaprasad.tummala@amd.com",
    "date": "2023-10-16T20:57:12",
    "name": "[v1,3/6] eventdev: support optional dequeue callbacks",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "c84de46001f14436f49f8c1fd03e07f012b29e4c",
    "submitter": {
        "id": 2510,
        "url": "https://patches.dpdk.org/api/people/2510/?format=api",
        "name": "Sivaprasad Tummala",
        "email": "Sivaprasad.Tummala@amd.com"
    },
    "delegate": {
        "id": 310,
        "url": "https://patches.dpdk.org/api/users/310/?format=api",
        "username": "jerin",
        "first_name": "Jerin",
        "last_name": "Jacob",
        "email": "jerinj@marvell.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20231016205715.970999-3-sivaprasad.tummala@amd.com/mbox/",
    "series": [
        {
            "id": 29856,
            "url": "https://patches.dpdk.org/api/series/29856/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=29856",
            "date": "2023-10-16T20:57:10",
            "name": "[v1,1/6] eventdev: add power monitoring API on event port",
            "version": 1,
            "mbox": "https://patches.dpdk.org/series/29856/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/132658/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/132658/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 2AF6B43182;\n\tMon, 16 Oct 2023 22:58:06 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 5F14D40DDB;\n\tMon, 16 Oct 2023 22:57:57 +0200 (CEST)",
            "from NAM10-DM6-obe.outbound.protection.outlook.com\n (mail-dm6nam10on2056.outbound.protection.outlook.com [40.107.93.56])\n by mails.dpdk.org (Postfix) with ESMTP id D7894402E5\n for <dev@dpdk.org>; Mon, 16 Oct 2023 22:57:54 +0200 (CEST)",
            "from CYZPR14CA0048.namprd14.prod.outlook.com (2603:10b6:930:a0::25)\n by DM4PR12MB7573.namprd12.prod.outlook.com (2603:10b6:8:10f::22) with\n Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6886.34; Mon, 16 Oct\n 2023 20:57:52 +0000",
            "from CY4PEPF0000E9D0.namprd03.prod.outlook.com\n (2603:10b6:930:a0:cafe::40) by CYZPR14CA0048.outlook.office365.com\n (2603:10b6:930:a0::25) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6886.35 via Frontend\n Transport; Mon, 16 Oct 2023 20:57:52 +0000",
            "from SATLEXMB04.amd.com (165.204.84.17) by\n CY4PEPF0000E9D0.mail.protection.outlook.com (10.167.241.143) with Microsoft\n SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id\n 15.20.6838.22 via Frontend Transport; Mon, 16 Oct 2023 20:57:52 +0000",
            "from telco-siena.amd.com (10.180.168.240) by SATLEXMB04.amd.com\n (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Mon, 16 Oct\n 2023 15:57:36 -0500"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n b=Wm0pOtFpOwU2TnEf2ne3wEueCiiHhivsVjv7NqcARSPl8RuKePcnIOnW4/zk+ZPxcThUn3pR22iueqZ8O5qRkzGNC6PPt0VdkyC+LjXTyJzrZPK5/e4EPyC9ljrxyQnr/Ar/Txx2VoDAgXjsjG6vC/pIp27e4+tiozZKLr/y5lw1ODN0Lrgs+T49HGGvhEY7hTm/qQ8X8QZKBFANocVJHyDFl3ueddtZkaIwEabXBik8d5QXD/hRQWjVRotse2GCSECq0uPYWjVrhuZ+TQW5fUMq9zvopX8nClpTRnzBpBXe0km/ZkLb6Vz+hTdkMSjDzCJNdpwS9Xr+jXjhyXy1Lw==",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n s=arcselector9901;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;\n bh=fOcCZGCCn4AtEdOVDu+1kF8ahl0/1bFawPr/C0KFNTU=;\n b=iXSbKkWLhTwtaFzYFiHFcwpMnLdp+Py4rmSAG3k6hZg3U2TYAi/y2eHfhKsYd5c4UhErA0INPHa2MNDFfQqcjhPbeV4UAKKGSMe1UVuS758Sw+BU6oMud0nGuY4FcjEVO93ZlGjHwlSCnbg87hcn7XHFgiG+RlWsdgyU9UgkINGvpwt9f+xjeZkop2aCWBeHK5x2vNN3LFXRqtNIzSYjVmnwksyin69v+sUAb+ysIOPVPDfAZYCJiT7hBuDq2tGEJh85l53yA16iyc9972hmmyAUNoJgwXiq+Yw6MT9vAHI/4is5ytZJ9reAlsnOp/C9vLOUCGuONjd4kPwFQ+932Q==",
        "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=pass (sender ip is\n 165.204.84.17) smtp.rcpttodomain=gmail.com smtp.mailfrom=amd.com; dmarc=pass\n (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com;\n dkim=none (message not signed); arc=none",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=fOcCZGCCn4AtEdOVDu+1kF8ahl0/1bFawPr/C0KFNTU=;\n b=ZSAB2jqsyr9MjICSFLAbZLv93m3ZBlADUheJFlhPpzi3wEn+1pi7kcTqyTBGbMaegzZStaA1tjinytY9cxDqOCuTN2Sjn0BjpyrZIaDKhhZwOb5bL1NUY1dN7KMyuNFFkCIaINcwFoI9zrcl2/IvpM/PX9psaeMshAhAlW6BQL0=",
        "X-MS-Exchange-Authentication-Results": "spf=pass (sender IP is 165.204.84.17)\n smtp.mailfrom=amd.com; dkim=none (message not signed)\n header.d=none;dmarc=pass action=none header.from=amd.com;",
        "Received-SPF": "Pass (protection.outlook.com: domain of amd.com designates\n 165.204.84.17 as permitted sender) receiver=protection.outlook.com;\n client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C",
        "From": "Sivaprasad Tummala <sivaprasad.tummala@amd.com>",
        "To": "<jerinjacobk@gmail.com>, <harry.van.haaren@intel.com>,\n <anatoly.burakov@intel.com>",
        "CC": "<dev@dpdk.org>, <ferruh.yigit@amd.com>, <david.hunt@intel.com>",
        "Subject": "[PATCH v1 3/6] eventdev: support optional dequeue callbacks",
        "Date": "Mon, 16 Oct 2023 13:57:12 -0700",
        "Message-ID": "<20231016205715.970999-3-sivaprasad.tummala@amd.com>",
        "X-Mailer": "git-send-email 2.34.1",
        "In-Reply-To": "<20231016205715.970999-1-sivaprasad.tummala@amd.com>",
        "References": "<20230419095427.563185-1-sivaprasad.tummala@amd.com>\n <20231016205715.970999-1-sivaprasad.tummala@amd.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[10.180.168.240]",
        "X-ClientProxiedBy": "SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com\n (10.181.40.145)",
        "X-EOPAttributedMessage": "0",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-TrafficTypeDiagnostic": "CY4PEPF0000E9D0:EE_|DM4PR12MB7573:EE_",
        "X-MS-Office365-Filtering-Correlation-Id": "5d24626f-0eb7-415b-7f98-08dbce8a9053",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-MS-Exchange-AntiSpam-Relay": "0",
        "X-Microsoft-Antispam": "BCL:0;",
        "X-Microsoft-Antispam-Message-Info": "\n tbEl8qJbGfd7d/xDcY7GcciU0zNpWRs0sVzTagjOTy/m4TQJe2jt4nn224N4BWd2n+Xthma1/PrBozr/OD3i47C8QbauqE+MfcW5r4FSEGP6c2Y+0czE1cQrOyGfS/1dQFkSgWstk6PQrMysyASQ3cB0XMxTpuleUjoTm9+vjoqdVobjtuYnIXlrHRz97R4Ovqv10L9awAGQ/DW/JSvAVa4U4vq0IaWFStBYgj4F55xIHZwQvyYPhRTbnJVQ4TDZNqLvC/q8KoUxyR1aZHGuvEWFy0whXwx550WgUHwr3Dci+QCl4JvzYJiHDN9LWbSmGuRaCDVE5JbrL54PzcsLvK61njO5kh79yLy3DPNFpKi3rexM+sFekeGI9lTg6GhunDSeUrIZDgoV2BtNCyQRIekGwUicQ4ldabfovkSQtFImpAxHCN1dNVx+L0oqYZTQ5wDjr2O8Z49pRmhhiAE2db04B+oP4mcaQ1xOPUOVHCreYY4S1bW3kKDPGfKQOwJPuADeZOeWLfwACa01iZmpPpAclPexeALe/lpLxPMPeX+f7b7VLnL63CRnhh8AAIjoah8FSY8hXL/DErzG9B+nOp6QzVd374iCHO5wIoYNBKek8J5weJedtrYurdUNUVP4Lkr9pM8sGOJq4rm2gkhI0Y8yIQHKNrYCZN6M6p/b6kiK4ifXvsV3/QneTOptI4fZMqXAquGSW09rQQS6xxgtqx5RTDGOSDQDwypnFzYX4Lmk3AOmGqwjU8iJCpBAwgwZVuvEXUxTYzOCRV66qv606A==",
        "X-Forefront-Antispam-Report": "CIP:165.204.84.17; CTRY:US; LANG:en; SCL:1; SRV:;\n IPV:CAL; SFV:NSPM; H:SATLEXMB04.amd.com; PTR:InfoDomainNonexistent; CAT:NONE;\n SFS:(13230031)(4636009)(39860400002)(376002)(136003)(346002)(396003)(230922051799003)(64100799003)(82310400011)(451199024)(1800799009)(186009)(40470700004)(46966006)(36840700001)(6666004)(40460700003)(36860700001)(54906003)(8936002)(70206006)(316002)(70586007)(110136005)(356005)(478600001)(81166007)(1076003)(82740400003)(2616005)(26005)(7696005)(16526019)(8676002)(47076005)(83380400001)(4326008)(426003)(336012)(40480700001)(30864003)(2906002)(5660300002)(36756003)(86362001)(41300700001)(44832011)(36900700001);\n DIR:OUT; SFP:1101;",
        "X-OriginatorOrg": "amd.com",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "16 Oct 2023 20:57:52.4163 (UTC)",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n 5d24626f-0eb7-415b-7f98-08dbce8a9053",
        "X-MS-Exchange-CrossTenant-Id": "3dd8961f-e488-4e60-8e11-a82d994e183d",
        "X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp": "\n TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d; Ip=[165.204.84.17];\n Helo=[SATLEXMB04.amd.com]",
        "X-MS-Exchange-CrossTenant-AuthSource": "\n CY4PEPF0000E9D0.namprd03.prod.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Anonymous",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "HybridOnPrem",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "DM4PR12MB7573",
        "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"
    },
    "content": "Add optional support for inline event processing within pmd dequeue\ncall. For a dequeue callback, events dequeued from the event port\nwere passed them to a callback function if configured, to allow\nadditional processing. e.g. unpack batch of packets from each event\non dequeue, before passing back to the application.\n\nSigned-off-by: Sivaprasad Tummala <sivaprasad.tummala@amd.com>\n---\n lib/eventdev/eventdev_pmd.h      |  38 +++++++++++\n lib/eventdev/eventdev_private.c  |   2 +\n lib/eventdev/rte_eventdev.c      | 107 +++++++++++++++++++++++++++++++\n lib/eventdev/rte_eventdev.h      |  95 +++++++++++++++++++++++++++\n lib/eventdev/rte_eventdev_core.h |  12 +++-\n lib/eventdev/version.map         |   3 +\n 6 files changed, 256 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/lib/eventdev/eventdev_pmd.h b/lib/eventdev/eventdev_pmd.h\nindex a0ee768ce7..ce067b1d5d 100644\n--- a/lib/eventdev/eventdev_pmd.h\n+++ b/lib/eventdev/eventdev_pmd.h\n@@ -97,6 +97,19 @@ struct rte_eventdev_global {\n \tuint8_t nb_devs;\t/**< Number of devices found */\n };\n \n+/**\n+ * @internal\n+ * Structure used to hold information about the callbacks to be called for a\n+ * port on dequeue.\n+ */\n+struct rte_event_dequeue_callback {\n+\tstruct rte_event_dequeue_callback *next;\n+\tunion{\n+\t\trte_dequeue_callback_fn dequeue;\n+\t} fn;\n+\tvoid *param;\n+};\n+\n /**\n  * @internal\n  * The data part, with no function pointers, associated with each device.\n@@ -171,6 +184,10 @@ struct rte_eventdev {\n \t/**< Pointer to PMD dequeue burst function. */\n \tevent_maintain_t maintain;\n \t/**< Pointer to PMD port maintenance function. */\n+\tstruct rte_event_dequeue_callback *post_dequeue_burst_cbs[RTE_EVENT_MAX_PORTS_PER_DEV];\n+\t/**<  User-supplied functions called from dequeue_burst to post-process\n+\t * received packets before passing them to the user\n+\t */\n \tevent_tx_adapter_enqueue_t txa_enqueue_same_dest;\n \t/**< Pointer to PMD eth Tx adapter burst enqueue function with\n \t * events destined to same Eth port & Tx queue.\n@@ -245,6 +262,27 @@ rte_event_pmd_is_valid_dev(uint8_t dev_id)\n \t\treturn 1;\n }\n \n+/**\n+ * Executes all the user application registered callbacks for the specific\n+ * event device.\n+ *\n+ * @param dev_id\n+ *   Event device index.\n+ * @param port_id\n+ *   Event port index\n+ * @param ev\n+ *   Points to an array of *nb_events* objects of type *rte_event* structure\n+ *   for output to be populated with the dequeued event objects.\n+ * @param nb_events\n+ *   number of event objects\n+ *\n+ * @return\n+ * The number of event objects\n+ */\n+__rte_internal\n+uint16_t rte_eventdev_pmd_dequeue_callback_process(uint8_t dev_id,\n+\t\tuint8_t port_id, struct rte_event ev[], uint16_t nb_events);\n+\n /**\n  * Definitions of all functions exported by a driver through the\n  * generic structure of type *event_dev_ops* supplied in the\ndiff --git a/lib/eventdev/eventdev_private.c b/lib/eventdev/eventdev_private.c\nindex 017f97ccab..052c526ce0 100644\n--- a/lib/eventdev/eventdev_private.c\n+++ b/lib/eventdev/eventdev_private.c\n@@ -137,4 +137,6 @@ event_dev_fp_ops_set(struct rte_event_fp_ops *fp_op,\n \tfp_op->dma_enqueue = dev->dma_enqueue;\n \tfp_op->profile_switch = dev->profile_switch;\n \tfp_op->data = dev->data->ports;\n+\tfp_op->ev_port.clbk = (void **)(uintptr_t)dev->post_dequeue_burst_cbs;\n+\tfp_op->ev_port.data = dev->data->ports;\n }\ndiff --git a/lib/eventdev/rte_eventdev.c b/lib/eventdev/rte_eventdev.c\nindex 5feb4326a2..f2540a6aa8 100644\n--- a/lib/eventdev/rte_eventdev.c\n+++ b/lib/eventdev/rte_eventdev.c\n@@ -18,6 +18,7 @@\n #include <rte_common.h>\n #include <rte_malloc.h>\n #include <rte_errno.h>\n+#include <rte_stdatomic.h>\n #include <ethdev_driver.h>\n #include <rte_cryptodev.h>\n #include <rte_dmadev.h>\n@@ -39,6 +40,9 @@ static struct rte_eventdev_global eventdev_globals = {\n /* Public fastpath APIs. */\n struct rte_event_fp_ops rte_event_fp_ops[RTE_EVENT_MAX_DEVS];\n \n+/* spinlock for add/remove dequeue callbacks */\n+static rte_spinlock_t event_dev_dequeue_cb_lock = RTE_SPINLOCK_INITIALIZER;\n+\n /* Event dev north bound API implementation */\n \n uint8_t\n@@ -884,6 +888,109 @@ rte_event_port_attr_get(uint8_t dev_id, uint8_t port_id, uint32_t attr_id,\n \treturn 0;\n }\n \n+const struct rte_event_dequeue_callback *\n+rte_event_add_dequeue_callback(uint8_t dev_id, uint8_t port_id,\n+\t\trte_dequeue_callback_fn fn, void *user_param)\n+{\n+\tstruct rte_eventdev *dev;\n+\tstruct rte_event_dequeue_callback *cb;\n+\tstruct rte_event_dequeue_callback *tail;\n+\n+\t/* check input parameters */\n+\tRTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, NULL);\n+\tdev = &rte_eventdevs[dev_id];\n+\tif (!is_valid_port(dev, port_id)) {\n+\t\tRTE_EDEV_LOG_ERR(\"Invalid port_id=%\" PRIu8, port_id);\n+\t\treturn NULL;\n+\t}\n+\n+\tcb = rte_zmalloc(NULL, sizeof(*cb), 0);\n+\tif (cb == NULL) {\n+\t\trte_errno = ENOMEM;\n+\t\treturn NULL;\n+\t}\n+\tcb->fn.dequeue = fn;\n+\tcb->param = user_param;\n+\n+\trte_spinlock_lock(&event_dev_dequeue_cb_lock);\n+\t/* Add the callbacks in fifo order. */\n+\ttail = rte_eventdevs[dev_id].post_dequeue_burst_cbs[port_id];\n+\tif (!tail) {\n+\t\t/* Stores to cb->fn and cb->param should complete before\n+\t\t * cb is visible to data plane.\n+\t\t */\n+\t\trte_atomic_store_explicit(\n+\t\t\t&rte_eventdevs[dev_id].post_dequeue_burst_cbs[port_id],\n+\t\t\tcb, __ATOMIC_RELEASE);\n+\t} else {\n+\t\twhile (tail->next)\n+\t\t\ttail = tail->next;\n+\t\t/* Stores to cb->fn and cb->param should complete before\n+\t\t * cb is visible to data plane.\n+\t\t */\n+\t\trte_atomic_store_explicit(&tail->next, cb, __ATOMIC_RELEASE);\n+\t}\n+\trte_spinlock_unlock(&event_dev_dequeue_cb_lock);\n+\n+\treturn cb;\n+}\n+\n+int\n+rte_event_remove_dequeue_callback(uint8_t dev_id, uint8_t port_id,\n+\t\tconst struct rte_event_dequeue_callback *user_cb)\n+{\n+\tstruct rte_eventdev *dev;\n+\tstruct rte_event_dequeue_callback *cb;\n+\tstruct rte_event_dequeue_callback **prev_cb;\n+\n+\t/* Check input parameters. */\n+\tRTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);\n+\tdev = &rte_eventdevs[dev_id];\n+\tif (user_cb == NULL || !is_valid_port(dev, port_id))\n+\t\treturn -EINVAL;\n+\n+\trte_spinlock_lock(&event_dev_dequeue_cb_lock);\n+\tprev_cb = &dev->post_dequeue_burst_cbs[port_id];\n+\tfor (; *prev_cb != NULL; prev_cb = &cb->next) {\n+\t\tcb = *prev_cb;\n+\t\tif (cb == user_cb) {\n+\t\t\t/* Remove the user cb from the callback list. */\n+\t\t\trte_atomic_store_explicit(prev_cb, cb->next,\n+\t\t\t\t\t\t__ATOMIC_RELAXED);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\trte_spinlock_unlock(&event_dev_dequeue_cb_lock);\n+\n+\treturn 0;\n+}\n+\n+uint16_t rte_eventdev_pmd_dequeue_callback_process(uint8_t dev_id,\n+\t\tuint8_t port_id, struct rte_event ev[], uint16_t nb_events)\n+{\n+\tstruct rte_event_dequeue_callback *cb;\n+\tconst struct rte_event_fp_ops *fp_ops;\n+\n+\tfp_ops = &rte_event_fp_ops[dev_id];\n+\n+\t/* __ATOMIC_RELEASE memory order was used when the\n+\t * call back was inserted into the list.\n+\t * Since there is a clear dependency between loading\n+\t * cb and cb->fn/cb->next, __ATOMIC_ACQUIRE memory order is\n+\t * not required.\n+\t */\n+\tcb = rte_atomic_load_explicit((void **)&fp_ops->ev_port.clbk[port_id],\n+\t\t\t\t\t__ATOMIC_RELAXED);\n+\tif (unlikely(cb != NULL))\n+\t\twhile (cb != NULL) {\n+\t\t\tnb_events = cb->fn.dequeue(dev_id, port_id, ev,\n+\t\t\tnb_events, cb->param);\n+\t\t\tcb = cb->next;\n+\t\t}\n+\n+\treturn nb_events;\n+}\n+\n int\n rte_event_port_get_monitor_addr(uint8_t dev_id, uint8_t port_id,\n \t\t\t\tstruct rte_power_monitor_cond *pmc)\ndiff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h\nindex 38dbbc2617..c0097c0a23 100644\n--- a/lib/eventdev/rte_eventdev.h\n+++ b/lib/eventdev/rte_eventdev.h\n@@ -954,6 +954,101 @@ void\n rte_event_port_quiesce(uint8_t dev_id, uint8_t port_id,\n \t\t       rte_eventdev_port_flush_t release_cb, void *args);\n \n+struct rte_event_dequeue_callback;\n+\n+/**\n+ * Function type used for dequeue event processing callbacks.\n+ *\n+ * The callback function is called on dequeue with a burst of events that have\n+ * been received on the given event port.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ * @param port_id\n+ *   The identifier of the event port.\n+ * @param[out] ev\n+ *   Points to an array of *nb_events* objects of type *rte_event* structure\n+ *   for output to be populated with the dequeued event objects.\n+ * @param nb_events\n+ *   The maximum number of event objects to dequeue, typically number of\n+ *   rte_event_port_dequeue_depth() available for this port.\n+ * @param opaque\n+ *   Opaque pointer of event port callback related data.\n+ *\n+ * @return\n+ *  The number of event objects returned to the user.\n+ */\n+typedef uint16_t (*rte_dequeue_callback_fn)(uint8_t dev_id, uint8_t port_id,\n+\t\tstruct rte_event *ev, uint16_t nb_events, void *user_param);\n+\n+/**\n+ * Add a callback to be called on event dequeue on a given event device port.\n+ *\n+ * This API configures a function to be called for each burst of\n+ * events dequeued on a given event device port. The return value is a pointer\n+ * that can be used to later remove the callback using\n+ * rte_event_remove_dequeue_callback().\n+ *\n+ * Multiple functions are called in the order that they are added.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ * @param port_id\n+ *   The identifier of the event port.\n+ * @param fn\n+ *   The callback function\n+ * @param user_param\n+ *   A generic pointer parameter which will be passed to each invocation of the\n+ *   callback function on this event device port. Inter-thread synchronization\n+ *   of any user data changes is the responsibility of the user.\n+ *\n+ * @return\n+ *   NULL on error.\n+ *   On success, a pointer value which can later be used to remove the callback.\n+ */\n+__rte_experimental\n+const struct rte_event_dequeue_callback *\n+rte_event_add_dequeue_callback(uint8_t dev_id, uint8_t port_id,\n+\t\trte_dequeue_callback_fn fn, void *user_param);\n+\n+/**\n+ * Remove a dequeue event callback from a given event device port.\n+ *\n+ * This API is used to removed callbacks that were added to a event device port\n+ * using rte_event_add_dequeue_callback().\n+ *\n+ * Note: the callback is removed from the callback list but it isn't freed\n+ * since the it may still be in use. The memory for the callback can be\n+ * subsequently freed back by the application by calling rte_free():\n+ *\n+ * - Immediately - if the device is stopped, or the user knows that no\n+ *   callbacks are in flight e.g. if called from the thread doing dequeue\n+ *   on that port.\n+ *\n+ * - After a short delay - where the delay is sufficient to allow any\n+ *   in-flight callbacks to complete. Alternately, the RCU mechanism can be\n+ *   used to detect when data plane threads have ceased referencing the\n+ *   callback memory.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ * @param port_id\n+ *   The identifier of the event port.\n+ * @param user_cb\n+ *   The callback function\n+ *\n+ * @return\n+ *   - 0: Success. Callback was removed.\n+ *   - -ENODEV:  If *dev_id* is invalid.\n+ *   - -EINVAL:  The port_id is out of range, or the callback\n+ *               is NULL.\n+ */\n+__rte_experimental\n+int\n+rte_event_remove_dequeue_callback(uint8_t dev_id, uint8_t port_id,\n+\t\tconst struct rte_event_dequeue_callback *user_cb);\n+\n+\n /**\n  * The queue depth of the port on the enqueue side\n  */\ndiff --git a/lib/eventdev/rte_eventdev_core.h b/lib/eventdev/rte_eventdev_core.h\nindex 5b405518d1..5ce93c4b6f 100644\n--- a/lib/eventdev/rte_eventdev_core.h\n+++ b/lib/eventdev/rte_eventdev_core.h\n@@ -49,6 +49,14 @@ typedef uint16_t (*event_dma_adapter_enqueue_t)(void *port, struct rte_event ev[\n typedef int (*event_profile_switch_t)(void *port, uint8_t profile);\n /**< @internal Switch active link profile on the event port. */\n \n+struct rte_eventdev_port_data {\n+\tvoid **data;\n+\t/**< points to array of internal port data pointers */\n+\tvoid **clbk;\n+\t/**< points to array of port callback data pointers */\n+};\n+/**< @internal Structure used to hold opaque eventdev port data. */\n+\n struct rte_event_fp_ops {\n \tvoid **data;\n \t/**< points to array of internal port data pointers */\n@@ -76,7 +84,9 @@ struct rte_event_fp_ops {\n \t/**< PMD DMA adapter enqueue function. */\n \tevent_profile_switch_t profile_switch;\n \t/**< PMD Event switch profile function. */\n-\tuintptr_t reserved[4];\n+\tstruct rte_eventdev_port_data ev_port;\n+\t/**< Eventdev port data. */\n+\tuintptr_t reserved[1];\n } __rte_cache_aligned;\n \n extern struct rte_event_fp_ops rte_event_fp_ops[RTE_EVENT_MAX_DEVS];\ndiff --git a/lib/eventdev/version.map b/lib/eventdev/version.map\nindex fa9eb069ff..a0c7aa5bbd 100644\n--- a/lib/eventdev/version.map\n+++ b/lib/eventdev/version.map\n@@ -155,6 +155,8 @@ EXPERIMENTAL {\n \trte_event_port_profile_unlink;\n \trte_event_port_profile_links_get;\n \trte_event_port_get_monitor_addr;\n+\trte_event_add_dequeue_callback;\n+\trte_event_remove_dequeue_callback;\n \t__rte_eventdev_trace_port_profile_switch;\n };\n \n@@ -165,6 +167,7 @@ INTERNAL {\n \tevent_dev_fp_ops_set;\n \tevent_dev_probing_finish;\n \trte_event_pmd_allocate;\n+\trte_eventdev_pmd_dequeue_callback_process;\n \trte_event_pmd_get_named_dev;\n \trte_event_pmd_is_valid_dev;\n \trte_event_pmd_pci_probe;\n",
    "prefixes": [
        "v1",
        "3/6"
    ]
}