get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 133262,
    "url": "http://patches.dpdk.org/api/patches/133262/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20231024102128.16832-3-shaibran@amazon.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": "<20231024102128.16832-3-shaibran@amazon.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20231024102128.16832-3-shaibran@amazon.com",
    "date": "2023-10-24T10:21:25",
    "name": "[2/5] net/ena: add support for connection tracking metric",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "d850e8d67aca96065c23f14ad496632abca7b958",
    "submitter": {
        "id": 2930,
        "url": "http://patches.dpdk.org/api/people/2930/?format=api",
        "name": "Brandes, Shai",
        "email": "shaibran@amazon.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/20231024102128.16832-3-shaibran@amazon.com/mbox/",
    "series": [
        {
            "id": 29965,
            "url": "http://patches.dpdk.org/api/series/29965/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=29965",
            "date": "2023-10-24T10:21:23",
            "name": "net/ena: v2.8.0 driver release",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/29965/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/133262/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/133262/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 9BC03431EF;\n\tTue, 24 Oct 2023 12:22:01 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 8EF81410D5;\n\tTue, 24 Oct 2023 12:21:53 +0200 (CEST)",
            "from smtp-fw-52002.amazon.com (smtp-fw-52002.amazon.com\n [52.119.213.150])\n by mails.dpdk.org (Postfix) with ESMTP id D69F5406FF\n for <dev@dpdk.org>; Tue, 24 Oct 2023 12:21:50 +0200 (CEST)",
            "from iad12-co-svc-p1-lb1-vlan3.amazon.com (HELO\n email-inbound-relay-pdx-2c-m6i4x-fad5e78e.us-west-2.amazon.com) ([10.43.8.6])\n by smtp-border-fw-52002.iad7.amazon.com with\n ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Oct 2023 10:21:49 +0000",
            "from smtpout.prod.us-west-2.prod.farcaster.email.amazon.dev\n (pdx2-ws-svc-p26-lb5-vlan3.pdx.amazon.com [10.39.38.70])\n by email-inbound-relay-pdx-2c-m6i4x-fad5e78e.us-west-2.amazon.com (Postfix)\n with ESMTPS id 09714A0BB6; Tue, 24 Oct 2023 10:21:47 +0000 (UTC)",
            "from EX19MTAEUB002.ant.amazon.com [10.0.17.79:51427]\n by smtpin.naws.eu-west-1.prod.farcaster.email.amazon.dev [10.0.38.116:2525]\n with esmtp (Farcaster)\n id 7b7da95d-9f7c-441b-99c1-67d20cb94211;\n Tue, 24 Oct 2023 10:21:46 +0000 (UTC)",
            "from EX19D017EUA003.ant.amazon.com (10.252.50.129) by\n EX19MTAEUB002.ant.amazon.com (10.252.51.59) with Microsoft SMTP Server\n (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n 15.2.1118.39; Tue, 24 Oct 2023 10:21:43 +0000",
            "from EX19MTAUWB001.ant.amazon.com (10.250.64.248) by\n EX19D017EUA003.ant.amazon.com (10.252.50.129) with Microsoft SMTP Server\n (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n 15.2.1118.39; Tue, 24 Oct 2023 10:21:42 +0000",
            "from HFA15-CG15235BS.amazon.com (10.85.143.172) by\n mail-relay.amazon.com (10.250.64.254) with Microsoft SMTP Server id\n 15.2.1118.39 via Frontend Transport; Tue, 24 Oct 2023 10:21:40 +0000"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=amazon.com; i=@amazon.com; q=dns/txt; s=amazon201209;\n t=1698142912; x=1729678912;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version;\n bh=1/aAeiQE88fqwOMnh9I9VKMTt+pv8MCMAK8yrUZjc3U=;\n b=i9KzpebFWla1mtJrOuZF/Ui/JlJb/Ew9VZop4MTsh/8LdjpssJmlx63p\n a8QeFuvUoo7R473B4P5Cp+GJ0o5L6HbrUm7smh9uKxoNmakYT//SByNcL\n BQXHtpocBXbOCAozH4qLGItKrPY79Do5Jq5q0nRUO/xfvr17YMVqWHBz5 A=;",
        "X-IronPort-AV": "E=Sophos;i=\"6.03,247,1694736000\"; d=\"scan'208\";a=\"590808201\"",
        "X-Farcaster-Flow-ID": "7b7da95d-9f7c-441b-99c1-67d20cb94211",
        "From": "<shaibran@amazon.com>",
        "To": "<ferruh.yigit@amd.com>",
        "CC": "<dev@dpdk.org>, Shai Brandes <shaibran@amazon.com>, Michal Krawczyk\n <mk@semihalf.com>, Evgeny Schemeilin <evgenys@amazon.com>, Igor Chauskin\n <igorch@amazon.com>, Ron Beider <rbeider@amazon.com>",
        "Subject": "[PATCH 2/5] net/ena: add support for connection tracking metric",
        "Date": "Tue, 24 Oct 2023 13:21:25 +0300",
        "Message-ID": "<20231024102128.16832-3-shaibran@amazon.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20231024102128.16832-1-shaibran@amazon.com>",
        "References": "<20231024102128.16832-1-shaibran@amazon.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "From: Shai Brandes <shaibran@amazon.com>\n\nThe driver publishes network performance metrics that the\napplication can use to troubleshoot performance issues,\nmonitor the workload, and benchmark applications to determine\nwhether they maximize the performance.\n\nThis patch adds support for the connection tracking allowance\nutilization metric (Conntrack_allowance_available) that allows\nmonitoring the available tracked connections that can be\nestablished before the interface exceeds its allowance.\n\nThe driver uses the redesigned HAL mechanism that is backward\ncompatible with the old method to query the metrics.\n\nProbing the customer metrics is performed via an admin command.\nThus, a multi-process proxy handler was added.\n\nSigned-off-by: Shai Brandes <shaibran@amazon.com>\nReviewed-by: Amit Bernstein <amitbern@amazon.com>\n---\n doc/guides/rel_notes/release_23_11.rst |   1 +\n drivers/net/ena/ena_ethdev.c           | 198 +++++++++++++++++--------\n drivers/net/ena/ena_ethdev.h           |  24 ++-\n 3 files changed, 161 insertions(+), 62 deletions(-)",
    "diff": "diff --git a/doc/guides/rel_notes/release_23_11.rst b/doc/guides/rel_notes/release_23_11.rst\nindex e3b0ba58c9..eefbcc08fe 100644\n--- a/doc/guides/rel_notes/release_23_11.rst\n+++ b/doc/guides/rel_notes/release_23_11.rst\n@@ -147,6 +147,7 @@ New Features\n * **Updated Amazon Elastic Network Adapter ena net driver.**\n \n   * Upgraded ENA HAL to latest version.\n+  * Added support for connection tracking allowance utilization metric.\n \n * **Updated Solarflare net driver.**\n \ndiff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c\nindex b764442dbb..daec7f7d16 100644\n--- a/drivers/net/ena/ena_ethdev.c\n+++ b/drivers/net/ena/ena_ethdev.c\n@@ -60,8 +60,8 @@ struct ena_stats {\n #define ENA_STAT_TX_ENTRY(stat) \\\n \tENA_STAT_ENTRY(stat, tx)\n \n-#define ENA_STAT_ENI_ENTRY(stat) \\\n-\tENA_STAT_ENTRY(stat, eni)\n+#define ENA_STAT_METRICS_ENTRY(stat) \\\n+\tENA_STAT_ENTRY(stat, metrics)\n \n #define ENA_STAT_GLOBAL_ENTRY(stat) \\\n \tENA_STAT_ENTRY(stat, dev)\n@@ -92,12 +92,17 @@ static const struct ena_stats ena_stats_global_strings[] = {\n \tENA_STAT_GLOBAL_ENTRY(tx_drops),\n };\n \n-static const struct ena_stats ena_stats_eni_strings[] = {\n-\tENA_STAT_ENI_ENTRY(bw_in_allowance_exceeded),\n-\tENA_STAT_ENI_ENTRY(bw_out_allowance_exceeded),\n-\tENA_STAT_ENI_ENTRY(pps_allowance_exceeded),\n-\tENA_STAT_ENI_ENTRY(conntrack_allowance_exceeded),\n-\tENA_STAT_ENI_ENTRY(linklocal_allowance_exceeded),\n+/*\n+ * The legacy metrics (also known as eni stats) consisted of 5 stats, while the reworked\n+ * metrics (also known as customer metrics) support an additional stat.\n+ */\n+static struct ena_stats ena_stats_metrics_strings[] = {\n+\tENA_STAT_METRICS_ENTRY(bw_in_allowance_exceeded),\n+\tENA_STAT_METRICS_ENTRY(bw_out_allowance_exceeded),\n+\tENA_STAT_METRICS_ENTRY(pps_allowance_exceeded),\n+\tENA_STAT_METRICS_ENTRY(conntrack_allowance_exceeded),\n+\tENA_STAT_METRICS_ENTRY(linklocal_allowance_exceeded),\n+\tENA_STAT_METRICS_ENTRY(conntrack_allowance_available),\n };\n \n static const struct ena_stats ena_stats_tx_strings[] = {\n@@ -124,7 +129,8 @@ static const struct ena_stats ena_stats_rx_strings[] = {\n };\n \n #define ENA_STATS_ARRAY_GLOBAL\tARRAY_SIZE(ena_stats_global_strings)\n-#define ENA_STATS_ARRAY_ENI\tARRAY_SIZE(ena_stats_eni_strings)\n+#define ENA_STATS_ARRAY_METRICS\tARRAY_SIZE(ena_stats_metrics_strings)\n+#define ENA_STATS_ARRAY_METRICS_LEGACY\t(ENA_STATS_ARRAY_METRICS - 1)\n #define ENA_STATS_ARRAY_TX\tARRAY_SIZE(ena_stats_tx_strings)\n #define ENA_STATS_ARRAY_RX\tARRAY_SIZE(ena_stats_rx_strings)\n \n@@ -262,8 +268,9 @@ static int ena_process_bool_devarg(const char *key,\n \t\t\t\t   void *opaque);\n static int ena_parse_devargs(struct ena_adapter *adapter,\n \t\t\t     struct rte_devargs *devargs);\n-static int ena_copy_eni_stats(struct ena_adapter *adapter,\n-\t\t\t      struct ena_stats_eni *stats);\n+static void ena_copy_customer_metrics(struct ena_adapter *adapter,\n+\t\t\t\t\tuint64_t *buf,\n+\t\t\t\t\tsize_t buf_size);\n static int ena_setup_rx_intr(struct rte_eth_dev *dev);\n static int ena_rx_queue_intr_enable(struct rte_eth_dev *dev,\n \t\t\t\t    uint16_t queue_id);\n@@ -314,7 +321,8 @@ enum ena_mp_req {\n \tENA_MP_ENI_STATS_GET,\n \tENA_MP_MTU_SET,\n \tENA_MP_IND_TBL_GET,\n-\tENA_MP_IND_TBL_SET\n+\tENA_MP_IND_TBL_SET,\n+\tENA_MP_CUSTOMER_METRICS_GET,\n };\n \n /** Proxy message body. Shared between requests and responses. */\n@@ -507,8 +515,8 @@ ENA_PROXY_DESC(ena_com_get_eni_stats, ENA_MP_ENI_STATS_GET,\n ({\n \tENA_TOUCH(rsp);\n \tENA_TOUCH(ena_dev);\n-\tif (stats != (struct ena_admin_eni_stats *)&adapter->eni_stats)\n-\t\trte_memcpy(stats, &adapter->eni_stats, sizeof(*stats));\n+\tif (stats != (struct ena_admin_eni_stats *)&adapter->metrics_stats)\n+\t\trte_memcpy(stats, &adapter->metrics_stats, sizeof(*stats));\n }),\n \tstruct ena_com_dev *ena_dev, struct ena_admin_eni_stats *stats);\n \n@@ -555,6 +563,24 @@ ENA_PROXY_DESC(ena_com_indirect_table_get, ENA_MP_IND_TBL_GET,\n }),\n \tstruct ena_com_dev *ena_dev, u32 *ind_tbl);\n \n+ENA_PROXY_DESC(ena_com_get_customer_metrics, ENA_MP_CUSTOMER_METRICS_GET,\n+({\n+\tENA_TOUCH(adapter);\n+\tENA_TOUCH(req);\n+\tENA_TOUCH(ena_dev);\n+\tENA_TOUCH(buf);\n+\tENA_TOUCH(buf_size);\n+}),\n+({\n+\tENA_TOUCH(rsp);\n+\tENA_TOUCH(ena_dev);\n+\tENA_TOUCH(buf_size);\n+\tif (buf != (char *)&adapter->metrics_stats)\n+\t\trte_memcpy(buf, &adapter->metrics_stats, adapter->metrics_num * sizeof(uint64_t));\n+}),\n+\tstruct ena_com_dev *ena_dev, char *buf, size_t buf_size);\n+\n+\n static inline void ena_trigger_reset(struct ena_adapter *adapter,\n \t\t\t\t     enum ena_regs_reset_reason_types reason)\n {\n@@ -756,7 +782,10 @@ static void ena_config_host_info(struct ena_com_dev *ena_dev)\n /* This function calculates the number of xstats based on the current config */\n static unsigned int ena_xstats_calc_num(struct rte_eth_dev_data *data)\n {\n-\treturn ENA_STATS_ARRAY_GLOBAL + ENA_STATS_ARRAY_ENI +\n+\tstruct ena_adapter *adapter = data->dev_private;\n+\n+\treturn ENA_STATS_ARRAY_GLOBAL +\n+\t\tadapter->metrics_num +\n \t\t(data->nb_tx_queues * ENA_STATS_ARRAY_TX) +\n \t\t(data->nb_rx_queues * ENA_STATS_ARRAY_RX);\n }\n@@ -1687,6 +1716,23 @@ static int ena_populate_rx_queue(struct ena_ring *rxq, unsigned int count)\n \treturn i;\n }\n \n+static size_t ena_get_metrics_entries(struct ena_adapter *adapter)\n+{\n+\tstruct ena_com_dev *ena_dev = &adapter->ena_dev;\n+\tsize_t metrics_num = 0;\n+\n+\tif (ena_com_get_cap(ena_dev, ENA_ADMIN_CUSTOMER_METRICS))\n+\t\tmetrics_num = ENA_STATS_ARRAY_METRICS;\n+\telse if (ena_com_get_cap(ena_dev, ENA_ADMIN_ENI_STATS))\n+\t\tmetrics_num = ENA_STATS_ARRAY_METRICS_LEGACY;\n+\tPMD_DRV_LOG(NOTICE, \"0x%x customer metrics are supported\\n\", (unsigned int)metrics_num);\n+\tif (metrics_num > ENA_MAX_CUSTOMER_METRICS) {\n+\t\tPMD_DRV_LOG(NOTICE, \"Not enough space for the requested customer metrics\\n\");\n+\t\tmetrics_num = ENA_MAX_CUSTOMER_METRICS;\n+\t}\n+\treturn metrics_num;\n+}\n+\n static int ena_device_init(struct ena_adapter *adapter,\n \t\t\t   struct rte_pci_device *pdev,\n \t\t\t   struct ena_com_dev_get_features_ctx *get_feat_ctx)\n@@ -1758,6 +1804,8 @@ static int ena_device_init(struct ena_adapter *adapter,\n \taenq_groups &= get_feat_ctx->aenq.supported_groups;\n \n \tadapter->all_aenq_groups = aenq_groups;\n+\t/* The actual supported number of metrics is negotiated with the device at runtime */\n+\tadapter->metrics_num = ena_get_metrics_entries(adapter);\n \n \treturn 0;\n \n@@ -2151,12 +2199,17 @@ static int eth_ena_dev_init(struct rte_eth_dev *eth_dev)\n \t\tPMD_INIT_LOG(CRIT, \"Failed to parse devargs\\n\");\n \t\tgoto err;\n \t}\n+\trc = ena_com_allocate_customer_metrics_buffer(ena_dev);\n+\tif (rc != 0) {\n+\t\tPMD_INIT_LOG(CRIT, \"Failed to allocate customer metrics buffer\\n\");\n+\t\tgoto err;\n+\t}\n \n \t/* device specific initialization routine */\n \trc = ena_device_init(adapter, pci_dev, &get_feat_ctx);\n \tif (rc) {\n \t\tPMD_INIT_LOG(CRIT, \"Failed to init ENA device\\n\");\n-\t\tgoto err;\n+\t\tgoto err_metrics_delete;\n \t}\n \n \t/* Check if device supports LSC */\n@@ -2259,7 +2312,8 @@ static int eth_ena_dev_init(struct rte_eth_dev *eth_dev)\n err_device_destroy:\n \tena_com_delete_host_info(ena_dev);\n \tena_com_admin_destroy(ena_dev);\n-\n+err_metrics_delete:\n+\tena_com_delete_customer_metrics_buffer(ena_dev);\n err:\n \treturn rc;\n }\n@@ -2286,6 +2340,7 @@ static void ena_destroy_device(struct rte_eth_dev *eth_dev)\n \tena_com_wait_for_abort_completion(ena_dev);\n \tena_com_admin_destroy(ena_dev);\n \tena_com_mmio_reg_read_request_destroy(ena_dev);\n+\tena_com_delete_customer_metrics_buffer(ena_dev);\n \n \tadapter->state = ENA_ADAPTER_STATE_FREE;\n }\n@@ -3139,29 +3194,47 @@ static uint16_t eth_ena_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,\n \treturn sent_idx;\n }\n \n-int ena_copy_eni_stats(struct ena_adapter *adapter, struct ena_stats_eni *stats)\n+static void ena_copy_customer_metrics(struct ena_adapter *adapter, uint64_t *buf,\n+\t\t\t\t\t     size_t num_metrics)\n {\n+\tstruct ena_com_dev *ena_dev = &adapter->ena_dev;\n \tint rc;\n \n-\trte_spinlock_lock(&adapter->admin_lock);\n-\t/* Retrieve and store the latest statistics from the AQ. This ensures\n-\t * that previous value is returned in case of a com error.\n-\t */\n-\trc = ENA_PROXY(adapter, ena_com_get_eni_stats, &adapter->ena_dev,\n-\t\t(struct ena_admin_eni_stats *)stats);\n-\trte_spinlock_unlock(&adapter->admin_lock);\n-\tif (rc != 0) {\n-\t\tif (rc == ENA_COM_UNSUPPORTED) {\n-\t\t\tPMD_DRV_LOG(DEBUG,\n-\t\t\t\t\"Retrieving ENI metrics is not supported\\n\");\n-\t\t} else {\n+\tif (ena_com_get_cap(ena_dev, ENA_ADMIN_CUSTOMER_METRICS)) {\n+\t\tif (num_metrics != ENA_STATS_ARRAY_METRICS) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Detected discrepancy in the number of customer metrics\");\n+\t\t\treturn;\n+\t\t}\n+\t\trte_spinlock_lock(&adapter->admin_lock);\n+\t\trc = ENA_PROXY(adapter,\n+\t\t\t\t\tena_com_get_customer_metrics,\n+\t\t\t\t\t&adapter->ena_dev,\n+\t\t\t\t\t(char *)buf,\n+\t\t\t\t\tnum_metrics * sizeof(uint64_t));\n+\t\trte_spinlock_unlock(&adapter->admin_lock);\n+\t\tif (rc != 0) {\n+\t\t\tPMD_DRV_LOG(WARNING, \"Failed to get customer metrics, rc: %d\\n\", rc);\n+\t\t\treturn;\n+\t\t}\n+\n+\t} else if (ena_com_get_cap(ena_dev, ENA_ADMIN_ENI_STATS)) {\n+\t\tif (num_metrics != ENA_STATS_ARRAY_METRICS_LEGACY) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Detected discrepancy in the number of legacy metrics\");\n+\t\t\treturn;\n+\t\t}\n+\n+\t\trte_spinlock_lock(&adapter->admin_lock);\n+\t\trc = ENA_PROXY(adapter,\n+\t\t\t       ena_com_get_eni_stats,\n+\t\t\t       &adapter->ena_dev,\n+\t\t\t       (struct ena_admin_eni_stats *)buf);\n+\t\trte_spinlock_unlock(&adapter->admin_lock);\n+\t\tif (rc != 0) {\n \t\t\tPMD_DRV_LOG(WARNING,\n \t\t\t\t\"Failed to get ENI metrics, rc: %d\\n\", rc);\n+\t\t\treturn;\n \t\t}\n-\t\treturn rc;\n \t}\n-\n-\treturn 0;\n }\n \n /**\n@@ -3181,6 +3254,7 @@ static int ena_xstats_get_names(struct rte_eth_dev *dev,\n \t\t\t\tstruct rte_eth_xstat_name *xstats_names,\n \t\t\t\tunsigned int n)\n {\n+\tstruct ena_adapter *adapter = dev->data->dev_private;\n \tunsigned int xstats_count = ena_xstats_calc_num(dev->data);\n \tunsigned int stat, i, count = 0;\n \n@@ -3191,9 +3265,10 @@ static int ena_xstats_get_names(struct rte_eth_dev *dev,\n \t\tstrcpy(xstats_names[count].name,\n \t\t\tena_stats_global_strings[stat].name);\n \n-\tfor (stat = 0; stat < ENA_STATS_ARRAY_ENI; stat++, count++)\n-\t\tstrcpy(xstats_names[count].name,\n-\t\t\tena_stats_eni_strings[stat].name);\n+\tfor (stat = 0; stat < adapter->metrics_num; stat++, count++)\n+\t\trte_strscpy(xstats_names[count].name,\n+\t\t\t    ena_stats_metrics_strings[stat].name,\n+\t\t\t    RTE_ETH_XSTATS_NAME_SIZE);\n \n \tfor (stat = 0; stat < ENA_STATS_ARRAY_RX; stat++)\n \t\tfor (i = 0; i < dev->data->nb_rx_queues; i++, count++)\n@@ -3233,6 +3308,7 @@ static int ena_xstats_get_names_by_id(struct rte_eth_dev *dev,\n \t\t\t\t      struct rte_eth_xstat_name *xstats_names,\n \t\t\t\t      unsigned int size)\n {\n+\tstruct ena_adapter *adapter = dev->data->dev_private;\n \tuint64_t xstats_count = ena_xstats_calc_num(dev->data);\n \tuint64_t id, qid;\n \tunsigned int i;\n@@ -3256,13 +3332,14 @@ static int ena_xstats_get_names_by_id(struct rte_eth_dev *dev,\n \t\t}\n \n \t\tid -= ENA_STATS_ARRAY_GLOBAL;\n-\t\tif (id < ENA_STATS_ARRAY_ENI) {\n-\t\t\tstrcpy(xstats_names[i].name,\n-\t\t\t       ena_stats_eni_strings[id].name);\n+\t\tif (id < adapter->metrics_num) {\n+\t\t\trte_strscpy(xstats_names[i].name,\n+\t\t\t\t    ena_stats_metrics_strings[id].name,\n+\t\t\t\t    RTE_ETH_XSTATS_NAME_SIZE);\n \t\t\tcontinue;\n \t\t}\n \n-\t\tid -= ENA_STATS_ARRAY_ENI;\n+\t\tid -= adapter->metrics_num;\n \t\tif (id < ENA_STATS_ARRAY_RX) {\n \t\t\tqid = id / dev->data->nb_rx_queues;\n \t\t\tid %= dev->data->nb_rx_queues;\n@@ -3310,10 +3387,10 @@ static int ena_xstats_get(struct rte_eth_dev *dev,\n {\n \tstruct ena_adapter *adapter = dev->data->dev_private;\n \tunsigned int xstats_count = ena_xstats_calc_num(dev->data);\n-\tstruct ena_stats_eni eni_stats;\n \tunsigned int stat, i, count = 0;\n \tint stat_offset;\n \tvoid *stats_begin;\n+\tuint64_t metrics_stats[ENA_MAX_CUSTOMER_METRICS];\n \n \tif (n < xstats_count)\n \t\treturn xstats_count;\n@@ -3330,13 +3407,10 @@ static int ena_xstats_get(struct rte_eth_dev *dev,\n \t\t\t((char *)stats_begin + stat_offset));\n \t}\n \n-\t/* Even if the function below fails, we should copy previous (or initial\n-\t * values) to keep structure of rte_eth_xstat consistent.\n-\t */\n-\tena_copy_eni_stats(adapter, &eni_stats);\n-\tfor (stat = 0; stat < ENA_STATS_ARRAY_ENI; stat++, count++) {\n-\t\tstat_offset = ena_stats_eni_strings[stat].stat_offset;\n-\t\tstats_begin = &eni_stats;\n+\tena_copy_customer_metrics(adapter, metrics_stats, adapter->metrics_num);\n+\tstats_begin = metrics_stats;\n+\tfor (stat = 0; stat < adapter->metrics_num; stat++, count++) {\n+\t\tstat_offset = ena_stats_metrics_strings[stat].stat_offset;\n \n \t\txstats[count].id = count;\n \t\txstats[count].value = *((uint64_t *)\n@@ -3374,13 +3448,13 @@ static int ena_xstats_get_by_id(struct rte_eth_dev *dev,\n \t\t\t\tunsigned int n)\n {\n \tstruct ena_adapter *adapter = dev->data->dev_private;\n-\tstruct ena_stats_eni eni_stats;\n \tuint64_t id;\n \tuint64_t rx_entries, tx_entries;\n \tunsigned int i;\n \tint qid;\n \tint valid = 0;\n-\tbool was_eni_copied = false;\n+\tbool were_metrics_copied = false;\n+\tuint64_t metrics_stats[ENA_MAX_CUSTOMER_METRICS];\n \n \tfor (i = 0; i < n; ++i) {\n \t\tid = ids[i];\n@@ -3393,22 +3467,25 @@ static int ena_xstats_get_by_id(struct rte_eth_dev *dev,\n \n \t\t/* Check if id belongs to ENI statistics */\n \t\tid -= ENA_STATS_ARRAY_GLOBAL;\n-\t\tif (id < ENA_STATS_ARRAY_ENI) {\n-\t\t\t/* Avoid reading ENI stats multiple times in a single\n+\t\tif (id < adapter->metrics_num) {\n+\t\t\t/* Avoid reading metrics multiple times in a single\n \t\t\t * function call, as it requires communication with the\n \t\t\t * admin queue.\n \t\t\t */\n-\t\t\tif (!was_eni_copied) {\n-\t\t\t\twas_eni_copied = true;\n-\t\t\t\tena_copy_eni_stats(adapter, &eni_stats);\n+\t\t\tif (!were_metrics_copied) {\n+\t\t\t\twere_metrics_copied = true;\n+\t\t\t\tena_copy_customer_metrics(adapter,\n+\t\t\t\t\t\tmetrics_stats,\n+\t\t\t\t\t\tadapter->metrics_num);\n \t\t\t}\n-\t\t\tvalues[i] = *((uint64_t *)&eni_stats + id);\n+\n+\t\t\tvalues[i] = *((uint64_t *)&metrics_stats + id);\n \t\t\t++valid;\n \t\t\tcontinue;\n \t\t}\n \n \t\t/* Check if id belongs to rx queue statistics */\n-\t\tid -= ENA_STATS_ARRAY_ENI;\n+\t\tid -= adapter->metrics_num;\n \t\trx_entries = ENA_STATS_ARRAY_RX * dev->data->nb_rx_queues;\n \t\tif (id < rx_entries) {\n \t\t\tqid = id % dev->data->nb_rx_queues;\n@@ -3883,7 +3960,7 @@ ena_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)\n \t\tbreak;\n \tcase ENA_MP_ENI_STATS_GET:\n \t\tres = ena_com_get_eni_stats(ena_dev,\n-\t\t\t(struct ena_admin_eni_stats *)&adapter->eni_stats);\n+\t\t\t(struct ena_admin_eni_stats *)&adapter->metrics_stats);\n \t\tbreak;\n \tcase ENA_MP_MTU_SET:\n \t\tres = ena_com_set_dev_mtu(ena_dev, req->args.mtu);\n@@ -3895,6 +3972,11 @@ ena_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)\n \tcase ENA_MP_IND_TBL_SET:\n \t\tres = ena_com_indirect_table_set(ena_dev);\n \t\tbreak;\n+\tcase ENA_MP_CUSTOMER_METRICS_GET:\n+\t\tres = ena_com_get_customer_metrics(ena_dev,\n+\t\t\t\t(char *)adapter->metrics_stats,\n+\t\t\t\tsizeof(uint64_t) * adapter->metrics_num);\n+\t\tbreak;\n \tdefault:\n \t\tPMD_DRV_LOG(ERR, \"Unknown request type %d\\n\", req->type);\n \t\tres = -EINVAL;\ndiff --git a/drivers/net/ena/ena_ethdev.h b/drivers/net/ena/ena_ethdev.h\nindex 4d27fba585..9268d44dde 100644\n--- a/drivers/net/ena/ena_ethdev.h\n+++ b/drivers/net/ena/ena_ethdev.h\n@@ -12,9 +12,9 @@\n #include <ethdev_pci.h>\n #include <rte_cycles.h>\n #include <rte_pci.h>\n-#include <bus_pci_driver.h>\n+#include <rte_bus_pci.h>\n #include <rte_timer.h>\n-#include <dev_driver.h>\n+#include <rte_dev.h>\n #include <rte_net.h>\n \n #include \"ena_com.h\"\n@@ -54,6 +54,12 @@\n #define ENA_REFILL_THRESH_DIVIDER      8\n #define ENA_REFILL_THRESH_PACKET       256\n \n+/*\n+ * The max customer metrics is equal or bigger than the ENI metrics. That\n+ * assumption simplifies the fallback to the legacy metrics mechanism.\n+ */\n+#define ENA_MAX_CUSTOMER_METRICS\t6\n+\n #define ENA_IDX_NEXT_MASKED(idx, mask) (((idx) + 1) & (mask))\n #define ENA_IDX_ADD_MASKED(idx, n, mask) (((idx) + (n)) & (mask))\n \n@@ -215,7 +221,7 @@ struct ena_stats_dev {\n \tu64 tx_drops;\n };\n \n-struct ena_stats_eni {\n+struct ena_stats_metrics {\n \t/*\n \t * The number of packets shaped due to inbound aggregate BW\n \t * allowance being exceeded\n@@ -239,6 +245,10 @@ struct ena_stats_eni {\n \t * allowance being exceeded\n \t */\n \tuint64_t linklocal_allowance_exceeded;\n+\t /*\n+\t  * The number of available connections\n+\t  */\n+\tuint64_t conntrack_allowance_available;\n };\n \n struct ena_offloads {\n@@ -293,7 +303,6 @@ struct ena_adapter {\n \tuint64_t keep_alive_timeout;\n \n \tstruct ena_stats_dev dev_stats;\n-\tstruct ena_stats_eni eni_stats;\n \tstruct ena_admin_basic_stats basic_stats;\n \n \tu32 indirect_table[ENA_RX_RSS_TABLE_SIZE];\n@@ -312,6 +321,13 @@ struct ena_adapter {\n \tuint64_t tx_cleanup_stall_delay;\n \n \tuint64_t memzone_cnt;\n+\n+\t/*\n+\t * Helper variables for holding the information about the supported\n+\t * metrics.\n+\t */\n+\tuint64_t metrics_stats[ENA_MAX_CUSTOMER_METRICS] __rte_cache_aligned;\n+\tuint16_t metrics_num;\n };\n \n int ena_mp_indirect_table_set(struct ena_adapter *adapter);\n",
    "prefixes": [
        "2/5"
    ]
}