Skip to content

Commit c2ea687

Browse files
PatrisiousHaddadrleon
authored andcommitted
RDMA/mlx5: Fix Q-counters per vport allocation
Previously Q-counters data was being allocated over the PF for all of the available vports, however that isn't necessary. Since each VF or SF has a Q-counter allocated for itself. So we only need to allocate two counters data structures, one for the device counters, and one for all the other vports to expose the representors, since they only need to read from it in order to determine mainly counters numbers and names, so they can all share. This in turn also solves a bug we previously had where we couldn't switch the device to switchdev mode when there were more than 128 SF/VFs configured, since that is the maximum amount of Q-counters available for a single port Fixes: d22467a ("RDMA/mlx5: Expand switchdev Q-counters to expose representor statistics") Signed-off-by: Patrisious Haddad <phaddad@nvidia.com> Reviewed-by: Mark Zhang <markzhang@nvidia.com> Link: https://lore.kernel.org/r/f54671df16e2227a069b229b33b62cd9ee24c475.1685960567.git.leon@kernel.org Signed-off-by: Leon Romanovsky <leon@kernel.org>
1 parent e1f4a52 commit c2ea687

1 file changed

Lines changed: 16 additions & 8 deletions

File tree

drivers/infiniband/hw/mlx5/counters.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,8 @@ static const struct mlx5_ib_counters *get_counters(struct mlx5_ib_dev *dev,
209209
!vport_qcounters_supported(dev)) || !port_num)
210210
return &dev->port[0].cnts;
211211

212-
return &dev->port[port_num - 1].cnts;
212+
return is_mdev_switchdev_mode(dev->mdev) ?
213+
&dev->port[1].cnts : &dev->port[port_num - 1].cnts;
213214
}
214215

215216
/**
@@ -262,7 +263,7 @@ static struct rdma_hw_stats *
262263
mlx5_ib_alloc_hw_port_stats(struct ib_device *ibdev, u32 port_num)
263264
{
264265
struct mlx5_ib_dev *dev = to_mdev(ibdev);
265-
const struct mlx5_ib_counters *cnts = &dev->port[port_num - 1].cnts;
266+
const struct mlx5_ib_counters *cnts = get_counters(dev, port_num);
266267

267268
return do_alloc_stats(cnts);
268269
}
@@ -725,11 +726,11 @@ static int __mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev,
725726
static void mlx5_ib_dealloc_counters(struct mlx5_ib_dev *dev)
726727
{
727728
u32 in[MLX5_ST_SZ_DW(dealloc_q_counter_in)] = {};
728-
int num_cnt_ports;
729+
int num_cnt_ports = dev->num_ports;
729730
int i, j;
730731

731-
num_cnt_ports = (!is_mdev_switchdev_mode(dev->mdev) ||
732-
vport_qcounters_supported(dev)) ? dev->num_ports : 1;
732+
if (is_mdev_switchdev_mode(dev->mdev))
733+
num_cnt_ports = min(2, num_cnt_ports);
733734

734735
MLX5_SET(dealloc_q_counter_in, in, opcode,
735736
MLX5_CMD_OP_DEALLOC_Q_COUNTER);
@@ -761,15 +762,22 @@ static int mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev)
761762
{
762763
u32 out[MLX5_ST_SZ_DW(alloc_q_counter_out)] = {};
763764
u32 in[MLX5_ST_SZ_DW(alloc_q_counter_in)] = {};
764-
int num_cnt_ports;
765+
int num_cnt_ports = dev->num_ports;
765766
int err = 0;
766767
int i;
767768
bool is_shared;
768769

769770
MLX5_SET(alloc_q_counter_in, in, opcode, MLX5_CMD_OP_ALLOC_Q_COUNTER);
770771
is_shared = MLX5_CAP_GEN(dev->mdev, log_max_uctx) != 0;
771-
num_cnt_ports = (!is_mdev_switchdev_mode(dev->mdev) ||
772-
vport_qcounters_supported(dev)) ? dev->num_ports : 1;
772+
773+
/*
774+
* In switchdev we need to allocate two ports, one that is used for
775+
* the device Q_counters and it is essentially the real Q_counters of
776+
* this device, while the other is used as a helper for PF to be able to
777+
* query all other vports.
778+
*/
779+
if (is_mdev_switchdev_mode(dev->mdev))
780+
num_cnt_ports = min(2, num_cnt_ports);
773781

774782
for (i = 0; i < num_cnt_ports; i++) {
775783
err = __mlx5_ib_alloc_counters(dev, &dev->port[i].cnts, i);

0 commit comments

Comments
 (0)