get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 19447,
    "url": "http://patches.dpdk.org/api/patches/19447/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1484581255-148720-15-git-send-email-harry.van.haaren@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1484581255-148720-15-git-send-email-harry.van.haaren@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1484581255-148720-15-git-send-email-harry.van.haaren@intel.com",
    "date": "2017-01-16T15:40:54",
    "name": "[dpdk-dev,14/15] event/sw: add xstats support",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "a992b93b60d5ddd37c7062bce24064da6b794c5a",
    "submitter": {
        "id": 317,
        "url": "http://patches.dpdk.org/api/people/317/?format=api",
        "name": "Van Haaren, Harry",
        "email": "harry.van.haaren@intel.com"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1484581255-148720-15-git-send-email-harry.van.haaren@intel.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/19447/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/19447/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id 9D919F96C;\n\tMon, 16 Jan 2017 16:41:54 +0100 (CET)",
            "from mga07.intel.com (mga07.intel.com [134.134.136.100])\n\tby dpdk.org (Postfix) with ESMTP id E6F582BA2\n\tfor <dev@dpdk.org>; Mon, 16 Jan 2017 16:41:25 +0100 (CET)",
            "from fmsmga004.fm.intel.com ([10.253.24.48])\n\tby orsmga105.jf.intel.com with ESMTP; 16 Jan 2017 07:41:25 -0800",
            "from silpixa00398672.ir.intel.com ([10.237.223.128])\n\tby fmsmga004.fm.intel.com with ESMTP; 16 Jan 2017 07:41:24 -0800"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.33,239,1477983600\"; d=\"scan'208\";a=\"213947073\"",
        "From": "Harry van Haaren <harry.van.haaren@intel.com>",
        "To": "jerin.jacob@caviumnetworks.com",
        "Cc": "dev@dpdk.org, Bruce Richardson <bruce.richardson@intel.com>,\n\tHarry van Haaren <harry.van.haaren@intel.com>",
        "Date": "Mon, 16 Jan 2017 15:40:54 +0000",
        "Message-Id": "<1484581255-148720-15-git-send-email-harry.van.haaren@intel.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": "<1484581255-148720-1-git-send-email-harry.van.haaren@intel.com>",
        "References": "<1484581255-148720-1-git-send-email-harry.van.haaren@intel.com>",
        "Subject": "[dpdk-dev] [PATCH 14/15] event/sw: add xstats support",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Bruce Richardson <bruce.richardson@intel.com>\n\nAdd support for xstats to report out on the state of the eventdev.\nUseful for debugging and for unit tests, as well as observability\nat runtime and performance tuning of apps to work well with the\nscheduler.\n\nSigned-off-by: Bruce Richardson <bruce.richardson@intel.com>\nSigned-off-by: Harry van Haaren <harry.van.haaren@intel.com>\n---\n drivers/event/sw/Makefile          |   1 +\n drivers/event/sw/sw_evdev.c        |   7 +\n drivers/event/sw/sw_evdev.h        |  10 +\n drivers/event/sw/sw_evdev_xstats.c | 401 +++++++++++++++++++++++++++++++++++++\n 4 files changed, 419 insertions(+)\n create mode 100644 drivers/event/sw/sw_evdev_xstats.c",
    "diff": "diff --git a/drivers/event/sw/Makefile b/drivers/event/sw/Makefile\nindex e96c457..890d2af 100644\n--- a/drivers/event/sw/Makefile\n+++ b/drivers/event/sw/Makefile\n@@ -55,6 +55,7 @@ EXPORT_MAP := rte_pmd_evdev_sw_version.map\n SRCS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += sw_evdev.c\n SRCS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += sw_evdev_worker.c\n SRCS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += sw_evdev_scheduler.c\n+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += sw_evdev_xstats.c\n \n # export include files\n SYMLINK-y-include +=\ndiff --git a/drivers/event/sw/sw_evdev.c b/drivers/event/sw/sw_evdev.c\nindex ea34b99..958e798 100644\n--- a/drivers/event/sw/sw_evdev.c\n+++ b/drivers/event/sw/sw_evdev.c\n@@ -545,6 +545,8 @@ sw_start(struct rte_eventdev *dev)\n \t\t\t}\n \t\t}\n \t}\n+\tif (sw_xstats_init(sw) < 0)\n+\t\treturn -1;\n \tsw->started = 1;\n \treturn 0;\n }\n@@ -553,6 +555,7 @@ static void\n sw_stop(struct rte_eventdev *dev)\n {\n \tstruct sw_evdev *sw = sw_pmd_priv(dev);\n+\tsw_xstats_uninit(sw);\n \tsw->started = 0;\n }\n \n@@ -618,6 +621,10 @@ sw_probe(const char *name, const char *params)\n \t\t\t.port_release = sw_port_release,\n \t\t\t.port_link = sw_port_link,\n \t\t\t.port_unlink = sw_port_unlink,\n+\n+\t\t\t.get_xstat_names = sw_get_xstat_names,\n+\t\t\t.get_xstats = sw_get_xstats,\n+\t\t\t.get_xstat_by_name = sw_get_xstat_by_name,\n \t};\n \n \tstatic const char *const args[] = { NUMA_NODE_ARG, SCHED_QUANTA_ARG, NULL };\ndiff --git a/drivers/event/sw/sw_evdev.h b/drivers/event/sw/sw_evdev.h\nindex a0f3668..d82e61a 100644\n--- a/drivers/event/sw/sw_evdev.h\n+++ b/drivers/event/sw/sw_evdev.h\n@@ -221,6 +221,8 @@ struct sw_evdev {\n \n \tuint32_t port_count;\n \tuint32_t qid_count;\n+\tuint32_t xstats_count;\n+\tstruct sw_xstats_entry *xstats;\n \n \t/* Contains all ports - load balanced and directed */\n \tstruct sw_port ports[SW_PORTS_MAX] __rte_cache_aligned;\n@@ -273,5 +275,13 @@ uint16_t sw_event_dequeue(void *port, struct rte_event *ev, uint64_t wait);\n uint16_t sw_event_dequeue_burst(void *port, struct rte_event *ev, uint16_t num,\n \t\t\tuint64_t wait);\n void sw_event_schedule(struct rte_eventdev *dev);\n+int sw_xstats_init(struct sw_evdev *dev);\n+int sw_xstats_uninit(struct sw_evdev *dev);\n+int sw_get_xstat_names(const struct rte_eventdev *dev,\n+\tstruct rte_event_dev_xstat_name *xstats_names, unsigned int size);\n+int sw_get_xstats(const struct rte_eventdev *dev, const unsigned int ids[],\n+\tuint64_t values[], unsigned int n);\n+uint64_t sw_get_xstat_by_name(const struct rte_eventdev *dev,\n+\t\tconst char *name, unsigned int *id);\n \n #endif /* _SW_EVDEV_H_ */\ndiff --git a/drivers/event/sw/sw_evdev_xstats.c b/drivers/event/sw/sw_evdev_xstats.c\nnew file mode 100644\nindex 0000000..f879303\n--- /dev/null\n+++ b/drivers/event/sw/sw_evdev_xstats.c\n@@ -0,0 +1,401 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2016-2017 Intel Corporation. All rights reserved.\n+ *\n+ *   Redistribution and use in source and binary forms, with or without\n+ *   modification, are permitted provided that the following conditions\n+ *   are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright\n+ *       notice, this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in\n+ *       the documentation and/or other materials provided with the\n+ *       distribution.\n+ *     * Neither the name of Intel Corporation nor the names of its\n+ *       contributors may be used to endorse or promote products derived\n+ *       from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#include \"sw_evdev.h\"\n+#include \"iq_ring.h\"\n+#include \"event_ring.h\"\n+\n+enum xstats_type {\n+\t/* common stats */\n+\trx,\n+\ttx,\n+\tdropped,\n+\tinflight,\n+\tcalls,\n+\tcredits,\n+\t/* device instance specific */\n+\tno_iq_enq,\n+\tno_cq_enq,\n+\t/* port_specific */\n+\trx_used,\n+\trx_free,\n+\ttx_used,\n+\ttx_free,\n+\tpkt_cycles,\n+\tpoll_return, /* for zero-count and used also for port bucket loop */\n+\t/* qid_specific */\n+\tiq_size,\n+\tiq_used,\n+\t/* qid port mapping specific */\n+\tpinned,\n+};\n+\n+typedef uint64_t (*xstats_fn)(const struct sw_evdev *dev,\n+\t\tuint16_t obj_idx, /* port or queue id */\n+\t\tenum xstats_type stat, int extra_arg);\n+\n+struct sw_xstats_entry {\n+\tstruct rte_event_dev_xstat_name name;\n+\txstats_fn fn;\n+\tuint16_t obj_idx;\n+\tenum xstats_type stat;\n+\tint extra_arg;\n+};\n+\n+static uint64_t\n+get_dev_stat(const struct sw_evdev *sw, uint16_t obj_idx __rte_unused,\n+\t\tenum xstats_type type, int extra_arg __rte_unused)\n+{\n+\tswitch (type) {\n+\tcase rx: return sw->stats.rx_pkts;\n+\tcase tx: return sw->stats.tx_pkts;\n+\tcase dropped: return sw->stats.rx_dropped;\n+\tcase calls: return sw->sched_called;\n+\tcase no_iq_enq: return sw->sched_no_iq_enqueues;\n+\tcase no_cq_enq: return sw->sched_no_cq_enqueues;\n+\tdefault: return -1;\n+\t}\n+}\n+\n+static uint64_t\n+get_port_stat(const struct sw_evdev *sw, uint16_t obj_idx,\n+\t\tenum xstats_type type, int extra_arg __rte_unused)\n+{\n+\tconst struct sw_port *p = &sw->ports[obj_idx];\n+\n+\tswitch (type) {\n+\tcase rx: return p->stats.rx_pkts;\n+\tcase tx: return p->stats.tx_pkts;\n+\tcase dropped: return p->stats.rx_dropped;\n+\tcase inflight: return p->inflights;\n+\tcase pkt_cycles: return p->avg_pkt_ticks;\n+\tcase calls: return p->total_polls;\n+\tcase credits: return p->inflight_credits;\n+\tcase poll_return: return p->zero_polls;\n+\tcase rx_used: return qe_ring_count(p->rx_worker_ring);\n+\tcase rx_free: return qe_ring_free_count(p->rx_worker_ring);\n+\tcase tx_used: return qe_ring_count(p->cq_worker_ring);\n+\tcase tx_free: return qe_ring_free_count(p->cq_worker_ring);\n+\tdefault: return -1;\n+\t}\n+}\n+\n+static uint64_t\n+get_port_bucket_stat(const struct sw_evdev *sw, uint16_t obj_idx,\n+\t\tenum xstats_type type, int extra_arg)\n+{\n+\tconst struct sw_port *p = &sw->ports[obj_idx];\n+\n+\tswitch (type) {\n+\tcase poll_return: return p->poll_buckets[extra_arg];\n+\tdefault: return -1;\n+\t}\n+}\n+\n+static uint64_t\n+get_qid_stat(const struct sw_evdev *sw, uint16_t obj_idx,\n+\t\tenum xstats_type type, int extra_arg __rte_unused)\n+{\n+\tconst struct sw_qid *qid = &sw->qids[obj_idx];\n+\n+\tswitch (type) {\n+\tcase rx: return qid->stats.rx_pkts;\n+\tcase tx: return qid->stats.tx_pkts;\n+\tcase dropped: return qid->stats.rx_dropped;\n+\tcase inflight:\n+\t\tdo {\n+\t\t\tuint64_t infl = 0;\n+\t\t\tunsigned int i;\n+\t\t\tfor (i = 0; i < RTE_DIM(qid->fids); i++)\n+\t\t\t\tinfl += qid->fids[i].pcount;\n+\t\t\treturn infl;\n+\t\t} while (0);\n+\t\tbreak;\n+\tcase iq_size: return RTE_DIM(qid->iq[0]->ring);\n+\tdefault: return -1;\n+\t}\n+}\n+\n+static uint64_t\n+get_qid_iq_stat(const struct sw_evdev *sw, uint16_t obj_idx,\n+\t\tenum xstats_type type, int extra_arg)\n+{\n+\tconst struct sw_qid *qid = &sw->qids[obj_idx];\n+\tconst int iq_idx = extra_arg;\n+\n+\tswitch (type) {\n+\tcase iq_used: return iq_ring_count(qid->iq[iq_idx]);\n+\tdefault: return -1;\n+\t}\n+}\n+\n+static uint64_t\n+get_qid_port_stat(const struct sw_evdev *sw, uint16_t obj_idx,\n+\t\tenum xstats_type type, int extra_arg)\n+{\n+\tconst struct sw_qid *qid = &sw->qids[obj_idx];\n+\tuint16_t port = extra_arg;\n+\n+\tswitch (type) {\n+\tcase pinned:\n+\t\tdo {\n+\t\t\tuint64_t pin = 0;\n+\t\t\tunsigned int i;\n+\t\t\tfor (i = 0; i < RTE_DIM(qid->fids); i++)\n+\t\t\t\tif (qid->fids[i].cq == port)\n+\t\t\t\t\tpin++;\n+\t\t\treturn pin;\n+\t\t} while (0);\n+\t\tbreak;\n+\tdefault: return -1;\n+\t}\n+}\n+\n+int\n+sw_xstats_init(struct sw_evdev *sw)\n+{\n+\t/*\n+\t * define the stats names and types. Used to build up the device\n+\t * xstats array\n+\t * There are multiple set of stats:\n+\t *   - device-level,\n+\t *   - per-port,\n+\t *   - per-port-dequeue-burst-sizes\n+\t *   - per-qid,\n+\t *   - per-iq\n+\t *   - per-port-per-qid\n+\t *\n+\t * For each of these sets, we have two parallel arrays, one for the\n+\t * names, the other for the stat type parameter to be passed in the fn\n+\t * call to get that stat. These two arrays must be kept in sync\n+\t */\n+\tstatic const char * const dev_stats[] = { \"rx\", \"tx\", \"drop\",\n+\t\t\t\"sched_calls\", \"sched_no_iq_enq\", \"sched_no_cq_enq\",\n+\t};\n+\tstatic const enum xstats_type dev_types[] = { rx, tx, dropped,\n+\t\t\tcalls, no_iq_enq, no_cq_enq,\n+\t};\n+\n+\tstatic const char * const port_stats[] = {\"rx\", \"tx\", \"drop\",\n+\t\t\t\"inflight\", \"avg_pkt_cycles\", \"credits\",\n+\t\t\t\"rx_ring_used\", \"rx_ring_free\",\n+\t\t\t\"cq_ring_used\", \"cq_ring_free\",\n+\t\t\t\"dequeue_calls\", \"dequeues_returning_0\",\n+\t};\n+\tstatic const enum xstats_type port_types[] = { rx, tx, dropped,\n+\t\t\tinflight, pkt_cycles, credits,\n+\t\t\trx_used, rx_free, tx_used, tx_free,\n+\t\t\tcalls, poll_return,\n+\t};\n+\n+\tstatic const char * const port_bucket_stats[] = {\n+\t\t\t\"dequeues_returning\" };\n+\tstatic const enum xstats_type port_bucket_types[] = { poll_return };\n+\n+\tstatic const char * const qid_stats[] = {\"rx\", \"tx\", \"drop\",\n+\t\t\t\"inflight\", \"iq_size\"\n+\t};\n+\tstatic const enum xstats_type qid_types[] = { rx, tx, dropped, inflight,\n+\t\t\tiq_size\n+\t};\n+\n+\tstatic const char * const qid_iq_stats[] = { \"used\" };\n+\tstatic const enum xstats_type qid_iq_types[] = { iq_used };\n+\n+\tstatic const char * const qid_port_stats[] = { \"pinned_flows\" };\n+\tstatic const enum xstats_type qid_port_types[] = { pinned };\n+\t/* ---- end of stat definitions ---- */\n+\n+\t/* check sizes, since a missed comma can lead to strings being\n+\t * joined by the compiler.\n+\t */\n+\tRTE_BUILD_BUG_ON(RTE_DIM(dev_stats) != RTE_DIM(dev_types));\n+\tRTE_BUILD_BUG_ON(RTE_DIM(port_stats) != RTE_DIM(port_types));\n+\tRTE_BUILD_BUG_ON(RTE_DIM(port_bucket_stats) != RTE_DIM(port_bucket_types));\n+\tRTE_BUILD_BUG_ON(RTE_DIM(qid_stats) != RTE_DIM(qid_types));\n+\tRTE_BUILD_BUG_ON(RTE_DIM(qid_iq_stats) != RTE_DIM(qid_iq_types));\n+\tRTE_BUILD_BUG_ON(RTE_DIM(qid_port_stats) != RTE_DIM(qid_port_types));\n+\n+\t/* other vars */\n+\tconst unsigned int count = RTE_DIM(dev_stats) +\n+\t\t\tsw->port_count * RTE_DIM(port_stats) +\n+\t\t\tsw->port_count * RTE_DIM(port_bucket_stats) *\n+\t\t\t\t((MAX_SW_CONS_Q_DEPTH >> SW_DEQ_STAT_BUCKET_SHIFT) + 1) +\n+\t\t\tsw->qid_count * RTE_DIM(qid_stats) +\n+\t\t\tsw->qid_count * SW_IQS_MAX * RTE_DIM(qid_iq_stats) +\n+\t\t\tsw->qid_count * sw->port_count * RTE_DIM(qid_port_stats);\n+\tunsigned int i, port, qid, iq, bkt, stat = 0;\n+\n+\tsw->xstats = rte_zmalloc_socket(NULL, sizeof(sw->xstats[0]) * count, 0,\n+\t\t\tsw->data->socket_id);\n+\tif (sw->xstats == NULL)\n+\t\treturn -ENOMEM;\n+\n+#define sname sw->xstats[stat].name.name\n+\tfor (i = 0; i < RTE_DIM(dev_stats); i++, stat++) {\n+\t\tsw->xstats[stat] = (struct sw_xstats_entry){\n+\t\t\t.fn = get_dev_stat,\n+\t\t\t.stat = dev_types[i],\n+\t\t};\n+\t\tsnprintf(sname, sizeof(sname), \"dev_%s\", dev_stats[i]);\n+\t}\n+\n+\tfor (port = 0; port < sw->port_count; port++) {\n+\t\tfor (i = 0; i < RTE_DIM(port_stats); i++, stat++) {\n+\t\t\tsw->xstats[stat] = (struct sw_xstats_entry){\n+\t\t\t\t.fn = get_port_stat,\n+\t\t\t\t.obj_idx = port,\n+\t\t\t\t.stat = port_types[i],\n+\t\t\t};\n+\t\t\tsnprintf(sname, sizeof(sname), \"port_%u_%s\",\n+\t\t\t\t\tport, port_stats[i]);\n+\t\t}\n+\n+\t\tfor (bkt = 0; bkt < (sw->ports[port].cq_worker_ring->size >>\n+\t\t\t\tSW_DEQ_STAT_BUCKET_SHIFT) + 1; bkt++) {\n+\t\t\tfor (i = 0; i < RTE_DIM(port_bucket_stats); i++, stat++) {\n+\t\t\t\tsw->xstats[stat] = (struct sw_xstats_entry){\n+\t\t\t\t\t.fn = get_port_bucket_stat,\n+\t\t\t\t\t.obj_idx = port,\n+\t\t\t\t\t.stat = port_bucket_types[i],\n+\t\t\t\t\t.extra_arg = bkt,\n+\t\t\t\t};\n+\t\t\t\tsnprintf(sname, sizeof(sname), \"port_%u_%s_%u-%u\",\n+\t\t\t\t\t\tport, port_bucket_stats[i],\n+\t\t\t\t\t\t(bkt << SW_DEQ_STAT_BUCKET_SHIFT) + 1,\n+\t\t\t\t\t\t(bkt + 1) << SW_DEQ_STAT_BUCKET_SHIFT);\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\tfor (qid = 0; qid < sw->qid_count; qid++) {\n+\t\tfor (i = 0; i < RTE_DIM(qid_stats); i++, stat++) {\n+\t\t\tsw->xstats[stat] = (struct sw_xstats_entry){\n+\t\t\t\t.fn = get_qid_stat,\n+\t\t\t\t.obj_idx = qid,\n+\t\t\t\t.stat = qid_types[i],\n+\t\t\t};\n+\t\t\tsnprintf(sname, sizeof(sname), \"qid_%u_%s\",\n+\t\t\t\t\tqid, qid_stats[i]);\n+\t\t}\n+\t\tfor (iq = 0; iq < SW_IQS_MAX; iq++)\n+\t\t\tfor (i = 0; i < RTE_DIM(qid_iq_stats); i++, stat++) {\n+\t\t\t\tsw->xstats[stat] = (struct sw_xstats_entry){\n+\t\t\t\t\t.fn = get_qid_iq_stat,\n+\t\t\t\t\t.obj_idx = qid,\n+\t\t\t\t\t.stat = qid_iq_types[i],\n+\t\t\t\t\t.extra_arg = iq\n+\t\t\t\t};\n+\t\t\t\tsnprintf(sname, sizeof(sname),\n+\t\t\t\t\t\t\"qid_%u_iq_%u_%s\",\n+\t\t\t\t\t\tqid, iq,\n+\t\t\t\t\t\tqid_iq_stats[i]);\n+\t\t\t}\n+\n+\t\tfor (port = 0; port < sw->port_count; port++)\n+\t\t\tfor (i = 0; i < RTE_DIM(qid_port_stats); i++, stat++) {\n+\t\t\t\tsw->xstats[stat] = (struct sw_xstats_entry){\n+\t\t\t\t\t.fn = get_qid_port_stat,\n+\t\t\t\t\t.obj_idx = qid,\n+\t\t\t\t\t.stat = qid_port_types[i],\n+\t\t\t\t\t.extra_arg = port\n+\t\t\t\t};\n+\t\t\t\tsnprintf(sname, sizeof(sname),\n+\t\t\t\t\t\t\"qid_%u_port_%u_%s\",\n+\t\t\t\t\t\tqid, port,\n+\t\t\t\t\t\tqid_port_stats[i]);\n+\t\t\t}\n+\t}\n+#undef sname\n+\n+\tsw->xstats_count = stat;\n+\n+\treturn stat;\n+}\n+\n+int\n+sw_xstats_uninit(struct sw_evdev *sw)\n+{\n+\trte_free(sw->xstats);\n+\tsw->xstats_count = 0;\n+\treturn 0;\n+}\n+\n+int\n+sw_get_xstat_names(const struct rte_eventdev *dev,\n+\tstruct rte_event_dev_xstat_name *xstats_names, unsigned int size)\n+{\n+\tconst struct sw_evdev *sw = sw_pmd_priv_const(dev);\n+\tunsigned int i;\n+\n+\tfor (i = 0; i < sw->xstats_count && i < size; i++)\n+\t\txstats_names[i] = sw->xstats[i].name;\n+\treturn sw->xstats_count;\n+}\n+\n+int\n+sw_get_xstats(const struct rte_eventdev *dev, const unsigned int ids[],\n+\tuint64_t values[], unsigned int n)\n+{\n+\tconst struct sw_evdev *sw = sw_pmd_priv_const(dev);\n+\tunsigned int i;\n+\n+\tfor (i = 0; i < n; i++) {\n+\t\tstruct sw_xstats_entry *xs = &sw->xstats[ids[i]];\n+\t\tif (ids[i] > sw->xstats_count)\n+\t\t\tcontinue;\n+\t\tvalues[i] = xs->fn(sw, xs->obj_idx, xs->stat, xs->extra_arg);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+uint64_t\n+sw_get_xstat_by_name(const struct rte_eventdev *dev,\n+\t\tconst char *name, unsigned int *id)\n+{\n+\tconst struct sw_evdev *sw = sw_pmd_priv_const(dev);\n+\tunsigned int i;\n+\n+\tfor (i = 0; i < sw->xstats_count; i++) {\n+\t\tstruct sw_xstats_entry *xs = &sw->xstats[i];\n+\t\tif (strncmp(xs->name.name, name,\n+\t\t\t\tRTE_EVENT_DEV_XSTAT_NAME_SIZE) == 0){\n+\t\t\tif (id != NULL)\n+\t\t\t\t*id = i;\n+\t\t\treturn xs->fn(sw, xs->obj_idx, xs->stat, xs->extra_arg);\n+\t\t}\n+\t}\n+\tif (id != NULL)\n+\t\t*id = (uint32_t)-1;\n+\treturn (uint64_t)-1;\n+}\n",
    "prefixes": [
        "dpdk-dev",
        "14/15"
    ]
}