]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
net/mlx4: support per-queue statistics via netlink
authorJoe Damato <jdamato@fastly.com>
Tue, 28 May 2024 18:11:38 +0000 (18:11 +0000)
committerJakub Kicinski <kuba@kernel.org>
Fri, 31 May 2024 00:14:45 +0000 (17:14 -0700)
Make mlx4 compatible with the newly added netlink queue stats API.

Signed-off-by: Joe Damato <jdamato@fastly.com>
Tested-by: Martin Karsten <mkarsten@uwaterloo.ca>
Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Link: https://lore.kernel.org/r/20240528181139.515070-4-jdamato@fastly.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/mellanox/mlx4/en_netdev.c

index 4d2f8c4583469dd5737e9b606107e6ff2fc13d2e..281b34af0bb48f6e9d386544736533f8872f6f97 100644 (file)
@@ -43,6 +43,7 @@
 #include <net/vxlan.h>
 #include <net/devlink.h>
 #include <net/rps.h>
+#include <net/netdev_queues.h>
 
 #include <linux/mlx4/driver.h>
 #include <linux/mlx4/device.h>
@@ -3100,6 +3101,77 @@ void mlx4_en_set_stats_bitmap(struct mlx4_dev *dev,
        last_i += NUM_PHY_STATS;
 }
 
+static void mlx4_get_queue_stats_rx(struct net_device *dev, int i,
+                                   struct netdev_queue_stats_rx *stats)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       const struct mlx4_en_rx_ring *ring;
+
+       spin_lock_bh(&priv->stats_lock);
+
+       if (!priv->port_up || mlx4_is_master(priv->mdev->dev))
+               goto out_unlock;
+
+       ring = priv->rx_ring[i];
+       stats->packets = READ_ONCE(ring->packets);
+       stats->bytes   = READ_ONCE(ring->bytes);
+       stats->alloc_fail = READ_ONCE(ring->alloc_fail);
+
+out_unlock:
+       spin_unlock_bh(&priv->stats_lock);
+}
+
+static void mlx4_get_queue_stats_tx(struct net_device *dev, int i,
+                                   struct netdev_queue_stats_tx *stats)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       const struct mlx4_en_tx_ring *ring;
+
+       spin_lock_bh(&priv->stats_lock);
+
+       if (!priv->port_up || mlx4_is_master(priv->mdev->dev))
+               goto out_unlock;
+
+       ring = priv->tx_ring[TX][i];
+       stats->packets = READ_ONCE(ring->packets);
+       stats->bytes   = READ_ONCE(ring->bytes);
+
+out_unlock:
+       spin_unlock_bh(&priv->stats_lock);
+}
+
+static void mlx4_get_base_stats(struct net_device *dev,
+                               struct netdev_queue_stats_rx *rx,
+                               struct netdev_queue_stats_tx *tx)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+
+       spin_lock_bh(&priv->stats_lock);
+
+       if (!priv->port_up || mlx4_is_master(priv->mdev->dev))
+               goto out_unlock;
+
+       if (priv->rx_ring_num) {
+               rx->packets = 0;
+               rx->bytes = 0;
+               rx->alloc_fail = 0;
+       }
+
+       if (priv->tx_ring_num[TX]) {
+               tx->packets = 0;
+               tx->bytes = 0;
+       }
+
+out_unlock:
+       spin_unlock_bh(&priv->stats_lock);
+}
+
+static const struct netdev_stat_ops mlx4_stat_ops = {
+       .get_queue_stats_rx     = mlx4_get_queue_stats_rx,
+       .get_queue_stats_tx     = mlx4_get_queue_stats_tx,
+       .get_base_stats         = mlx4_get_base_stats,
+};
+
 int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
                        struct mlx4_en_port_profile *prof)
 {
@@ -3263,6 +3335,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
        netif_set_real_num_tx_queues(dev, priv->tx_ring_num[TX]);
        netif_set_real_num_rx_queues(dev, priv->rx_ring_num);
 
+       dev->stat_ops = &mlx4_stat_ops;
        dev->ethtool_ops = &mlx4_en_ethtool_ops;
 
        /*