RDMA/mlx5: Add optional counter support in get_hw_stats callback

When get_hw_stats is called, query and return the optional counter
statistic as well.

Link: https://lore.kernel.org/r/20211008122439.166063-14-markzhang@nvidia.com
Signed-off-by: Aharon Landau <aharonl@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Mark Zhang <markzhang@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
Aharon Landau 2021-10-08 15:24:39 +03:00 committed by Jason Gunthorpe
parent a29b934ceb
commit a020094090
1 changed files with 85 additions and 3 deletions

View File

@ -270,9 +270,9 @@ free:
return ret;
}
static int mlx5_ib_get_hw_stats(struct ib_device *ibdev,
struct rdma_hw_stats *stats,
u32 port_num, int index)
static int do_get_hw_stats(struct ib_device *ibdev,
struct rdma_hw_stats *stats,
u32 port_num, int index)
{
struct mlx5_ib_dev *dev = to_mdev(ibdev);
const struct mlx5_ib_counters *cnts = get_counters(dev, port_num - 1);
@ -324,6 +324,88 @@ done:
return num_counters;
}
static int do_get_op_stat(struct ib_device *ibdev,
struct rdma_hw_stats *stats,
u32 port_num, int index)
{
struct mlx5_ib_dev *dev = to_mdev(ibdev);
const struct mlx5_ib_counters *cnts;
const struct mlx5_ib_op_fc *opfcs;
u64 packets = 0, bytes;
u32 type;
int ret;
cnts = get_counters(dev, port_num - 1);
opfcs = cnts->opfcs;
type = *(u32 *)cnts->descs[index].priv;
if (type >= MLX5_IB_OPCOUNTER_MAX)
return -EINVAL;
if (!opfcs[type].fc)
goto out;
ret = mlx5_fc_query(dev->mdev, opfcs[type].fc,
&packets, &bytes);
if (ret)
return ret;
out:
stats->value[index] = packets;
return index;
}
static int do_get_op_stats(struct ib_device *ibdev,
struct rdma_hw_stats *stats,
u32 port_num)
{
struct mlx5_ib_dev *dev = to_mdev(ibdev);
const struct mlx5_ib_counters *cnts;
int index, ret, num_hw_counters;
cnts = get_counters(dev, port_num - 1);
num_hw_counters = cnts->num_q_counters + cnts->num_cong_counters +
cnts->num_ext_ppcnt_counters;
for (index = num_hw_counters;
index < (num_hw_counters + cnts->num_op_counters); index++) {
ret = do_get_op_stat(ibdev, stats, port_num, index);
if (ret != index)
return ret;
}
return cnts->num_op_counters;
}
static int mlx5_ib_get_hw_stats(struct ib_device *ibdev,
struct rdma_hw_stats *stats,
u32 port_num, int index)
{
int num_counters, num_hw_counters, num_op_counters;
struct mlx5_ib_dev *dev = to_mdev(ibdev);
const struct mlx5_ib_counters *cnts;
cnts = get_counters(dev, port_num - 1);
num_hw_counters = cnts->num_q_counters + cnts->num_cong_counters +
cnts->num_ext_ppcnt_counters;
num_counters = num_hw_counters + cnts->num_op_counters;
if (index < 0 || index > num_counters)
return -EINVAL;
else if (index > 0 && index < num_hw_counters)
return do_get_hw_stats(ibdev, stats, port_num, index);
else if (index >= num_hw_counters && index < num_counters)
return do_get_op_stat(ibdev, stats, port_num, index);
num_hw_counters = do_get_hw_stats(ibdev, stats, port_num, index);
if (num_hw_counters < 0)
return num_hw_counters;
num_op_counters = do_get_op_stats(ibdev, stats, port_num);
if (num_op_counters < 0)
return num_op_counters;
return num_hw_counters + num_op_counters;
}
static struct rdma_hw_stats *
mlx5_ib_counter_alloc_stats(struct rdma_counter *counter)
{