Skip to content

Commit 7b66ae5

Browse files
jdamato-fslydavem330
authored andcommitted
net/mlx5e: Add per queue netdev-genl stats
./cli.py --spec netlink/specs/netdev.yaml \ --dump qstats-get --json '{"scope": "queue"}' ...snip {'ifindex': 7, 'queue-id': 62, 'queue-type': 'rx', 'rx-alloc-fail': 0, 'rx-bytes': 105965251, 'rx-packets': 179790}, {'ifindex': 7, 'queue-id': 0, 'queue-type': 'tx', 'tx-bytes': 9402665, 'tx-packets': 17551}, ...snip Also tested with the script tools/testing/selftests/drivers/net/stats.py in several scenarios to ensure stats tallying was correct: - on boot (default queue counts) - adjusting queue count up or down (ethtool -L eth0 combined ...) The tools/testing/selftests/drivers/net/stats.py brings the device up, so to test with the device down, I did the following: $ ip link show eth4 7: eth4: <BROADCAST,MULTICAST> mtu 9000 qdisc mq state DOWN [..snip..] [..snip..] $ cat /proc/net/dev | grep eth4 eth4: 235710489 434811 [..snip rx..] 2878744 21227 [..snip tx..] $ ./cli.py --spec ../../../Documentation/netlink/specs/netdev.yaml \ --dump qstats-get --json '{"ifindex": 7}' [{'ifindex': 7, 'rx-alloc-fail': 0, 'rx-bytes': 235710489, 'rx-packets': 434811, 'tx-bytes': 2878744, 'tx-packets': 21227}] Compare the values in /proc/net/dev match the output of cli for the same device, even while the device is down. Note that while the device is down, per queue stats output nothing (because the device is down there are no queues): $ ./cli.py --spec ../../../Documentation/netlink/specs/netdev.yaml \ --dump qstats-get --json '{"scope": "queue", "ifindex": 7}' [] Signed-off-by: Joe Damato <[email protected]> Reviewed-by: Tariq Toukan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 0a3e5c1 commit 7b66ae5

File tree

1 file changed

+132
-0
lines changed
  • drivers/net/ethernet/mellanox/mlx5/core

1 file changed

+132
-0
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en_main.c

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include <linux/debugfs.h>
4040
#include <linux/if_bridge.h>
4141
#include <linux/filter.h>
42+
#include <net/netdev_queues.h>
4243
#include <net/page_pool/types.h>
4344
#include <net/pkt_sched.h>
4445
#include <net/xdp_sock_drv.h>
@@ -5298,6 +5299,136 @@ static bool mlx5e_tunnel_any_tx_proto_supported(struct mlx5_core_dev *mdev)
52985299
return (mlx5_vxlan_allowed(mdev->vxlan) || mlx5_geneve_tx_allowed(mdev));
52995300
}
53005301

