Show a patch.

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

{
    "id": 44566,
    "url": "http://patches.dpdk.org/api/patches/44566/",
    "web_url": "http://patches.dpdk.org/patch/44566/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/",
        "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"
    },
    "msgid": "<20180911080216.3017-10-mattias.ronnblom@ericsson.com>",
    "date": "2018-09-11T08:02:15",
    "name": "[v3,09/10] event/dsw: implement eventdev 'xstats' counters in DSW",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "d1e4450d6c8f6dc8976334dd97f0bebb21ee8848",
    "submitter": {
        "id": 1077,
        "url": "http://patches.dpdk.org/api/people/1077/",
        "name": "Mattias Rönnblom",
        "email": "mattias.ronnblom@ericsson.com"
    },
    "delegate": {
        "id": 310,
        "url": "http://patches.dpdk.org/api/users/310/",
        "username": "jerin",
        "first_name": "Jerin",
        "last_name": "Jacob",
        "email": "jerin.jacob@caviumnetworks.com"
    },
    "mbox": "http://patches.dpdk.org/patch/44566/mbox/",
    "series": [
        {
            "id": 1264,
            "url": "http://patches.dpdk.org/api/series/1264/",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=1264",
            "date": "2018-09-11T08:02:07",
            "name": "A Distributed Software Event Device",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/1264/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/44566/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/44566/checks/",
    "tags": {},
    "headers": {
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "In-Reply-To": "<20180911080216.3017-1-mattias.ronnblom@ericsson.com>",
        "Errors-To": "dev-bounces@dpdk.org",
        "X-Mailer": "git-send-email 2.17.1",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 9242B5F17;\n\tTue, 11 Sep 2018 10:03:32 +0200 (CEST)",
            "from mail.lysator.liu.se (mail.lysator.liu.se [130.236.254.3])\n\tby dpdk.org (Postfix) with ESMTP id AAED94F94\n\tfor <dev@dpdk.org>; Tue, 11 Sep 2018 10:03:20 +0200 (CEST)",
            "from mail.lysator.liu.se (localhost [127.0.0.1])\n\tby mail.lysator.liu.se (Postfix) with ESMTP id 720924007C\n\tfor <dev@dpdk.org>; Tue, 11 Sep 2018 10:03:20 +0200 (CEST)",
            "by mail.lysator.liu.se (Postfix, from userid 1004)\n\tid 5DC7340085; Tue, 11 Sep 2018 10:03:20 +0200 (CEST)",
            "from isengard.friendlyfire.se\n\t(host-90-232-156-190.mobileonline.telia.com [90.232.156.190])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby mail.lysator.liu.se (Postfix) with ESMTPSA id 77EEE40020;\n\tTue, 11 Sep 2018 10:03:14 +0200 (CEST)"
        ],
        "References": "<20180911080216.3017-1-mattias.ronnblom@ericsson.com>",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "MIME-Version": "1.0",
        "Message-Id": "<20180911080216.3017-10-mattias.ronnblom@ericsson.com>",
        "X-Virus-Scanned": "ClamAV using ClamSMTP",
        "Delivered-To": "patchwork@dpdk.org",
        "Content-Transfer-Encoding": "8bit",
        "From": "=?utf-8?q?Mattias_R=C3=B6nnblom?= <mattias.ronnblom@ericsson.com>",
        "X-Original-To": "patchwork@dpdk.org",
        "Content-Type": "text/plain; charset=UTF-8",
        "List-Post": "<mailto:dev@dpdk.org>",
        "Return-Path": "<dev-bounces@dpdk.org>",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "To": "jerin.jacob@caviumnetworks.com",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "X-Spam-Status": "No, score=-0.9 required=5.0 tests=ALL_TRUSTED,AWL\n\tautolearn=disabled version=3.4.1",
        "X-Spam-Level": "",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "X-Spam-Checker-Version": "SpamAssassin 3.4.1 (2015-04-28) on\n\tbernadotte.lysator.liu.se",
        "X-BeenThere": "dev@dpdk.org",
        "Date": "Tue, 11 Sep 2018 10:02:15 +0200",
        "Cc": "bruce.richardson@intel.com, dev@dpdk.org, =?utf-8?q?Mattias_R=C3=B6nnb?=\n\t=?utf-8?q?lom?= <mattias.ronnblom@ericsson.com>",
        "X-Spam-Score": "-0.9",
        "Subject": "[dpdk-dev] [PATCH v3 09/10] event/dsw: implement eventdev 'xstats'\n\tcounters in DSW"
    },
    "content": "The DSW event device now implements the 'xstats' interface and a\nnumber of port- and device-level counters.\n\nSigned-off-by: Mattias Rönnblom <mattias.ronnblom@ericsson.com>\n---\n drivers/event/dsw/Makefile     |   3 +-\n drivers/event/dsw/dsw_evdev.c  |   5 +-\n drivers/event/dsw/dsw_evdev.h  |  19 +++\n drivers/event/dsw/dsw_event.c  |  35 ++++\n drivers/event/dsw/dsw_xstats.c | 288 +++++++++++++++++++++++++++++++++\n drivers/event/dsw/meson.build  |   2 +-\n 6 files changed, 349 insertions(+), 3 deletions(-)\n create mode 100644 drivers/event/dsw/dsw_xstats.c",
    "diff": "diff --git a/drivers/event/dsw/Makefile b/drivers/event/dsw/Makefile\nindex 6374a454e..ea1e5259a 100644\n--- a/drivers/event/dsw/Makefile\n+++ b/drivers/event/dsw/Makefile\n@@ -21,6 +21,7 @@ LIBABIVER := 1\n \n EXPORT_MAP := rte_pmd_dsw_event_version.map\n \n-SRCS-$(CONFIG_RTE_LIBRTE_PMD_DSW_EVENTDEV) += dsw_evdev.c dsw_event.c\n+SRCS-$(CONFIG_RTE_LIBRTE_PMD_DSW_EVENTDEV) += \\\n+\tdsw_evdev.c dsw_event.c dsw_xstats.c\n \n include $(RTE_SDK)/mk/rte.lib.mk\ndiff --git a/drivers/event/dsw/dsw_evdev.c b/drivers/event/dsw/dsw_evdev.c\nindex 2ecb365ba..33ba13647 100644\n--- a/drivers/event/dsw/dsw_evdev.c\n+++ b/drivers/event/dsw/dsw_evdev.c\n@@ -378,7 +378,10 @@ static struct rte_eventdev_ops dsw_evdev_ops = {\n \t.dev_configure = dsw_configure,\n \t.dev_start = dsw_start,\n \t.dev_stop = dsw_stop,\n-\t.dev_close = dsw_close\n+\t.dev_close = dsw_close,\n+\t.xstats_get = dsw_xstats_get,\n+\t.xstats_get_names = dsw_xstats_get_names,\n+\t.xstats_get_by_name = dsw_xstats_get_by_name\n };\n \n static int\ndiff --git a/drivers/event/dsw/dsw_evdev.h b/drivers/event/dsw/dsw_evdev.h\nindex f6f8f0454..dc28ab125 100644\n--- a/drivers/event/dsw/dsw_evdev.h\n+++ b/drivers/event/dsw/dsw_evdev.h\n@@ -176,6 +176,14 @@ struct dsw_port {\n \tuint16_t seen_events_idx;\n \tstruct dsw_queue_flow seen_events[DSW_MAX_EVENTS_RECORDED];\n \n+\tuint64_t new_enqueued;\n+\tuint64_t forward_enqueued;\n+\tuint64_t release_enqueued;\n+\tuint64_t queue_enqueued[DSW_MAX_QUEUES];\n+\n+\tuint64_t dequeued;\n+\tuint64_t queue_dequeued[DSW_MAX_QUEUES];\n+\n \tuint16_t out_buffer_len[DSW_MAX_PORTS];\n \tstruct rte_event out_buffer[DSW_MAX_PORTS][DSW_MAX_PORT_OUT_BUFFER];\n \n@@ -243,6 +251,17 @@ uint16_t dsw_event_dequeue(void *port, struct rte_event *ev, uint64_t wait);\n uint16_t dsw_event_dequeue_burst(void *port, struct rte_event *events,\n \t\t\t\t uint16_t num, uint64_t wait);\n \n+int dsw_xstats_get_names(const struct rte_eventdev *dev,\n+\t\t\t enum rte_event_dev_xstats_mode mode,\n+\t\t\t uint8_t queue_port_id,\n+\t\t\t struct rte_event_dev_xstats_name *xstats_names,\n+\t\t\t unsigned int *ids, unsigned int size);\n+int dsw_xstats_get(const struct rte_eventdev *dev,\n+\t\t   enum rte_event_dev_xstats_mode mode, uint8_t queue_port_id,\n+\t\t   const unsigned int ids[], uint64_t values[], unsigned int n);\n+uint64_t dsw_xstats_get_by_name(const struct rte_eventdev *dev,\n+\t\t\t\tconst char *name, unsigned int *id);\n+\n static inline struct dsw_evdev *\n dsw_pmd_priv(const struct rte_eventdev *eventdev)\n {\ndiff --git a/drivers/event/dsw/dsw_event.c b/drivers/event/dsw/dsw_event.c\nindex a84b19c33..61a66fabf 100644\n--- a/drivers/event/dsw/dsw_event.c\n+++ b/drivers/event/dsw/dsw_event.c\n@@ -82,6 +82,33 @@ dsw_port_return_credits(struct dsw_evdev *dsw, struct dsw_port *port,\n \t}\n }\n \n+static void\n+dsw_port_enqueue_stats(struct dsw_port *port, uint16_t num_new,\n+\t\t       uint16_t num_forward, uint16_t num_release)\n+{\n+\tport->new_enqueued += num_new;\n+\tport->forward_enqueued += num_forward;\n+\tport->release_enqueued += num_release;\n+}\n+\n+static void\n+dsw_port_queue_enqueue_stats(struct dsw_port *source_port, uint8_t queue_id)\n+{\n+\tsource_port->queue_enqueued[queue_id]++;\n+}\n+\n+static void\n+dsw_port_dequeue_stats(struct dsw_port *port, uint16_t num)\n+{\n+\tport->dequeued += num;\n+}\n+\n+static void\n+dsw_port_queue_dequeued_stats(struct dsw_port *source_port, uint8_t queue_id)\n+{\n+\tsource_port->queue_dequeued[queue_id]++;\n+}\n+\n static void\n dsw_port_load_record(struct dsw_port *port, unsigned int dequeued)\n {\n@@ -1059,12 +1086,16 @@ dsw_event_enqueue_burst_generic(void *port, const struct rte_event events[],\n \n \tsource_port->pending_releases -= num_release;\n \n+\tdsw_port_enqueue_stats(source_port, num_new,\n+\t\t\t       num_non_release-num_new, num_release);\n+\n \tfor (i = 0; i < events_len; i++) {\n \t\tconst struct rte_event *event = &events[i];\n \n \t\tif (likely(num_release == 0 ||\n \t\t\t   event->op != RTE_EVENT_OP_RELEASE))\n \t\t\tdsw_port_buffer_event(dsw, source_port, event);\n+\t\tdsw_port_queue_enqueue_stats(source_port, event->queue_id);\n \t}\n \n \tDSW_LOG_DP_PORT(DEBUG, source_port->id, \"%d non-release events \"\n@@ -1109,6 +1140,8 @@ dsw_port_record_seen_events(struct dsw_port *port, struct rte_event *events,\n {\n \tuint16_t i;\n \n+\tdsw_port_dequeue_stats(port, num);\n+\n \tfor (i = 0; i < num; i++) {\n \t\tuint16_t l_idx = port->seen_events_idx;\n \t\tstruct dsw_queue_flow *qf = &port->seen_events[l_idx];\n@@ -1117,6 +1150,8 @@ dsw_port_record_seen_events(struct dsw_port *port, struct rte_event *events,\n \t\tqf->flow_hash = dsw_flow_id_hash(event->flow_id);\n \n \t\tport->seen_events_idx = (l_idx+1) % DSW_MAX_EVENTS_RECORDED;\n+\n+\t\tdsw_port_queue_dequeued_stats(port, event->queue_id);\n \t}\n \n \tif (unlikely(port->seen_events_len != DSW_MAX_EVENTS_RECORDED))\ndiff --git a/drivers/event/dsw/dsw_xstats.c b/drivers/event/dsw/dsw_xstats.c\nnew file mode 100644\nindex 000000000..bf2eec527\n--- /dev/null\n+++ b/drivers/event/dsw/dsw_xstats.c\n@@ -0,0 +1,288 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2018 Ericsson AB\n+ */\n+\n+#include \"dsw_evdev.h\"\n+\n+#include <stdbool.h>\n+#include <string.h>\n+\n+#include <rte_debug.h>\n+\n+/* The high bits in the xstats id is used to store an additional\n+ * parameter (beyond the queue or port id already in the xstats\n+ * interface).\n+ */\n+#define DSW_XSTATS_ID_PARAM_BITS (8)\n+#define DSW_XSTATS_ID_STAT_BITS\t\t\t\t\t\\\n+\t(sizeof(unsigned int)*CHAR_BIT - DSW_XSTATS_ID_PARAM_BITS)\n+#define DSW_XSTATS_ID_STAT_MASK ((1 << DSW_XSTATS_ID_STAT_BITS) - 1)\n+\n+#define DSW_XSTATS_ID_GET_PARAM(id)\t\t\\\n+\t((id)>>DSW_XSTATS_ID_STAT_BITS)\n+\n+#define DSW_XSTATS_ID_GET_STAT(id)\t\t\\\n+\t((id) & DSW_XSTATS_ID_STAT_MASK)\n+\n+#define DSW_XSTATS_ID_CREATE(id, param_value)\t\t\t\\\n+\t(((param_value) << DSW_XSTATS_ID_STAT_BITS) | id)\n+\n+typedef\n+uint64_t (*dsw_xstats_dev_get_value_fn)(struct dsw_evdev *dsw);\n+\n+struct dsw_xstat_dev {\n+\tconst char *name;\n+\tdsw_xstats_dev_get_value_fn get_value_fn;\n+};\n+\n+typedef\n+uint64_t (*dsw_xstats_port_get_value_fn)(struct dsw_evdev *dsw,\n+\t\t\t\t\t uint8_t port_id, uint8_t queue_id);\n+\n+struct dsw_xstats_port {\n+\tconst char *name_fmt;\n+\tdsw_xstats_port_get_value_fn get_value_fn;\n+\tbool per_queue;\n+};\n+\n+static uint64_t\n+dsw_xstats_dev_credits_on_loan(struct dsw_evdev *dsw)\n+{\n+\treturn rte_atomic32_read(&dsw->credits_on_loan);\n+}\n+\n+static struct dsw_xstat_dev dsw_dev_xstats[] = {\n+\t{ \"dev_credits_on_loan\", dsw_xstats_dev_credits_on_loan }\n+};\n+\n+#define DSW_GEN_PORT_ACCESS_FN(_variable)\t\t\t\t\\\n+\tstatic uint64_t\t\t\t\t\t\t\t\\\n+\tdsw_xstats_port_get_ ## _variable(struct dsw_evdev *dsw,\t\\\n+\t\t\t\t\t  uint8_t port_id,\t\t\\\n+\t\t\t\t\t  uint8_t queue_id __rte_unused) \\\n+\t{\t\t\t\t\t\t\t\t\\\n+\t\treturn dsw->ports[port_id]._variable;\t\t\t\\\n+\t}\n+\n+DSW_GEN_PORT_ACCESS_FN(new_enqueued)\n+DSW_GEN_PORT_ACCESS_FN(forward_enqueued)\n+DSW_GEN_PORT_ACCESS_FN(release_enqueued)\n+\n+static uint64_t\n+dsw_xstats_port_get_queue_enqueued(struct dsw_evdev *dsw, uint8_t port_id,\n+\t\t\t\t   uint8_t queue_id)\n+{\n+\treturn dsw->ports[port_id].queue_enqueued[queue_id];\n+}\n+\n+DSW_GEN_PORT_ACCESS_FN(dequeued)\n+\n+static uint64_t\n+dsw_xstats_port_get_queue_dequeued(struct dsw_evdev *dsw, uint8_t port_id,\n+\t\t\t\t   uint8_t queue_id)\n+{\n+\treturn dsw->ports[port_id].queue_dequeued[queue_id];\n+}\n+\n+DSW_GEN_PORT_ACCESS_FN(migrations)\n+\n+static uint64_t\n+dsw_xstats_port_get_migration_latency(struct dsw_evdev *dsw, uint8_t port_id,\n+\t\t\t\t      uint8_t queue_id __rte_unused)\n+{\n+\tuint64_t total_latency = dsw->ports[port_id].migration_latency;\n+\tuint64_t num_migrations = dsw->ports[port_id].migrations;\n+\n+\treturn num_migrations > 0 ? total_latency / num_migrations : 0;\n+}\n+\n+static uint64_t\n+dsw_xstats_port_get_event_proc_latency(struct dsw_evdev *dsw, uint8_t port_id,\n+\t\t\t\t       uint8_t queue_id __rte_unused)\n+{\n+\tuint64_t total_busy_cycles =\n+\t\tdsw->ports[port_id].total_busy_cycles;\n+\tuint64_t dequeued =\n+\t\tdsw->ports[port_id].dequeued;\n+\n+\treturn dequeued > 0 ? total_busy_cycles / dequeued : 0;\n+}\n+\n+DSW_GEN_PORT_ACCESS_FN(inflight_credits)\n+\n+static uint64_t\n+dsw_xstats_port_get_load(struct dsw_evdev *dsw, uint8_t port_id,\n+\t\t\t uint8_t queue_id __rte_unused)\n+{\n+\tint16_t load;\n+\n+\tload = rte_atomic16_read(&dsw->ports[port_id].load);\n+\n+\treturn DSW_LOAD_TO_PERCENT(load);\n+}\n+\n+DSW_GEN_PORT_ACCESS_FN(last_bg)\n+\n+static struct dsw_xstats_port dsw_port_xstats[] = {\n+\t{ \"port_%u_new_enqueued\", dsw_xstats_port_get_new_enqueued,\n+\t  false },\n+\t{ \"port_%u_forward_enqueued\", dsw_xstats_port_get_forward_enqueued,\n+\t  false },\n+\t{ \"port_%u_release_enqueued\", dsw_xstats_port_get_release_enqueued,\n+\t  false },\n+\t{ \"port_%u_queue_%u_enqueued\", dsw_xstats_port_get_queue_enqueued,\n+\t  true },\n+\t{ \"port_%u_dequeued\", dsw_xstats_port_get_dequeued,\n+\t  false },\n+\t{ \"port_%u_queue_%u_dequeued\", dsw_xstats_port_get_queue_dequeued,\n+\t  true },\n+\t{ \"port_%u_migrations\", dsw_xstats_port_get_migrations,\n+\t  false },\n+\t{ \"port_%u_migration_latency\", dsw_xstats_port_get_migration_latency,\n+\t  false },\n+\t{ \"port_%u_event_proc_latency\", dsw_xstats_port_get_event_proc_latency,\n+\t  false },\n+\t{ \"port_%u_inflight_credits\", dsw_xstats_port_get_inflight_credits,\n+\t  false },\n+\t{ \"port_%u_load\", dsw_xstats_port_get_load,\n+\t  false },\n+\t{ \"port_%u_last_bg\", dsw_xstats_port_get_last_bg,\n+\t  false }\n+};\n+\n+static int\n+dsw_xstats_dev_get_names(struct rte_event_dev_xstats_name *xstats_names,\n+\t\t\t unsigned int *ids, unsigned int size)\n+{\n+\tunsigned int i;\n+\n+\tfor (i = 0; i < RTE_DIM(dsw_dev_xstats) && i < size; i++) {\n+\t\tids[i] = i;\n+\t\tstrcpy(xstats_names[i].name, dsw_dev_xstats[i].name);\n+\t}\n+\n+\treturn i;\n+}\n+\n+static int\n+dsw_xstats_port_get_names(struct dsw_evdev *dsw, uint8_t port_id,\n+\t\t\t  struct rte_event_dev_xstats_name *xstats_names,\n+\t\t\t  unsigned int *ids, unsigned int size)\n+{\n+\tuint8_t queue_id = 0;\n+\tunsigned int id_idx;\n+\tunsigned int stat_idx;\n+\n+\tfor (id_idx = 0, stat_idx = 0;\n+\t     id_idx < size && stat_idx < RTE_DIM(dsw_port_xstats);\n+\t     id_idx++) {\n+\t\tstruct dsw_xstats_port *xstat = &dsw_port_xstats[stat_idx];\n+\n+\t\tif (xstat->per_queue) {\n+\t\t\tids[id_idx] = DSW_XSTATS_ID_CREATE(stat_idx, queue_id);\n+\t\t\tsnprintf(xstats_names[id_idx].name,\n+\t\t\t\t RTE_EVENT_DEV_XSTATS_NAME_SIZE,\n+\t\t\t\t dsw_port_xstats[stat_idx].name_fmt, port_id,\n+\t\t\t\t queue_id);\n+\t\t\tqueue_id++;\n+\t\t} else {\n+\t\t\tids[id_idx] = stat_idx;\n+\t\t\tsnprintf(xstats_names[id_idx].name,\n+\t\t\t\t RTE_EVENT_DEV_XSTATS_NAME_SIZE,\n+\t\t\t\t dsw_port_xstats[stat_idx].name_fmt, port_id);\n+\t\t}\n+\n+\t\tif (!(xstat->per_queue && queue_id < dsw->num_queues)) {\n+\t\t\tstat_idx++;\n+\t\t\tqueue_id = 0;\n+\t\t}\n+\t}\n+\treturn id_idx;\n+}\n+\n+int\n+dsw_xstats_get_names(const struct rte_eventdev *dev,\n+\t\t     enum rte_event_dev_xstats_mode mode,\n+\t\t     uint8_t queue_port_id,\n+\t\t     struct rte_event_dev_xstats_name *xstats_names,\n+\t\t     unsigned int *ids, unsigned int size)\n+{\n+\tstruct dsw_evdev *dsw = dsw_pmd_priv(dev);\n+\n+\tswitch (mode) {\n+\tcase RTE_EVENT_DEV_XSTATS_DEVICE:\n+\t\treturn dsw_xstats_dev_get_names(xstats_names, ids, size);\n+\tcase RTE_EVENT_DEV_XSTATS_PORT:\n+\t\treturn dsw_xstats_port_get_names(dsw, queue_port_id,\n+\t\t\t\t\t\t xstats_names, ids, size);\n+\tcase RTE_EVENT_DEV_XSTATS_QUEUE:\n+\t\treturn 0;\n+\tdefault:\n+\t\tRTE_ASSERT(false);\n+\t\treturn -1;\n+\t}\n+}\n+\n+static int\n+dsw_xstats_dev_get(const struct rte_eventdev *dev,\n+\t\t   const unsigned int ids[], uint64_t values[], unsigned int n)\n+{\n+\tstruct dsw_evdev *dsw = dsw_pmd_priv(dev);\n+\tunsigned int i;\n+\n+\tfor (i = 0; i < n; i++) {\n+\t\tunsigned int id = ids[i];\n+\t\tstruct dsw_xstat_dev *xstat = &dsw_dev_xstats[id];\n+\t\tvalues[i] = xstat->get_value_fn(dsw);\n+\t}\n+\treturn n;\n+}\n+\n+static int\n+dsw_xstats_port_get(const struct rte_eventdev *dev, uint8_t port_id,\n+\t\t    const unsigned int ids[], uint64_t values[], unsigned int n)\n+{\n+\tstruct dsw_evdev *dsw = dsw_pmd_priv(dev);\n+\tunsigned int i;\n+\n+\tfor (i = 0; i < n; i++) {\n+\t\tunsigned int id = ids[i];\n+\t\tunsigned int stat_idx = DSW_XSTATS_ID_GET_STAT(id);\n+\t\tstruct dsw_xstats_port *xstat = &dsw_port_xstats[stat_idx];\n+\t\tuint8_t queue_id = 0;\n+\n+\t\tif (xstat->per_queue)\n+\t\t\tqueue_id = DSW_XSTATS_ID_GET_PARAM(id);\n+\n+\t\tvalues[i] = xstat->get_value_fn(dsw, port_id, queue_id);\n+\t}\n+\treturn n;\n+}\n+\n+int\n+dsw_xstats_get(const struct rte_eventdev *dev,\n+\t       enum rte_event_dev_xstats_mode mode, uint8_t queue_port_id,\n+\t       const unsigned int ids[], uint64_t values[], unsigned int n)\n+{\n+\tswitch (mode) {\n+\tcase RTE_EVENT_DEV_XSTATS_DEVICE:\n+\t\treturn dsw_xstats_dev_get(dev, ids, values, n);\n+\tcase RTE_EVENT_DEV_XSTATS_PORT:\n+\t\treturn dsw_xstats_port_get(dev, queue_port_id, ids, values, n);\n+\tcase RTE_EVENT_DEV_XSTATS_QUEUE:\n+\t\treturn 0;\n+\tdefault:\n+\t\tRTE_ASSERT(false);\n+\t\treturn -1;\n+\t}\n+\treturn 0;\n+}\n+\n+uint64_t dsw_xstats_get_by_name(const struct rte_eventdev *dev,\n+\t\t\t\tconst char *name, unsigned int *id)\n+{\n+\tRTE_SET_USED(dev);\n+\tRTE_SET_USED(name);\n+\tRTE_SET_USED(id);\n+\treturn 0;\n+}\ndiff --git a/drivers/event/dsw/meson.build b/drivers/event/dsw/meson.build\nindex bd2e4c809..a6b7bfa59 100644\n--- a/drivers/event/dsw/meson.build\n+++ b/drivers/event/dsw/meson.build\n@@ -3,4 +3,4 @@\n \n allow_experimental_apis = true\n deps += ['bus_vdev']\n-sources = files('dsw_evdev.c', 'dsw_event.c')\n+sources = files('dsw_evdev.c', 'dsw_event.c', 'dsw_xstats.c')\n",
    "prefixes": [
        "v3",
        "09/10"
    ]
}