Skip to content

Commit

Permalink
IB/mlx5: Update counter implementation for dual port RoCE
Browse files Browse the repository at this point in the history
Update the counter interface for multiple ports. Some counter sets
always comes from the primary device.

Port specific counters should be accessed per mlx5_core_dev not always
through the IB master mdev.

Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
Signed-off-by: Parav Pandit <parav@mellanox.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
  • Loading branch information
Daniel Jurgens authored and Jason Gunthorpe committed Jan 8, 2018
1 parent a9e546e commit aac4492
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 28 deletions.
69 changes: 41 additions & 28 deletions drivers/infiniband/hw/mlx5/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3885,11 +3885,12 @@ static const struct mlx5_ib_counter extended_err_cnts[] = {

static void mlx5_ib_dealloc_counters(struct mlx5_ib_dev *dev)
{
unsigned int i;
int i;

for (i = 0; i < dev->num_ports; i++) {
mlx5_core_dealloc_q_counter(dev->mdev,
dev->port[i].cnts.set_id);
if (dev->port[i].cnts.set_id)
mlx5_core_dealloc_q_counter(dev->mdev,
dev->port[i].cnts.set_id);
kfree(dev->port[i].cnts.names);
kfree(dev->port[i].cnts.offsets);
}
Expand Down Expand Up @@ -3931,6 +3932,7 @@ static int __mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev,

err_names:
kfree(cnts->names);
cnts->names = NULL;
return -ENOMEM;
}

Expand Down Expand Up @@ -3977,37 +3979,33 @@ static void mlx5_ib_fill_counters(struct mlx5_ib_dev *dev,

static int mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev)
{
int err = 0;
int i;
int ret;

for (i = 0; i < dev->num_ports; i++) {
struct mlx5_ib_port *port = &dev->port[i];
err = __mlx5_ib_alloc_counters(dev, &dev->port[i].cnts);
if (err)
goto err_alloc;

mlx5_ib_fill_counters(dev, dev->port[i].cnts.names,
dev->port[i].cnts.offsets);

ret = mlx5_core_alloc_q_counter(dev->mdev,
&port->cnts.set_id);
if (ret) {
err = mlx5_core_alloc_q_counter(dev->mdev,
&dev->port[i].cnts.set_id);
if (err) {
mlx5_ib_warn(dev,
"couldn't allocate queue counter for port %d, err %d\n",
i + 1, ret);
goto dealloc_counters;
i + 1, err);
goto err_alloc;
}

ret = __mlx5_ib_alloc_counters(dev, &port->cnts);
if (ret)
goto dealloc_counters;

mlx5_ib_fill_counters(dev, port->cnts.names,
port->cnts.offsets);
dev->port[i].cnts.set_id_valid = true;
}

return 0;

dealloc_counters:
while (--i >= 0)
mlx5_core_dealloc_q_counter(dev->mdev,
dev->port[i].cnts.set_id);

return ret;
err_alloc:
mlx5_ib_dealloc_counters(dev);
return err;
}

static struct rdma_hw_stats *mlx5_ib_alloc_hw_stats(struct ib_device *ibdev,
Expand All @@ -4026,7 +4024,7 @@ static struct rdma_hw_stats *mlx5_ib_alloc_hw_stats(struct ib_device *ibdev,
RDMA_HW_STATS_DEFAULT_LIFESPAN);
}

static int mlx5_ib_query_q_counters(struct mlx5_ib_dev *dev,
static int mlx5_ib_query_q_counters(struct mlx5_core_dev *mdev,
struct mlx5_ib_port *port,
struct rdma_hw_stats *stats)
{
Expand All @@ -4039,7 +4037,7 @@ static int mlx5_ib_query_q_counters(struct mlx5_ib_dev *dev,
if (!out)
return -ENOMEM;

ret = mlx5_core_query_q_counter(dev->mdev,
ret = mlx5_core_query_q_counter(mdev,
port->cnts.set_id, 0,
out, outlen);
if (ret)
Expand All @@ -4061,28 +4059,43 @@ static int mlx5_ib_get_hw_stats(struct ib_device *ibdev,
{
struct mlx5_ib_dev *dev = to_mdev(ibdev);
struct mlx5_ib_port *port = &dev->port[port_num - 1];
struct mlx5_core_dev *mdev;
int ret, num_counters;
u8 mdev_port_num;

if (!stats)
return -EINVAL;

ret = mlx5_ib_query_q_counters(dev, port, stats);
num_counters = port->cnts.num_q_counters + port->cnts.num_cong_counters;

/* q_counters are per IB device, query the master mdev */
ret = mlx5_ib_query_q_counters(dev->mdev, port, stats);
if (ret)
return ret;
num_counters = port->cnts.num_q_counters;

if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) {
mdev = mlx5_ib_get_native_port_mdev(dev, port_num,
&mdev_port_num);
if (!mdev) {
/* If port is not affiliated yet, its in down state
* which doesn't have any counters yet, so it would be
* zero. So no need to read from the HCA.
*/
goto done;
}
ret = mlx5_lag_query_cong_counters(dev->mdev,
stats->value +
port->cnts.num_q_counters,
port->cnts.num_cong_counters,
port->cnts.offsets +
port->cnts.num_q_counters);

mlx5_ib_put_native_port_mdev(dev, port_num);
if (ret)
return ret;
num_counters += port->cnts.num_cong_counters;
}

done:
return num_counters;
}

Expand Down
1 change: 1 addition & 0 deletions drivers/infiniband/hw/mlx5/mlx5_ib.h
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,7 @@ struct mlx5_ib_counters {
u32 num_q_counters;
u32 num_cong_counters;
u16 set_id;
bool set_id_valid;
};

struct mlx5_ib_multiport_info;
Expand Down

0 comments on commit aac4492

Please sign in to comment.