From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 5CD81A0517; Wed, 10 Jun 2020 11:34:31 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id DD65014581; Wed, 10 Jun 2020 11:33:17 +0200 (CEST) Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60051.outbound.protection.outlook.com [40.107.6.51]) by dpdk.org (Postfix) with ESMTP id 0335B4C89 for ; Wed, 10 Jun 2020 11:33:15 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=ocJMzb7KJ3rTySFLWcg9M5BuFOuoHrHWb84ZblyijmX8cgZQV+BJ8/2XZjqB0IyiD5OUgAXFw4nJ0egLmbsdiTe9Z8tqq6nJj9BGVFsV4I/E1R+4RdzPW4pnwQbqdhDPuETHzUvIMH695CBMMf09iObOc7+qvXwVJEimZLc8BZiG0Dh0H7enE7ay/ek2NMJzCXOFvlWr2Q11KqK7JNemHZLpE9xAkxkAd8JDvUGKusFA0uD426YKzVRG/p0x18olnLUJpbFaOHRuOFF4ZP7Zx6VzBCBiZrSn5yzxKAbV0ug8oIUpysstR5vBnZE3UdS9i15lucZWVohjD7rH43gw6w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=jkhPRYEr1OIVQQCT9da9o1ag4AP3k/gkQ6/01htckRk=; b=aYrobvC81NH5zJP1Rdc+3qA8pMKZimB/XJhvlrBbwgEyhkcW5ViijYu7zFJfxDLWcNPk6Kw346en3mL6wE9ty7AZGrOmlFdrpskuhxJijuGrwseNrqhj//BRWyip/G/jrXanmp3FyK8ojPtxcm45oey6lvH4og89L+W/bPo7VsFTJgU889+Z4zTmdGK0Y014E2bABB8taZLCp7W7WfluiAh4qyYPtQIKTUWvLFOARZT4tXglasU6Zb61zSmjiDkD7fLY9ciD/TVadrlUn1Hs+xFONa/E8mbyyfoFYUgir5oIJwvdJsTrwGC05Mfx1taCRSU3VsjmrCVMXpZCIaFMpw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=mellanox.com; dmarc=pass action=none header.from=mellanox.com; dkim=pass header.d=mellanox.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=jkhPRYEr1OIVQQCT9da9o1ag4AP3k/gkQ6/01htckRk=; b=MCiJSLL5sEEGs86NiSPh1ZQuOGeNyrlbJOXLdZMwJ5uUy45ERdpabUiv8AwqqGma2evSp9j6l3wE+taOSzcpJyN2q+ZNi4QKYktpbl5LizOxngHFZHk/OLWpsCc2/e+Ltay8RdbYzGXjtYueny9zluxyE2e2uSeKP+8sm82mlDg= Authentication-Results: dpdk.org; dkim=none (message not signed) header.d=none;dpdk.org; dmarc=none action=none header.from=mellanox.com; Received: from AM0PR05MB4209.eurprd05.prod.outlook.com (2603:10a6:208:61::22) by AM0PR05MB4545.eurprd05.prod.outlook.com (2603:10a6:208:b9::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3088.20; Wed, 10 Jun 2020 09:33:13 +0000 Received: from AM0PR05MB4209.eurprd05.prod.outlook.com ([fe80::1068:89a9:41d3:b14a]) by AM0PR05MB4209.eurprd05.prod.outlook.com ([fe80::1068:89a9:41d3:b14a%3]) with mapi id 15.20.3066.023; Wed, 10 Jun 2020 09:33:13 +0000 From: Ophir Munk To: dev@dpdk.org, Matan Azrad , Raslan Darawsheh Cc: Ophir Munk Date: Wed, 10 Jun 2020 09:32:33 +0000 Message-Id: <20200610093233.23902-9-ophirmu@mellanox.com> X-Mailer: git-send-email 2.8.4 In-Reply-To: <20200610093233.23902-1-ophirmu@mellanox.com> References: <20200610093233.23902-1-ophirmu@mellanox.com> Content-Type: text/plain X-ClientProxiedBy: MRXP264CA0003.FRAP264.PROD.OUTLOOK.COM (2603:10a6:500:15::15) To AM0PR05MB4209.eurprd05.prod.outlook.com (2603:10a6:208:61::22) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from mellanox.com (37.142.13.130) by MRXP264CA0003.FRAP264.PROD.OUTLOOK.COM (2603:10a6:500:15::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3088.18 via Frontend Transport; Wed, 10 Jun 2020 09:33:12 +0000 X-Mailer: git-send-email 2.8.4 X-Originating-IP: [37.142.13.130] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: f6c28b48-0b74-4838-0d13-08d80d214bae X-MS-TrafficTypeDiagnostic: AM0PR05MB4545: X-LD-Processed: a652971c-7d2e-4d9b-a6a4-d149256f461b,ExtFwd X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:454; X-Forefront-PRVS: 0430FA5CB7 X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: vIGCfCLmO8I5R038HX9bR4PgROkDZT2KGLmp5EF2afw+IIzZQNX133pX1A6T1Kqw3dCGsavlfm18fziApdS6J/vFBTz906gKxGAyUzxBjHV+luZr0QDI/YrTYVBekgKZDV9Ahy5ATUknNv4kxhfWy0DmALLai0EXhQ28r0/Cyg+ScXBnNVcQyrZb1CQ8RnnJ6Xtnf4VWCDAIxAtNETcR8zn+hQGFBUZ7pfpyvP+LAh2DiO4Wnj0oDF86fY8HcJJsZITnTUx31FSa7Rd91uAksiqYf1nnrZY1sweGrreoxzZKnQJGUvrDiHvmHlVEoRUOy4IjWbsUJR95a5VWDPP7mg== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM0PR05MB4209.eurprd05.prod.outlook.com; PTR:; CAT:NONE; SFTY:; SFS:(4636009)(346002)(376002)(39860400002)(396003)(366004)(136003)(6666004)(478600001)(26005)(186003)(8676002)(5660300002)(8886007)(66476007)(66556008)(36756003)(66946007)(2906002)(956004)(2616005)(55016002)(52116002)(7696005)(8936002)(6636002)(110136005)(1076003)(16526019)(83380400001)(316002)(30864003)(86362001)(107886003)(4326008); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData: OpKNmXAYsgSYBRHJAe0vniY+qUkP+qkXh2Hy0QuUzLjuMaDp6A7KL6vqKXbYUf0q2tvL955dl7lfJ8uWnu81w/SciInJY6TSokCdYFNdsg/O6p6pLVpdX+CwSND4hijctZ+QGziER+eEqL+OOzwiJtzzDx9Na8qscXXL7xcVA5IMGIkwaGowl2vhAKNAgXELHrTRnx3hIUUZw+H6dSYiThOznBi9nxcFkXuFkPyVlATIM94VE15SE5GsGdUI7XH7h4nYMfebnhf9NUDTKSDBtCt4pQX36sG/wTLpfM99Xt8hwf4S3+Y4ghWhwMGBsnmonPCIEyYkdhb6AnvXg23N3E4tpgpJQl6Z77zs5Ckx27RUq6iyyD3fVUYJzDCCWcykhDmxyrnq/Ee/tk2eJR8WXhl89PnqZW8FLCtCaf/rBOAVr/FXNJmGSFSlOlWMv2ACQnBEP11I26fEmSBFIBYUd+d6DQXxjyyreVlrRfIU9VMVZFrFq2Qv1qBDbjzW9CSK X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-Network-Message-Id: f6c28b48-0b74-4838-0d13-08d80d214bae X-MS-Exchange-CrossTenant-OriginalArrivalTime: 10 Jun 2020 09:33:13.7419 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: U+UEEw800iaQDkRWYUWB+LdwDaFHoTiqOTOzyX6rUkC2iPz9WrNHFNDP9ChJFZwnyx+dqCtUm/MXkRn9WStQ2Q== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0PR05MB4545 Subject: [dpdk-dev] [PATCH v1 8/8] net/mlx5: refactor statistics X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" mlx5 statistics are calculated by several methods: 1. In software when packets go through datapath. 2. Calling ioctl with ETHTOOL command (Linux specific). 3. Reading counters from SYSFS device path (Linux specific). The Linux related functions are moved to file linux/mlx5_os.c. Signed-off-by: Ophir Munk --- drivers/net/mlx5/linux/mlx5_os.c | 328 ++++++++++++++++++++++++++++++++++++++ drivers/net/mlx5/mlx5.h | 8 +- drivers/net/mlx5/mlx5_stats.c | 332 ++------------------------------------- drivers/net/mlx5/mlx5_trigger.c | 2 +- 4 files changed, 344 insertions(+), 326 deletions(-) diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c index 2888234..6187c2b 100644 --- a/drivers/net/mlx5/linux/mlx5_os.c +++ b/drivers/net/mlx5/linux/mlx5_os.c @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include /* Verbs header. */ @@ -1993,6 +1995,332 @@ mlx5_os_dev_shared_handler_uninstall(struct mlx5_dev_ctx_shared *sh) #endif } +/** + * Read statistics by a named counter. + * + * @param[in] priv + * Pointer to the private device data structure. + * @param[in] ctr_name + * Pointer to the name of the statistic counter to read + * @param[out] stat + * Pointer to read statistic value. + * @return + * 0 on success and stat is valud, 1 if failed to read the value + * rte_errno is set. + * + */ +int +mlx5_os_read_dev_stat(struct mlx5_priv *priv, const char *ctr_name, + uint64_t *stat) +{ + int fd; + + if (priv->sh) { + MKSTR(path, "%s/ports/%d/hw_counters/%s", + priv->sh->ibdev_path, + priv->dev_port, + ctr_name); + fd = open(path, O_RDONLY); + if (fd != -1) { + char buf[21] = {'\0'}; + ssize_t n = read(fd, buf, sizeof(buf)); + + close(fd); + if (n != -1) { + *stat = strtoull(buf, NULL, 10); + return 0; + } + } + } + *stat = 0; + return 1; +} + +/** + * Read device counters table. + * + * @param dev + * Pointer to Ethernet device. + * @param[out] stats + * Counters table output buffer. + * + * @return + * 0 on success and stats is filled, negative errno value otherwise and + * rte_errno is set. + */ +int +mlx5_os_read_dev_counters(struct rte_eth_dev *dev, uint64_t *stats) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl; + unsigned int i; + struct ifreq ifr; + unsigned int stats_sz = xstats_ctrl->stats_n * sizeof(uint64_t); + unsigned char et_stat_buf[sizeof(struct ethtool_stats) + stats_sz]; + struct ethtool_stats *et_stats = (struct ethtool_stats *)et_stat_buf; + int ret; + + et_stats->cmd = ETHTOOL_GSTATS; + et_stats->n_stats = xstats_ctrl->stats_n; + ifr.ifr_data = (caddr_t)et_stats; + ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr); + if (ret) { + DRV_LOG(WARNING, + "port %u unable to read statistic values from device", + dev->data->port_id); + return ret; + } + for (i = 0; i != xstats_ctrl->mlx5_stats_n; ++i) { + if (xstats_ctrl->info[i].dev) { + ret = mlx5_os_read_dev_stat(priv, + xstats_ctrl->info[i].ctr_name, + &stats[i]); + /* return last xstats counter if fail to read. */ + if (ret == 0) + xstats_ctrl->xstats[i] = stats[i]; + else + stats[i] = xstats_ctrl->xstats[i]; + } else { + stats[i] = (uint64_t) + et_stats->data[xstats_ctrl->dev_table_idx[i]]; + } + } + return 0; +} + +/** + * Query the number of statistics provided by ETHTOOL. + * + * @param dev + * Pointer to Ethernet device. + * + * @return + * Number of statistics on success, negative errno value otherwise and + * rte_errno is set. + */ +int +mlx5_os_get_stats_n(struct rte_eth_dev *dev) +{ + struct ethtool_drvinfo drvinfo; + struct ifreq ifr; + int ret; + + drvinfo.cmd = ETHTOOL_GDRVINFO; + ifr.ifr_data = (caddr_t)&drvinfo; + ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr); + if (ret) { + DRV_LOG(WARNING, "port %u unable to query number of statistics", + dev->data->port_id); + return ret; + } + return drvinfo.n_stats; +} + +static const struct mlx5_counter_ctrl mlx5_counters_init[] = { + { + .dpdk_name = "rx_port_unicast_bytes", + .ctr_name = "rx_vport_unicast_bytes", + }, + { + .dpdk_name = "rx_port_multicast_bytes", + .ctr_name = "rx_vport_multicast_bytes", + }, + { + .dpdk_name = "rx_port_broadcast_bytes", + .ctr_name = "rx_vport_broadcast_bytes", + }, + { + .dpdk_name = "rx_port_unicast_packets", + .ctr_name = "rx_vport_unicast_packets", + }, + { + .dpdk_name = "rx_port_multicast_packets", + .ctr_name = "rx_vport_multicast_packets", + }, + { + .dpdk_name = "rx_port_broadcast_packets", + .ctr_name = "rx_vport_broadcast_packets", + }, + { + .dpdk_name = "tx_port_unicast_bytes", + .ctr_name = "tx_vport_unicast_bytes", + }, + { + .dpdk_name = "tx_port_multicast_bytes", + .ctr_name = "tx_vport_multicast_bytes", + }, + { + .dpdk_name = "tx_port_broadcast_bytes", + .ctr_name = "tx_vport_broadcast_bytes", + }, + { + .dpdk_name = "tx_port_unicast_packets", + .ctr_name = "tx_vport_unicast_packets", + }, + { + .dpdk_name = "tx_port_multicast_packets", + .ctr_name = "tx_vport_multicast_packets", + }, + { + .dpdk_name = "tx_port_broadcast_packets", + .ctr_name = "tx_vport_broadcast_packets", + }, + { + .dpdk_name = "rx_wqe_err", + .ctr_name = "rx_wqe_err", + }, + { + .dpdk_name = "rx_crc_errors_phy", + .ctr_name = "rx_crc_errors_phy", + }, + { + .dpdk_name = "rx_in_range_len_errors_phy", + .ctr_name = "rx_in_range_len_errors_phy", + }, + { + .dpdk_name = "rx_symbol_err_phy", + .ctr_name = "rx_symbol_err_phy", + }, + { + .dpdk_name = "tx_errors_phy", + .ctr_name = "tx_errors_phy", + }, + { + .dpdk_name = "rx_out_of_buffer", + .ctr_name = "out_of_buffer", + .dev = 1, + }, + { + .dpdk_name = "tx_packets_phy", + .ctr_name = "tx_packets_phy", + }, + { + .dpdk_name = "rx_packets_phy", + .ctr_name = "rx_packets_phy", + }, + { + .dpdk_name = "tx_discards_phy", + .ctr_name = "tx_discards_phy", + }, + { + .dpdk_name = "rx_discards_phy", + .ctr_name = "rx_discards_phy", + }, + { + .dpdk_name = "tx_bytes_phy", + .ctr_name = "tx_bytes_phy", + }, + { + .dpdk_name = "rx_bytes_phy", + .ctr_name = "rx_bytes_phy", + }, + /* Representor only */ + { + .dpdk_name = "rx_packets", + .ctr_name = "vport_rx_packets", + }, + { + .dpdk_name = "rx_bytes", + .ctr_name = "vport_rx_bytes", + }, + { + .dpdk_name = "tx_packets", + .ctr_name = "vport_tx_packets", + }, + { + .dpdk_name = "tx_bytes", + .ctr_name = "vport_tx_bytes", + }, +}; + +static const unsigned int xstats_n = RTE_DIM(mlx5_counters_init); + +/** + * Init the structures to read device counters. + * + * @param dev + * Pointer to Ethernet device. + */ +void +mlx5_os_stats_init(struct rte_eth_dev *dev) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl; + struct mlx5_stats_ctrl *stats_ctrl = &priv->stats_ctrl; + unsigned int i; + unsigned int j; + struct ifreq ifr; + struct ethtool_gstrings *strings = NULL; + unsigned int dev_stats_n; + unsigned int str_sz; + int ret; + + /* So that it won't aggregate for each init. */ + xstats_ctrl->mlx5_stats_n = 0; + ret = mlx5_os_get_stats_n(dev); + if (ret < 0) { + DRV_LOG(WARNING, "port %u no extended statistics available", + dev->data->port_id); + return; + } + dev_stats_n = ret; + /* Allocate memory to grab stat names and values. */ + str_sz = dev_stats_n * ETH_GSTRING_LEN; + strings = (struct ethtool_gstrings *) + rte_malloc("xstats_strings", + str_sz + sizeof(struct ethtool_gstrings), 0); + if (!strings) { + DRV_LOG(WARNING, "port %u unable to allocate memory for xstats", + dev->data->port_id); + return; + } + strings->cmd = ETHTOOL_GSTRINGS; + strings->string_set = ETH_SS_STATS; + strings->len = dev_stats_n; + ifr.ifr_data = (caddr_t)strings; + ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr); + if (ret) { + DRV_LOG(WARNING, "port %u unable to get statistic names", + dev->data->port_id); + goto free; + } + for (i = 0; i != dev_stats_n; ++i) { + const char *curr_string = (const char *) + &strings->data[i * ETH_GSTRING_LEN]; + + for (j = 0; j != xstats_n; ++j) { + if (!strcmp(mlx5_counters_init[j].ctr_name, + curr_string)) { + unsigned int idx = xstats_ctrl->mlx5_stats_n++; + + xstats_ctrl->dev_table_idx[idx] = i; + xstats_ctrl->info[idx] = mlx5_counters_init[j]; + break; + } + } + } + /* Add dev counters. */ + for (i = 0; i != xstats_n; ++i) { + if (mlx5_counters_init[i].dev) { + unsigned int idx = xstats_ctrl->mlx5_stats_n++; + + xstats_ctrl->info[idx] = mlx5_counters_init[i]; + xstats_ctrl->hw_stats[idx] = 0; + } + } + MLX5_ASSERT(xstats_ctrl->mlx5_stats_n <= MLX5_MAX_XSTATS); + xstats_ctrl->stats_n = dev_stats_n; + /* Copy to base at first time. */ + ret = mlx5_os_read_dev_counters(dev, xstats_ctrl->base); + if (ret) + DRV_LOG(ERR, "port %u cannot read device counters: %s", + dev->data->port_id, strerror(rte_errno)); + mlx5_os_read_dev_stat(priv, "out_of_buffer", &stats_ctrl->imissed_base); + stats_ctrl->imissed = 0; +free: + rte_free(strings); +} + const struct eth_dev_ops mlx5_os_dev_ops = { .dev_configure = mlx5_dev_configure, .dev_start = mlx5_dev_start, diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index fcce9a8..94a3667 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -141,7 +141,7 @@ struct mlx5_counter_ctrl { char dpdk_name[RTE_ETH_XSTATS_NAME_SIZE]; /* Name of the counter on the device table. */ char ctr_name[RTE_ETH_XSTATS_NAME_SIZE]; - uint32_t ib:1; /**< Nonzero for IB counters. */ + uint32_t dev:1; /**< Nonzero for dev counters. */ }; struct mlx5_xstats_ctrl { @@ -807,7 +807,6 @@ int mlx5_allmulticast_disable(struct rte_eth_dev *dev); /* mlx5_stats.c */ -void mlx5_stats_init(struct rte_eth_dev *dev); int mlx5_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats); int mlx5_stats_reset(struct rte_eth_dev *dev); int mlx5_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *stats, @@ -936,4 +935,9 @@ int mlx5_os_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, struct rte_pci_device *pci_dev); void mlx5_os_dev_shared_handler_install(struct mlx5_dev_ctx_shared *sh); void mlx5_os_dev_shared_handler_uninstall(struct mlx5_dev_ctx_shared *sh); +int mlx5_os_read_dev_stat(struct mlx5_priv *priv, + const char *ctr_name, uint64_t *stat); +int mlx5_os_read_dev_counters(struct rte_eth_dev *dev, uint64_t *stats); +int mlx5_os_get_stats_n(struct rte_eth_dev *dev); +void mlx5_os_stats_init(struct rte_eth_dev *dev); #endif /* RTE_PMD_MLX5_H_ */ diff --git a/drivers/net/mlx5/mlx5_stats.c b/drivers/net/mlx5/mlx5_stats.c index 7999c5f..a9b33ee 100644 --- a/drivers/net/mlx5/mlx5_stats.c +++ b/drivers/net/mlx5/mlx5_stats.c @@ -3,10 +3,7 @@ * Copyright 2015 Mellanox Technologies, Ltd */ -#include #include -#include -#include #include #include #include @@ -21,317 +18,6 @@ #include "mlx5.h" #include "mlx5_rxtx.h" - -static const struct mlx5_counter_ctrl mlx5_counters_init[] = { - { - .dpdk_name = "rx_port_unicast_bytes", - .ctr_name = "rx_vport_unicast_bytes", - }, - { - .dpdk_name = "rx_port_multicast_bytes", - .ctr_name = "rx_vport_multicast_bytes", - }, - { - .dpdk_name = "rx_port_broadcast_bytes", - .ctr_name = "rx_vport_broadcast_bytes", - }, - { - .dpdk_name = "rx_port_unicast_packets", - .ctr_name = "rx_vport_unicast_packets", - }, - { - .dpdk_name = "rx_port_multicast_packets", - .ctr_name = "rx_vport_multicast_packets", - }, - { - .dpdk_name = "rx_port_broadcast_packets", - .ctr_name = "rx_vport_broadcast_packets", - }, - { - .dpdk_name = "tx_port_unicast_bytes", - .ctr_name = "tx_vport_unicast_bytes", - }, - { - .dpdk_name = "tx_port_multicast_bytes", - .ctr_name = "tx_vport_multicast_bytes", - }, - { - .dpdk_name = "tx_port_broadcast_bytes", - .ctr_name = "tx_vport_broadcast_bytes", - }, - { - .dpdk_name = "tx_port_unicast_packets", - .ctr_name = "tx_vport_unicast_packets", - }, - { - .dpdk_name = "tx_port_multicast_packets", - .ctr_name = "tx_vport_multicast_packets", - }, - { - .dpdk_name = "tx_port_broadcast_packets", - .ctr_name = "tx_vport_broadcast_packets", - }, - { - .dpdk_name = "rx_wqe_err", - .ctr_name = "rx_wqe_err", - }, - { - .dpdk_name = "rx_crc_errors_phy", - .ctr_name = "rx_crc_errors_phy", - }, - { - .dpdk_name = "rx_in_range_len_errors_phy", - .ctr_name = "rx_in_range_len_errors_phy", - }, - { - .dpdk_name = "rx_symbol_err_phy", - .ctr_name = "rx_symbol_err_phy", - }, - { - .dpdk_name = "tx_errors_phy", - .ctr_name = "tx_errors_phy", - }, - { - .dpdk_name = "rx_out_of_buffer", - .ctr_name = "out_of_buffer", - .ib = 1, - }, - { - .dpdk_name = "tx_packets_phy", - .ctr_name = "tx_packets_phy", - }, - { - .dpdk_name = "rx_packets_phy", - .ctr_name = "rx_packets_phy", - }, - { - .dpdk_name = "tx_discards_phy", - .ctr_name = "tx_discards_phy", - }, - { - .dpdk_name = "rx_discards_phy", - .ctr_name = "rx_discards_phy", - }, - { - .dpdk_name = "tx_bytes_phy", - .ctr_name = "tx_bytes_phy", - }, - { - .dpdk_name = "rx_bytes_phy", - .ctr_name = "rx_bytes_phy", - }, - /* Representor only */ - { - .dpdk_name = "rx_packets", - .ctr_name = "vport_rx_packets", - }, - { - .dpdk_name = "rx_bytes", - .ctr_name = "vport_rx_bytes", - }, - { - .dpdk_name = "tx_packets", - .ctr_name = "vport_tx_packets", - }, - { - .dpdk_name = "tx_bytes", - .ctr_name = "vport_tx_bytes", - }, -}; - -static const unsigned int xstats_n = RTE_DIM(mlx5_counters_init); - -static inline int -mlx5_read_ib_stat(struct mlx5_priv *priv, const char *ctr_name, uint64_t *stat) -{ - int fd; - - if (priv->sh) { - MKSTR(path, "%s/ports/%d/hw_counters/%s", - priv->sh->ibdev_path, - priv->dev_port, - ctr_name); - fd = open(path, O_RDONLY); - if (fd != -1) { - char buf[21] = {'\0'}; - ssize_t n = read(fd, buf, sizeof(buf)); - - close(fd); - if (n != -1) { - *stat = strtoull(buf, NULL, 10); - return 0; - } - } - } - *stat = 0; - return 1; -} - -/** - * Read device counters table. - * - * @param dev - * Pointer to Ethernet device. - * @param[out] stats - * Counters table output buffer. - * - * @return - * 0 on success and stats is filled, negative errno value otherwise and - * rte_errno is set. - */ -static int -mlx5_read_dev_counters(struct rte_eth_dev *dev, uint64_t *stats) -{ - struct mlx5_priv *priv = dev->data->dev_private; - struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl; - unsigned int i; - struct ifreq ifr; - unsigned int stats_sz = xstats_ctrl->stats_n * sizeof(uint64_t); - unsigned char et_stat_buf[sizeof(struct ethtool_stats) + stats_sz]; - struct ethtool_stats *et_stats = (struct ethtool_stats *)et_stat_buf; - int ret; - - et_stats->cmd = ETHTOOL_GSTATS; - et_stats->n_stats = xstats_ctrl->stats_n; - ifr.ifr_data = (caddr_t)et_stats; - ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr); - if (ret) { - DRV_LOG(WARNING, - "port %u unable to read statistic values from device", - dev->data->port_id); - return ret; - } - for (i = 0; i != xstats_ctrl->mlx5_stats_n; ++i) { - if (xstats_ctrl->info[i].ib) { - ret = mlx5_read_ib_stat(priv, - xstats_ctrl->info[i].ctr_name, - &stats[i]); - /* return last xstats counter if fail to read. */ - if (ret == 0) - xstats_ctrl->xstats[i] = stats[i]; - else - stats[i] = xstats_ctrl->xstats[i]; - } else { - stats[i] = (uint64_t) - et_stats->data[xstats_ctrl->dev_table_idx[i]]; - } - } - return 0; -} - -/** - * Query the number of statistics provided by ETHTOOL. - * - * @param dev - * Pointer to Ethernet device. - * - * @return - * Number of statistics on success, negative errno value otherwise and - * rte_errno is set. - */ -static int -mlx5_ethtool_get_stats_n(struct rte_eth_dev *dev) { - struct ethtool_drvinfo drvinfo; - struct ifreq ifr; - int ret; - - drvinfo.cmd = ETHTOOL_GDRVINFO; - ifr.ifr_data = (caddr_t)&drvinfo; - ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr); - if (ret) { - DRV_LOG(WARNING, "port %u unable to query number of statistics", - dev->data->port_id); - return ret; - } - return drvinfo.n_stats; -} - -/** - * Init the structures to read device counters. - * - * @param dev - * Pointer to Ethernet device. - */ -void -mlx5_stats_init(struct rte_eth_dev *dev) -{ - struct mlx5_priv *priv = dev->data->dev_private; - struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl; - struct mlx5_stats_ctrl *stats_ctrl = &priv->stats_ctrl; - unsigned int i; - unsigned int j; - struct ifreq ifr; - struct ethtool_gstrings *strings = NULL; - unsigned int dev_stats_n; - unsigned int str_sz; - int ret; - - /* So that it won't aggregate for each init. */ - xstats_ctrl->mlx5_stats_n = 0; - ret = mlx5_ethtool_get_stats_n(dev); - if (ret < 0) { - DRV_LOG(WARNING, "port %u no extended statistics available", - dev->data->port_id); - return; - } - dev_stats_n = ret; - /* Allocate memory to grab stat names and values. */ - str_sz = dev_stats_n * ETH_GSTRING_LEN; - strings = (struct ethtool_gstrings *) - rte_malloc("xstats_strings", - str_sz + sizeof(struct ethtool_gstrings), 0); - if (!strings) { - DRV_LOG(WARNING, "port %u unable to allocate memory for xstats", - dev->data->port_id); - return; - } - strings->cmd = ETHTOOL_GSTRINGS; - strings->string_set = ETH_SS_STATS; - strings->len = dev_stats_n; - ifr.ifr_data = (caddr_t)strings; - ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr); - if (ret) { - DRV_LOG(WARNING, "port %u unable to get statistic names", - dev->data->port_id); - goto free; - } - for (i = 0; i != dev_stats_n; ++i) { - const char *curr_string = (const char *) - &strings->data[i * ETH_GSTRING_LEN]; - - for (j = 0; j != xstats_n; ++j) { - if (!strcmp(mlx5_counters_init[j].ctr_name, - curr_string)) { - unsigned int idx = xstats_ctrl->mlx5_stats_n++; - - xstats_ctrl->dev_table_idx[idx] = i; - xstats_ctrl->info[idx] = mlx5_counters_init[j]; - break; - } - } - } - /* Add IB counters. */ - for (i = 0; i != xstats_n; ++i) { - if (mlx5_counters_init[i].ib) { - unsigned int idx = xstats_ctrl->mlx5_stats_n++; - - xstats_ctrl->info[idx] = mlx5_counters_init[i]; - xstats_ctrl->hw_stats[idx] = 0; - } - } - MLX5_ASSERT(xstats_ctrl->mlx5_stats_n <= MLX5_MAX_XSTATS); - xstats_ctrl->stats_n = dev_stats_n; - /* Copy to base at first time. */ - ret = mlx5_read_dev_counters(dev, xstats_ctrl->base); - if (ret) - DRV_LOG(ERR, "port %u cannot read device counters: %s", - dev->data->port_id, strerror(rte_errno)); - mlx5_read_ib_stat(priv, "out_of_buffer", &stats_ctrl->imissed_base); - stats_ctrl->imissed = 0; -free: - rte_free(strings); -} - /** * DPDK callback to get extended device statistics. * @@ -360,17 +46,17 @@ mlx5_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *stats, int stats_n; int ret; - stats_n = mlx5_ethtool_get_stats_n(dev); + stats_n = mlx5_os_get_stats_n(dev); if (stats_n < 0) return stats_n; if (xstats_ctrl->stats_n != stats_n) - mlx5_stats_init(dev); - ret = mlx5_read_dev_counters(dev, counters); + mlx5_os_stats_init(dev); + ret = mlx5_os_read_dev_counters(dev, counters); if (ret) return ret; for (i = 0; i != mlx5_stats_n; ++i) { stats[i].id = i; - if (xstats_ctrl->info[i].ib) { + if (xstats_ctrl->info[i].dev) { uint64_t wrap_n; uint64_t hw_stat = xstats_ctrl->hw_stats[i]; @@ -456,7 +142,7 @@ mlx5_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) #endif tmp.oerrors += txq->stats.oerrors; } - ret = mlx5_read_ib_stat(priv, "out_of_buffer", &tmp.imissed); + ret = mlx5_os_read_dev_stat(priv, "out_of_buffer", &tmp.imissed); if (ret == 0) { tmp.imissed = (tmp.imissed - stats_ctrl->imissed_base) & (uint64_t)UINT32_MAX; @@ -503,7 +189,7 @@ mlx5_stats_reset(struct rte_eth_dev *dev) memset(&(*priv->txqs)[i]->stats, 0, sizeof(struct mlx5_txq_stats)); } - mlx5_read_ib_stat(priv, "out_of_buffer", &stats_ctrl->imissed_base); + mlx5_os_read_dev_stat(priv, "out_of_buffer", &stats_ctrl->imissed_base); stats_ctrl->imissed = 0; #ifndef MLX5_PMD_SOFT_COUNTERS /* FIXME: reset hardware counters. */ @@ -533,15 +219,15 @@ mlx5_xstats_reset(struct rte_eth_dev *dev) uint64_t counters[n]; int ret; - stats_n = mlx5_ethtool_get_stats_n(dev); + stats_n = mlx5_os_get_stats_n(dev); if (stats_n < 0) { DRV_LOG(ERR, "port %u cannot get stats: %s", dev->data->port_id, strerror(-stats_n)); return stats_n; } if (xstats_ctrl->stats_n != stats_n) - mlx5_stats_init(dev); - ret = mlx5_read_dev_counters(dev, counters); + mlx5_os_stats_init(dev); + ret = mlx5_os_read_dev_counters(dev, counters); if (ret) { DRV_LOG(ERR, "port %u cannot read device counters: %s", dev->data->port_id, strerror(rte_errno)); diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c index a9af2e6..c7c2ee6 100644 --- a/drivers/net/mlx5/mlx5_trigger.c +++ b/drivers/net/mlx5/mlx5_trigger.c @@ -316,7 +316,7 @@ mlx5_dev_start(struct rte_eth_dev *dev) dev->data->port_id); goto error; } - mlx5_stats_init(dev); + mlx5_os_stats_init(dev); ret = mlx5_traffic_enable(dev); if (ret) { DRV_LOG(ERR, "port %u failed to set defaults flows", -- 2.8.4