get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 22850,
    "url": "http://patches.dpdk.org/api/patches/22850/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1490829963-106807-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": "<1490829963-106807-15-git-send-email-harry.van.haaren@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1490829963-106807-15-git-send-email-harry.van.haaren@intel.com",
    "date": "2017-03-29T23:25:56",
    "name": "[dpdk-dev,v6,14/21] event/sw: add xstats support",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "902e723133b7eba35cb009e35767850991429056",
    "submitter": {
        "id": 317,
        "url": "http://patches.dpdk.org/api/people/317/?format=api",
        "name": "Van Haaren, Harry",
        "email": "harry.van.haaren@intel.com"
    },
    "delegate": {
        "id": 310,
        "url": "http://patches.dpdk.org/api/users/310/?format=api",
        "username": "jerin",
        "first_name": "Jerin",
        "last_name": "Jacob",
        "email": "jerinj@marvell.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1490829963-106807-15-git-send-email-harry.van.haaren@intel.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/22850/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/22850/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 4059110CD3;\n\tThu, 30 Mar 2017 02:40:27 +0200 (CEST)",
            "from mga11.intel.com (mga11.intel.com [192.55.52.93])\n\tby dpdk.org (Postfix) with ESMTP id 2621A9E3\n\tfor <dev@dpdk.org>; Thu, 30 Mar 2017 01:26:34 +0200 (CEST)",
            "from fmsmga006.fm.intel.com ([10.253.24.20])\n\tby fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t29 Mar 2017 16:26:33 -0700",
            "from silpixa00398672.ir.intel.com ([10.237.223.128])\n\tby fmsmga006.fm.intel.com with ESMTP; 29 Mar 2017 16:26:32 -0700"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=simple/simple;\n\td=intel.com; i=@intel.com; q=dns/txt; s=intel;\n\tt=1490829994; x=1522365994;\n\th=from:to:cc:subject:date:message-id:in-reply-to: references;\n\tbh=kR3jbrQnwdl2NmBGdKgBK+7UEVe/NKLtl464EzwOC0s=;\n\tb=DeU2G2fwJTIcAcFt4eX0oHlBnXzE4sAUFcDPXrgYpolO79k8f/9JlhGb\n\t+aVRh8s5x5q17ZVo/dkDLdhslrz71Q==;",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.36,243,1486454400\"; d=\"scan'208\";a=\"82491251\"",
        "From": "Harry van Haaren <harry.van.haaren@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "jerin.jacob@caviumnetworks.com,\n\tBruce Richardson <bruce.richardson@intel.com>,\n\tHarry van Haaren <harry.van.haaren@intel.com>",
        "Date": "Thu, 30 Mar 2017 00:25:56 +0100",
        "Message-Id": "<1490829963-106807-15-git-send-email-harry.van.haaren@intel.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": "<1490829963-106807-1-git-send-email-harry.van.haaren@intel.com>",
        "References": "<1490374395-149320-1-git-send-email-harry.van.haaren@intel.com>\n\t<1490829963-106807-1-git-send-email-harry.van.haaren@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v6 14/21] 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        |   9 +\n drivers/event/sw/sw_evdev.h        |  33 +-\n drivers/event/sw/sw_evdev_xstats.c | 674 +++++++++++++++++++++++++++++++++++++\n 4 files changed, 716 insertions(+), 1 deletion(-)\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 a7f5b3d..eb0dc4c 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 37f5db5..b40c0fc 100644\n--- a/drivers/event/sw/sw_evdev.c\n+++ b/drivers/event/sw/sw_evdev.c\n@@ -626,6 +626,9 @@ sw_start(struct rte_eventdev *dev)\n \t\t}\n \t}\n \n+\tif (sw_xstats_init(sw) < 0)\n+\t\treturn -EINVAL;\n+\n \trte_smp_wmb();\n \tsw->started = 1;\n \n@@ -636,6 +639,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 \trte_smp_wmb();\n }\n@@ -712,6 +716,11 @@ 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.xstats_get = sw_xstats_get,\n+\t\t\t.xstats_get_names = sw_xstats_get_names,\n+\t\t\t.xstats_get_by_name = sw_xstats_get_by_name,\n+\t\t\t.xstats_reset = sw_xstats_reset,\n \t};\n \n \tstatic const char *const args[] = {\ndiff --git a/drivers/event/sw/sw_evdev.h b/drivers/event/sw/sw_evdev.h\nindex 7c157c7..61c671d 100644\n--- a/drivers/event/sw/sw_evdev.h\n+++ b/drivers/event/sw/sw_evdev.h\n@@ -62,6 +62,8 @@\n \n #define SW_SCHED_TYPE_DIRECT (RTE_SCHED_TYPE_PARALLEL + 1)\n \n+#define SW_NUM_POLL_BUCKETS (MAX_SW_CONS_Q_DEPTH >> SW_DEQ_STAT_BUCKET_SHIFT)\n+\n enum {\n \tQE_FLAG_VALID_SHIFT = 0,\n \tQE_FLAG_COMPLETE_SHIFT,\n@@ -203,7 +205,7 @@ struct sw_port {\n \tuint64_t avg_pkt_ticks;      /* tracks average over NUM_SAMPLES burst */\n \tuint64_t total_polls;        /* how many polls were counted in stats */\n \tuint64_t zero_polls;         /* tracks polls returning nothing */\n-\tuint32_t poll_buckets[MAX_SW_CONS_Q_DEPTH >> SW_DEQ_STAT_BUCKET_SHIFT];\n+\tuint32_t poll_buckets[SW_NUM_POLL_BUCKETS];\n \t\t/* bucket values in 4s for shorter reporting */\n \n \t/* History list structs, containing info on pkts egressed to worker */\n@@ -230,6 +232,11 @@ 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+\tuint32_t xstats_count_mode_dev;\n+\tuint32_t xstats_count_mode_port;\n+\tuint32_t xstats_count_mode_queue;\n \n \t/* Contains all ports - load balanced and directed */\n \tstruct sw_port ports[SW_PORTS_MAX] __rte_cache_aligned;\n@@ -261,6 +268,13 @@ struct sw_evdev {\n \n \tuint8_t started;\n \tuint32_t credit_update_quanta;\n+\n+\t/* store num stats and offset of the stats for each port */\n+\tuint16_t xstats_count_per_port[SW_PORTS_MAX];\n+\tuint16_t xstats_offset_for_port[SW_PORTS_MAX];\n+\t/* store num stats and offset of the stats for each queue */\n+\tuint16_t xstats_count_per_qid[RTE_EVENT_MAX_QUEUES_PER_DEV];\n+\tuint16_t xstats_offset_for_qid[RTE_EVENT_MAX_QUEUES_PER_DEV];\n };\n \n static inline struct sw_evdev *\n@@ -283,5 +297,22 @@ 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_xstats_get_names(const struct rte_eventdev *dev,\n+\tenum rte_event_dev_xstats_mode mode, uint8_t queue_port_id,\n+\tstruct rte_event_dev_xstats_name *xstats_names,\n+\tunsigned int *ids, unsigned int size);\n+int sw_xstats_get(const struct rte_eventdev *dev,\n+\t\tenum rte_event_dev_xstats_mode mode, uint8_t queue_port_id,\n+\t\tconst unsigned int ids[], uint64_t values[], unsigned int n);\n+uint64_t sw_xstats_get_by_name(const struct rte_eventdev *dev,\n+\t\tconst char *name, unsigned int *id);\n+int sw_xstats_reset(struct rte_eventdev *dev,\n+\t\tenum rte_event_dev_xstats_mode mode,\n+\t\tint16_t queue_port_id,\n+\t\tconst uint32_t ids[],\n+\t\tuint32_t nb_ids);\n+\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..38f03c2\n--- /dev/null\n+++ b/drivers/event/sw/sw_evdev_xstats.c\n@@ -0,0 +1,674 @@\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_xstats_name name;\n+\txstats_fn fn;\n+\tuint16_t obj_idx;\n+\tenum xstats_type stat;\n+\tenum rte_event_dev_xstats_mode mode;\n+\tint extra_arg;\n+\tuint8_t reset_allowed; /* when set, this value can be reset */\n+\tuint64_t reset_value; /* an offset to be taken away to emulate resets */\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 three 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. The third array allows resetting or not.\n+\t * All these 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+\t/* all device stats are allowed to be reset */\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+\tstatic const uint8_t port_reset_allowed[] = {1, 1, 1,\n+\t\t\t0, 1, 0,\n+\t\t\t0, 0, 0, 0,\n+\t\t\t1, 1,\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+\t/* all bucket dequeues are allowed to be reset, handled in loop below */\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,\n+\t\t\tinflight, iq_size\n+\t};\n+\tstatic const uint8_t qid_reset_allowed[] = {1, 1, 1,\n+\t\t\t0, 0\n+\t};\n+\n+\tstatic const char * const qid_iq_stats[] = { \"used\" };\n+\tstatic const enum xstats_type qid_iq_types[] = { iq_used };\n+\t/* reset allowed */\n+\n+\tstatic const char * const qid_port_stats[] = { \"pinned_flows\" };\n+\tstatic const enum xstats_type qid_port_types[] = { pinned };\n+\t/* reset allowed */\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(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+\tRTE_BUILD_BUG_ON(RTE_DIM(port_bucket_stats) !=\n+\t\t\tRTE_DIM(port_bucket_types));\n+\n+\tRTE_BUILD_BUG_ON(RTE_DIM(port_stats) != RTE_DIM(port_reset_allowed));\n+\tRTE_BUILD_BUG_ON(RTE_DIM(qid_stats) != RTE_DIM(qid_reset_allowed));\n+\n+\t/* other vars */\n+\tconst uint32_t cons_bkt_shift =\n+\t\t(MAX_SW_CONS_Q_DEPTH >> SW_DEQ_STAT_BUCKET_SHIFT);\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(cons_bkt_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 *\n+\t\t\t\tRTE_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\t.mode = RTE_EVENT_DEV_XSTATS_DEVICE,\n+\t\t\t.reset_allowed = 1,\n+\t\t};\n+\t\tsnprintf(sname, sizeof(sname), \"dev_%s\", dev_stats[i]);\n+\t}\n+\tsw->xstats_count_mode_dev = stat;\n+\n+\tfor (port = 0; port < sw->port_count; port++) {\n+\t\tsw->xstats_offset_for_port[port] = stat;\n+\n+\t\tuint32_t count_offset = stat;\n+\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\t.mode = RTE_EVENT_DEV_XSTATS_PORT,\n+\t\t\t\t.reset_allowed = port_reset_allowed[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++) {\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.mode = RTE_EVENT_DEV_XSTATS_PORT,\n+\t\t\t\t\t.extra_arg = bkt,\n+\t\t\t\t\t.reset_allowed = 1,\n+\t\t\t\t};\n+\t\t\t\tsnprintf(sname, sizeof(sname),\n+\t\t\t\t\t\"port_%u_%s_%u-%u\",\n+\t\t\t\t\tport, port_bucket_stats[i],\n+\t\t\t\t\t(bkt << SW_DEQ_STAT_BUCKET_SHIFT) + 1,\n+\t\t\t\t\t(bkt + 1) << SW_DEQ_STAT_BUCKET_SHIFT);\n+\t\t\t\tstat++;\n+\t\t\t}\n+\t\t}\n+\n+\t\tsw->xstats_count_per_port[port] = stat - count_offset;\n+\t}\n+\n+\tsw->xstats_count_mode_port = stat - sw->xstats_count_mode_dev;\n+\n+\tfor (qid = 0; qid < sw->qid_count; qid++) {\n+\t\tuint32_t count_offset = stat;\n+\t\tsw->xstats_offset_for_qid[qid] = stat;\n+\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\t.mode = RTE_EVENT_DEV_XSTATS_QUEUE,\n+\t\t\t\t.reset_allowed = qid_reset_allowed[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.mode = RTE_EVENT_DEV_XSTATS_QUEUE,\n+\t\t\t\t\t.extra_arg = iq,\n+\t\t\t\t\t.reset_allowed = 0,\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.mode = RTE_EVENT_DEV_XSTATS_QUEUE,\n+\t\t\t\t\t.extra_arg = port,\n+\t\t\t\t\t.reset_allowed = 0,\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+\n+\t\tsw->xstats_count_per_qid[qid] = stat - count_offset;\n+\t}\n+\n+\tsw->xstats_count_mode_queue = stat -\n+\t\t(sw->xstats_count_mode_dev + sw->xstats_count_mode_port);\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_xstats_get_names(const struct rte_eventdev *dev,\n+\t\tenum rte_event_dev_xstats_mode mode, uint8_t queue_port_id,\n+\t\tstruct rte_event_dev_xstats_name *xstats_names,\n+\t\tunsigned int *ids, unsigned int size)\n+{\n+\tconst struct sw_evdev *sw = sw_pmd_priv_const(dev);\n+\tunsigned int i;\n+\tunsigned int xidx = 0;\n+\tRTE_SET_USED(mode);\n+\tRTE_SET_USED(queue_port_id);\n+\n+\tuint32_t xstats_mode_count = 0;\n+\tuint32_t start_offset = 0;\n+\n+\tswitch (mode) {\n+\tcase RTE_EVENT_DEV_XSTATS_DEVICE:\n+\t\txstats_mode_count = sw->xstats_count_mode_dev;\n+\t\tbreak;\n+\tcase RTE_EVENT_DEV_XSTATS_PORT:\n+\t\tif (queue_port_id >= (signed int)sw->port_count)\n+\t\t\tbreak;\n+\t\txstats_mode_count = sw->xstats_count_per_port[queue_port_id];\n+\t\tstart_offset = sw->xstats_offset_for_port[queue_port_id];\n+\t\tbreak;\n+\tcase RTE_EVENT_DEV_XSTATS_QUEUE:\n+\t\tif (queue_port_id >= (signed int)sw->qid_count)\n+\t\t\tbreak;\n+\t\txstats_mode_count = sw->xstats_count_per_qid[queue_port_id];\n+\t\tstart_offset = sw->xstats_offset_for_qid[queue_port_id];\n+\t\tbreak;\n+\tdefault:\n+\t\tSW_LOG_ERR(\"Invalid mode received in sw_xstats_get_names()\\n\");\n+\t\treturn -EINVAL;\n+\t};\n+\n+\tif (xstats_mode_count > size || !ids || !xstats_names)\n+\t\treturn xstats_mode_count;\n+\n+\tfor (i = 0; i < sw->xstats_count && xidx < size; i++) {\n+\t\tif (sw->xstats[i].mode != mode)\n+\t\t\tcontinue;\n+\n+\t\tif (mode != RTE_EVENT_DEV_XSTATS_DEVICE &&\n+\t\t\t\tqueue_port_id != sw->xstats[i].obj_idx)\n+\t\t\tcontinue;\n+\n+\t\txstats_names[xidx] = sw->xstats[i].name;\n+\t\tif (ids)\n+\t\t\tids[xidx] = start_offset + xidx;\n+\t\txidx++;\n+\t}\n+\treturn xidx;\n+}\n+\n+static int\n+sw_xstats_update(struct sw_evdev *sw, enum rte_event_dev_xstats_mode mode,\n+\t\tuint8_t queue_port_id, const unsigned int ids[],\n+\t\tuint64_t values[], unsigned int n, const uint32_t reset,\n+\t\tconst uint32_t ret_if_n_lt_nstats)\n+{\n+\tunsigned int i;\n+\tunsigned int xidx = 0;\n+\tRTE_SET_USED(mode);\n+\tRTE_SET_USED(queue_port_id);\n+\n+\tuint32_t xstats_mode_count = 0;\n+\n+\tswitch (mode) {\n+\tcase RTE_EVENT_DEV_XSTATS_DEVICE:\n+\t\txstats_mode_count = sw->xstats_count_mode_dev;\n+\t\tbreak;\n+\tcase RTE_EVENT_DEV_XSTATS_PORT:\n+\t\tif (queue_port_id >= (signed int)sw->port_count)\n+\t\t\tgoto invalid_value;\n+\t\txstats_mode_count = sw->xstats_count_per_port[queue_port_id];\n+\t\tbreak;\n+\tcase RTE_EVENT_DEV_XSTATS_QUEUE:\n+\t\tif (queue_port_id >= (signed int)sw->qid_count)\n+\t\t\tgoto invalid_value;\n+\t\txstats_mode_count = sw->xstats_count_per_qid[queue_port_id];\n+\t\tbreak;\n+\tdefault:\n+\t\tSW_LOG_ERR(\"Invalid mode received in sw_xstats_get()\\n\");\n+\t\tgoto invalid_value;\n+\t};\n+\n+\t/* this function can check num stats and return them (xstats_get() style\n+\t * behaviour) or ignore n for reset() of a single stat style behaviour.\n+\t */\n+\tif (ret_if_n_lt_nstats && xstats_mode_count > n)\n+\t\treturn xstats_mode_count;\n+\n+\tfor (i = 0; i < n && xidx < xstats_mode_count; i++) {\n+\t\tstruct sw_xstats_entry *xs = &sw->xstats[ids[i]];\n+\t\tif (ids[i] > sw->xstats_count || xs->mode != mode)\n+\t\t\tcontinue;\n+\n+\t\tif (mode != RTE_EVENT_DEV_XSTATS_DEVICE &&\n+\t\t\t\tqueue_port_id != xs->obj_idx)\n+\t\t\tcontinue;\n+\n+\t\tuint64_t val = xs->fn(sw, xs->obj_idx, xs->stat, xs->extra_arg)\n+\t\t\t\t\t- xs->reset_value;\n+\n+\t\tif (values)\n+\t\t\tvalues[xidx] = val;\n+\n+\t\tif (xs->reset_allowed && reset)\n+\t\t\txs->reset_value = val;\n+\n+\t\txidx++;\n+\t}\n+\n+\treturn xidx;\n+invalid_value:\n+\treturn -EINVAL;\n+}\n+\n+int\n+sw_xstats_get(const struct rte_eventdev *dev,\n+\t\tenum rte_event_dev_xstats_mode mode, uint8_t queue_port_id,\n+\t\tconst unsigned int ids[], uint64_t values[], unsigned int n)\n+{\n+\tstruct sw_evdev *sw = sw_pmd_priv(dev);\n+\tconst uint32_t reset = 0;\n+\tconst uint32_t ret_n_lt_stats = 1;\n+\treturn sw_xstats_update(sw, mode, queue_port_id, ids, values, n,\n+\t\t\t\treset, ret_n_lt_stats);\n+}\n+\n+uint64_t\n+sw_xstats_get_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_XSTATS_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\t\t\t- xs->reset_value;\n+\t\t}\n+\t}\n+\tif (id != NULL)\n+\t\t*id = (uint32_t)-1;\n+\treturn (uint64_t)-1;\n+}\n+\n+static void\n+sw_xstats_reset_range(struct sw_evdev *sw, uint32_t start, uint32_t num)\n+{\n+\tuint32_t i;\n+\tfor (i = start; i < start + num; i++) {\n+\t\tstruct sw_xstats_entry *xs = &sw->xstats[i];\n+\t\tif (!xs->reset_allowed)\n+\t\t\tcontinue;\n+\n+\t\tuint64_t val = xs->fn(sw, xs->obj_idx, xs->stat, xs->extra_arg)\n+\t\t\t\t\t- xs->reset_value;\n+\t\txs->reset_value = val;\n+\t}\n+}\n+\n+static int\n+sw_xstats_reset_queue(struct sw_evdev *sw, uint8_t queue_id,\n+\t\tconst uint32_t ids[], uint32_t nb_ids)\n+{\n+\tconst uint32_t reset = 1;\n+\tconst uint32_t ret_n_lt_stats = 0;\n+\tif (ids) {\n+\t\tuint32_t nb_reset = sw_xstats_update(sw,\n+\t\t\t\t\tRTE_EVENT_DEV_XSTATS_QUEUE,\n+\t\t\t\t\tqueue_id, ids, NULL, nb_ids,\n+\t\t\t\t\treset, ret_n_lt_stats);\n+\t\treturn nb_reset == nb_ids ? 0 : -EINVAL;\n+\t}\n+\n+\tif (ids == NULL)\n+\t\tsw_xstats_reset_range(sw, sw->xstats_offset_for_qid[queue_id],\n+\t\t\t\t      sw->xstats_count_per_qid[queue_id]);\n+\n+\treturn 0;\n+}\n+\n+static int\n+sw_xstats_reset_port(struct sw_evdev *sw, uint8_t port_id,\n+\t\tconst uint32_t ids[], uint32_t nb_ids)\n+{\n+\tconst uint32_t reset = 1;\n+\tconst uint32_t ret_n_lt_stats = 0;\n+\tint offset = sw->xstats_offset_for_port[port_id];\n+\tint nb_stat = sw->xstats_count_per_port[port_id];\n+\n+\tif (ids) {\n+\t\tuint32_t nb_reset = sw_xstats_update(sw,\n+\t\t\t\t\tRTE_EVENT_DEV_XSTATS_PORT, port_id,\n+\t\t\t\t\tids, NULL, nb_ids,\n+\t\t\t\t\treset, ret_n_lt_stats);\n+\t\treturn nb_reset == nb_ids ? 0 : -EINVAL;\n+\t} else\n+\t\tsw_xstats_reset_range(sw, offset, nb_stat);\n+\n+\treturn 0;\n+}\n+\n+static int\n+sw_xstats_reset_dev(struct sw_evdev *sw, const uint32_t ids[], uint32_t nb_ids)\n+{\n+\tuint32_t i;\n+\tif (ids) {\n+\t\tfor (i = 0; i < nb_ids; i++) {\n+\t\t\tuint32_t id = ids[i];\n+\t\t\tif (id >= sw->xstats_count_mode_dev)\n+\t\t\t\treturn -EINVAL;\n+\t\t\tsw_xstats_reset_range(sw, id, 1);\n+\t\t}\n+\t} else {\n+\t\tfor (i = 0; i < sw->xstats_count_mode_dev; i++)\n+\t\t\tsw_xstats_reset_range(sw, i, 1);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int\n+sw_xstats_reset(struct rte_eventdev *dev,\n+\t\tenum rte_event_dev_xstats_mode mode,\n+\t\tint16_t queue_port_id,\n+\t\tconst uint32_t ids[],\n+\t\tuint32_t nb_ids)\n+{\n+\tstruct sw_evdev *sw = sw_pmd_priv(dev);\n+\tuint32_t i, err;\n+\n+\t/* handle -1 for queue_port_id here, looping over all ports/queues */\n+\tswitch (mode) {\n+\tcase RTE_EVENT_DEV_XSTATS_DEVICE:\n+\t\tsw_xstats_reset_dev(sw, ids, nb_ids);\n+\t\tbreak;\n+\tcase RTE_EVENT_DEV_XSTATS_PORT:\n+\t\tif (queue_port_id == -1) {\n+\t\t\tfor (i = 0; i < sw->port_count; i++) {\n+\t\t\t\terr = sw_xstats_reset_port(sw, i, ids, nb_ids);\n+\t\t\t\tif (err)\n+\t\t\t\t\treturn -EINVAL;\n+\t\t\t}\n+\t\t} else if (queue_port_id < (int16_t)sw->port_count)\n+\t\t\tsw_xstats_reset_port(sw, queue_port_id, ids, nb_ids);\n+\t\tbreak;\n+\tcase RTE_EVENT_DEV_XSTATS_QUEUE:\n+\t\tif (queue_port_id == -1) {\n+\t\t\tfor (i = 0; i < sw->qid_count; i++) {\n+\t\t\t\terr = sw_xstats_reset_queue(sw, i, ids, nb_ids);\n+\t\t\t\tif (err)\n+\t\t\t\t\treturn -EINVAL;\n+\t\t\t}\n+\t\t} else if (queue_port_id < (int16_t)sw->qid_count)\n+\t\t\tsw_xstats_reset_queue(sw, queue_port_id, ids, nb_ids);\n+\t\tbreak;\n+\t};\n+\n+\treturn 0;\n+}\n",
    "prefixes": [
        "dpdk-dev",
        "v6",
        "14/21"
    ]
}