From patchwork Sun Mar 28 13:48:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xueming Li X-Patchwork-Id: 89974 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: 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]) by inbox.dpdk.org (Postfix) with ESMTP id 9AE0FA034F; Sun, 28 Mar 2021 15:49:52 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id D1455140E25; Sun, 28 Mar 2021 15:49:28 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by mails.dpdk.org (Postfix) with ESMTP id B7F66140E1E for ; Sun, 28 Mar 2021 15:49:26 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from xuemingl@nvidia.com) with SMTP; 28 Mar 2021 16:49:24 +0300 Received: from nvidia.com (pegasus05.mtr.labs.mlnx [10.210.16.100]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 12SDmlHq018703; Sun, 28 Mar 2021 16:49:23 +0300 From: Xueming Li To: Viacheslav Ovsiienko Cc: dev@dpdk.org, xuemingl@nvidia.com, Asaf Penso , Matan Azrad , Shahaf Shuler Date: Sun, 28 Mar 2021 13:48:14 +0000 Message-Id: <1616939297-15627-9-git-send-email-xuemingl@nvidia.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1616939297-15627-1-git-send-email-xuemingl@nvidia.com> References: <1616939297-15627-1-git-send-email-xuemingl@nvidia.com> In-Reply-To: <1608304614-13908-2-git-send-email-xuemingl@nvidia.com> References: <1608304614-13908-2-git-send-email-xuemingl@nvidia.com> Subject: [dpdk-dev] [PATCH v5 8/9] net/mlx5: improve xstats of bonding port X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" In case of kernel bonding device, counter was read from first bonding PF member. This patch reads all member PFs and sums to get bond xstats. Signed-off-by: Xueming Li Acked-by: Viacheslav Ovsiienko --- drivers/net/mlx5/linux/mlx5_ethdev_os.c | 127 +++++++++++++++++++----- 1 file changed, 102 insertions(+), 25 deletions(-) diff --git a/drivers/net/mlx5/linux/mlx5_ethdev_os.c b/drivers/net/mlx5/linux/mlx5_ethdev_os.c index e7ec07e364..e8aaa0d36a 100644 --- a/drivers/net/mlx5/linux/mlx5_ethdev_os.c +++ b/drivers/net/mlx5/linux/mlx5_ethdev_os.c @@ -169,10 +169,10 @@ mlx5_get_ifname(const struct rte_eth_dev *dev, char (*ifname)[MLX5_NAMESIZE]) } /** - * Perform ifreq ioctl() on associated Ethernet device. + * Perform ifreq ioctl() on associated netdev ifname. * - * @param[in] dev - * Pointer to Ethernet device. + * @param[in] ifname + * Pointer to netdev name. * @param req * Request number to pass to ioctl(). * @param[out] ifr @@ -182,7 +182,7 @@ mlx5_get_ifname(const struct rte_eth_dev *dev, char (*ifname)[MLX5_NAMESIZE]) * 0 on success, a negative errno value otherwise and rte_errno is set. */ static int -mlx5_ifreq(const struct rte_eth_dev *dev, int req, struct ifreq *ifr) +mlx5_ifreq_by_ifname(const char *ifname, int req, struct ifreq *ifr) { int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); int ret = 0; @@ -191,9 +191,7 @@ mlx5_ifreq(const struct rte_eth_dev *dev, int req, struct ifreq *ifr) rte_errno = errno; return -rte_errno; } - ret = mlx5_get_ifname(dev, &ifr->ifr_name); - if (ret) - goto error; + rte_strscpy(ifr->ifr_name, ifname, sizeof(ifr->ifr_name)); ret = ioctl(sock, req, ifr); if (ret == -1) { rte_errno = errno; @@ -206,6 +204,31 @@ mlx5_ifreq(const struct rte_eth_dev *dev, int req, struct ifreq *ifr) return -rte_errno; } +/** + * Perform ifreq ioctl() on associated Ethernet device. + * + * @param[in] dev + * Pointer to Ethernet device. + * @param req + * Request number to pass to ioctl(). + * @param[out] ifr + * Interface request structure output buffer. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_ifreq(const struct rte_eth_dev *dev, int req, struct ifreq *ifr) +{ + char ifname[sizeof(ifr->ifr_name)]; + int ret; + + ret = mlx5_get_ifname(dev, &ifname); + if (ret) + return -rte_errno; + return mlx5_ifreq_by_ifname(ifname, req, ifr); +} + /** * Get device MTU. * @@ -1243,6 +1266,8 @@ int mlx5_get_module_eeprom(struct rte_eth_dev *dev, * * @param dev * Pointer to Ethernet device. + * @param[in] pf + * PF index in case of bonding device, -1 otherwise * @param[out] stats * Counters table output buffer. * @@ -1250,8 +1275,8 @@ int mlx5_get_module_eeprom(struct rte_eth_dev *dev, * 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) +static int +_mlx5_os_read_dev_counters(struct rte_eth_dev *dev, int pf, uint64_t *stats) { struct mlx5_priv *priv = dev->data->dev_private; struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl; @@ -1265,7 +1290,11 @@ mlx5_os_read_dev_counters(struct rte_eth_dev *dev, uint64_t *stats) 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 (pf >= 0) + ret = mlx5_ifreq_by_ifname(priv->sh->bond.ports[pf].ifname, + SIOCETHTOOL, &ifr); + else + ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr); if (ret) { DRV_LOG(WARNING, "port %u unable to read statistic values from device", @@ -1273,23 +1302,60 @@ mlx5_os_read_dev_counters(struct rte_eth_dev *dev, uint64_t *stats) 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]]; - } + if (xstats_ctrl->info[i].dev) + continue; + stats[i] += (uint64_t) + et_stats->data[xstats_ctrl->dev_table_idx[i]]; } return 0; } +/** + * Read device counters. + * + * @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; + int ret = 0, i; + + memset(stats, 0, sizeof(*stats) * xstats_ctrl->mlx5_stats_n); + /* Read ifreq counters. */ + if (priv->master && priv->pf_bond >= 0) { + /* Sum xstats from bonding device member ports. */ + for (i = 0; i < priv->sh->bond.n_port; i++) { + ret = _mlx5_os_read_dev_counters(dev, i, stats); + if (ret) + return ret; + } + } else { + ret = _mlx5_os_read_dev_counters(dev, -1, stats); + } + /* Read IB counters. */ + for (i = 0; i != xstats_ctrl->mlx5_stats_n; ++i) { + if (!xstats_ctrl->info[i].dev) + continue; + 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]; + } + return ret; +} + /** * Query the number of statistics provided by ETHTOOL. * @@ -1303,13 +1369,19 @@ mlx5_os_read_dev_counters(struct rte_eth_dev *dev, uint64_t *stats) int mlx5_os_get_stats_n(struct rte_eth_dev *dev) { + struct mlx5_priv *priv = dev->data->dev_private; 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 (priv->master && priv->pf_bond >= 0) + /* Bonding PF. */ + ret = mlx5_ifreq_by_ifname(priv->sh->bond.ports[0].ifname, + SIOCETHTOOL, &ifr); + else + ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr); if (ret) { DRV_LOG(WARNING, "port %u unable to query number of statistics", dev->data->port_id); @@ -1480,7 +1552,12 @@ mlx5_os_stats_init(struct rte_eth_dev *dev) strings->string_set = ETH_SS_STATS; strings->len = dev_stats_n; ifr.ifr_data = (caddr_t)strings; - ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr); + if (priv->master && priv->pf_bond >= 0) + /* Bonding master. */ + ret = mlx5_ifreq_by_ifname(priv->sh->bond.ports[0].ifname, + SIOCETHTOOL, &ifr); + else + ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr); if (ret) { DRV_LOG(WARNING, "port %u unable to get statistic names", dev->data->port_id);