Add per-device Q counters support
Subsystems (2)
cover Add per-device Q counters support
From: Leon Romanovsky <[email protected]>
Hi,
This series is based on top -rc series [1] and may be considered to be part of it, but can go to -next too.
Thanks
[1] https://lore.kernel.org/linux-rdma/[email protected]
Parav Pandit (2):
IB/mlx5: Refactor code for counters allocation IB/mlx5: Support per device q counters in switchdev mode
drivers/infiniband/hw/mlx5/main.c | 107 ++++++++++++++++++--------- drivers/infiniband/hw/mlx5/mlx5_ib.h | 1 + drivers/infiniband/hw/mlx5/qp.c | 25 ++++--- 3 files changed, 85 insertions(+), 48 deletions(-)
--
2.20.1
PATCH 1/2 IB/mlx5: Refactor code for counters allocation
From: Parav Pandit <[email protected]>
To support per device counters in switchdev mode (instead of per port counter), refactor query routines to work on mlx5_ib_counter structure instead of mlx5_ib_port structure.
--- drivers/infiniband/hw/mlx5/main.c | 60 +++++++++++++++---------------- 1 file changed, 29 insertions(+), 31 deletions(-)
drivers/infiniband/hw/mlx5/main.c +29 -31
@@ -5466,21 +5466,21 @@ static struct rdma_hw_stats *mlx5_ib_alloc_hw_stats(struct ib_device *ibdev, u8 port_num) {struct mlx5_ib_dev *dev =to_mdev (ibdev); -struct mlx5_ib_port *port = &dev->port[port_num -1 ]; +const struct mlx5_ib_counters *cnts = &dev->port[port_num -1 ].cnts;/* We support only per port stats */ if (port_num ==0 )return NULL ; -return rdma_alloc_hw_stats_struct (port->cnts.names, - port->cnts.num_q_counters + - port->cnts.num_cong_counters + - port->cnts.num_ext_ppcnt_counters, +return rdma_alloc_hw_stats_struct (cnts->names, + cnts->num_q_counters + + cnts->num_cong_counters + + cnts->num_ext_ppcnt_counters,RDMA_HW_STATS_DEFAULT_LIFESPAN ); }static int mlx5_ib_query_q_counters (struct mlx5_core_dev *mdev, -struct mlx5_ib_port *port, +const struct mlx5_ib_counters *cnts,struct rdma_hw_stats *stats,u16 set_id) {
@@ -5497,8 +5497,8 @@ static int mlx5_ib_query_q_counters(struct mlx5_core_dev *mdev,if (ret) goto free; -for (i =0 ; i < port->cnts.num_q_counters; i++) { - val = *(__be32 *)(out + port->cnts.offsets[i]); +for (i =0 ; i < cnts->num_q_counters; i++) { + val = *(__be32 *)(out + cnts->offsets[i]); stats->value[i] = (u64 )be32_to_cpu (val); }
@@ -5508,10 +5508,10 @@ static int mlx5_ib_query_q_counters(struct mlx5_core_dev *mdev, }static int mlx5_ib_query_ext_ppcnt_counters (struct mlx5_ib_dev *dev, -struct mlx5_ib_port *port, -struct rdma_hw_stats *stats) +const struct mlx5_ib_counters *cnts, +struct rdma_hw_stats *stats) { -int offset = port->cnts.num_q_counters + port->cnts.num_cong_counters; +int offset = cnts->num_q_counters + cnts->num_cong_counters;int sz =MLX5_ST_SZ_BYTES (ppcnt_reg);int ret, i;void *out;
@@ -5524,12 +5524,10 @@ static int mlx5_ib_query_ext_ppcnt_counters(struct mlx5_ib_dev *dev,if (ret) goto free; -for (i =0 ; i < port->cnts.num_ext_ppcnt_counters; i++) { +for (i =0 ; i < cnts->num_ext_ppcnt_counters; i++) stats->value[i + offset] =be64_to_cpup ((__be64 *)(out + - port->cnts.offsets[i + offset])); - } - + cnts->offsets[i + offset])); free:kvfree (out);return ret;
@@ -5540,7 +5538,7 @@ static int mlx5_ib_get_hw_stats(struct ib_device *ibdev, u8 port_num, int index) {struct mlx5_ib_dev *dev =to_mdev (ibdev); -struct mlx5_ib_port *port = &dev->port[port_num -1 ]; +struct mlx5_ib_counters *cnts = &dev->port[port_num -1 ].cnts;struct mlx5_core_dev *mdev;int ret, num_counters;u8 mdev_port_num;
@@ -5548,18 +5546,17 @@ static int mlx5_ib_get_hw_stats(struct ib_device *ibdev,if (!stats)return -EINVAL ; - num_counters = port->cnts.num_q_counters + - port->cnts.num_cong_counters + - port->cnts.num_ext_ppcnt_counters; + num_counters = cnts->num_q_counters + + cnts->num_cong_counters + + cnts->num_ext_ppcnt_counters;/* q_counters are per IB device, query the master mdev */ - ret =mlx5_ib_query_q_counters (dev->mdev, port, stats, - port->cnts.set_id); + ret =mlx5_ib_query_q_counters (dev->mdev, cnts, stats, cnts->set_id);if (ret)return ret;if (MLX5_CAP_PCAM_FEATURE (dev->mdev, rx_icrc_encapsulated_counter)) { - ret =mlx5_ib_query_ext_ppcnt_counters (dev, port, stats); + ret =mlx5_ib_query_ext_ppcnt_counters (dev, cnts, stats);if (ret)return ret; }
@@ -5576,10 +5573,10 @@ static int mlx5_ib_get_hw_stats(struct ib_device *ibdev, } 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); + cnts->num_q_counters, + cnts->num_cong_counters, + cnts->offsets + + cnts->num_q_counters);mlx5_ib_put_native_port_mdev (dev, port_num);if (ret)
@@ -5594,20 +5591,21 @@ static struct rdma_hw_stats * mlx5_ib_counter_alloc_stats(struct rdma_counter *counter) {struct mlx5_ib_dev *dev =to_mdev (counter->device); -struct mlx5_ib_port *port = &dev->port[counter->port -1 ]; +const struct mlx5_ib_counters *cnts = + &dev->port[counter->port -1 ].cnts;/* Q counters are in the beginning of all counters */ -return rdma_alloc_hw_stats_struct (port->cnts.names, - port->cnts.num_q_counters, +return rdma_alloc_hw_stats_struct (cnts->names, + cnts->num_q_counters,RDMA_HW_STATS_DEFAULT_LIFESPAN ); }static int mlx5_ib_counter_update_stats (struct rdma_counter *counter) {struct mlx5_ib_dev *dev =to_mdev (counter->device); -struct mlx5_ib_port *port = &dev->port[counter->port -1 ]; +struct mlx5_ib_counters *cnts = &dev->port[counter->port -1 ].cnts; -return mlx5_ib_query_q_counters (dev->mdev, port, +return mlx5_ib_query_q_counters (dev->mdev, cnts, counter->stats, counter->id); }
Signature · 1 line
2.20.1
PATCH 2/2 IB/mlx5: Support per device q counters in switchdev mode
In reply to Leon RomanovskyFrom: Parav Pandit <[email protected]>
When parent mlx5_core_dev is in switchdev mode, q_counters are not applicable to multiple non uplink vports.
Hence, have make them limited to device level.
While at it, correct __mlx5_ib_qp_set_counter() and __mlx5_ib_modify_qp() to use u16 set_id as defined by the device.
--- drivers/infiniband/hw/mlx5/main.c | 55 +++++++++++++++++++++++----- drivers/infiniband/hw/mlx5/mlx5_ib.h | 1 + drivers/infiniband/hw/mlx5/qp.c | 25 +++++++------ 3 files changed, 60 insertions(+), 21 deletions(-)
drivers/infiniband/hw/mlx5/main.c +46 -9
@@ -5322,11 +5322,21 @@ static const struct mlx5_ib_counter ext_ppcnt_cnts[] = { INIT_EXT_PPCNT_COUNTER(rx_icrc_encapsulated), }; +static bool is_mdev_switchdev_mode (const struct mlx5_core_dev *mdev) +{ +return MLX5_ESWITCH_MANAGER (mdev) && +mlx5_ib_eswitch_mode (mdev->priv.eswitch) == +MLX5_ESWITCH_OFFLOADS ; +} +static void mlx5_ib_dealloc_counters (struct mlx5_ib_dev *dev) { +int num_cnt_ports;int i; -for (i =0 ; i < dev->num_ports; i++) { + num_cnt_ports =is_mdev_switchdev_mode (dev->mdev) ?1 : dev->num_ports; + +for (i =0 ; i < num_cnt_ports; i++) {if (dev->port[i].cnts.set_id_valid)mlx5_core_dealloc_q_counter (dev->mdev, dev->port[i].cnts.set_id);
@@ -5428,13 +5438,15 @@ static void mlx5_ib_fill_counters(struct mlx5_ib_dev *dev,static int mlx5_ib_alloc_counters (struct mlx5_ib_dev *dev) { +int num_cnt_ports;int err =0 ;int i;bool is_shared; is_shared =MLX5_CAP_GEN (dev->mdev, log_max_uctx) !=0 ; + num_cnt_ports =is_mdev_switchdev_mode (dev->mdev) ?1 : dev->num_ports; -for (i =0 ; i < dev->num_ports; i++) { +for (i =0 ; i < num_cnt_ports; i++) { err =__mlx5_ib_alloc_counters (dev, &dev->port[i].cnts);if (err) goto err_alloc;
@@ -5454,7 +5466,6 @@ static int mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev) } dev->port[i].cnts.set_id_valid = true; } -return 0 ; err_alloc:
@@ -5462,16 +5473,41 @@ static int mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev)return err; } +static const struct mlx5_ib_counters *get_counters (struct mlx5_ib_dev *dev, +u8 port_num) +{ +return is_mdev_switchdev_mode (dev->mdev) ? &dev->port[0 ].cnts : + &dev->port[port_num].cnts; +} + +/** +* mlx5_ib_get_counters_id - Returns counters id to use for device+port +* @dev: Pointer to mlx5 IB device +* @port_num: Zero based port number +* +* mlx5_ib_get_counters_id() Returns counters set id to use for given +* device port combination in switchdev and non switchdev mode of the +* parent device. +*/ +u16 mlx5_ib_get_counters_id (struct mlx5_ib_dev *dev,u8 port_num) +{ +const struct mlx5_ib_counters *cnts =get_counters (dev, port_num); + +return cnts->set_id; +} +static struct rdma_hw_stats *mlx5_ib_alloc_hw_stats (struct ib_device *ibdev,u8 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; +bool is_switchdev =is_mdev_switchdev_mode (dev->mdev); -/* We support only per port stats */ -if (port_num ==0 ) +if ((is_switchdev && port_num) || (!is_switchdev && !port_num))return NULL ; + cnts =get_counters (dev, port_num -1 ); + return rdma_alloc_hw_stats_struct(cnts->names, cnts->num_q_counters + cnts->num_cong_counters +
@@ -5538,7 +5574,7 @@ static int mlx5_ib_get_hw_stats(struct ib_device *ibdev, u8 port_num, int index) {struct mlx5_ib_dev *dev =to_mdev (ibdev); -struct mlx5_ib_counters *cnts = &dev->port[port_num -1 ].cnts; +const struct mlx5_ib_counters *cnts =get_counters (dev, port_num -1 );struct mlx5_core_dev *mdev;int ret, num_counters;u8 mdev_port_num;
@@ -5592,7 +5628,7 @@ mlx5_ib_counter_alloc_stats(struct rdma_counter *counter) {struct mlx5_ib_dev *dev =to_mdev (counter->device);const struct mlx5_ib_counters *cnts = - &dev->port[counter->port -1 ].cnts; +get_counters (dev, counter->port -1 );/* Q counters are in the beginning of all counters */ return rdma_alloc_hw_stats_struct(cnts->names,
@@ -5603,7 +5639,8 @@ mlx5_ib_counter_alloc_stats(struct rdma_counter *counter)static int mlx5_ib_counter_update_stats (struct rdma_counter *counter) {struct mlx5_ib_dev *dev =to_mdev (counter->device); -struct mlx5_ib_counters *cnts = &dev->port[counter->port -1 ].cnts; +const struct mlx5_ib_counters *cnts = +get_counters (dev, counter->port -1 );return mlx5_ib_query_q_counters (dev->mdev, cnts, counter->stats, counter->id);
drivers/infiniband/hw/mlx5/mlx5_ib.h +1 -0
@@ -1475,4 +1475,5 @@ int bfregn_to_uar_index(struct mlx5_ib_dev *dev, bool dyn_bfreg);int mlx5_ib_qp_set_counter (struct ib_qp *qp,struct rdma_counter *counter); +u16 mlx5_ib_get_counters_id (struct mlx5_ib_dev *dev,u8 port_num);#endif /* MLX5_IB_H */
drivers/infiniband/hw/mlx5/qp.c +13 -12
@@ -3386,19 +3386,16 @@ static int __mlx5_ib_qp_set_counter(struct ib_qp *qp,struct mlx5_ib_dev *dev =to_mdev (qp->device);struct mlx5_ib_qp *mqp =to_mqp (qp);struct mlx5_qp_context context = {}; -struct mlx5_ib_port *mibport =NULL ;struct mlx5_ib_qp_base *base;u32 set_id;if (!MLX5_CAP_GEN (dev->mdev, rts2rts_qp_counters_set_id))return 0 ; -if (counter) { +if (counter) set_id = counter->id; - }else { - mibport = &dev->port[mqp->port -1 ]; - set_id = mibport->cnts.set_id; - } +else + set_id =mlx5_ib_get_counters_id (dev, mqp->port -1 ); base = &mqp->trans_qp.base; context.qp_counter_set_usr_page &=cpu_to_be32 (0xffffff );
@@ -3459,7 +3456,6 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,struct mlx5_ib_cq *send_cq, *recv_cq;struct mlx5_qp_context *context;struct mlx5_ib_pd *pd; -struct mlx5_ib_port *mibport =NULL ;enum mlx5_qp_state mlx5_cur, mlx5_new;enum mlx5_qp_optpar optpar;u32 set_id =0 ;
@@ -3624,11 +3620,10 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,if (qp->flags &MLX5_IB_QP_UNDERLAY ) port_num =0 ; - mibport = &dev->port[port_num];if (ibqp->counter) set_id = ibqp->counter->id;else - set_id = mibport->cnts.set_id; + set_id =mlx5_ib_get_counters_id (dev, port_num); context->qp_counter_set_usr_page |=cpu_to_be32 (set_id <<24 ); }
@@ -3817,6 +3812,8 @@ static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr, dctc =MLX5_ADDR_OF (create_dct_in, qp->dct.in, dct_context_entry);if (cur_state ==IB_QPS_RESET && new_state ==IB_QPS_INIT ) { +u16 set_id; + required |=IB_QP_ACCESS_FLAGS |IB_QP_PKEY_INDEX |IB_QP_PORT ;if (!is_valid_mask (attr_mask, required,0 ))return -EINVAL ;
@@ -3843,7 +3840,9 @@ static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr, }MLX5_SET (dctc, dctc, pkey_index, attr->pkey_index);MLX5_SET (dctc, dctc, port, attr->port_num); -MLX5_SET (dctc, dctc, counter_set_id, dev->port[attr->port_num -1 ].cnts.set_id); + + set_id =mlx5_ib_get_counters_id (dev, attr->port_num -1 ); +MLX5_SET (dctc, dctc, counter_set_id, set_id); }else if (cur_state ==IB_QPS_INIT && new_state ==IB_QPS_RTR ) {struct mlx5_ib_modify_qp_resp resp = {};
@@ -6331,11 +6330,13 @@ int mlx5_ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr, }if (curr_wq_state ==IB_WQS_RESET && wq_state ==IB_WQS_RDY ) { +u16 set_id; + + set_id =mlx5_ib_get_counters_id (dev,0 );if (MLX5_CAP_GEN (dev->mdev, modify_rq_counter_set_id)) {MLX5_SET64 (modify_rq_in, in, modify_bitmask,MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_RQ_COUNTER_SET_ID ); -MLX5_SET (rqc, rqc, counter_set_id, - dev->port->cnts.set_id); +MLX5_SET (rqc, rqc, counter_set_id, set_id); }else dev_info_once( &dev->ib_dev.dev,
Signature · 1 line
2.20.1
Quoted 7 lines · Leon Romanovsky
From: Leon Romanovsky <[email protected]>
Hi,
This series is based on top -rc series [1] and may be considered to be part of it, but can go to -next too.
Quoted 8 lines
Thanks
[1]
https://lore.kernel.org/linux-rdma/[email protected]Parav Pandit (2):
IB/mlx5: Refactor code for counters allocation IB/mlx5: Support per device q counters in switchdev mode
I don't think this series is really -rc material. Too much churn for something where the user would have to actively go read files in /sys in order to even make any sort of problems appear.
Assuming my build test completes, applied to for-next. Thanks.
Signature · 3 lines
Doug Ledford <[email protected]> GPG KeyID: B826A3330E572FDD Fingerprint = AE6B 1BDA 122B 23B4 265B 1274 B826 A333 0E57 2FDD
Quoted 17 lines · Doug Ledford
Quoted 7 lines · Leon Romanovsky
From: Leon Romanovsky <[email protected]>
Hi,
This series is based on top -rc series [1] and may be considered to be part of it, but can go to -next too.
Quoted 8 lines
Thanks
[1]
https://lore.kernel.org/linux-rdma/[email protected]Parav Pandit (2):
IB/mlx5: Refactor code for counters allocation IB/mlx5: Support per device q counters in switchdev mode
Quoted 5 lines
I don't think this series is really -rc material. Too much churn for something where the user would have to actively go read files in /sys in order to even make any sort of problems appear.
Assuming my build test completes, applied to for-next. Thanks.
Thanks.
Quoted 5 lines
--
Doug Ledford <[email protected]>GPG KeyID: B826A3330E572FDD Fingerprint = AE6B 1BDA 122B 23B4 265B 1274 B826 A333 0E57 2FDD