diff options
Diffstat (limited to 'drivers/infiniband/hw/mlx5/counters.c')
| -rw-r--r-- | drivers/infiniband/hw/mlx5/counters.c | 89 | 
1 files changed, 62 insertions, 27 deletions
diff --git a/drivers/infiniband/hw/mlx5/counters.c b/drivers/infiniband/hw/mlx5/counters.c index 1c06920505d2..93257fa5aae8 100644 --- a/drivers/infiniband/hw/mlx5/counters.c +++ b/drivers/infiniband/hw/mlx5/counters.c @@ -209,7 +209,8 @@ static const struct mlx5_ib_counters *get_counters(struct mlx5_ib_dev *dev,  	     !vport_qcounters_supported(dev)) || !port_num)  		return &dev->port[0].cnts; -	return &dev->port[port_num - 1].cnts; +	return is_mdev_switchdev_mode(dev->mdev) ? +	       &dev->port[1].cnts : &dev->port[port_num - 1].cnts;  }  /** @@ -262,7 +263,7 @@ static struct rdma_hw_stats *  mlx5_ib_alloc_hw_port_stats(struct ib_device *ibdev, u32 port_num)  {  	struct mlx5_ib_dev *dev = to_mdev(ibdev); -	const struct mlx5_ib_counters *cnts = &dev->port[port_num - 1].cnts; +	const struct mlx5_ib_counters *cnts = get_counters(dev, port_num);  	return do_alloc_stats(cnts);  } @@ -329,6 +330,7 @@ static int mlx5_ib_query_q_counters_vport(struct mlx5_ib_dev *dev,  {  	u32 out[MLX5_ST_SZ_DW(query_q_counter_out)] = {};  	u32 in[MLX5_ST_SZ_DW(query_q_counter_in)] = {}; +	struct mlx5_core_dev *mdev;  	__be32 val;  	int ret, i; @@ -336,12 +338,16 @@ static int mlx5_ib_query_q_counters_vport(struct mlx5_ib_dev *dev,  	    dev->port[port_num].rep->vport == MLX5_VPORT_UPLINK)  		return 0; +	mdev = mlx5_eswitch_get_core_dev(dev->port[port_num].rep->esw); +	if (!mdev) +		return -EOPNOTSUPP; +  	MLX5_SET(query_q_counter_in, in, opcode, MLX5_CMD_OP_QUERY_Q_COUNTER);  	MLX5_SET(query_q_counter_in, in, other_vport, 1);  	MLX5_SET(query_q_counter_in, in, vport_number,  		 dev->port[port_num].rep->vport);  	MLX5_SET(query_q_counter_in, in, aggregate, 1); -	ret = mlx5_cmd_exec_inout(dev->mdev, query_q_counter, in, out); +	ret = mlx5_cmd_exec_inout(mdev, query_q_counter, in, out);  	if (ret)  		return ret; @@ -575,43 +581,53 @@ static void mlx5_ib_fill_counters(struct mlx5_ib_dev *dev,  	bool is_vport = is_mdev_switchdev_mode(dev->mdev) &&  			port_num != MLX5_VPORT_PF;  	const struct mlx5_ib_counter *names; -	int j = 0, i; +	int j = 0, i, size;  	names = is_vport ? vport_basic_q_cnts : basic_q_cnts; -	for (i = 0; i < ARRAY_SIZE(basic_q_cnts); i++, j++) { +	size = is_vport ? ARRAY_SIZE(vport_basic_q_cnts) : +			  ARRAY_SIZE(basic_q_cnts); +	for (i = 0; i < size; i++, j++) {  		descs[j].name = names[i].name; -		offsets[j] = basic_q_cnts[i].offset; +		offsets[j] = names[i].offset;  	}  	names = is_vport ? vport_out_of_seq_q_cnts : out_of_seq_q_cnts; +	size = is_vport ? ARRAY_SIZE(vport_out_of_seq_q_cnts) : +			  ARRAY_SIZE(out_of_seq_q_cnts);  	if (MLX5_CAP_GEN(dev->mdev, out_of_seq_cnt)) { -		for (i = 0; i < ARRAY_SIZE(out_of_seq_q_cnts); i++, j++) { +		for (i = 0; i < size; i++, j++) {  			descs[j].name = names[i].name; -			offsets[j] = out_of_seq_q_cnts[i].offset; +			offsets[j] = names[i].offset;  		}  	}  	names = is_vport ? vport_retrans_q_cnts : retrans_q_cnts; +	size = is_vport ? ARRAY_SIZE(vport_retrans_q_cnts) : +			  ARRAY_SIZE(retrans_q_cnts);  	if (MLX5_CAP_GEN(dev->mdev, retransmission_q_counters)) { -		for (i = 0; i < ARRAY_SIZE(retrans_q_cnts); i++, j++) { +		for (i = 0; i < size; i++, j++) {  			descs[j].name = names[i].name; -			offsets[j] = retrans_q_cnts[i].offset; +			offsets[j] = names[i].offset;  		}  	}  	names = is_vport ? vport_extended_err_cnts : extended_err_cnts; +	size = is_vport ? ARRAY_SIZE(vport_extended_err_cnts) : +			  ARRAY_SIZE(extended_err_cnts);  	if (MLX5_CAP_GEN(dev->mdev, enhanced_error_q_counters)) { -		for (i = 0; i < ARRAY_SIZE(extended_err_cnts); i++, j++) { +		for (i = 0; i < size; i++, j++) {  			descs[j].name = names[i].name; -			offsets[j] = extended_err_cnts[i].offset; +			offsets[j] = names[i].offset;  		}  	}  	names = is_vport ? vport_roce_accl_cnts : roce_accl_cnts; +	size = is_vport ? ARRAY_SIZE(vport_roce_accl_cnts) : +			  ARRAY_SIZE(roce_accl_cnts);  	if (MLX5_CAP_GEN(dev->mdev, roce_accl)) { -		for (i = 0; i < ARRAY_SIZE(roce_accl_cnts); i++, j++) { +		for (i = 0; i < size; i++, j++) {  			descs[j].name = names[i].name; -			offsets[j] = roce_accl_cnts[i].offset; +			offsets[j] = names[i].offset;  		}  	} @@ -661,25 +677,37 @@ static void mlx5_ib_fill_counters(struct mlx5_ib_dev *dev,  static int __mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev,  				    struct mlx5_ib_counters *cnts, u32 port_num)  { -	u32 num_counters, num_op_counters = 0; +	bool is_vport = is_mdev_switchdev_mode(dev->mdev) && +			port_num != MLX5_VPORT_PF; +	u32 num_counters, num_op_counters = 0, size; -	num_counters = ARRAY_SIZE(basic_q_cnts); +	size = is_vport ? ARRAY_SIZE(vport_basic_q_cnts) : +			  ARRAY_SIZE(basic_q_cnts); +	num_counters = size; +	size = is_vport ? ARRAY_SIZE(vport_out_of_seq_q_cnts) : +			  ARRAY_SIZE(out_of_seq_q_cnts);  	if (MLX5_CAP_GEN(dev->mdev, out_of_seq_cnt)) -		num_counters += ARRAY_SIZE(out_of_seq_q_cnts); +		num_counters += size; +	size = is_vport ? ARRAY_SIZE(vport_retrans_q_cnts) : +			  ARRAY_SIZE(retrans_q_cnts);  	if (MLX5_CAP_GEN(dev->mdev, retransmission_q_counters)) -		num_counters += ARRAY_SIZE(retrans_q_cnts); +		num_counters += size; +	size = is_vport ? ARRAY_SIZE(vport_extended_err_cnts) : +			  ARRAY_SIZE(extended_err_cnts);  	if (MLX5_CAP_GEN(dev->mdev, enhanced_error_q_counters)) -		num_counters += ARRAY_SIZE(extended_err_cnts); +		num_counters += size; +	size = is_vport ? ARRAY_SIZE(vport_roce_accl_cnts) : +			  ARRAY_SIZE(roce_accl_cnts);  	if (MLX5_CAP_GEN(dev->mdev, roce_accl)) -		num_counters += ARRAY_SIZE(roce_accl_cnts); +		num_counters += size;  	cnts->num_q_counters = num_counters; -	if (is_mdev_switchdev_mode(dev->mdev) && port_num != MLX5_VPORT_PF) +	if (is_vport)  		goto skip_non_qcounters;  	if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) { @@ -725,11 +753,11 @@ err:  static void mlx5_ib_dealloc_counters(struct mlx5_ib_dev *dev)  {  	u32 in[MLX5_ST_SZ_DW(dealloc_q_counter_in)] = {}; -	int num_cnt_ports; +	int num_cnt_ports = dev->num_ports;  	int i, j; -	num_cnt_ports = (!is_mdev_switchdev_mode(dev->mdev) || -			 vport_qcounters_supported(dev)) ? dev->num_ports : 1; +	if (is_mdev_switchdev_mode(dev->mdev)) +		num_cnt_ports = min(2, num_cnt_ports);  	MLX5_SET(dealloc_q_counter_in, in, opcode,  		 MLX5_CMD_OP_DEALLOC_Q_COUNTER); @@ -761,15 +789,22 @@ static int mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev)  {  	u32 out[MLX5_ST_SZ_DW(alloc_q_counter_out)] = {};  	u32 in[MLX5_ST_SZ_DW(alloc_q_counter_in)] = {}; -	int num_cnt_ports; +	int num_cnt_ports = dev->num_ports;  	int err = 0;  	int i;  	bool is_shared;  	MLX5_SET(alloc_q_counter_in, in, opcode, MLX5_CMD_OP_ALLOC_Q_COUNTER);  	is_shared = MLX5_CAP_GEN(dev->mdev, log_max_uctx) != 0; -	num_cnt_ports = (!is_mdev_switchdev_mode(dev->mdev) || -			 vport_qcounters_supported(dev)) ? dev->num_ports : 1; + +	/* +	 * In switchdev we need to allocate two ports, one that is used for +	 * the device Q_counters and it is essentially the real Q_counters of +	 * this device, while the other is used as a helper for PF to be able to +	 * query all other vports. +	 */ +	if (is_mdev_switchdev_mode(dev->mdev)) +		num_cnt_ports = min(2, num_cnt_ports);  	for (i = 0; i < num_cnt_ports; i++) {  		err = __mlx5_ib_alloc_counters(dev, &dev->port[i].cnts, i);  |