get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 81438,
    "url": "http://patches.dpdk.org/api/patches/81438/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1603182389-10087-2-git-send-email-humin29@huawei.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": "<1603182389-10087-2-git-send-email-humin29@huawei.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1603182389-10087-2-git-send-email-humin29@huawei.com",
    "date": "2020-10-20T08:26:28",
    "name": "[RFC,V2,1/2] app/testpmd: fix queue stats mapping configuration",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "fe63d6c908f20bcb074426444f84dddf77de1710",
    "submitter": {
        "id": 1944,
        "url": "http://patches.dpdk.org/api/people/1944/?format=api",
        "name": "humin (Q)",
        "email": "humin29@huawei.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1603182389-10087-2-git-send-email-humin29@huawei.com/mbox/",
    "series": [
        {
            "id": 13130,
            "url": "http://patches.dpdk.org/api/series/13130/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=13130",
            "date": "2020-10-20T08:26:29",
            "name": "fix queue stats mapping",
            "version": 2,
            "mbox": "http://patches.dpdk.org/series/13130/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/81438/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/81438/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 dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 19A48A04DC;\n\tTue, 20 Oct 2020 10:26:17 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 46245BBA2;\n\tTue, 20 Oct 2020 10:26:01 +0200 (CEST)",
            "from huawei.com (szxga05-in.huawei.com [45.249.212.191])\n by dpdk.org (Postfix) with ESMTP id 05791A8E3\n for <dev@dpdk.org>; Tue, 20 Oct 2020 10:25:56 +0200 (CEST)",
            "from DGGEMS405-HUB.china.huawei.com (unknown [172.30.72.58])\n by Forcepoint Email with ESMTP id BAD95B71FC0318403F86;\n Tue, 20 Oct 2020 16:25:53 +0800 (CST)",
            "from localhost.localdomain (10.69.192.56) by\n DGGEMS405-HUB.china.huawei.com (10.3.19.205) with Microsoft SMTP Server id\n 14.3.487.0; Tue, 20 Oct 2020 16:25:46 +0800"
        ],
        "From": "\"Min Hu (Connor)\" <humin29@huawei.com>",
        "To": "<dev@dpdk.org>",
        "CC": "<ferruh.yigit@intel.com>, <bruce.richardson@intel.com>,\n <thomas.monjalon@6wind.com>, <lihuisong@huawei.com>",
        "Date": "Tue, 20 Oct 2020 16:26:28 +0800",
        "Message-ID": "<1603182389-10087-2-git-send-email-humin29@huawei.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": "<1603182389-10087-1-git-send-email-humin29@huawei.com>",
        "References": "<1603182389-10087-1-git-send-email-humin29@huawei.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[10.69.192.56]",
        "X-CFilter-Loop": "Reflected",
        "Subject": "[dpdk-dev] [RFC V2 1/2] app/testpmd: fix queue stats mapping\n\tconfiguration",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "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",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Huisong Li <lihuisong@huawei.com>\n\nCurrently, the queue stats mapping has the following problems:\n1) Many PMD drivers don't support queue stats mapping. But there is no\nfailure message after executing the command \"set stat_qmap rx 0 2 2\".\n2) Once queue mapping is set, unrelated and unmapped queues are also\ndisplayed.\n3) There is no need to keep cache line alignment for\n'struct queue_stats_mappings'.\n4) The mapping arrays, 'tx_queue_stats_mappings_array' &\n'rx_queue_stats_mappings_array' are global and their sizes are based on\nfixed max port and queue size assumptions.\n5) The configuration result does not take effect or can not be queried\nin real time.\n\nTherefore, we have made the following adjustments:\n1) If PMD supports queue stats mapping, configure to driver in real time\nafter executing the command \"set stat_qmap rx/tx ...\". If not,\nthe command can not be accepted.\n2) Only display queues that mapping done by adding a new 'active' field\n in queue_stats_mappings struct.\n3) Remove cache alignment for 'struct queue_stats_mappings'.\n4) Add a new port_stats_mappings struct in rte_port.\nThe struct contains number of rx/txq stats mapping, rx/tx\nqueue_stats_mapping_enabled flag, and rx/tx queue_stats_mapping array.\nSize of queue_stats_mapping_array is set to \"RTE_ETHDEV_QUEUE_STAT_CNTRS\"\n to ensure that the same number of queues can be set for each port.\n\nFixes: 4dccdc789bf4b (\"app/testpmd: simplify handling of stats mappings error\")\nFixes: 013af9b6b64f6 (\"app/testpmd: various updates\")\nFixes: ed30d9b691b21 (\"app/testpmd: add stats per queue\")\n\nSigned-off-by: Huisong Li <lihuisong@huawei.com>\n---\n app/test-pmd/config.c     | 180 +++++++++++++++++++++++++++++-----------------\n app/test-pmd/parameters.c |  63 ++++++++--------\n app/test-pmd/testpmd.c    | 180 ++++++++++++++++++++++++++++++++--------------\n app/test-pmd/testpmd.h    |  41 ++++++-----\n 4 files changed, 292 insertions(+), 172 deletions(-)",
    "diff": "diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c\nindex ba17f3b..325c42f 100644\n--- a/app/test-pmd/config.c\n+++ b/app/test-pmd/config.c\n@@ -177,13 +177,13 @@ nic_stats_display(portid_t port_id)\n \tstatic uint64_t prev_bytes_rx[RTE_MAX_ETHPORTS];\n \tstatic uint64_t prev_bytes_tx[RTE_MAX_ETHPORTS];\n \tstatic uint64_t prev_ns[RTE_MAX_ETHPORTS];\n+\tstruct port_stats_mappings *p_stats_map;\n \tstruct timespec cur_time;\n \tuint64_t diff_pkts_rx, diff_pkts_tx, diff_bytes_rx, diff_bytes_tx,\n \t\t\t\t\t\t\t\tdiff_ns;\n \tuint64_t mpps_rx, mpps_tx, mbps_rx, mbps_tx;\n \tstruct rte_eth_stats stats;\n-\tstruct rte_port *port = &ports[port_id];\n-\tuint8_t i;\n+\tstruct rte_port *port;\n \n \tstatic const char *nic_stats_border = \"########################\";\n \n@@ -195,7 +195,10 @@ nic_stats_display(portid_t port_id)\n \tprintf(\"\\n  %s NIC statistics for port %-2d %s\\n\",\n \t       nic_stats_border, port_id, nic_stats_border);\n \n-\tif ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {\n+\tport = &ports[port_id];\n+\tp_stats_map = &port->p_stats_map;\n+\tif ((!p_stats_map->rx_queue_stats_mapping_enabled) &&\n+\t\t(!p_stats_map->tx_queue_stats_mapping_enabled)) {\n \t\tprintf(\"  RX-packets: %-10\"PRIu64\" RX-missed: %-10\"PRIu64\" RX-bytes:  \"\n \t\t       \"%-\"PRIu64\"\\n\",\n \t\t       stats.ipackets, stats.imissed, stats.ibytes);\n@@ -205,36 +208,20 @@ nic_stats_display(portid_t port_id)\n \t\tprintf(\"  TX-packets: %-10\"PRIu64\" TX-errors: %-10\"PRIu64\" TX-bytes:  \"\n \t\t       \"%-\"PRIu64\"\\n\",\n \t\t       stats.opackets, stats.oerrors, stats.obytes);\n-\t}\n-\telse {\n-\t\tprintf(\"  RX-packets:              %10\"PRIu64\"    RX-errors: %10\"PRIu64\n-\t\t       \"    RX-bytes: %10\"PRIu64\"\\n\",\n-\t\t       stats.ipackets, stats.ierrors, stats.ibytes);\n-\t\tprintf(\"  RX-errors:  %10\"PRIu64\"\\n\", stats.ierrors);\n-\t\tprintf(\"  RX-nombuf:               %10\"PRIu64\"\\n\",\n+\t} else {\n+\t\tprintf(\"  RX-packets:             %14\"PRIu64\"    RX-missed: \"\n+\t\t       \"%14\"PRIu64\"    RX-bytes: %14\"PRIu64\"\\n\",\n+\t\t       stats.ipackets, stats.imissed, stats.ibytes);\n+\t\tprintf(\"  RX-errors:              %14\"PRIu64\"\\n\",\n+\t\t       stats.ierrors);\n+\t\tprintf(\"  RX-nombuf:              %14\"PRIu64\"\\n\",\n \t\t       stats.rx_nombuf);\n-\t\tprintf(\"  TX-packets:              %10\"PRIu64\"    TX-errors: %10\"PRIu64\n-\t\t       \"    TX-bytes: %10\"PRIu64\"\\n\",\n+\t\tprintf(\"  TX-packets:             %14\"PRIu64\"    TX-errors: \"\n+\t\t       \"%14\"PRIu64\"    TX-bytes: %14\"PRIu64\"\\n\",\n \t\t       stats.opackets, stats.oerrors, stats.obytes);\n \t}\n \n-\tif (port->rx_queue_stats_mapping_enabled) {\n-\t\tprintf(\"\\n\");\n-\t\tfor (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {\n-\t\t\tprintf(\"  Stats reg %2d RX-packets: %10\"PRIu64\n-\t\t\t       \"    RX-errors: %10\"PRIu64\n-\t\t\t       \"    RX-bytes: %10\"PRIu64\"\\n\",\n-\t\t\t       i, stats.q_ipackets[i], stats.q_errors[i], stats.q_ibytes[i]);\n-\t\t}\n-\t}\n-\tif (port->tx_queue_stats_mapping_enabled) {\n-\t\tprintf(\"\\n\");\n-\t\tfor (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {\n-\t\t\tprintf(\"  Stats reg %2d TX-packets: %10\"PRIu64\n-\t\t\t       \"                             TX-bytes: %10\"PRIu64\"\\n\",\n-\t\t\t       i, stats.q_opackets[i], stats.q_obytes[i]);\n-\t\t}\n-\t}\n+\tport_stats_mapping_display(port_id, &stats);\n \n \tdiff_ns = 0;\n \tif (clock_gettime(CLOCK_TYPE_ID, &cur_time) == 0) {\n@@ -400,7 +387,9 @@ nic_xstats_clear(portid_t port_id)\n void\n nic_stats_mapping_display(portid_t port_id)\n {\n-\tstruct rte_port *port = &ports[port_id];\n+\tstruct port_stats_mappings *p_stats_map;\n+\tstruct queue_stats_mappings *q_stats_map;\n+\tstruct rte_port *port;\n \tuint16_t i;\n \n \tstatic const char *nic_stats_mapping_border = \"########################\";\n@@ -410,7 +399,10 @@ nic_stats_mapping_display(portid_t port_id)\n \t\treturn;\n \t}\n \n-\tif ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {\n+\tport = &ports[port_id];\n+\tp_stats_map = &port->p_stats_map;\n+\tif ((!p_stats_map->rx_queue_stats_mapping_enabled) &&\n+\t\t(!p_stats_map->tx_queue_stats_mapping_enabled)) {\n \t\tprintf(\"Port id %d - either does not support queue statistic mapping or\"\n \t\t       \" no queue statistic mapping set\\n\", port_id);\n \t\treturn;\n@@ -419,24 +411,26 @@ nic_stats_mapping_display(portid_t port_id)\n \tprintf(\"\\n  %s NIC statistics mapping for port %-2d %s\\n\",\n \t       nic_stats_mapping_border, port_id, nic_stats_mapping_border);\n \n-\tif (port->rx_queue_stats_mapping_enabled) {\n-\t\tfor (i = 0; i < nb_rx_queue_stats_mappings; i++) {\n-\t\t\tif (rx_queue_stats_mappings[i].port_id == port_id) {\n+\tif (p_stats_map->rx_queue_stats_mapping_enabled) {\n+\t\tfor (i = 0; i < p_stats_map->nb_rxq_stats_mappings; i++) {\n+\t\t\tq_stats_map = &p_stats_map->rxq_map_array[i];\n+\t\t\tif (q_stats_map->active) {\n \t\t\t\tprintf(\"  RX-queue %2d mapped to Stats Reg %2d\\n\",\n-\t\t\t\t       rx_queue_stats_mappings[i].queue_id,\n-\t\t\t\t       rx_queue_stats_mappings[i].stats_counter_id);\n+\t\t\t\t       q_stats_map->queue_id,\n+\t\t\t\t       q_stats_map->stats_counter_id);\n \t\t\t}\n \t\t}\n \t\tprintf(\"\\n\");\n \t}\n \n \n-\tif (port->tx_queue_stats_mapping_enabled) {\n-\t\tfor (i = 0; i < nb_tx_queue_stats_mappings; i++) {\n-\t\t\tif (tx_queue_stats_mappings[i].port_id == port_id) {\n+\tif (p_stats_map->tx_queue_stats_mapping_enabled) {\n+\t\tfor (i = 0; i < p_stats_map->nb_txq_stats_mappings; i++) {\n+\t\t\tq_stats_map = &p_stats_map->txq_map_array[i];\n+\t\t\tif (q_stats_map->active) {\n \t\t\t\tprintf(\"  TX-queue %2d mapped to Stats Reg %2d\\n\",\n-\t\t\t\t       tx_queue_stats_mappings[i].queue_id,\n-\t\t\t\t       tx_queue_stats_mappings[i].stats_counter_id);\n+\t\t\t\t       q_stats_map->queue_id,\n+\t\t\t\t       q_stats_map->stats_counter_id);\n \t\t\t}\n \t\t}\n \t}\n@@ -4546,8 +4540,13 @@ tx_vlan_pvid_set(portid_t port_id, uint16_t vlan_id, int on)\n void\n set_qmap(portid_t port_id, uint8_t is_rx, uint16_t queue_id, uint8_t map_value)\n {\n+\tstruct port_stats_mappings *p_stats_map;\n+\tstruct queue_stats_mappings *q_stats_map;\n+\tbool existing_mapping_found = false;\n+\tstruct rte_port *port;\n+\tuint16_t cur_map_idx;\n \tuint16_t i;\n-\tuint8_t existing_mapping_found = 0;\n+\tint ret;\n \n \tif (port_id_is_invalid(port_id, ENABLED_WARN))\n \t\treturn;\n@@ -4561,37 +4560,88 @@ set_qmap(portid_t port_id, uint8_t is_rx, uint16_t queue_id, uint8_t map_value)\n \t\treturn;\n \t}\n \n-\tif (!is_rx) { /*then tx*/\n-\t\tfor (i = 0; i < nb_tx_queue_stats_mappings; i++) {\n-\t\t\tif ((tx_queue_stats_mappings[i].port_id == port_id) &&\n-\t\t\t    (tx_queue_stats_mappings[i].queue_id == queue_id)) {\n-\t\t\t\ttx_queue_stats_mappings[i].stats_counter_id = map_value;\n-\t\t\t\texisting_mapping_found = 1;\n+\tport = &ports[port_id];\n+\tp_stats_map = &port->p_stats_map;\n+\tif (!is_rx) { /* tx */\n+\t\tfor (i = 0; i < p_stats_map->nb_txq_stats_mappings; i++) {\n+\t\t\tq_stats_map = &p_stats_map->txq_map_array[i];\n+\t\t\tif (q_stats_map->queue_id == queue_id) {\n+\t\t\t\tret =\n+\t\t\t\trte_eth_dev_set_tx_queue_stats_mapping(port_id,\n+\t\t\t\t\t\t\tqueue_id, map_value);\n+\t\t\t\tif (ret) {\n+\t\t\t\t\tprintf(\"failed to set tx queue stats \"\n+\t\t\t\t\t\t\"mapping.\\n\");\n+\t\t\t\t\treturn;\n+\t\t\t\t}\n+\n+\t\t\t\tq_stats_map->stats_counter_id = map_value;\n+\t\t\t\tq_stats_map->active = true;\n+\t\t\t\texisting_mapping_found = true;\n \t\t\t\tbreak;\n \t\t\t}\n \t\t}\n-\t\tif (!existing_mapping_found) { /* A new additional mapping... */\n-\t\t\ttx_queue_stats_mappings[nb_tx_queue_stats_mappings].port_id = port_id;\n-\t\t\ttx_queue_stats_mappings[nb_tx_queue_stats_mappings].queue_id = queue_id;\n-\t\t\ttx_queue_stats_mappings[nb_tx_queue_stats_mappings].stats_counter_id = map_value;\n-\t\t\tnb_tx_queue_stats_mappings++;\n+\n+\t\t/* A new additional mapping... */\n+\t\tif (!existing_mapping_found) {\n+\t\t\tret = rte_eth_dev_set_tx_queue_stats_mapping(port_id,\n+\t\t\t\t\t\t\t\t     queue_id,\n+\t\t\t\t\t\t\t\t     map_value);\n+\t\t\tif (ret) {\n+\t\t\t\tprintf(\"failed to set tx queue stats \"\n+\t\t\t\t\t\"mapping.\\n\");\n+\t\t\t\treturn;\n+\t\t\t}\n+\n+\t\t\tcur_map_idx = p_stats_map->nb_txq_stats_mappings;\n+\t\t\tq_stats_map = &p_stats_map->txq_map_array[cur_map_idx];\n+\t\t\tq_stats_map->queue_id = queue_id;\n+\t\t\tq_stats_map->stats_counter_id = map_value;\n+\t\t\tq_stats_map->active = true;\n+\t\t\tp_stats_map->nb_txq_stats_mappings++;\n \t\t}\n-\t}\n-\telse { /*rx*/\n-\t\tfor (i = 0; i < nb_rx_queue_stats_mappings; i++) {\n-\t\t\tif ((rx_queue_stats_mappings[i].port_id == port_id) &&\n-\t\t\t    (rx_queue_stats_mappings[i].queue_id == queue_id)) {\n-\t\t\t\trx_queue_stats_mappings[i].stats_counter_id = map_value;\n-\t\t\t\texisting_mapping_found = 1;\n+\n+\t\tp_stats_map->tx_queue_stats_mapping_enabled = true;\n+\t} else { /* rx */\n+\t\tfor (i = 0; i < p_stats_map->nb_rxq_stats_mappings; i++) {\n+\t\t\tq_stats_map = &p_stats_map->rxq_map_array[i];\n+\t\t\tif (q_stats_map->queue_id == queue_id) {\n+\t\t\t\tret =\n+\t\t\t\trte_eth_dev_set_rx_queue_stats_mapping(port_id,\n+\t\t\t\t\t\t\tqueue_id, map_value);\n+\t\t\t\tif (ret) {\n+\t\t\t\t\tprintf(\"failed to set rx queue stats \"\n+\t\t\t\t\t\t\"mapping.\\n\");\n+\t\t\t\t\treturn;\n+\t\t\t\t}\n+\n+\t\t\t\tq_stats_map->stats_counter_id = map_value;\n+\t\t\t\tq_stats_map->active = true;\n+\t\t\t\texisting_mapping_found = true;\n \t\t\t\tbreak;\n \t\t\t}\n \t\t}\n-\t\tif (!existing_mapping_found) { /* A new additional mapping... */\n-\t\t\trx_queue_stats_mappings[nb_rx_queue_stats_mappings].port_id = port_id;\n-\t\t\trx_queue_stats_mappings[nb_rx_queue_stats_mappings].queue_id = queue_id;\n-\t\t\trx_queue_stats_mappings[nb_rx_queue_stats_mappings].stats_counter_id = map_value;\n-\t\t\tnb_rx_queue_stats_mappings++;\n+\n+\t\t/* A new additional mapping... */\n+\t\tif (!existing_mapping_found) {\n+\t\t\tret = rte_eth_dev_set_rx_queue_stats_mapping(port_id,\n+\t\t\t\t\t\t\t\t     queue_id,\n+\t\t\t\t\t\t\t\t     map_value);\n+\t\t\tif (ret) {\n+\t\t\t\tprintf(\"failed to set rx queue stats \"\n+\t\t\t\t\t\"mapping.\\n\");\n+\t\t\t\treturn;\n+\t\t\t}\n+\n+\t\t\tcur_map_idx = p_stats_map->nb_rxq_stats_mappings;\n+\t\t\tq_stats_map = &p_stats_map->rxq_map_array[cur_map_idx];\n+\t\t\tq_stats_map->queue_id = queue_id;\n+\t\t\tq_stats_map->stats_counter_id = map_value;\n+\t\t\tq_stats_map->active = true;\n+\t\t\tp_stats_map->nb_rxq_stats_mappings++;\n \t\t}\n+\n+\t\tp_stats_map->rx_queue_stats_mapping_enabled = true;\n \t}\n }\n \ndiff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c\nindex 5ae0cb6..ee2501b 100644\n--- a/app/test-pmd/parameters.c\n+++ b/app/test-pmd/parameters.c\n@@ -300,7 +300,6 @@ parse_fwd_portmask(const char *portmask)\n \t\tset_fwd_ports_mask((uint64_t) pm);\n }\n \n-\n static int\n parse_queue_stats_mapping_config(const char *q_arg, int is_rx)\n {\n@@ -315,11 +314,13 @@ parse_queue_stats_mapping_config(const char *q_arg, int is_rx)\n \t};\n \tunsigned long int_fld[_NUM_FLD];\n \tchar *str_fld[_NUM_FLD];\n+\tstruct rte_port *port;\n \tint i;\n \tunsigned size;\n-\n-\t/* reset from value set at definition */\n-\tis_rx ? (nb_rx_queue_stats_mappings = 0) : (nb_tx_queue_stats_mappings = 0);\n+\tint port_id;\n+\tstruct queue_stats_mappings *q_stats_map;\n+\tstruct port_stats_mappings *p_stats_map;\n+\tuint16_t q_map_idx;\n \n \twhile ((p = strchr(p0,'(')) != NULL) {\n \t\t++p;\n@@ -346,44 +347,40 @@ parse_queue_stats_mapping_config(const char *q_arg, int is_rx)\n \t\t\treturn -1;\n \t\t}\n \n+\t\tport_id = (uint8_t)int_fld[FLD_PORT];\n+\t\tport = &ports[port_id];\n+\t\tp_stats_map = &port->p_stats_map;\n \t\tif (!is_rx) {\n-\t\t\tif ((nb_tx_queue_stats_mappings >=\n-\t\t\t\t\t\tMAX_TX_QUEUE_STATS_MAPPINGS)) {\n+\t\t\tq_map_idx = p_stats_map->nb_txq_stats_mappings;\n+\t\t\tif (q_map_idx >= RTE_ETHDEV_QUEUE_STAT_CNTRS) {\n \t\t\t\tprintf(\"exceeded max number of TX queue \"\n-\t\t\t\t\t\t\"statistics mappings: %hu\\n\",\n-\t\t\t\t\t\tnb_tx_queue_stats_mappings);\n+\t\t\t\t\t\"statistics mappings: %hu\\n\",\n+\t\t\t\t\tp_stats_map->nb_txq_stats_mappings);\n \t\t\t\treturn -1;\n \t\t\t}\n-\t\t\ttx_queue_stats_mappings_array[nb_tx_queue_stats_mappings].port_id =\n-\t\t\t\t(uint8_t)int_fld[FLD_PORT];\n-\t\t\ttx_queue_stats_mappings_array[nb_tx_queue_stats_mappings].queue_id =\n-\t\t\t\t(uint8_t)int_fld[FLD_QUEUE];\n-\t\t\ttx_queue_stats_mappings_array[nb_tx_queue_stats_mappings].stats_counter_id =\n-\t\t\t\t(uint8_t)int_fld[FLD_STATS_COUNTER];\n-\t\t\t++nb_tx_queue_stats_mappings;\n-\t\t}\n-\t\telse {\n-\t\t\tif ((nb_rx_queue_stats_mappings >=\n-\t\t\t\t\t\tMAX_RX_QUEUE_STATS_MAPPINGS)) {\n+\t\t\tq_stats_map =\n+\t\t\t\t&p_stats_map->txq_map_array[q_map_idx];\n+\t\t\tq_stats_map->queue_id = int_fld[FLD_QUEUE];\n+\t\t\tq_stats_map->stats_counter_id =\n+\t\t\t\t\t\tint_fld[FLD_STATS_COUNTER];\n+\t\t\t++p_stats_map->nb_txq_stats_mappings;\n+\t\t} else {\n+\t\t\tq_map_idx = p_stats_map->nb_rxq_stats_mappings;\n+\t\t\tif (q_map_idx >= RTE_ETHDEV_QUEUE_STAT_CNTRS) {\n \t\t\t\tprintf(\"exceeded max number of RX queue \"\n-\t\t\t\t\t\t\"statistics mappings: %hu\\n\",\n-\t\t\t\t\t\tnb_rx_queue_stats_mappings);\n+\t\t\t\t\t\"statistics mappings: %hu\\n\",\n+\t\t\t\t\tp_stats_map->nb_rxq_stats_mappings);\n \t\t\t\treturn -1;\n \t\t\t}\n-\t\t\trx_queue_stats_mappings_array[nb_rx_queue_stats_mappings].port_id =\n-\t\t\t\t(uint8_t)int_fld[FLD_PORT];\n-\t\t\trx_queue_stats_mappings_array[nb_rx_queue_stats_mappings].queue_id =\n-\t\t\t\t(uint8_t)int_fld[FLD_QUEUE];\n-\t\t\trx_queue_stats_mappings_array[nb_rx_queue_stats_mappings].stats_counter_id =\n-\t\t\t\t(uint8_t)int_fld[FLD_STATS_COUNTER];\n-\t\t\t++nb_rx_queue_stats_mappings;\n+\t\t\tq_stats_map =\n+\t\t\t\t&p_stats_map->rxq_map_array[q_map_idx];\n+\t\t\tq_stats_map->queue_id = int_fld[FLD_QUEUE];\n+\t\t\tq_stats_map->stats_counter_id =\n+\t\t\t\t\t\tint_fld[FLD_STATS_COUNTER];\n+\t\t\t++p_stats_map->nb_rxq_stats_mappings;\n \t\t}\n-\n \t}\n-/* Reassign the rx/tx_queue_stats_mappings pointer to point to this newly populated array rather */\n-/* than to the default array (that was set at its definition) */\n-\tis_rx ? (rx_queue_stats_mappings = rx_queue_stats_mappings_array) :\n-\t\t(tx_queue_stats_mappings = tx_queue_stats_mappings_array);\n+\n \treturn 0;\n }\n \ndiff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c\nindex 94e3688..86e3271 100644\n--- a/app/test-pmd/testpmd.c\n+++ b/app/test-pmd/testpmd.c\n@@ -476,15 +476,6 @@ struct rte_fdir_conf fdir_conf = {\n \n volatile int test_done = 1; /* stop packet forwarding when set to 1. */\n \n-struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];\n-struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];\n-\n-struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array;\n-struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array;\n-\n-uint16_t nb_tx_queue_stats_mappings = 0;\n-uint16_t nb_rx_queue_stats_mappings = 0;\n-\n /*\n  * Display zero values by default for xstats\n  */\n@@ -1809,10 +1800,84 @@ fwd_stream_stats_display(streamid_t stream_id)\n }\n \n void\n+port_stats_mapping_display(portid_t pt_id, struct rte_eth_stats *stats)\n+{\n+\tstruct port_stats_mappings *p_stats_map;\n+\tstruct queue_stats_mappings *q_stats_map;\n+\tbool txq_stats_map_found = false;\n+\tbool rxq_stats_map_found = false;\n+\tuint16_t nb_txq_stats_map;\n+\tuint16_t nb_rxq_stats_map;\n+\tstruct rte_port *port;\n+\tuint16_t i, j;\n+\n+\tif (stats == NULL) {\n+\t\tprintf(\"input stats address is null pointer.\\n\");\n+\t\treturn;\n+\t}\n+\n+\tif (port_id_is_invalid(pt_id, ENABLED_WARN)) {\n+\t\tprint_valid_ports();\n+\t\treturn;\n+\t}\n+\n+\tport = &ports[pt_id];\n+\tp_stats_map = &port->p_stats_map;\n+\tif (p_stats_map->rx_queue_stats_mapping_enabled) {\n+\t\tprintf(\"\\n\");\n+\t\tnb_rxq_stats_map = p_stats_map->nb_rxq_stats_mappings;\n+\t\tfor (j = 0; j < RTE_ETHDEV_QUEUE_STAT_CNTRS; j++) {\n+\t\t\tfor (i = 0; i < nb_rxq_stats_map; i++) {\n+\t\t\t\tq_stats_map = &p_stats_map->rxq_map_array[i];\n+\t\t\t\tif (q_stats_map->stats_counter_id == j &&\n+\t\t\t\t\tq_stats_map->active) {\n+\t\t\t\t\trxq_stats_map_found = true;\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t}\n+\n+\t\t\tif (rxq_stats_map_found) {\n+\t\t\t\tprintf(\"  Stats reg %2d RX-packets:%14\"PRIu64\n+\t\t\t\t       \"    RX-errors: %14\"PRIu64\n+\t\t\t\t       \"    RX-bytes:%14\"PRIu64\"\\n\",\n+\t\t\t\t       j, stats->q_ipackets[j],\n+\t\t\t\t       stats->q_errors[j],\n+\t\t\t\t       stats->q_ibytes[j]);\n+\t\t\t\trxq_stats_map_found = false;\n+\t\t\t}\n+\t\t}\n+\t}\n+\tif (p_stats_map->tx_queue_stats_mapping_enabled) {\n+\t\tprintf(\"\\n\");\n+\t\tnb_txq_stats_map = p_stats_map->nb_txq_stats_mappings;\n+\t\tfor (j = 0; j < RTE_ETHDEV_QUEUE_STAT_CNTRS; j++) {\n+\t\t\tfor (i = 0; i < nb_txq_stats_map; i++) {\n+\t\t\t\tq_stats_map = &p_stats_map->txq_map_array[i];\n+\t\t\t\tif (q_stats_map->stats_counter_id == j &&\n+\t\t\t\t\tq_stats_map->active) {\n+\t\t\t\t\ttxq_stats_map_found = true;\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t}\n+\n+\t\t\tif (txq_stats_map_found) {\n+\t\t\t\tprintf(\"  Stats reg %2d TX-packets:%14\"PRIu64\n+\t\t\t\t       \"\t\t\t\t TX-bytes:%14\"\n+\t\t\t\t       PRIu64\"\\n\",\n+\t\t\t\t       j, stats->q_opackets[j],\n+\t\t\t\t       stats->q_obytes[j]);\n+\t\t\t\ttxq_stats_map_found = false;\n+\t\t\t}\n+\t\t}\n+\t}\n+}\n+\n+void\n fwd_stats_display(void)\n {\n \tstatic const char *fwd_stats_border = \"----------------------\";\n \tstatic const char *acc_stats_border = \"+++++++++++++++\";\n+\tstruct port_stats_mappings *p_stats_map;\n \tstruct {\n \t\tstruct fwd_stream *rx_stream;\n \t\tstruct fwd_stream *tx_stream;\n@@ -1857,8 +1922,6 @@ fwd_stats_display(void)\n \t\t\tfwd_cycles += fs->core_cycles;\n \t}\n \tfor (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {\n-\t\tuint8_t j;\n-\n \t\tpt_id = fwd_ports_ids[i];\n \t\tport = &ports[pt_id];\n \n@@ -1881,8 +1944,9 @@ fwd_stats_display(void)\n \t\tprintf(\"\\n  %s Forward statistics for port %-2d %s\\n\",\n \t\t       fwd_stats_border, pt_id, fwd_stats_border);\n \n-\t\tif (!port->rx_queue_stats_mapping_enabled &&\n-\t\t    !port->tx_queue_stats_mapping_enabled) {\n+\t\tp_stats_map = &port->p_stats_map;\n+\t\tif (!p_stats_map->rx_queue_stats_mapping_enabled &&\n+\t\t    !p_stats_map->tx_queue_stats_mapping_enabled) {\n \t\t\tprintf(\"  RX-packets: %-14\"PRIu64\n \t\t\t       \" RX-dropped: %-14\"PRIu64\n \t\t\t       \"RX-total: %-\"PRIu64\"\\n\",\n@@ -1944,26 +2008,7 @@ fwd_stats_display(void)\n \t\t\t\t\t&ports_stats[pt_id].tx_stream->tx_burst_stats);\n \t\t}\n \n-\t\tif (port->rx_queue_stats_mapping_enabled) {\n-\t\t\tprintf(\"\\n\");\n-\t\t\tfor (j = 0; j < RTE_ETHDEV_QUEUE_STAT_CNTRS; j++) {\n-\t\t\t\tprintf(\"  Stats reg %2d RX-packets:%14\"PRIu64\n-\t\t\t\t       \"     RX-errors:%14\"PRIu64\n-\t\t\t\t       \"    RX-bytes:%14\"PRIu64\"\\n\",\n-\t\t\t\t       j, stats.q_ipackets[j],\n-\t\t\t\t       stats.q_errors[j], stats.q_ibytes[j]);\n-\t\t\t}\n-\t\t\tprintf(\"\\n\");\n-\t\t}\n-\t\tif (port->tx_queue_stats_mapping_enabled) {\n-\t\t\tfor (j = 0; j < RTE_ETHDEV_QUEUE_STAT_CNTRS; j++) {\n-\t\t\t\tprintf(\"  Stats reg %2d TX-packets:%14\"PRIu64\n-\t\t\t\t       \"                                 TX-bytes:%14\"\n-\t\t\t\t       PRIu64\"\\n\",\n-\t\t\t\t       j, stats.q_opackets[j],\n-\t\t\t\t       stats.q_obytes[j]);\n-\t\t\t}\n-\t\t}\n+\t\tport_stats_mapping_display(pt_id, &stats);\n \n \t\tprintf(\"  %s--------------------------------%s\\n\",\n \t\t       fwd_stats_border, fwd_stats_border);\n@@ -3355,59 +3400,84 @@ dev_event_callback(const char *device_name, enum rte_dev_event_type type,\n static int\n set_tx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port)\n {\n+\tstruct port_stats_mappings *p_stats_map;\n+\tstruct queue_stats_mappings *q_stats_map;\n+\tbool mapping_found = false;\n \tuint16_t i;\n \tint diag;\n-\tuint8_t mapping_found = 0;\n \n-\tfor (i = 0; i < nb_tx_queue_stats_mappings; i++) {\n-\t\tif ((tx_queue_stats_mappings[i].port_id == port_id) &&\n-\t\t\t\t(tx_queue_stats_mappings[i].queue_id < nb_txq )) {\n+\tp_stats_map = &port->p_stats_map;\n+\tfor (i = 0; i < p_stats_map->nb_txq_stats_mappings; i++) {\n+\t\tq_stats_map = &p_stats_map->txq_map_array[i];\n+\t\tif (q_stats_map->active) {\n+\t\t\tmapping_found = true;\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tif (q_stats_map->queue_id < nb_txq) {\n \t\t\tdiag = rte_eth_dev_set_tx_queue_stats_mapping(port_id,\n-\t\t\t\t\ttx_queue_stats_mappings[i].queue_id,\n-\t\t\t\t\ttx_queue_stats_mappings[i].stats_counter_id);\n+\t\t\t\t\tq_stats_map->queue_id,\n+\t\t\t\t\tq_stats_map->stats_counter_id);\n \t\t\tif (diag != 0)\n \t\t\t\treturn diag;\n-\t\t\tmapping_found = 1;\n+\t\t\tq_stats_map->active = true;\n+\t\t\tmapping_found = true;\n \t\t}\n \t}\n \tif (mapping_found)\n-\t\tport->tx_queue_stats_mapping_enabled = 1;\n+\t\tp_stats_map->tx_queue_stats_mapping_enabled = true;\n+\n \treturn 0;\n }\n \n static int\n set_rx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port)\n {\n+\tstruct port_stats_mappings *p_stats_map;\n+\tstruct queue_stats_mappings *q_stats_map;\n+\tbool mapping_found = false;\n \tuint16_t i;\n \tint diag;\n-\tuint8_t mapping_found = 0;\n \n-\tfor (i = 0; i < nb_rx_queue_stats_mappings; i++) {\n-\t\tif ((rx_queue_stats_mappings[i].port_id == port_id) &&\n-\t\t\t\t(rx_queue_stats_mappings[i].queue_id < nb_rxq )) {\n+\tp_stats_map = &port->p_stats_map;\n+\tfor (i = 0; i < p_stats_map->nb_rxq_stats_mappings; i++) {\n+\t\tq_stats_map = &p_stats_map->rxq_map_array[i];\n+\t\tif (q_stats_map->active) {\n+\t\t\tmapping_found = true;\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tif (q_stats_map->queue_id < nb_rxq) {\n \t\t\tdiag = rte_eth_dev_set_rx_queue_stats_mapping(port_id,\n-\t\t\t\t\trx_queue_stats_mappings[i].queue_id,\n-\t\t\t\t\trx_queue_stats_mappings[i].stats_counter_id);\n+\t\t\t\t\tq_stats_map->queue_id,\n+\t\t\t\t\tq_stats_map->stats_counter_id);\n \t\t\tif (diag != 0)\n \t\t\t\treturn diag;\n-\t\t\tmapping_found = 1;\n+\t\t\tq_stats_map->active = true;\n+\t\t\tmapping_found = true;\n \t\t}\n \t}\n \tif (mapping_found)\n-\t\tport->rx_queue_stats_mapping_enabled = 1;\n+\t\tp_stats_map->rx_queue_stats_mapping_enabled = true;\n+\n \treturn 0;\n }\n \n static void\n map_port_queue_stats_mapping_registers(portid_t pi, struct rte_port *port)\n {\n+\tstruct port_stats_mappings *p_stats_map = &port->p_stats_map;\n \tint diag = 0;\n \n \tdiag = set_tx_queue_stats_mapping_registers(pi, port);\n \tif (diag != 0) {\n \t\tif (diag == -ENOTSUP) {\n-\t\t\tport->tx_queue_stats_mapping_enabled = 0;\n-\t\t\tprintf(\"TX queue stats mapping not supported port id=%d\\n\", pi);\n+\t\t\tmemset(p_stats_map->txq_map_array, 0,\n+\t\t\t\tsizeof(p_stats_map->txq_map_array));\n+\t\t\tp_stats_map->nb_txq_stats_mappings = 0;\n+\t\t\tp_stats_map->tx_queue_stats_mapping_enabled = false;\n+\t\t\tprintf(\"TX queue stats mapping not supported \"\n+\t\t\t\t\"port id=%d\\n\", pi);\n \t\t}\n \t\telse\n \t\t\trte_exit(EXIT_FAILURE,\n@@ -3419,8 +3489,12 @@ map_port_queue_stats_mapping_registers(portid_t pi, struct rte_port *port)\n \tdiag = set_rx_queue_stats_mapping_registers(pi, port);\n \tif (diag != 0) {\n \t\tif (diag == -ENOTSUP) {\n-\t\t\tport->rx_queue_stats_mapping_enabled = 0;\n-\t\t\tprintf(\"RX queue stats mapping not supported port id=%d\\n\", pi);\n+\t\t\tmemset(p_stats_map->rxq_map_array, 0,\n+\t\t\t\tsizeof(p_stats_map->rxq_map_array));\n+\t\t\tp_stats_map->nb_rxq_stats_mappings = 0;\n+\t\t\tp_stats_map->rx_queue_stats_mapping_enabled = false;\n+\t\t\tprintf(\"RX queue stats mapping not supported \"\n+\t\t\t\t\"port id=%d\\n\", pi);\n \t\t}\n \t\telse\n \t\t\trte_exit(EXIT_FAILURE,\ndiff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h\nindex 833ca14..0397d6d 100644\n--- a/app/test-pmd/testpmd.h\n+++ b/app/test-pmd/testpmd.h\n@@ -181,6 +181,24 @@ struct tunnel_ops {\n \tuint32_t items:1;\n };\n \n+struct queue_stats_mappings {\n+\tuint16_t queue_id;\n+\tuint8_t stats_counter_id;\n+\tbool active;\n+};\n+\n+/**\n+ * The data of queue stats mapping on this port.\n+ */\n+struct port_stats_mappings {\n+\tstruct queue_stats_mappings rxq_map_array[RTE_ETHDEV_QUEUE_STAT_CNTRS];\n+\tstruct queue_stats_mappings txq_map_array[RTE_ETHDEV_QUEUE_STAT_CNTRS];\n+\tuint16_t nb_rxq_stats_mappings;\n+\tuint16_t nb_txq_stats_mappings;\n+\tbool rx_queue_stats_mapping_enabled;\n+\tbool tx_queue_stats_mapping_enabled;\n+};\n+\n /**\n  * The data structure associated with each port.\n  */\n@@ -195,8 +213,7 @@ struct rte_port {\n \tuint16_t                tunnel_tso_segsz; /**< Segmentation offload MSS for tunneled pkts. */\n \tuint16_t                tx_vlan_id;/**< The tag ID */\n \tuint16_t                tx_vlan_id_outer;/**< The outer tag ID */\n-\tuint8_t                 tx_queue_stats_mapping_enabled;\n-\tuint8_t                 rx_queue_stats_mapping_enabled;\n+\tstruct port_stats_mappings p_stats_map;\n \tvolatile uint16_t        port_status;    /**< port started or not */\n \tuint8_t                 need_setup;     /**< port just attached */\n \tuint8_t                 need_reconfig;  /**< need reconfiguring port or not */\n@@ -315,25 +332,6 @@ enum dcb_mode_enable\n \tDCB_ENABLED\n };\n \n-#define MAX_TX_QUEUE_STATS_MAPPINGS 1024 /* MAX_PORT of 32 @ 32 tx_queues/port */\n-#define MAX_RX_QUEUE_STATS_MAPPINGS 4096 /* MAX_PORT of 32 @ 128 rx_queues/port */\n-\n-struct queue_stats_mappings {\n-\tportid_t port_id;\n-\tuint16_t queue_id;\n-\tuint8_t stats_counter_id;\n-} __rte_cache_aligned;\n-\n-extern struct queue_stats_mappings tx_queue_stats_mappings_array[];\n-extern struct queue_stats_mappings rx_queue_stats_mappings_array[];\n-\n-/* Assign both tx and rx queue stats mappings to the same default values */\n-extern struct queue_stats_mappings *tx_queue_stats_mappings;\n-extern struct queue_stats_mappings *rx_queue_stats_mappings;\n-\n-extern uint16_t nb_tx_queue_stats_mappings;\n-extern uint16_t nb_rx_queue_stats_mappings;\n-\n extern uint8_t xstats_hide_zero; /**< Hide zero values for xstats display */\n \n /* globals used for configuration */\n@@ -780,6 +778,7 @@ void nic_stats_clear(portid_t port_id);\n void nic_xstats_display(portid_t port_id);\n void nic_xstats_clear(portid_t port_id);\n void nic_stats_mapping_display(portid_t port_id);\n+void port_stats_mapping_display(portid_t pt_id, struct rte_eth_stats *stats);\n void device_infos_display(const char *identifier);\n void port_infos_display(portid_t port_id);\n void port_summary_display(portid_t port_id);\n",
    "prefixes": [
        "RFC",
        "V2",
        "1/2"
    ]
}