get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 130773,
    "url": "http://patchwork.dpdk.org/api/patches/130773/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20230825184435.2986-2-pbhagavatula@marvell.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": "<20230825184435.2986-2-pbhagavatula@marvell.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230825184435.2986-2-pbhagavatula@marvell.com",
    "date": "2023-08-25T18:44:33",
    "name": "[1/3] eventdev: introduce link profiles",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "efbbf9240d64b37b79e377f907e54d29d0f64747",
    "submitter": {
        "id": 1183,
        "url": "http://patchwork.dpdk.org/api/people/1183/?format=api",
        "name": "Pavan Nikhilesh Bhagavatula",
        "email": "pbhagavatula@marvell.com"
    },
    "delegate": {
        "id": 310,
        "url": "http://patchwork.dpdk.org/api/users/310/?format=api",
        "username": "jerin",
        "first_name": "Jerin",
        "last_name": "Jacob",
        "email": "jerinj@marvell.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20230825184435.2986-2-pbhagavatula@marvell.com/mbox/",
    "series": [
        {
            "id": 29349,
            "url": "http://patchwork.dpdk.org/api/series/29349/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=29349",
            "date": "2023-08-25T18:44:32",
            "name": "Introduce event link profiles",
            "version": 1,
            "mbox": "http://patchwork.dpdk.org/series/29349/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/130773/comments/",
    "check": "success",
    "checks": "http://patchwork.dpdk.org/api/patches/130773/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 2C2CA43103;\n\tFri, 25 Aug 2023 20:44:54 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 1620F4323A;\n\tFri, 25 Aug 2023 20:44:54 +0200 (CEST)",
            "from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com\n [67.231.156.173])\n by mails.dpdk.org (Postfix) with ESMTP id AE8AB4323A\n for <dev@dpdk.org>; Fri, 25 Aug 2023 20:44:52 +0200 (CEST)",
            "from pps.filterd (m0045851.ppops.net [127.0.0.1])\n by mx0b-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id\n 37PIAqmo002038; Fri, 25 Aug 2023 11:44:52 -0700",
            "from dc5-exch02.marvell.com ([199.233.59.182])\n by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3spmk2ag1v-1\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT);\n Fri, 25 Aug 2023 11:44:51 -0700",
            "from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH02.marvell.com\n (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.48;\n Fri, 25 Aug 2023 11:44:49 -0700",
            "from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com\n (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.48 via Frontend\n Transport; Fri, 25 Aug 2023 11:44:49 -0700",
            "from MININT-80QBFE8.corp.innovium.com (MININT-80QBFE8.marvell.com\n [10.28.164.106])\n by maili.marvell.com (Postfix) with ESMTP id EAA603F7095;\n Fri, 25 Aug 2023 11:44:43 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com;\n h=from : to : cc :\n subject : date : message-id : in-reply-to : references : mime-version :\n content-transfer-encoding : content-type; s=pfpt0220;\n bh=9jEt0eODXHyroPZcSDCNXU2tD7LvnnfOyCfGl6AtsMQ=;\n b=bAPiQ+xTR7qu+pj20RjFz/C7uhU+TFXdsY7j9fVUoSaTbg7jxO+1YWsKyYJsQIZ1Luoi\n IyZWhHlPzyVaSBl4FFK8yyH+XbfCV8HflWW06X/+EJeCXxy4y7+vRKhdiX86Sbo77h9c\n WIGbusOUnp596raGvASNFKLF8DCTn07aucH2GA3+QIq2haxsUUrqqQjfXOQrlQROPoq4\n alonjNrcOi3WUsPjSrZH+G4sdE2rnycMHm3UtrpTIWn94hUYhWO+uO/G0EfyWAOtrpwy\n cXpIf+GV6EQmU3QaAviC4bUpO23NuAIcSRnCEQemKFMfnLuiZHcQLGDRqr8ZWvjNUL6F Bw==",
        "From": "<pbhagavatula@marvell.com>",
        "To": "<jerinj@marvell.com>, <pbhagavatula@marvell.com>, <sthotton@marvell.com>,\n <timothy.mcdaniel@intel.com>, <hemant.agrawal@nxp.com>,\n <sachin.saxena@nxp.com>, <mattias.ronnblom@ericsson.com>,\n <liangma@liangbit.com>, <peter.mccarthy@intel.com>,\n <harry.van.haaren@intel.com>, <erik.g.carrillo@intel.com>,\n <abhinandan.gujjar@intel.com>, <s.v.naga.harish.k@intel.com>,\n <anatoly.burakov@intel.com>",
        "CC": "<dev@dpdk.org>",
        "Subject": "[PATCH 1/3] eventdev: introduce link profiles",
        "Date": "Sat, 26 Aug 2023 00:14:33 +0530",
        "Message-ID": "<20230825184435.2986-2-pbhagavatula@marvell.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20230825184435.2986-1-pbhagavatula@marvell.com>",
        "References": "<20230809142617.6482-1-pbhagavatula@marvell.com>\n <20230825184435.2986-1-pbhagavatula@marvell.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-Proofpoint-ORIG-GUID": "waRg2dDbbosAhYKuhXoIXNwrS7kLxzUA",
        "X-Proofpoint-GUID": "waRg2dDbbosAhYKuhXoIXNwrS7kLxzUA",
        "X-Proofpoint-Virus-Version": "vendor=baseguard\n engine=ICAP:2.0.267,Aquarius:18.0.957,Hydra:6.0.601,FMLib:17.11.176.26\n definitions=2023-08-25_16,2023-08-25_01,2023-05-22_02",
        "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": "From: Pavan Nikhilesh <pbhagavatula@marvell.com>\n\nA collection of event queues linked to an event port can be\nassociated with a unique identifier called as a profile, multiple\nsuch profiles can be created based on the event device capability\nusing the function `rte_event_port_profile_links_set` which takes\narguments similar to `rte_event_port_link` in addition to the profile\nidentifier.\n\nThe maximum link profiles that are supported by an event device\nis advertised through the structure member\n`rte_event_dev_info::max_profiles_per_port`.\nBy default, event ports are configured to use the link profile 0\non initialization.\n\nOnce multiple link profiles are set up and the event device is started,\nthe application can use the function `rte_event_port_profile_switch`\nto change the currently active profile on an event port. This effects\nthe next `rte_event_dequeue_burst` call, where the event queues\nassociated with the newly active link profile will participate in\nscheduling.\n\nAn unlink function `rte_event_port_profile_unlink` is provided\nto modify the links associated to a profile, and\n`rte_event_port_profile_links_get` can be used to retrieve the\nlinks associated with a profile.\n\nUsing Link profiles can reduce the overhead of linking/unlinking and\nwaiting for unlinks in progress in fast-path and gives applications\nthe ability to switch between preset profiles on the fly.\n\nSigned-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>\n---\n config/rte_config.h                        |   1 +\n doc/guides/eventdevs/features/default.ini  |   1 +\n doc/guides/prog_guide/eventdev.rst         |  40 ++++\n doc/guides/rel_notes/release_23_11.rst     |  17 ++\n drivers/event/cnxk/cnxk_eventdev.c         |   3 +-\n drivers/event/dlb2/dlb2.c                  |   1 +\n drivers/event/dpaa/dpaa_eventdev.c         |   1 +\n drivers/event/dpaa2/dpaa2_eventdev.c       |   2 +-\n drivers/event/dsw/dsw_evdev.c              |   1 +\n drivers/event/octeontx/ssovf_evdev.c       |   2 +-\n drivers/event/opdl/opdl_evdev.c            |   1 +\n drivers/event/skeleton/skeleton_eventdev.c |   1 +\n drivers/event/sw/sw_evdev.c                |   1 +\n lib/eventdev/eventdev_pmd.h                |  59 +++++-\n lib/eventdev/eventdev_private.c            |   9 +\n lib/eventdev/eventdev_trace.h              |  22 ++\n lib/eventdev/eventdev_trace_points.c       |   6 +\n lib/eventdev/rte_eventdev.c                | 146 ++++++++++---\n lib/eventdev/rte_eventdev.h                | 231 +++++++++++++++++++++\n lib/eventdev/rte_eventdev_core.h           |   4 +\n lib/eventdev/rte_eventdev_trace_fp.h       |   8 +\n lib/eventdev/version.map                   |   6 +\n 22 files changed, 533 insertions(+), 30 deletions(-)",
    "diff": "diff --git a/config/rte_config.h b/config/rte_config.h\nindex 400e44e3cf..d43b3eecb8 100644\n--- a/config/rte_config.h\n+++ b/config/rte_config.h\n@@ -73,6 +73,7 @@\n #define RTE_EVENT_MAX_DEVS 16\n #define RTE_EVENT_MAX_PORTS_PER_DEV 255\n #define RTE_EVENT_MAX_QUEUES_PER_DEV 255\n+#define RTE_EVENT_MAX_PROFILES_PER_PORT 8\n #define RTE_EVENT_TIMER_ADAPTER_NUM_MAX 32\n #define RTE_EVENT_ETH_INTR_RING_SIZE 1024\n #define RTE_EVENT_CRYPTO_ADAPTER_MAX_INSTANCE 32\ndiff --git a/doc/guides/eventdevs/features/default.ini b/doc/guides/eventdevs/features/default.ini\nindex 00360f60c6..1c0082352b 100644\n--- a/doc/guides/eventdevs/features/default.ini\n+++ b/doc/guides/eventdevs/features/default.ini\n@@ -18,6 +18,7 @@ multiple_queue_port        =\n carry_flow_id              =\n maintenance_free           =\n runtime_queue_attr         =\n+profile_links              =\n \n ;\n ; Features of a default Ethernet Rx adapter.\ndiff --git a/doc/guides/prog_guide/eventdev.rst b/doc/guides/prog_guide/eventdev.rst\nindex 2c83176846..9c07870a79 100644\n--- a/doc/guides/prog_guide/eventdev.rst\n+++ b/doc/guides/prog_guide/eventdev.rst\n@@ -317,6 +317,46 @@ can be achieved like this:\n         }\n         int links_made = rte_event_port_link(dev_id, tx_port_id, &single_link_q, &priority, 1);\n \n+Linking Queues to Ports with profiles\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+An application can use link profiles if supported by the underlying event device to setup up\n+multiple link profile per port and change them run time depending up on heuristic data.\n+Using Link profiles can reduce the overhead of linking/unlinking and wait for unlinks in progress\n+in fast-path and gives applications the ability to switch between preset profiles on the fly.\n+\n+An Example use case could be as follows.\n+\n+Config path:\n+\n+.. code-block:: c\n+\n+        uint8_t lq[4] = {4, 5, 6, 7};\n+        uint8_t hq[4] = {0, 1, 2, 3};\n+\n+        if (rte_event_dev_info.max_profiles_per_port < 2)\n+            return -ENOTSUP;\n+\n+        rte_event_port_profile_links_set(0, 0, hq, NULL, 4, 0);\n+        rte_event_port_profile_links_set(0, 0, lq, NULL, 4, 1);\n+\n+Worker path:\n+\n+.. code-block:: c\n+\n+        uint8_t profile_id_to_switch;\n+\n+        while (1) {\n+            deq = rte_event_dequeue_burst(0, 0, &ev, 1, 0);\n+            if (deq == 0) {\n+                profile_id_to_switch = app_findprofile_id_to_switch();\n+                rte_event_port_profile_switch(0, 0, profile_id_to_switch);\n+                continue;\n+            }\n+\n+            // Process the event received.\n+        }\n+\n Starting the EventDev\n ~~~~~~~~~~~~~~~~~~~~~\n \ndiff --git a/doc/guides/rel_notes/release_23_11.rst b/doc/guides/rel_notes/release_23_11.rst\nindex 333e1d95a2..e19a0ed3c3 100644\n--- a/doc/guides/rel_notes/release_23_11.rst\n+++ b/doc/guides/rel_notes/release_23_11.rst\n@@ -78,6 +78,23 @@ New Features\n * build: Optional libraries can now be selected with the new ``enable_libs``\n   build option similarly to the existing ``enable_drivers`` build option.\n \n+* **Added eventdev support to link queues to port with profile.**\n+\n+  Introduced event link profiles that can be used to associated links between\n+  event queues and an event port with a unique identifier termed as profile.\n+  The profile can be used to switch between the associated links in fast-path\n+  without the additional overhead of linking/unlinking and waiting for unlinking.\n+\n+  * Added ``rte_event_port_profile_links_set`` to link event queues to an event\n+    port with a unique profile identifier.\n+\n+  * Added ``rte_event_port_profile_unlink`` to unlink event queues from an event\n+    port associated with a profile.\n+\n+  * Added ``rte_event_port_profile_links_get`` to retrieve links associated to a\n+    profile.\n+\n+  * Added ``rte_event_port_profile_switch`` to switch between profiles as needed.\n \n Removed Items\n -------------\ndiff --git a/drivers/event/cnxk/cnxk_eventdev.c b/drivers/event/cnxk/cnxk_eventdev.c\nindex 27883a3619..529622cac6 100644\n--- a/drivers/event/cnxk/cnxk_eventdev.c\n+++ b/drivers/event/cnxk/cnxk_eventdev.c\n@@ -31,6 +31,7 @@ cnxk_sso_info_get(struct cnxk_sso_evdev *dev,\n \t\t\t\t  RTE_EVENT_DEV_CAP_CARRY_FLOW_ID |\n \t\t\t\t  RTE_EVENT_DEV_CAP_MAINTENANCE_FREE |\n \t\t\t\t  RTE_EVENT_DEV_CAP_RUNTIME_QUEUE_ATTR;\n+\tdev_info->max_profiles_per_port = 1;\n }\n \n int\n@@ -133,7 +134,7 @@ cnxk_sso_restore_links(const struct rte_eventdev *event_dev,\n \tfor (i = 0; i < dev->nb_event_ports; i++) {\n \t\tuint16_t nb_hwgrp = 0;\n \n-\t\tlinks_map = event_dev->data->links_map;\n+\t\tlinks_map = event_dev->data->links_map[0];\n \t\t/* Point links_map to this port specific area */\n \t\tlinks_map += (i * RTE_EVENT_MAX_QUEUES_PER_DEV);\n \ndiff --git a/drivers/event/dlb2/dlb2.c b/drivers/event/dlb2/dlb2.c\nindex 60c5cd4804..580057870f 100644\n--- a/drivers/event/dlb2/dlb2.c\n+++ b/drivers/event/dlb2/dlb2.c\n@@ -79,6 +79,7 @@ static struct rte_event_dev_info evdev_dlb2_default_info = {\n \t\t\t  RTE_EVENT_DEV_CAP_RUNTIME_PORT_LINK |\n \t\t\t  RTE_EVENT_DEV_CAP_MULTIPLE_QUEUE_PORT |\n \t\t\t  RTE_EVENT_DEV_CAP_MAINTENANCE_FREE),\n+\t.max_profiles_per_port = 1,\n };\n \n struct process_local_port_data\ndiff --git a/drivers/event/dpaa/dpaa_eventdev.c b/drivers/event/dpaa/dpaa_eventdev.c\nindex 4b3d16735b..f615da3813 100644\n--- a/drivers/event/dpaa/dpaa_eventdev.c\n+++ b/drivers/event/dpaa/dpaa_eventdev.c\n@@ -359,6 +359,7 @@ dpaa_event_dev_info_get(struct rte_eventdev *dev,\n \t\tRTE_EVENT_DEV_CAP_NONSEQ_MODE |\n \t\tRTE_EVENT_DEV_CAP_CARRY_FLOW_ID |\n \t\tRTE_EVENT_DEV_CAP_MAINTENANCE_FREE;\n+\tdev_info->max_profiles_per_port = 1;\n }\n \n static int\ndiff --git a/drivers/event/dpaa2/dpaa2_eventdev.c b/drivers/event/dpaa2/dpaa2_eventdev.c\nindex fa1a1ade80..ffc5550f85 100644\n--- a/drivers/event/dpaa2/dpaa2_eventdev.c\n+++ b/drivers/event/dpaa2/dpaa2_eventdev.c\n@@ -411,7 +411,7 @@ dpaa2_eventdev_info_get(struct rte_eventdev *dev,\n \t\tRTE_EVENT_DEV_CAP_QUEUE_ALL_TYPES |\n \t\tRTE_EVENT_DEV_CAP_CARRY_FLOW_ID |\n \t\tRTE_EVENT_DEV_CAP_MAINTENANCE_FREE;\n-\n+\tdev_info->max_profiles_per_port = 1;\n }\n \n static int\ndiff --git a/drivers/event/dsw/dsw_evdev.c b/drivers/event/dsw/dsw_evdev.c\nindex 6c5cde2468..785c12f61f 100644\n--- a/drivers/event/dsw/dsw_evdev.c\n+++ b/drivers/event/dsw/dsw_evdev.c\n@@ -218,6 +218,7 @@ dsw_info_get(struct rte_eventdev *dev __rte_unused,\n \t\t.max_event_port_dequeue_depth = DSW_MAX_PORT_DEQUEUE_DEPTH,\n \t\t.max_event_port_enqueue_depth = DSW_MAX_PORT_ENQUEUE_DEPTH,\n \t\t.max_num_events = DSW_MAX_EVENTS,\n+\t\t.max_profiles_per_port = 1,\n \t\t.event_dev_cap = RTE_EVENT_DEV_CAP_BURST_MODE|\n \t\tRTE_EVENT_DEV_CAP_DISTRIBUTED_SCHED|\n \t\tRTE_EVENT_DEV_CAP_NONSEQ_MODE|\ndiff --git a/drivers/event/octeontx/ssovf_evdev.c b/drivers/event/octeontx/ssovf_evdev.c\nindex 650266b996..0eb9358981 100644\n--- a/drivers/event/octeontx/ssovf_evdev.c\n+++ b/drivers/event/octeontx/ssovf_evdev.c\n@@ -158,7 +158,7 @@ ssovf_info_get(struct rte_eventdev *dev, struct rte_event_dev_info *dev_info)\n \t\t\t\t\tRTE_EVENT_DEV_CAP_NONSEQ_MODE |\n \t\t\t\t\tRTE_EVENT_DEV_CAP_CARRY_FLOW_ID |\n \t\t\t\t\tRTE_EVENT_DEV_CAP_MAINTENANCE_FREE;\n-\n+\tdev_info->max_profiles_per_port = 1;\n }\n \n static int\ndiff --git a/drivers/event/opdl/opdl_evdev.c b/drivers/event/opdl/opdl_evdev.c\nindex 9ce8b39b60..dd25749654 100644\n--- a/drivers/event/opdl/opdl_evdev.c\n+++ b/drivers/event/opdl/opdl_evdev.c\n@@ -378,6 +378,7 @@ opdl_info_get(struct rte_eventdev *dev, struct rte_event_dev_info *info)\n \t\t.event_dev_cap = RTE_EVENT_DEV_CAP_BURST_MODE |\n \t\t\t\t RTE_EVENT_DEV_CAP_CARRY_FLOW_ID |\n \t\t\t\t RTE_EVENT_DEV_CAP_MAINTENANCE_FREE,\n+\t\t.max_profiles_per_port = 1,\n \t};\n \n \t*info = evdev_opdl_info;\ndiff --git a/drivers/event/skeleton/skeleton_eventdev.c b/drivers/event/skeleton/skeleton_eventdev.c\nindex 8513b9a013..dc9b131641 100644\n--- a/drivers/event/skeleton/skeleton_eventdev.c\n+++ b/drivers/event/skeleton/skeleton_eventdev.c\n@@ -104,6 +104,7 @@ skeleton_eventdev_info_get(struct rte_eventdev *dev,\n \t\t\t\t\tRTE_EVENT_DEV_CAP_EVENT_QOS |\n \t\t\t\t\tRTE_EVENT_DEV_CAP_CARRY_FLOW_ID |\n \t\t\t\t\tRTE_EVENT_DEV_CAP_MAINTENANCE_FREE;\n+\tdev_info->max_profiles_per_port = 1;\n }\n \n static int\ndiff --git a/drivers/event/sw/sw_evdev.c b/drivers/event/sw/sw_evdev.c\nindex cfd659d774..6d1816b76d 100644\n--- a/drivers/event/sw/sw_evdev.c\n+++ b/drivers/event/sw/sw_evdev.c\n@@ -609,6 +609,7 @@ sw_info_get(struct rte_eventdev *dev, struct rte_event_dev_info *info)\n \t\t\t\tRTE_EVENT_DEV_CAP_NONSEQ_MODE |\n \t\t\t\tRTE_EVENT_DEV_CAP_CARRY_FLOW_ID |\n \t\t\t\tRTE_EVENT_DEV_CAP_MAINTENANCE_FREE),\n+\t\t\t.max_profiles_per_port = 1,\n \t};\n \n \t*info = evdev_sw_info;\ndiff --git a/lib/eventdev/eventdev_pmd.h b/lib/eventdev/eventdev_pmd.h\nindex f62f42e140..66fdad71f3 100644\n--- a/lib/eventdev/eventdev_pmd.h\n+++ b/lib/eventdev/eventdev_pmd.h\n@@ -119,8 +119,8 @@ struct rte_eventdev_data {\n \t/**< Array of port configuration structures. */\n \tstruct rte_event_queue_conf queues_cfg[RTE_EVENT_MAX_QUEUES_PER_DEV];\n \t/**< Array of queue configuration structures. */\n-\tuint16_t links_map[RTE_EVENT_MAX_PORTS_PER_DEV *\n-\t\t\t   RTE_EVENT_MAX_QUEUES_PER_DEV];\n+\tuint16_t links_map[RTE_EVENT_MAX_PROFILES_PER_PORT]\n+\t\t\t  [RTE_EVENT_MAX_PORTS_PER_DEV * RTE_EVENT_MAX_QUEUES_PER_DEV];\n \t/**< Memory to store queues to port connections. */\n \tvoid *dev_private;\n \t/**< PMD-specific private data */\n@@ -178,6 +178,9 @@ struct rte_eventdev {\n \tevent_tx_adapter_enqueue_t txa_enqueue;\n \t/**< Pointer to PMD eth Tx adapter enqueue function. */\n \tevent_crypto_adapter_enqueue_t ca_enqueue;\n+\t/**< PMD Crypto adapter enqueue function. */\n+\tevent_profile_switch_t profile_switch;\n+\t/**< PMD Event switch profile function. */\n \n \tuint64_t reserved_64s[4]; /**< Reserved for future fields */\n \tvoid *reserved_ptrs[3];\t  /**< Reserved for future fields */\n@@ -437,6 +440,32 @@ typedef int (*eventdev_port_link_t)(struct rte_eventdev *dev, void *port,\n \t\tconst uint8_t queues[], const uint8_t priorities[],\n \t\tuint16_t nb_links);\n \n+/**\n+ * Link multiple source event queues associated with a profile to a destination\n+ * event port.\n+ *\n+ * @param dev\n+ *   Event device pointer\n+ * @param port\n+ *   Event port pointer\n+ * @param queues\n+ *   Points to an array of *nb_links* event queues to be linked\n+ *   to the event port.\n+ * @param priorities\n+ *   Points to an array of *nb_links* service priorities associated with each\n+ *   event queue link to event port.\n+ * @param nb_links\n+ *   The number of links to establish.\n+ * @param profile\n+ *   The profile ID to associate the links.\n+ *\n+ * @return\n+ *   Returns 0 on success.\n+ */\n+typedef int (*eventdev_port_link_profile_t)(struct rte_eventdev *dev, void *port,\n+\t\t\t\t\t    const uint8_t queues[], const uint8_t priorities[],\n+\t\t\t\t\t    uint16_t nb_links, uint8_t profile);\n+\n /**\n  * Unlink multiple source event queues from destination event port.\n  *\n@@ -455,6 +484,28 @@ typedef int (*eventdev_port_link_t)(struct rte_eventdev *dev, void *port,\n typedef int (*eventdev_port_unlink_t)(struct rte_eventdev *dev, void *port,\n \t\tuint8_t queues[], uint16_t nb_unlinks);\n \n+/**\n+ * Unlink multiple source event queues associated with a profile from destination\n+ * event port.\n+ *\n+ * @param dev\n+ *   Event device pointer\n+ * @param port\n+ *   Event port pointer\n+ * @param queues\n+ *   An array of *nb_unlinks* event queues to be unlinked from the event port.\n+ * @param nb_unlinks\n+ *   The number of unlinks to establish\n+ * @param profile\n+ *   The profile ID of the associated links.\n+ *\n+ * @return\n+ *   Returns 0 on success.\n+ */\n+typedef int (*eventdev_port_unlink_profile_t)(struct rte_eventdev *dev, void *port,\n+\t\t\t\t\t      uint8_t queues[], uint16_t nb_unlinks,\n+\t\t\t\t\t      uint8_t profile);\n+\n /**\n  * Unlinks in progress. Returns number of unlinks that the PMD is currently\n  * performing, but have not yet been completed.\n@@ -1348,8 +1399,12 @@ struct eventdev_ops {\n \n \teventdev_port_link_t port_link;\n \t/**< Link event queues to an event port. */\n+\teventdev_port_link_profile_t port_link_profile;\n+\t/**< Link event queues associated with a profile to an event port. */\n \teventdev_port_unlink_t port_unlink;\n \t/**< Unlink event queues from an event port. */\n+\teventdev_port_unlink_profile_t port_unlink_profile;\n+\t/**< Unlink event queues associated with a profile from an event port. */\n \teventdev_port_unlinks_in_progress_t port_unlinks_in_progress;\n \t/**< Unlinks in progress on an event port. */\n \teventdev_dequeue_timeout_ticks_t timeout_ticks;\ndiff --git a/lib/eventdev/eventdev_private.c b/lib/eventdev/eventdev_private.c\nindex 1d3d9d357e..a5e0bd3de0 100644\n--- a/lib/eventdev/eventdev_private.c\n+++ b/lib/eventdev/eventdev_private.c\n@@ -81,6 +81,13 @@ dummy_event_crypto_adapter_enqueue(__rte_unused void *port,\n \treturn 0;\n }\n \n+static int\n+dummy_event_port_profile_switch(__rte_unused void *port, __rte_unused uint8_t profile)\n+{\n+\tRTE_EDEV_LOG_ERR(\"change profile requested for unconfigured event device\");\n+\treturn -EINVAL;\n+}\n+\n void\n event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op)\n {\n@@ -97,6 +104,7 @@ event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op)\n \t\t.txa_enqueue_same_dest =\n \t\t\tdummy_event_tx_adapter_enqueue_same_dest,\n \t\t.ca_enqueue = dummy_event_crypto_adapter_enqueue,\n+\t\t.profile_switch = dummy_event_port_profile_switch,\n \t\t.data = dummy_data,\n \t};\n \n@@ -117,5 +125,6 @@ event_dev_fp_ops_set(struct rte_event_fp_ops *fp_op,\n \tfp_op->txa_enqueue = dev->txa_enqueue;\n \tfp_op->txa_enqueue_same_dest = dev->txa_enqueue_same_dest;\n \tfp_op->ca_enqueue = dev->ca_enqueue;\n+\tfp_op->profile_switch = dev->profile_switch;\n \tfp_op->data = dev->data->ports;\n }\ndiff --git a/lib/eventdev/eventdev_trace.h b/lib/eventdev/eventdev_trace.h\nindex f008ef0091..7b89b8d53f 100644\n--- a/lib/eventdev/eventdev_trace.h\n+++ b/lib/eventdev/eventdev_trace.h\n@@ -76,6 +76,17 @@ RTE_TRACE_POINT(\n \trte_trace_point_emit_int(rc);\n )\n \n+RTE_TRACE_POINT(\n+\trte_eventdev_trace_port_link_with_profile,\n+\tRTE_TRACE_POINT_ARGS(uint8_t dev_id, uint8_t port_id,\n+\t\tuint16_t nb_links, uint8_t profile, int rc),\n+\trte_trace_point_emit_u8(dev_id);\n+\trte_trace_point_emit_u8(port_id);\n+\trte_trace_point_emit_u16(nb_links);\n+\trte_trace_point_emit_u8(profile);\n+\trte_trace_point_emit_int(rc);\n+)\n+\n RTE_TRACE_POINT(\n \trte_eventdev_trace_port_unlink,\n \tRTE_TRACE_POINT_ARGS(uint8_t dev_id, uint8_t port_id,\n@@ -86,6 +97,17 @@ RTE_TRACE_POINT(\n \trte_trace_point_emit_int(rc);\n )\n \n+RTE_TRACE_POINT(\n+\trte_eventdev_trace_port_unlink_with_profile,\n+\tRTE_TRACE_POINT_ARGS(uint8_t dev_id, uint8_t port_id,\n+\t\tuint16_t nb_unlinks, uint8_t profile, int rc),\n+\trte_trace_point_emit_u8(dev_id);\n+\trte_trace_point_emit_u8(port_id);\n+\trte_trace_point_emit_u16(nb_unlinks);\n+\trte_trace_point_emit_u8(profile);\n+\trte_trace_point_emit_int(rc);\n+)\n+\n RTE_TRACE_POINT(\n \trte_eventdev_trace_start,\n \tRTE_TRACE_POINT_ARGS(uint8_t dev_id, int rc),\ndiff --git a/lib/eventdev/eventdev_trace_points.c b/lib/eventdev/eventdev_trace_points.c\nindex 76144cfe75..cfde20b2a8 100644\n--- a/lib/eventdev/eventdev_trace_points.c\n+++ b/lib/eventdev/eventdev_trace_points.c\n@@ -19,9 +19,15 @@ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_setup,\n RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_link,\n \tlib.eventdev.port.link)\n \n+RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_link_with_profile,\n+\t\t\t lib.eventdev.port.link_with_profile)\n+\n RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_unlink,\n \tlib.eventdev.port.unlink)\n \n+RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_unlink_with_profile,\n+\t\t\t lib.eventdev.port.unlink_with_profile)\n+\n RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_start,\n \tlib.eventdev.start)\n \ndiff --git a/lib/eventdev/rte_eventdev.c b/lib/eventdev/rte_eventdev.c\nindex 6ab4524332..2171d131ad 100644\n--- a/lib/eventdev/rte_eventdev.c\n+++ b/lib/eventdev/rte_eventdev.c\n@@ -270,7 +270,7 @@ event_dev_port_config(struct rte_eventdev *dev, uint8_t nb_ports)\n \tvoid **ports;\n \tuint16_t *links_map;\n \tstruct rte_event_port_conf *ports_cfg;\n-\tunsigned int i;\n+\tunsigned int i, j;\n \n \tRTE_EDEV_LOG_DEBUG(\"Setup %d ports on device %u\", nb_ports,\n \t\t\t dev->data->dev_id);\n@@ -281,7 +281,6 @@ event_dev_port_config(struct rte_eventdev *dev, uint8_t nb_ports)\n \n \t\tports = dev->data->ports;\n \t\tports_cfg = dev->data->ports_cfg;\n-\t\tlinks_map = dev->data->links_map;\n \n \t\tfor (i = nb_ports; i < old_nb_ports; i++)\n \t\t\t(*dev->dev_ops->port_release)(ports[i]);\n@@ -297,9 +296,11 @@ event_dev_port_config(struct rte_eventdev *dev, uint8_t nb_ports)\n \t\t\t\tsizeof(ports[0]) * new_ps);\n \t\t\tmemset(ports_cfg + old_nb_ports, 0,\n \t\t\t\tsizeof(ports_cfg[0]) * new_ps);\n-\t\t\tfor (i = old_links_map_end; i < links_map_end; i++)\n-\t\t\t\tlinks_map[i] =\n-\t\t\t\t\tEVENT_QUEUE_SERVICE_PRIORITY_INVALID;\n+\t\t\tfor (i = 0; i < RTE_EVENT_MAX_PROFILES_PER_PORT; i++) {\n+\t\t\t\tlinks_map = dev->data->links_map[i];\n+\t\t\t\tfor (j = old_links_map_end; j < links_map_end; j++)\n+\t\t\t\t\tlinks_map[j] = EVENT_QUEUE_SERVICE_PRIORITY_INVALID;\n+\t\t\t}\n \t\t}\n \t} else {\n \t\tif (*dev->dev_ops->port_release == NULL)\n@@ -953,21 +954,44 @@ rte_event_port_link(uint8_t dev_id, uint8_t port_id,\n \t\t    const uint8_t queues[], const uint8_t priorities[],\n \t\t    uint16_t nb_links)\n {\n-\tstruct rte_eventdev *dev;\n-\tuint8_t queues_list[RTE_EVENT_MAX_QUEUES_PER_DEV];\n+\treturn rte_event_port_profile_links_set(dev_id, port_id, queues, priorities, nb_links, 0);\n+}\n+\n+int\n+rte_event_port_profile_links_set(uint8_t dev_id, uint8_t port_id, const uint8_t queues[],\n+\t\t\t\t const uint8_t priorities[], uint16_t nb_links, uint8_t profile)\n+{\n \tuint8_t priorities_list[RTE_EVENT_MAX_QUEUES_PER_DEV];\n+\tuint8_t queues_list[RTE_EVENT_MAX_QUEUES_PER_DEV];\n+\tstruct rte_event_dev_info info;\n+\tstruct rte_eventdev *dev;\n \tuint16_t *links_map;\n \tint i, diag;\n \n \tRTE_EVENTDEV_VALID_DEVID_OR_ERRNO_RET(dev_id, EINVAL, 0);\n \tdev = &rte_eventdevs[dev_id];\n \n+\tif (*dev->dev_ops->dev_infos_get == NULL)\n+\t\treturn -ENOTSUP;\n+\n+\t(*dev->dev_ops->dev_infos_get)(dev, &info);\n+\tif (profile >= RTE_EVENT_MAX_PROFILES_PER_PORT || profile >= info.max_profiles_per_port) {\n+\t\tRTE_EDEV_LOG_ERR(\"Invalid profile=%\" PRIu8, profile);\n+\t\treturn -EINVAL;\n+\t}\n+\n \tif (*dev->dev_ops->port_link == NULL) {\n \t\tRTE_EDEV_LOG_ERR(\"Function not supported\\n\");\n \t\trte_errno = ENOTSUP;\n \t\treturn 0;\n \t}\n \n+\tif (profile && *dev->dev_ops->port_link_profile == NULL) {\n+\t\tRTE_EDEV_LOG_ERR(\"Function not supported\\n\");\n+\t\trte_errno = ENOTSUP;\n+\t\treturn 0;\n+\t}\n+\n \tif (!is_valid_port(dev, port_id)) {\n \t\tRTE_EDEV_LOG_ERR(\"Invalid port_id=%\" PRIu8, port_id);\n \t\trte_errno = EINVAL;\n@@ -995,18 +1019,22 @@ rte_event_port_link(uint8_t dev_id, uint8_t port_id,\n \t\t\treturn 0;\n \t\t}\n \n-\tdiag = (*dev->dev_ops->port_link)(dev, dev->data->ports[port_id],\n-\t\t\t\t\t\tqueues, priorities, nb_links);\n+\tif (profile)\n+\t\tdiag = (*dev->dev_ops->port_link_profile)(dev, dev->data->ports[port_id], queues,\n+\t\t\t\t\t\t\t  priorities, nb_links, profile);\n+\telse\n+\t\tdiag = (*dev->dev_ops->port_link)(dev, dev->data->ports[port_id], queues,\n+\t\t\t\t\t\t  priorities, nb_links);\n \tif (diag < 0)\n \t\treturn diag;\n \n-\tlinks_map = dev->data->links_map;\n+\tlinks_map = dev->data->links_map[profile];\n \t/* Point links_map to this port specific area */\n \tlinks_map += (port_id * RTE_EVENT_MAX_QUEUES_PER_DEV);\n \tfor (i = 0; i < diag; i++)\n \t\tlinks_map[queues[i]] = (uint8_t)priorities[i];\n \n-\trte_eventdev_trace_port_link(dev_id, port_id, nb_links, diag);\n+\trte_eventdev_trace_port_link_with_profile(dev_id, port_id, nb_links, profile, diag);\n \treturn diag;\n }\n \n@@ -1014,27 +1042,50 @@ int\n rte_event_port_unlink(uint8_t dev_id, uint8_t port_id,\n \t\t      uint8_t queues[], uint16_t nb_unlinks)\n {\n-\tstruct rte_eventdev *dev;\n+\treturn rte_event_port_profile_unlink(dev_id, port_id, queues, nb_unlinks, 0);\n+}\n+\n+int\n+rte_event_port_profile_unlink(uint8_t dev_id, uint8_t port_id, uint8_t queues[],\n+\t\t\t      uint16_t nb_unlinks, uint8_t profile)\n+{\n \tuint8_t all_queues[RTE_EVENT_MAX_QUEUES_PER_DEV];\n-\tint i, diag, j;\n+\tstruct rte_event_dev_info info;\n+\tstruct rte_eventdev *dev;\n \tuint16_t *links_map;\n+\tint i, diag, j;\n \n \tRTE_EVENTDEV_VALID_DEVID_OR_ERRNO_RET(dev_id, EINVAL, 0);\n \tdev = &rte_eventdevs[dev_id];\n \n+\tif (*dev->dev_ops->dev_infos_get == NULL)\n+\t\treturn -ENOTSUP;\n+\n+\t(*dev->dev_ops->dev_infos_get)(dev, &info);\n+\tif (profile >= RTE_EVENT_MAX_PROFILES_PER_PORT || profile >= info.max_profiles_per_port) {\n+\t\tRTE_EDEV_LOG_ERR(\"Invalid profile=%\" PRIu8, profile);\n+\t\treturn -EINVAL;\n+\t}\n+\n \tif (*dev->dev_ops->port_unlink == NULL) {\n \t\tRTE_EDEV_LOG_ERR(\"Function not supported\");\n \t\trte_errno = ENOTSUP;\n \t\treturn 0;\n \t}\n \n+\tif (profile && *dev->dev_ops->port_unlink_profile == NULL) {\n+\t\tRTE_EDEV_LOG_ERR(\"Function not supported\");\n+\t\trte_errno = ENOTSUP;\n+\t\treturn 0;\n+\t}\n+\n \tif (!is_valid_port(dev, port_id)) {\n \t\tRTE_EDEV_LOG_ERR(\"Invalid port_id=%\" PRIu8, port_id);\n \t\trte_errno = EINVAL;\n \t\treturn 0;\n \t}\n \n-\tlinks_map = dev->data->links_map;\n+\tlinks_map = dev->data->links_map[profile];\n \t/* Point links_map to this port specific area */\n \tlinks_map += (port_id * RTE_EVENT_MAX_QUEUES_PER_DEV);\n \n@@ -1063,16 +1114,19 @@ rte_event_port_unlink(uint8_t dev_id, uint8_t port_id,\n \t\t\treturn 0;\n \t\t}\n \n-\tdiag = (*dev->dev_ops->port_unlink)(dev, dev->data->ports[port_id],\n-\t\t\t\t\tqueues, nb_unlinks);\n-\n+\tif (profile)\n+\t\tdiag = (*dev->dev_ops->port_unlink_profile)(dev, dev->data->ports[port_id], queues,\n+\t\t\t\t\t\t\t    nb_unlinks, profile);\n+\telse\n+\t\tdiag = (*dev->dev_ops->port_unlink)(dev, dev->data->ports[port_id], queues,\n+\t\t\t\t\t\t    nb_unlinks);\n \tif (diag < 0)\n \t\treturn diag;\n \n \tfor (i = 0; i < diag; i++)\n \t\tlinks_map[queues[i]] = EVENT_QUEUE_SERVICE_PRIORITY_INVALID;\n \n-\trte_eventdev_trace_port_unlink(dev_id, port_id, nb_unlinks, diag);\n+\trte_eventdev_trace_port_unlink_with_profile(dev_id, port_id, nb_unlinks, profile, diag);\n \treturn diag;\n }\n \n@@ -1116,7 +1170,50 @@ rte_event_port_links_get(uint8_t dev_id, uint8_t port_id,\n \t\treturn -EINVAL;\n \t}\n \n-\tlinks_map = dev->data->links_map;\n+\t/* Use the default profile. */\n+\tlinks_map = dev->data->links_map[0];\n+\t/* Point links_map to this port specific area */\n+\tlinks_map += (port_id * RTE_EVENT_MAX_QUEUES_PER_DEV);\n+\tfor (i = 0; i < dev->data->nb_queues; i++) {\n+\t\tif (links_map[i] != EVENT_QUEUE_SERVICE_PRIORITY_INVALID) {\n+\t\t\tqueues[count] = i;\n+\t\t\tpriorities[count] = (uint8_t)links_map[i];\n+\t\t\t++count;\n+\t\t}\n+\t}\n+\n+\trte_eventdev_trace_port_links_get(dev_id, port_id, count);\n+\n+\treturn count;\n+}\n+\n+int\n+rte_event_port_profile_links_get(uint8_t dev_id, uint8_t port_id, uint8_t queues[],\n+\t\t\t\t uint8_t priorities[], uint8_t profile)\n+{\n+\tstruct rte_event_dev_info info;\n+\tstruct rte_eventdev *dev;\n+\tuint16_t *links_map;\n+\tint i, count = 0;\n+\n+\tRTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);\n+\n+\tdev = &rte_eventdevs[dev_id];\n+\tif (*dev->dev_ops->dev_infos_get == NULL)\n+\t\treturn -ENOTSUP;\n+\n+\t(*dev->dev_ops->dev_infos_get)(dev, &info);\n+\tif (profile >= RTE_EVENT_MAX_PROFILES_PER_PORT || profile >= info.max_profiles_per_port) {\n+\t\tRTE_EDEV_LOG_ERR(\"Invalid profile=%\" PRIu8, profile);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (!is_valid_port(dev, port_id)) {\n+\t\tRTE_EDEV_LOG_ERR(\"Invalid port_id=%\" PRIu8, port_id);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tlinks_map = dev->data->links_map[profile];\n \t/* Point links_map to this port specific area */\n \tlinks_map += (port_id * RTE_EVENT_MAX_QUEUES_PER_DEV);\n \tfor (i = 0; i < dev->data->nb_queues; i++) {\n@@ -1440,7 +1537,7 @@ eventdev_data_alloc(uint8_t dev_id, struct rte_eventdev_data **data,\n {\n \tchar mz_name[RTE_EVENTDEV_NAME_MAX_LEN];\n \tconst struct rte_memzone *mz;\n-\tint n;\n+\tint i, n;\n \n \t/* Generate memzone name */\n \tn = snprintf(mz_name, sizeof(mz_name), \"rte_eventdev_data_%u\", dev_id);\n@@ -1460,11 +1557,10 @@ eventdev_data_alloc(uint8_t dev_id, struct rte_eventdev_data **data,\n \t*data = mz->addr;\n \tif (rte_eal_process_type() == RTE_PROC_PRIMARY) {\n \t\tmemset(*data, 0, sizeof(struct rte_eventdev_data));\n-\t\tfor (n = 0; n < RTE_EVENT_MAX_PORTS_PER_DEV *\n-\t\t\t\t\tRTE_EVENT_MAX_QUEUES_PER_DEV;\n-\t\t     n++)\n-\t\t\t(*data)->links_map[n] =\n-\t\t\t\tEVENT_QUEUE_SERVICE_PRIORITY_INVALID;\n+\t\tfor (i = 0; i < RTE_EVENT_MAX_PROFILES_PER_PORT; i++)\n+\t\t\tfor (n = 0; n < RTE_EVENT_MAX_PORTS_PER_DEV * RTE_EVENT_MAX_QUEUES_PER_DEV;\n+\t\t\t     n++)\n+\t\t\t\t(*data)->links_map[i][n] = EVENT_QUEUE_SERVICE_PRIORITY_INVALID;\n \t}\n \n \treturn 0;\ndiff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h\nindex 2ba8a7b090..7a169de067 100644\n--- a/lib/eventdev/rte_eventdev.h\n+++ b/lib/eventdev/rte_eventdev.h\n@@ -320,6 +320,12 @@ struct rte_event;\n  * rte_event_queue_setup().\n  */\n \n+#define RTE_EVENT_DEV_CAP_PROFILE_LINK (1ULL << 12)\n+/** Event device is capable of supporting multiple link profiles per event port\n+ * i.e., the value of `rte_event_dev_info::max_profiles_per_port` is greater\n+ * than one.\n+ */\n+\n /* Event device priority levels */\n #define RTE_EVENT_DEV_PRIORITY_HIGHEST   0\n /**< Highest priority expressed across eventdev subsystem\n@@ -446,6 +452,10 @@ struct rte_event_dev_info {\n \t * device. These ports and queues are not accounted for in\n \t * max_event_ports or max_event_queues.\n \t */\n+\tuint8_t max_profiles_per_port;\n+\t/**< Maximum number of event queue profiles per event port.\n+\t * A device that doesn't support multiple profiles will set this as 1.\n+\t */\n };\n \n /**\n@@ -1536,6 +1546,10 @@ rte_event_dequeue_timeout_ticks(uint8_t dev_id, uint64_t ns,\n  * latency of critical work by establishing the link with more event ports\n  * at runtime.\n  *\n+ * When the value of ``rte_event_dev_info::max_profiles_per_port`` is greater\n+ * than or equal to one, this function links the event queues to the default\n+ * profile i.e. profile 0 of the event port.\n+ *\n  * @param dev_id\n  *   The identifier of the device.\n  *\n@@ -1593,6 +1607,10 @@ rte_event_port_link(uint8_t dev_id, uint8_t port_id,\n  * Event queue(s) to event port unlink establishment can be changed at runtime\n  * without re-configuring the device.\n  *\n+ * When the value of ``rte_event_dev_info::max_profiles_per_port`` is greater\n+ * than or equal to one, this function unlinks the event queues from the default\n+ * profile i.e. profile 0 of the event port.\n+ *\n  * @see rte_event_port_unlinks_in_progress() to poll for completed unlinks.\n  *\n  * @param dev_id\n@@ -1626,6 +1644,136 @@ int\n rte_event_port_unlink(uint8_t dev_id, uint8_t port_id,\n \t\t      uint8_t queues[], uint16_t nb_unlinks);\n \n+/**\n+ * Link multiple source event queues supplied in *queues* to the destination\n+ * event port designated by its *port_id* with associated profile identifier\n+ * supplied in *profile* with service priorities supplied in *priorities* on\n+ * the event device designated by its *dev_id*.\n+ *\n+ * If *profile* is set to 0 then, the links created by the call `rte_event_port_link`\n+ * will be overwritten.\n+ *\n+ * Event ports by default use profile 0 unless it is changed using the\n+ * call ``rte_event_port_profile_switch()``.\n+ *\n+ * The link establishment shall enable the event port *port_id* from\n+ * receiving events from the specified event queue(s) supplied in *queues*\n+ *\n+ * An event queue may link to one or more event ports.\n+ * The number of links can be established from an event queue to event port is\n+ * implementation defined.\n+ *\n+ * Event queue(s) to event port link establishment can be changed at runtime\n+ * without re-configuring the device to support scaling and to reduce the\n+ * latency of critical work by establishing the link with more event ports\n+ * at runtime.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ *\n+ * @param port_id\n+ *   Event port identifier to select the destination port to link.\n+ *\n+ * @param queues\n+ *   Points to an array of *nb_links* event queues to be linked\n+ *   to the event port.\n+ *   NULL value is allowed, in which case this function links all the configured\n+ *   event queues *nb_event_queues* which previously supplied to\n+ *   rte_event_dev_configure() to the event port *port_id*\n+ *\n+ * @param priorities\n+ *   Points to an array of *nb_links* service priorities associated with each\n+ *   event queue link to event port.\n+ *   The priority defines the event port's servicing priority for\n+ *   event queue, which may be ignored by an implementation.\n+ *   The requested priority should in the range of\n+ *   [RTE_EVENT_DEV_PRIORITY_HIGHEST, RTE_EVENT_DEV_PRIORITY_LOWEST].\n+ *   The implementation shall normalize the requested priority to\n+ *   implementation supported priority value.\n+ *   NULL value is allowed, in which case this function links the event queues\n+ *   with RTE_EVENT_DEV_PRIORITY_NORMAL servicing priority\n+ *\n+ * @param nb_links\n+ *   The number of links to establish. This parameter is ignored if queues is\n+ *   NULL.\n+ *\n+ * @param profile\n+ *   The profile identifier associated with the links between event queues and\n+ *   event port. Should be less than the max capability reported by\n+ *   ``rte_event_dev_info::max_profiles_per_port``\n+ *\n+ * @return\n+ * The number of links actually established. The return value can be less than\n+ * the value of the *nb_links* parameter when the implementation has the\n+ * limitation on specific queue to port link establishment or if invalid\n+ * parameters are specified in *queues*\n+ * If the return value is less than *nb_links*, the remaining links at the end\n+ * of link[] are not established, and the caller has to take care of them.\n+ * If return value is less than *nb_links* then implementation shall update the\n+ * rte_errno accordingly, Possible rte_errno values are\n+ * (EDQUOT) Quota exceeded(Application tried to link the queue configured with\n+ *  RTE_EVENT_QUEUE_CFG_SINGLE_LINK to more than one event ports)\n+ * (EINVAL) Invalid parameter\n+ *\n+ */\n+__rte_experimental\n+int\n+rte_event_port_profile_links_set(uint8_t dev_id, uint8_t port_id, const uint8_t queues[],\n+\t\t\t\t const uint8_t priorities[], uint16_t nb_links, uint8_t profile);\n+\n+/**\n+ * Unlink multiple source event queues supplied in *queues* that belong to profile\n+ * designated by *profile* from the destination event port designated by its\n+ * *port_id* on the event device designated by its *dev_id*.\n+ *\n+ * If *profile* is set to 0 i.e., the default profile then, then this function will\n+ * act as ``rte_event_port_unlink``.\n+ *\n+ * The unlink call issues an async request to disable the event port *port_id*\n+ * from receiving events from the specified event queue *queue_id*.\n+ * Event queue(s) to event port unlink establishment can be changed at runtime\n+ * without re-configuring the device.\n+ *\n+ * @see rte_event_port_unlinks_in_progress() to poll for completed unlinks.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ *\n+ * @param port_id\n+ *   Event port identifier to select the destination port to unlink.\n+ *\n+ * @param queues\n+ *   Points to an array of *nb_unlinks* event queues to be unlinked\n+ *   from the event port.\n+ *   NULL value is allowed, in which case this function unlinks all the\n+ *   event queue(s) from the event port *port_id*.\n+ *\n+ * @param nb_unlinks\n+ *   The number of unlinks to establish. This parameter is ignored if queues is\n+ *   NULL.\n+ *\n+ * @param profile\n+ *   The profile identifier associated with the links between event queues and\n+ *   event port. Should be less than the max capability reported by\n+ *   ``rte_event_dev_info::max_profiles_per_port``\n+ *\n+ * @return\n+ * The number of unlinks successfully requested. The return value can be less\n+ * than the value of the *nb_unlinks* parameter when the implementation has the\n+ * limitation on specific queue to port unlink establishment or\n+ * if invalid parameters are specified.\n+ * If the return value is less than *nb_unlinks*, the remaining queues at the\n+ * end of queues[] are not unlinked, and the caller has to take care of them.\n+ * If return value is less than *nb_unlinks* then implementation shall update\n+ * the rte_errno accordingly, Possible rte_errno values are\n+ * (EINVAL) Invalid parameter\n+ *\n+ */\n+__rte_experimental\n+int\n+rte_event_port_profile_unlink(uint8_t dev_id, uint8_t port_id, uint8_t queues[],\n+\t\t\t      uint16_t nb_unlinks, uint8_t profile);\n+\n /**\n  * Returns the number of unlinks in progress.\n  *\n@@ -1680,6 +1828,42 @@ int\n rte_event_port_links_get(uint8_t dev_id, uint8_t port_id,\n \t\t\t uint8_t queues[], uint8_t priorities[]);\n \n+/**\n+ * Retrieve the list of source event queues and its service priority\n+ * associated to a profile and linked to the destination event port\n+ * designated by its *port_id* on the event device designated by its *dev_id*.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ *\n+ * @param port_id\n+ *   Event port identifier.\n+ *\n+ * @param[out] queues\n+ *   Points to an array of *queues* for output.\n+ *   The caller has to allocate *RTE_EVENT_MAX_QUEUES_PER_DEV* bytes to\n+ *   store the event queue(s) linked with event port *port_id*\n+ *\n+ * @param[out] priorities\n+ *   Points to an array of *priorities* for output.\n+ *   The caller has to allocate *RTE_EVENT_MAX_QUEUES_PER_DEV* bytes to\n+ *   store the service priority associated with each event queue linked\n+ *\n+ * @param profile\n+ *   The profile identifier associated with the links between event queues and\n+ *   event port. Should be less than the max capability reported by\n+ *   ``rte_event_dev_info::max_profiles_per_port``\n+ *\n+ * @return\n+ * The number of links established on the event port designated by its\n+ *  *port_id*.\n+ * - <0 on failure.\n+ */\n+__rte_experimental\n+int\n+rte_event_port_profile_links_get(uint8_t dev_id, uint8_t port_id, uint8_t queues[],\n+\t\t\t\t uint8_t priorities[], uint8_t profile);\n+\n /**\n  * Retrieve the service ID of the event dev. If the adapter doesn't use\n  * a rte_service function, this function returns -ESRCH.\n@@ -2265,6 +2449,53 @@ rte_event_maintain(uint8_t dev_id, uint8_t port_id, int op)\n \treturn 0;\n }\n \n+/**\n+ * Change the active profile on an event port.\n+ *\n+ * This function is used to change the current active profile on an event port\n+ * when multiple link profiles are configured on an event port through the\n+ * function call ``rte_event_port_profile_links_set``.\n+ *\n+ * On the subsequent ``rte_event_dequeue_burst`` call, only the event queues\n+ * that were associated with the newly active profile will participate in\n+ * scheduling.\n+ *\n+ * @param dev_id\n+ *   The identifier of the device.\n+ * @param port_id\n+ *   The identifier of the event port.\n+ * @param profile\n+ *   The identifier of the profile.\n+ * @return\n+ *  - 0 on success.\n+ *  - -EINVAL if *dev_id*,  *port_id*, or *profile* is invalid.\n+ */\n+__rte_experimental\n+static inline uint8_t\n+rte_event_port_profile_switch(uint8_t dev_id, uint8_t port_id, uint8_t profile)\n+{\n+\tconst struct rte_event_fp_ops *fp_ops;\n+\tvoid *port;\n+\n+\tfp_ops = &rte_event_fp_ops[dev_id];\n+\tport = fp_ops->data[port_id];\n+\n+#ifdef RTE_LIBRTE_EVENTDEV_DEBUG\n+\tif (dev_id >= RTE_EVENT_MAX_DEVS ||\n+\t    port_id >= RTE_EVENT_MAX_PORTS_PER_DEV)\n+\t\treturn -EINVAL;\n+\n+\tif (port == NULL)\n+\t\treturn -EINVAL;\n+\n+\tif (profile >= RTE_EVENT_MAX_PROFILES_PER_PORT)\n+\t\treturn -EINVAL;\n+#endif\n+\trte_eventdev_trace_change_profile(dev_id, port_id, profile);\n+\n+\treturn fp_ops->profile_switch(port, profile);\n+}\n+\n #ifdef __cplusplus\n }\n #endif\ndiff --git a/lib/eventdev/rte_eventdev_core.h b/lib/eventdev/rte_eventdev_core.h\nindex c328bdbc82..dfde8500fc 100644\n--- a/lib/eventdev/rte_eventdev_core.h\n+++ b/lib/eventdev/rte_eventdev_core.h\n@@ -42,6 +42,8 @@ typedef uint16_t (*event_crypto_adapter_enqueue_t)(void *port,\n \t\t\t\t\t\t   uint16_t nb_events);\n /**< @internal Enqueue burst of events on crypto adapter */\n \n+typedef int (*event_profile_switch_t)(void *port, uint8_t profile);\n+\n struct rte_event_fp_ops {\n \tvoid **data;\n \t/**< points to array of internal port data pointers */\n@@ -65,6 +67,8 @@ struct rte_event_fp_ops {\n \t/**< PMD Tx adapter enqueue same destination function. */\n \tevent_crypto_adapter_enqueue_t ca_enqueue;\n \t/**< PMD Crypto adapter enqueue function. */\n+\tevent_profile_switch_t profile_switch;\n+\t/**< PMD Event switch profile function. */\n \tuintptr_t reserved[6];\n } __rte_cache_aligned;\n \ndiff --git a/lib/eventdev/rte_eventdev_trace_fp.h b/lib/eventdev/rte_eventdev_trace_fp.h\nindex af2172d2a5..141a45ed58 100644\n--- a/lib/eventdev/rte_eventdev_trace_fp.h\n+++ b/lib/eventdev/rte_eventdev_trace_fp.h\n@@ -46,6 +46,14 @@ RTE_TRACE_POINT_FP(\n \trte_trace_point_emit_int(op);\n )\n \n+RTE_TRACE_POINT_FP(\n+\trte_eventdev_trace_change_profile,\n+\tRTE_TRACE_POINT_ARGS(uint8_t dev_id, uint8_t port_id, uint8_t profile),\n+\trte_trace_point_emit_u8(dev_id);\n+\trte_trace_point_emit_u8(port_id);\n+\trte_trace_point_emit_u8(profile);\n+)\n+\n RTE_TRACE_POINT_FP(\n \trte_eventdev_trace_eth_tx_adapter_enqueue,\n \tRTE_TRACE_POINT_ARGS(uint8_t dev_id, uint8_t port_id, void *ev_table,\ndiff --git a/lib/eventdev/version.map b/lib/eventdev/version.map\nindex b03c10d99f..67efee5489 100644\n--- a/lib/eventdev/version.map\n+++ b/lib/eventdev/version.map\n@@ -131,6 +131,12 @@ EXPERIMENTAL {\n \trte_event_eth_tx_adapter_runtime_params_init;\n \trte_event_eth_tx_adapter_runtime_params_set;\n \trte_event_timer_remaining_ticks_get;\n+\n+\t# added in 23.11\n+\trte_event_port_profile_links_set;\n+\trte_event_port_profile_unlink;\n+\trte_event_port_profile_links_get;\n+\trte_event_port_profile_switch;\n };\n \n INTERNAL {\n",
    "prefixes": [
        "1/3"
    ]
}