From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from EUR02-AM5-obe.outbound.protection.outlook.com (mail-eopbgr00062.outbound.protection.outlook.com [40.107.0.62]) by dpdk.org (Postfix) with ESMTP id D0A0E2B99 for ; Tue, 17 Jan 2017 15:39:54 +0100 (CET) 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; bh=N+TUmuaNlNOdiLXnLZNtv0WcddkItWiY8CfyO286vAE=; b=odw7FxsQyP38aKyz7nJ+YajS8RQRdTjs9B4VpwoAy0vjdAHo9A+nf803PTaxa/uj4ZYxUwlJHRwdzlyHdYrlUuAqwcTLE5243zE7k1GRBdUBBhcRCJ2v6rHGqaRZ5SqbpiS/Cj9utfDK2p5+5b9KoJIFESXDDRcZyjOJODehO7g= Received: from AM4PR05MB1505.eurprd05.prod.outlook.com (10.164.79.147) by AM4PR05MB1508.eurprd05.prod.outlook.com (10.164.79.150) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.845.12; Tue, 17 Jan 2017 14:39:53 +0000 Received: from AM4PR05MB1505.eurprd05.prod.outlook.com ([10.164.79.147]) by AM4PR05MB1505.eurprd05.prod.outlook.com ([10.164.79.147]) with mapi id 15.01.0845.013; Tue, 17 Jan 2017 14:39:52 +0000 From: Shahaf Shuler To: Shahaf Shuler , Adrien Mazarguil CC: "dev@dpdk.org" , Elad Persiko Thread-Topic: [dpdk-dev] [PATCH] net/mlx5: support extended statistics Thread-Index: AQHScM4YhFyIXDaDbUOKBRd2EmcHgaE8vOsw Date: Tue, 17 Jan 2017 14:39:52 +0000 Message-ID: References: <1484573439-10752-1-git-send-email-shahafs@mellanox.com> <1484663349-55599-1-git-send-email-shahafs@mellanox.com> In-Reply-To: <1484663349-55599-1-git-send-email-shahafs@mellanox.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: spf=none (sender IP is ) smtp.mailfrom=shahafs@mellanox.com; x-originating-ip: [31.154.10.107] x-ld-processed: a652971c-7d2e-4d9b-a6a4-d149256f461b,ExtAddr x-microsoft-exchange-diagnostics: 1; AM4PR05MB1508; 7:KzNKLpfoTrIzYtTwBh4i3PK1RoLI9Zlnvg8NBcWqxxsw4qfAAbEF6AdqybJSy9wRporjCL0rI29GPja+NdHwPv8PHc3d1+srP4bmVq6Mrxl/3kgXmeo2oYlZI0W5idgFVYT4datMGsd5yjJ98fKRmvflV+8m/pURoS2WNzvpCzickKmvXL2NN6VECmOk0xC6ATr5NC/TUZvZJ8EQAJeX4uZm6HvlIgxV4HMhSyz5oFIv+BvFGfzBYEmNZqIG2yCBKM1+OCi1mpjBR/GgWqMHqKyGMVZtSNdpA7K/G95V3Na7xNrlSaypE5VjKwEYsBINkIrN0Ogov7drvRtT16oYSPWuI9Uu9Y1LeRWrbwPtWmzu5lYmDMHtzP8cSKb1sF3XDhrP4zpavG18iyARXzexT/HI2jRlvcBEK1exWfUE1oTgChxQqq8TQI/3w/cf2dCj38s79Lwq0Caa8WeaR6zjAA== x-forefront-antispam-report: SFV:SKI; SCL:-1SFV:NSPM; SFS:(10009020)(6009001)(7916002)(39850400002)(39410400002)(39840400002)(39450400003)(39860400002)(189002)(377454003)(199003)(6436002)(106116001)(105586002)(99286003)(33656002)(3660700001)(9686003)(7736002)(55016002)(54906002)(68736007)(8676002)(305945005)(2950100002)(86362001)(77096006)(50986999)(229853002)(76176999)(5660300001)(122556002)(54356999)(81156014)(30001)(66066001)(8936002)(6506006)(74316002)(38730400001)(7696004)(81166006)(101416001)(189998001)(4001430100002)(2906002)(4326007)(97736004)(2900100001)(5001770100001)(25786008)(3280700002)(6116002)(107886002)(102836003)(92566002)(106356001)(3846002); DIR:OUT; SFP:1101; SCL:1; SRVR:AM4PR05MB1508; H:AM4PR05MB1505.eurprd05.prod.outlook.com; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:1; LANG:en; x-ms-office365-filtering-correlation-id: e6ce3b78-9984-41d7-2207-08d43ee6b290 x-microsoft-antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001);SRVR:AM4PR05MB1508; x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(788757137089)(95692535739014); x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(6040375)(601004)(2401047)(5005006)(8121501046)(10201501046)(3002001)(6055026)(6041248)(20161123555025)(20161123560025)(20161123564025)(20161123562025)(6072148); SRVR:AM4PR05MB1508; BCL:0; PCL:0; RULEID:; SRVR:AM4PR05MB1508; x-forefront-prvs: 01901B3451 received-spf: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-originalarrivaltime: 17 Jan 2017 14:39:52.3191 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM4PR05MB1508 Subject: Re: [dpdk-dev] [PATCH] net/mlx5: support extended 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: , X-List-Received-Date: Tue, 17 Jan 2017 14:39:55 -0000 Please ignore, forgot to add v4 to subject.=20 Tuesday, January 17, 2017 4:29 PM, Shahaf Shuler: >=20 > Implement extended statistics callbacks. >=20 > Suggested-by: Hanoch Haim > Signed-off-by: Shahaf Shuler > Signed-off-by: Elad Persiko > Acked-by: Adrien Mazarguil > --- > on v4: > * fix compilation issue with clang > * coding style adjustments > * replace strcpy with strncpy >=20 > on v3: > * change commit log > * add const to mlx5_counters_init > * change warning message for unrecognized counter >=20 > --- > drivers/net/mlx5/mlx5.c | 3 + > drivers/net/mlx5/mlx5.h | 15 ++ > drivers/net/mlx5/mlx5_defs.h | 3 + > drivers/net/mlx5/mlx5_stats.c | 328 > ++++++++++++++++++++++++++++++++++++++++ > drivers/net/mlx5/mlx5_trigger.c | 1 + > 5 files changed, 350 insertions(+) >=20 > diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index > 55c5b87..11ef301 100644 > --- a/drivers/net/mlx5/mlx5.c > +++ b/drivers/net/mlx5/mlx5.c > @@ -202,6 +202,9 @@ > .link_update =3D mlx5_link_update, > .stats_get =3D mlx5_stats_get, > .stats_reset =3D mlx5_stats_reset, > + .xstats_get =3D mlx5_xstats_get, > + .xstats_reset =3D mlx5_xstats_reset, > + .xstats_get_names =3D mlx5_xstats_get_names, > .dev_infos_get =3D mlx5_dev_infos_get, > .dev_supported_ptypes_get =3D mlx5_dev_supported_ptypes_get, > .vlan_filter_set =3D mlx5_vlan_filter_set, diff --git > a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index > a163983..27bb01c 100644 > --- a/drivers/net/mlx5/mlx5.h > +++ b/drivers/net/mlx5/mlx5.h > @@ -89,6 +89,14 @@ enum { > PCI_DEVICE_ID_MELLANOX_CONNECTX5EXVF =3D 0x101a, }; >=20 > +struct mlx5_xstats_ctrl { > + /* Number of device stats. */ > + uint16_t stats_n; > + /* Index in the device counters table. */ > + uint16_t dev_table_idx[MLX5_MAX_XSTATS]; > + uint64_t base[MLX5_MAX_XSTATS]; > +}; > + > struct priv { > struct rte_eth_dev *dev; /* Ethernet device. */ > struct ibv_context *ctx; /* Verbs context. */ @@ -143,6 +151,7 @@ > struct priv { > struct fdir_queue *fdir_drop_queue; /* Flow director drop queue. > */ > LIST_HEAD(mlx5_flows, rte_flow) flows; /* RTE Flow rules. */ > uint32_t link_speed_capa; /* Link speed capabilities. */ > + struct mlx5_xstats_ctrl xstats_ctrl; /* Extended stats control. */ > rte_spinlock_t lock; /* Lock for control functions. */ }; >=20 > @@ -251,8 +260,14 @@ int mlx5_dev_rss_reta_update(struct rte_eth_dev > *, >=20 > /* mlx5_stats.c */ >=20 > +void priv_xstats_init(struct priv *); > void mlx5_stats_get(struct rte_eth_dev *, struct rte_eth_stats *); void > mlx5_stats_reset(struct rte_eth_dev *); > +int mlx5_xstats_get(struct rte_eth_dev *, > + struct rte_eth_xstat *, unsigned int); void > +mlx5_xstats_reset(struct rte_eth_dev *); int > +mlx5_xstats_get_names(struct rte_eth_dev *, > + struct rte_eth_xstat_name *, unsigned int); >=20 > /* mlx5_vlan.c */ >=20 > diff --git a/drivers/net/mlx5/mlx5_defs.h b/drivers/net/mlx5/mlx5_defs.h > index b32816e..beabb70 100644 > --- a/drivers/net/mlx5/mlx5_defs.h > +++ b/drivers/net/mlx5/mlx5_defs.h > @@ -79,4 +79,7 @@ > /* Alarm timeout. */ > #define MLX5_ALARM_TIMEOUT_US 100000 >=20 > +/* Maximum number of extended statistics counters. */ #define > +MLX5_MAX_XSTATS 32 > + > #endif /* RTE_PMD_MLX5_DEFS_H_ */ > diff --git a/drivers/net/mlx5/mlx5_stats.c b/drivers/net/mlx5/mlx5_stats.= c > index f2b5781..20c957e 100644 > --- a/drivers/net/mlx5/mlx5_stats.c > +++ b/drivers/net/mlx5/mlx5_stats.c > @@ -31,11 +31,16 @@ > * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH > DAMAGE. > */ >=20 > +#include > +#include > + > /* DPDK headers don't like -pedantic. */ #ifdef PEDANTIC #pragma GCC > diagnostic ignored "-Wpedantic" > #endif > #include > +#include > +#include > #ifdef PEDANTIC > #pragma GCC diagnostic error "-Wpedantic" > #endif > @@ -44,6 +49,252 @@ > #include "mlx5_rxtx.h" > #include "mlx5_defs.h" >=20 > +struct mlx5_counter_ctrl { > + /* Name of the counter. */ > + char dpdk_name[RTE_ETH_XSTATS_NAME_SIZE]; > + /* Name of the counter on the device table. */ > + char ctr_name[RTE_ETH_XSTATS_NAME_SIZE]; > +}; > + > +static const struct mlx5_counter_ctrl mlx5_counters_init[] =3D { > + { > + .dpdk_name =3D "rx_port_unicast_bytes", > + .ctr_name =3D "rx_vport_unicast_bytes", > + }, > + { > + .dpdk_name =3D "rx_port_multicast_bytes", > + .ctr_name =3D "rx_vport_multicast_bytes", > + }, > + { > + .dpdk_name =3D "rx_port_broadcast_bytes", > + .ctr_name =3D "rx_vport_broadcast_bytes", > + }, > + { > + .dpdk_name =3D "rx_port_unicast_packets", > + .ctr_name =3D "rx_vport_unicast_packets", > + }, > + { > + .dpdk_name =3D "rx_port_multicast_packets", > + .ctr_name =3D "rx_vport_multicast_packets", > + }, > + { > + .dpdk_name =3D "rx_port_broadcast_packets", > + .ctr_name =3D "rx_vport_broadcast_packets", > + }, > + { > + .dpdk_name =3D "tx_port_unicast_bytes", > + .ctr_name =3D "tx_vport_unicast_bytes", > + }, > + { > + .dpdk_name =3D "tx_port_multicast_bytes", > + .ctr_name =3D "tx_vport_multicast_bytes", > + }, > + { > + .dpdk_name =3D "tx_port_broadcast_bytes", > + .ctr_name =3D "tx_vport_broadcast_bytes", > + }, > + { > + .dpdk_name =3D "tx_port_unicast_packets", > + .ctr_name =3D "tx_vport_unicast_packets", > + }, > + { > + .dpdk_name =3D "tx_port_multicast_packets", > + .ctr_name =3D "tx_vport_multicast_packets", > + }, > + { > + .dpdk_name =3D "tx_port_broadcast_packets", > + .ctr_name =3D "tx_vport_broadcast_packets", > + }, > + { > + .dpdk_name =3D "rx_wqe_err", > + .ctr_name =3D "rx_wqe_err", > + }, > + { > + .dpdk_name =3D "rx_crc_errors_phy", > + .ctr_name =3D "rx_crc_errors_phy", > + }, > + { > + .dpdk_name =3D "rx_in_range_len_errors_phy", > + .ctr_name =3D "rx_in_range_len_errors_phy", > + }, > + { > + .dpdk_name =3D "rx_symbol_err_phy", > + .ctr_name =3D "rx_symbol_err_phy", > + }, > + { > + .dpdk_name =3D "tx_errors_phy", > + .ctr_name =3D "tx_errors_phy", > + }, > +}; > + > +static const unsigned int xstats_n =3D RTE_DIM(mlx5_counters_init); > + > +/** > + * Read device counters table. > + * > + * @param priv > + * Pointer to private structure. > + * @param[out] stats > + * Counters table output buffer. > + * > + * @return > + * 0 on success and stats is filled, negative on error. > + */ > +static int > +priv_read_dev_counters(struct priv *priv, uint64_t *stats) { > + struct mlx5_xstats_ctrl *xstats_ctrl =3D &priv->xstats_ctrl; > + unsigned int i; > + struct ifreq ifr; > + unsigned int stats_sz =3D (xstats_ctrl->stats_n * sizeof(uint64_t)) + > + sizeof(struct ethtool_stats); > + struct ethtool_stats et_stats[(stats_sz + ( > + sizeof(struct ethtool_stats) - 1)) / > + sizeof(struct ethtool_stats)]; > + > + et_stats->cmd =3D ETHTOOL_GSTATS; > + et_stats->n_stats =3D xstats_ctrl->stats_n; > + ifr.ifr_data =3D (caddr_t)et_stats; > + if (priv_ifreq(priv, SIOCETHTOOL, &ifr) !=3D 0) { > + WARN("unable to read statistic values from device"); > + return -1; > + } > + for (i =3D 0; i !=3D xstats_n; ++i) > + stats[i] =3D (uint64_t) > + et_stats->data[xstats_ctrl->dev_table_idx[i]]; > + return 0; > +} > + > +/** > + * Init the structures to read device counters. > + * > + * @param priv > + * Pointer to private structure. > + */ > +void > +priv_xstats_init(struct priv *priv) > +{ > + struct mlx5_xstats_ctrl *xstats_ctrl =3D &priv->xstats_ctrl; > + unsigned int i; > + unsigned int j; > + char ifname[IF_NAMESIZE]; > + struct ifreq ifr; > + struct ethtool_drvinfo drvinfo; > + struct ethtool_gstrings *strings =3D NULL; > + unsigned int dev_stats_n; > + unsigned int str_sz; > + > + if (priv_get_ifname(priv, &ifname)) { > + WARN("unable to get interface name"); > + return; > + } > + /* How many statistics are available. */ > + drvinfo.cmd =3D ETHTOOL_GDRVINFO; > + ifr.ifr_data =3D (caddr_t)&drvinfo; > + if (priv_ifreq(priv, SIOCETHTOOL, &ifr) !=3D 0) { > + WARN("unable to get driver info"); > + return; > + } > + dev_stats_n =3D drvinfo.n_stats; > + if (dev_stats_n < 1) { > + WARN("no extended statistics available"); > + return; > + } > + xstats_ctrl->stats_n =3D dev_stats_n; > + /* Allocate memory to grab stat names and values. */ > + str_sz =3D dev_stats_n * ETH_GSTRING_LEN; > + strings =3D (struct ethtool_gstrings *) > + rte_malloc("xstats_strings", > + str_sz + sizeof(struct ethtool_gstrings), 0); > + if (!strings) { > + WARN("unable to allocate memory for xstats"); > + return; > + } > + strings->cmd =3D ETHTOOL_GSTRINGS; > + strings->string_set =3D ETH_SS_STATS; > + strings->len =3D dev_stats_n; > + ifr.ifr_data =3D (caddr_t)strings; > + if (priv_ifreq(priv, SIOCETHTOOL, &ifr) !=3D 0) { > + WARN("unable to get statistic names"); > + goto free; > + } > + for (j =3D 0; j !=3D xstats_n; ++j) > + xstats_ctrl->dev_table_idx[j] =3D dev_stats_n; > + for (i =3D 0; i !=3D dev_stats_n; ++i) { > + const char *curr_string =3D (const char *) > + &strings->data[i * ETH_GSTRING_LEN]; > + > + for (j =3D 0; j !=3D xstats_n; ++j) { > + if (!strcmp(mlx5_counters_init[j].ctr_name, > + curr_string)) { > + xstats_ctrl->dev_table_idx[j] =3D i; > + break; > + } > + } > + } > + for (j =3D 0; j !=3D xstats_n; ++j) { > + if (xstats_ctrl->dev_table_idx[j] >=3D dev_stats_n) { > + WARN("counter \"%s\" is not recognized", > + mlx5_counters_init[j].dpdk_name); > + goto free; > + } > + } > + /* Copy to base at first time. */ > + assert(xstats_n <=3D MLX5_MAX_XSTATS); > + priv_read_dev_counters(priv, xstats_ctrl->base); > +free: > + rte_free(strings); > +} > + > +/** > + * Get device extended statistics. > + * > + * @param priv > + * Pointer to private structure. > + * @param[out] stats > + * Pointer to rte extended stats table. > + * > + * @return > + * Number of extended stats on success and stats is filled, > + * negative on error. > + */ > +static int > +priv_xstats_get(struct priv *priv, struct rte_eth_xstat *stats) { > + struct mlx5_xstats_ctrl *xstats_ctrl =3D &priv->xstats_ctrl; > + unsigned int i; > + unsigned int n =3D xstats_n; > + uint64_t counters[n]; > + > + if (priv_read_dev_counters(priv, counters) < 0) > + return -1; > + for (i =3D 0; i !=3D xstats_n; ++i) { > + stats[i].id =3D i; > + stats[i].value =3D (counters[i] - xstats_ctrl->base[i]); > + } > + return n; > +} > + > +/** > + * Reset device extended statistics. > + * > + * @param priv > + * Pointer to private structure. > + */ > +static void > +priv_xstats_reset(struct priv *priv) > +{ > + struct mlx5_xstats_ctrl *xstats_ctrl =3D &priv->xstats_ctrl; > + unsigned int i; > + unsigned int n =3D xstats_n; > + uint64_t counters[n]; > + > + if (priv_read_dev_counters(priv, counters) < 0) > + return; > + for (i =3D 0; i !=3D n; ++i) > + xstats_ctrl->base[i] =3D counters[i]; > +} > + > /** > * DPDK callback to get device statistics. > * > @@ -142,3 +393,80 @@ > #endif > priv_unlock(priv); > } > + > +/** > + * DPDK callback to get extended device statistics. > + * > + * @param dev > + * Pointer to Ethernet device structure. > + * @param[out] stats > + * Stats table output buffer. > + * @param n > + * The size of the stats table. > + * > + * @return > + * Number of xstats on success, negative on failure. > + */ > +int > +mlx5_xstats_get(struct rte_eth_dev *dev, > + struct rte_eth_xstat *stats, unsigned int n) { > + struct priv *priv =3D mlx5_get_priv(dev); > + int ret =3D xstats_n; > + > + if (n >=3D xstats_n && stats) { > + priv_lock(priv); > + ret =3D priv_xstats_get(priv, stats); > + priv_unlock(priv); > + } > + return ret; > +} > + > +/** > + * DPDK callback to clear device extended statistics. > + * > + * @param dev > + * Pointer to Ethernet device structure. > + */ > +void > +mlx5_xstats_reset(struct rte_eth_dev *dev) { > + struct priv *priv =3D mlx5_get_priv(dev); > + > + priv_lock(priv); > + priv_xstats_reset(priv); > + priv_unlock(priv); > +} > + > +/** > + * DPDK callback to retrieve names of extended device statistics > + * > + * @param dev > + * Pointer to Ethernet device structure. > + * @param[out] xstats_names > + * Buffer to insert names into. > + * @param n > + * Number of names. > + * > + * @return > + * Number of xstats names. > + */ > +int > +mlx5_xstats_get_names(struct rte_eth_dev *dev, > + struct rte_eth_xstat_name *xstats_names, unsigned int n) { > + struct priv *priv =3D mlx5_get_priv(dev); > + unsigned int i; > + > + if (n >=3D xstats_n && xstats_names) { > + priv_lock(priv); > + for (i =3D 0; i !=3D xstats_n; ++i) { > + strncpy(xstats_names[i].name, > + mlx5_counters_init[i].dpdk_name, > + RTE_ETH_XSTATS_NAME_SIZE); > + > xstats_names[i].name[RTE_ETH_XSTATS_NAME_SIZE - 1] =3D 0; > + } > + priv_unlock(priv); > + } > + return xstats_n; > +} > diff --git a/drivers/net/mlx5/mlx5_trigger.c > b/drivers/net/mlx5/mlx5_trigger.c index 2399243..30addd2 100644 > --- a/drivers/net/mlx5/mlx5_trigger.c > +++ b/drivers/net/mlx5/mlx5_trigger.c > @@ -91,6 +91,7 @@ > priv_fdir_enable(priv); > priv_dev_interrupt_handler_install(priv, dev); > err =3D priv_flow_start(priv); > + priv_xstats_init(priv); > priv_unlock(priv); > return -err; > } > -- > 1.8.3.1