5302+
static void mlx5e_get_queue_stats_rx(struct net_device *dev, int i,
5303+
struct netdev_queue_stats_rx *stats)
5304+
{
5305+
struct mlx5e_priv *priv = netdev_priv(dev);
5306+
struct mlx5e_channel_stats *channel_stats;
5307+
struct mlx5e_rq_stats *xskrq_stats;
5308+
struct mlx5e_rq_stats *rq_stats;
5309+
5310+
ASSERT_RTNL();
5311+
if (mlx5e_is_uplink_rep(priv))
5312+
return;
5313+
5314+
channel_stats = priv->channel_stats[i];
5315+
xskrq_stats = &channel_stats->xskrq;
5316+
rq_stats = &channel_stats->rq;
5317+
5318+
stats->packets = rq_stats->packets + xskrq_stats->packets;
5319+
stats->bytes = rq_stats->bytes + xskrq_stats->bytes;
5320+
stats->alloc_fail = rq_stats->buff_alloc_err +
5321+
xskrq_stats->buff_alloc_err;
5322+
}
5323+
5324+
static void mlx5e_get_queue_stats_tx(struct net_device *dev, int i,
5325+
struct netdev_queue_stats_tx *stats)
5326+
{
5327+
struct mlx5e_priv *priv = netdev_priv(dev);
5328+
struct mlx5e_sq_stats *sq_stats;
5329+
5330+
ASSERT_RTNL();
5331+
/* no special case needed for ptp htb etc since txq2sq_stats is kept up
5332+
* to date for active sq_stats, otherwise get_base_stats takes care of
5333+
* inactive sqs.
5334+
*/
5335+
sq_stats = priv->txq2sq_stats[i];
5336+
stats->packets = sq_stats->packets;
5337+
stats->bytes = sq_stats->bytes;
5338+
}
5339+
5340+
static void mlx5e_get_base_stats(struct net_device *dev,
5341+
struct netdev_queue_stats_rx *rx,
5342+
struct netdev_queue_stats_tx *tx)
5343+
{
5344+
struct mlx5e_priv *priv = netdev_priv(dev);
5345+
struct mlx5e_ptp *ptp_channel;
5346+
int i, tc;
5347+
5348+
ASSERT_RTNL();
5349+
if (!mlx5e_is_uplink_rep(priv)) {
5350+
rx->packets = 0;
5351+
rx->bytes = 0;
5352+
rx->alloc_fail = 0;
5353+
5354+
for (i = priv->channels.params.num_channels; i < priv->stats_nch; i++) {
5355+
struct netdev_queue_stats_rx rx_i = {0};
5356+
5357+
mlx5e_get_queue_stats_rx(dev, i, &rx_i);
5358+
5359+
rx->packets += rx_i.packets;
5360+
rx->bytes += rx_i.bytes;
5361+
rx->alloc_fail += rx_i.alloc_fail;
5362+
}
5363+
5364+
/* always report PTP RX stats from base as there is no
5365+
* corresponding channel to report them under in
5366+
* mlx5e_get_queue_stats_rx.
5367+
*/
5368+
if (priv->rx_ptp_opened) {
5369+
struct mlx5e_rq_stats *rq_stats = &priv->ptp_stats.rq;
5370+
5371+
rx->packets += rq_stats->packets;
5372+
rx->bytes += rq_stats->bytes;
5373+
}
5374+
}
5375+
5376+
tx->packets = 0;
5377+
tx->bytes = 0;
5378+
5379+
for (i = 0; i < priv->stats_nch; i++) {
5380+
struct mlx5e_channel_stats *channel_stats = priv->channel_stats[i];
5381+
5382+
/* handle two cases:
5383+
*
5384+
* 1. channels which are active. In this case,
5385+
* report only deactivated TCs on these channels.
5386+
*
5387+
* 2. channels which were deactivated
5388+
* (i > priv->channels.params.num_channels)
5389+
* must have all of their TCs [0 .. priv->max_opened_tc)
5390+
* examined because deactivated channels will not be in the
5391+
* range of [0..real_num_tx_queues) and will not have their
5392+
* stats reported by mlx5e_get_queue_stats_tx.
5393+
*/
5394+
if (i < priv->channels.params.num_channels)
5395+
tc = mlx5e_get_dcb_num_tc(&priv->channels.params);
5396+
else
5397+
tc = 0;
5398+
5399+
for (; tc < priv->max_opened_tc; tc++) {
5400+
struct mlx5e_sq_stats *sq_stats = &channel_stats->sq[tc];
5401+
5402+
tx->packets += sq_stats->packets;
5403+
tx->bytes += sq_stats->bytes;
5404+
}
5405+
}
5406+
5407+
/* if PTP TX was opened at some point and has since either:
5408+
* - been shutdown and set to NULL, or
5409+
* - simply disabled (bit unset)
5410+
*
5411+
* report stats directly from the ptp_stats structures as these queues
5412+
* are now unavailable and there is no txq index to retrieve these
5413+
* stats via calls to mlx5e_get_queue_stats_tx.
5414+
*/
5415+
ptp_channel = priv->channels.ptp;
5416+
if (priv->tx_ptp_opened && (!ptp_channel || !test_bit(MLX5E_PTP_STATE_TX, ptp_channel->state))) {
5417+
for (tc = 0; tc < priv->max_opened_tc; tc++) {
5418+
struct mlx5e_sq_stats *sq_stats = &priv->ptp_stats.sq[tc];
5419+
5420+
tx->packets += sq_stats->packets;
5421+
tx->bytes += sq_stats->bytes;
5422+
}
5423+
}
5424+
}
5425+
5426+
static const struct netdev_stat_ops mlx5e_stat_ops = {
5427+
.get_queue_stats_rx = mlx5e_get_queue_stats_rx,
5428+
.get_queue_stats_tx = mlx5e_get_queue_stats_tx,
5429+
.get_base_stats = mlx5e_get_base_stats,
5430+
};
5431+
53015432
static void mlx5e_build_nic_netdev(struct net_device *netdev)
53025433
{
53035434
struct mlx5e_priv *priv = netdev_priv(netdev);
@@ -5315,6 +5446,7 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
53155446

53165447
netdev->watchdog_timeo = 15 * HZ;
53175448

5449+
netdev->stat_ops = &mlx5e_stat_ops;
53185450
netdev->ethtool_ops = &mlx5e_ethtool_ops;
53195451

53205452
netdev->vlan_features |= NETIF_F_SG;

0 commit comments

Comments
 (0)