IB/mlx5: Expose Q counters groups only when they are supported by FW
Subsystems (3)
PATCH 1/2 IB/mlx5: Expose Q counters groups only when they are supported by FW
From: Kamal Heib <kamalh-VPRAkNaXOzVWk0Htik3J/[email protected]>
This patch modify the Q counters implementation, so each one of the three Q counters groups will be exposed by the driver only if they are supported by the firmware.
--- drivers/infiniband/hw/mlx5/main.c | 158 ++++++++++++++++++++++++++--------- drivers/infiniband/hw/mlx5/mlx5_ib.h | 9 +- drivers/infiniband/hw/mlx5/qp.c | 4 +- 3 files changed, 128 insertions(+), 43 deletions(-)
drivers/infiniband/hw/mlx5/main.c +118 -40
@@ -3002,13 +3002,102 @@ static void mlx5_disable_eth(struct mlx5_ib_dev *dev)mlx5_nic_vport_disable_roce (dev->mdev); } +struct mlx5_ib_q_counter { +const char *name; +size_t offset; +}; + +#define INIT_Q_COUNTER (_name) \ + { .name = #_name, .offset = MLX5_BYTE_OFF(query_q_counter_out, _name)} + +static const struct mlx5_ib_q_counter basic_q_cnts[] = { +INIT_Q_COUNTER (rx_write_requests), +INIT_Q_COUNTER (rx_read_requests), +INIT_Q_COUNTER (rx_atomic_requests), +INIT_Q_COUNTER (out_of_buffer), +}; + +static const struct mlx5_ib_q_counter out_of_seq_q_cnts[] = { +INIT_Q_COUNTER (out_of_sequence), +}; + +static const struct mlx5_ib_q_counter retrans_q_cnts[] = { +INIT_Q_COUNTER (duplicate_request), +INIT_Q_COUNTER (rnr_nak_retry_err), +INIT_Q_COUNTER (packet_seq_err), +INIT_Q_COUNTER (implied_nak_seq_err), +INIT_Q_COUNTER (local_ack_timeout_err), +}; +static void mlx5_ib_dealloc_q_counters (struct mlx5_ib_dev *dev) {unsigned int i; -for (i =0 ; i < dev->num_ports; i++) +for (i =0 ; i < dev->num_ports; i++) {mlx5_core_dealloc_q_counter (dev->mdev, - dev->port[i].q_cnt_id); + dev->port[i].q_cnts.set_id); +kfree (dev->port[i].q_cnts.names); +kfree (dev->port[i].q_cnts.offsets); + } +} + +static int __mlx5_ib_alloc_q_counters (struct mlx5_ib_dev *dev, +const char ***names, +size_t **offsets, +u32 *num) +{ +u32 num_counters; + + num_counters =ARRAY_SIZE (basic_q_cnts); + +if (MLX5_CAP_GEN (dev->mdev, out_of_seq_cnt)) + num_counters +=ARRAY_SIZE (out_of_seq_q_cnts); + +if (MLX5_CAP_GEN (dev->mdev, retransmission_q_counters)) + num_counters +=ARRAY_SIZE (retrans_q_cnts); + + *names =kcalloc (num_counters,sizeof (**names),GFP_KERNEL ); +if (!*names) +return -ENOMEM ; + + *offsets =kcalloc (num_counters,sizeof (**offsets),GFP_KERNEL ); +if (!*offsets) + goto err_names; + + *num = num_counters; + +return 0 ; + +err_names: +kfree (*names); +return -ENOMEM ; +} + +static void mlx5_ib_fill_q_counters (struct mlx5_ib_dev *dev, +const char **names, +size_t *offsets) +{ +int i; +int j =0 ; + +for (i =0 ; i <ARRAY_SIZE (basic_q_cnts); i++, j++) { + names[j] = basic_q_cnts[i].name; + offsets[j] = basic_q_cnts[i].offset; + } + +if (MLX5_CAP_GEN (dev->mdev, out_of_seq_cnt)) { +for (i =0 ; i <ARRAY_SIZE (out_of_seq_q_cnts); i++, j++) { + names[j] = out_of_seq_q_cnts[i].name; + offsets[j] = out_of_seq_q_cnts[i].offset; + } + } + +if (MLX5_CAP_GEN (dev->mdev, retransmission_q_counters)) { +for (i =0 ; i <ARRAY_SIZE (retrans_q_cnts); i++, j++) { + names[j] = retrans_q_cnts[i].name; + offsets[j] = retrans_q_cnts[i].offset; + } + } }static int mlx5_ib_alloc_q_counters (struct mlx5_ib_dev *dev)
@@ -3017,14 +3106,26 @@ static int mlx5_ib_alloc_q_counters(struct mlx5_ib_dev *dev)int ret;for (i =0 ; i < dev->num_ports; i++) { +struct mlx5_ib_port *port = &dev->port[i]; + ret =mlx5_core_alloc_q_counter (dev->mdev, - &dev->port[i].q_cnt_id); + &port->q_cnts.set_id);if (ret) {mlx5_ib_warn (dev,"couldn't allocate queue counter for port %d, err %d\n" , i +1 , ret); goto dealloc_counters; } + + ret =__mlx5_ib_alloc_q_counters (dev, + &port->q_cnts.names, + &port->q_cnts.offsets, + &port->q_cnts.num_counters); +if (ret) + goto dealloc_counters; + +mlx5_ib_fill_q_counters (dev, port->q_cnts.names, + port->q_cnts.offsets); }return 0 ;
@@ -3032,62 +3133,39 @@ static int mlx5_ib_alloc_q_counters(struct mlx5_ib_dev *dev) dealloc_counters:while (--i >=0 )mlx5_core_dealloc_q_counter (dev->mdev, - dev->port[i].q_cnt_id); + dev->port[i].q_cnts.set_id);return ret; } -static const char *const names[] = { -"rx_write_requests" , -"rx_read_requests" , -"rx_atomic_requests" , -"out_of_buffer" , -"out_of_sequence" , -"duplicate_request" , -"rnr_nak_retry_err" , -"packet_seq_err" , -"implied_nak_seq_err" , -"local_ack_timeout_err" , -}; - -static const size_t stats_offsets[] = { -MLX5_BYTE_OFF (query_q_counter_out, rx_write_requests), -MLX5_BYTE_OFF (query_q_counter_out, rx_read_requests), -MLX5_BYTE_OFF (query_q_counter_out, rx_atomic_requests), -MLX5_BYTE_OFF (query_q_counter_out, out_of_buffer), -MLX5_BYTE_OFF (query_q_counter_out, out_of_sequence), -MLX5_BYTE_OFF (query_q_counter_out, duplicate_request), -MLX5_BYTE_OFF (query_q_counter_out, rnr_nak_retry_err), -MLX5_BYTE_OFF (query_q_counter_out, packet_seq_err), -MLX5_BYTE_OFF (query_q_counter_out, implied_nak_seq_err), -MLX5_BYTE_OFF (query_q_counter_out, local_ack_timeout_err), -}; -static struct rdma_hw_stats *mlx5_ib_alloc_hw_stats (struct ib_device *ibdev,u8 port_num) { -BUILD_BUG_ON (ARRAY_SIZE (names) !=ARRAY_SIZE (stats_offsets)); +struct mlx5_ib_dev *dev =to_mdev (ibdev); +struct mlx5_ib_port *port = &dev->port[port_num -1 ];/* We support only per port stats */ if (port_num ==0 )return NULL ; -return rdma_alloc_hw_stats_struct (names,ARRAY_SIZE (names), +return rdma_alloc_hw_stats_struct (port->q_cnts.names, + port->q_cnts.num_counters,RDMA_HW_STATS_DEFAULT_LIFESPAN ); }static int mlx5_ib_get_hw_stats (struct ib_device *ibdev,struct rdma_hw_stats *stats, -u8 port,int index) +u8 port_num,int index) {struct mlx5_ib_dev *dev =to_mdev (ibdev); +struct mlx5_ib_port *port = &dev->port[port_num -1 ];int outlen =MLX5_ST_SZ_BYTES (query_q_counter_out);void *out;__be32 val;int ret;int i; -if (!port || !stats) +if (!stats)return -ENOSYS ; out =mlx5_vzalloc (outlen);
@@ -3095,18 +3173,19 @@ static int mlx5_ib_get_hw_stats(struct ib_device *ibdev,return -ENOMEM ; ret =mlx5_core_query_q_counter (dev->mdev, - dev->port[port -1 ].q_cnt_id,0 , + port->q_cnts.set_id,0 , out, outlen);if (ret) goto free; -for (i =0 ; i <ARRAY_SIZE (names); i++) { - val = *(__be32 *)(out + stats_offsets[i]); +for (i =0 ; i < port->q_cnts.num_counters; i++) { + val = *(__be32 *)(out + port->q_cnts.offsets[i]); stats->value[i] = (u64 )be32_to_cpu (val); } + free:kvfree (out); -return ARRAY_SIZE (names); +return port->q_cnts.num_counters; }static void *mlx5_ib_add (struct mlx5_core_dev *mdev)
@@ -3258,8 +3337,7 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev) (1ull <<IB_USER_VERBS_CMD_DEALLOC_MW ); } -if (MLX5_CAP_GEN (dev->mdev, out_of_seq_cnt) && -MLX5_CAP_GEN (dev->mdev, retransmission_q_counters)) { +if (MLX5_CAP_GEN (dev->mdev, max_qp_cnt)) { dev->ib_dev.get_hw_stats = mlx5_ib_get_hw_stats; dev->ib_dev.alloc_hw_stats = mlx5_ib_alloc_hw_stats; }
drivers/infiniband/hw/mlx5/mlx5_ib.h +8 -1
@@ -579,8 +579,15 @@ struct mlx5_ib_resources {struct mutex mutex; }; +struct mlx5_ib_q_counters { +const char **names; +size_t *offsets; +u32 num_counters; +u16 set_id; +}; +struct mlx5_ib_port { -u16 q_cnt_id; +struct mlx5_ib_q_counters q_cnts; };struct mlx5_roce {
drivers/infiniband/hw/mlx5/qp.c +2 -2
@@ -2777,7 +2777,7 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp, qp->port) - 1; mibport = &dev->port[port_num]; context->qp_counter_set_usr_page |= -cpu_to_be32 ((u32)(mibport->q_cnt_id) <<24 ); +cpu_to_be32 ((u32)(mibport->q_cnts.set_id) <<24 ); }if (!ibqp->uobject && cur_state ==IB_QPS_RESET && new_state ==IB_QPS_INIT )
@@ -2805,7 +2805,7 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp, raw_qp_param.operation = op;if (cur_state ==IB_QPS_RESET && new_state ==IB_QPS_INIT ) { - raw_qp_param.rq_q_ctr_id = mibport->q_cnt_id; + raw_qp_param.rq_q_ctr_id = mibport->q_cnts.set_id; raw_qp_param.set_mask |=MLX5_RAW_QP_MOD_SET_RQ_Q_CTR_ID ; }
Signature · 6 lines
2.10.2 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): 20170118132510.4586-1-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org
PATCH 2/2 IB/mlx5: Add port counter support for Receive WQs
From: Majd Dibbiny <majd-VPRAkNaXOzVWk0Htik3J/[email protected]>
Counters weren't updated due to Receive WQs' traffic since the counter-id was not associated with the RQ.
Added support for associating the q-counter-id with the Receive WQ. The attachment is done only when changing WQ's state from RESET to READY in modify-WQ command.
FW support is required for the above, without this support Receive WQ counters will not count.
--- drivers/infiniband/hw/mlx5/qp.c | 12 +++++++++++- include/linux/mlx5/mlx5_ifc.h | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-)
drivers/infiniband/hw/mlx5/qp.c +11 -1
@@ -2422,7 +2422,7 @@ static int modify_raw_packet_qp_rq(struct mlx5_ib_dev *dev,if (raw_qp_param->set_mask &MLX5_RAW_QP_MOD_SET_RQ_Q_CTR_ID ) {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_MODIFY_RQ_COUNTER_SET_ID ); +MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_RQ_COUNTER_SET_ID );MLX5_SET (rqc, rqc, counter_set_id, raw_qp_param->rq_q_ctr_id); }else pr_info_once("%s: RAW PACKET QP counters are not supported on current FW\n",
@@ -4896,6 +4896,16 @@ int mlx5_ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr,MLX5_SET (modify_rq_in, in, rq_state, curr_wq_state);MLX5_SET (rqc, rqc, state, wq_state); +if (curr_wq_state ==IB_WQS_RESET && wq_state ==IB_WQS_RDY ) { +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->q_cnts.set_id); + }else +pr_info_once ("%s: Receive WQ counters are not supported on current FW\n" , + dev->ib_dev.name); + } + err =mlx5_core_modify_rq (dev->mdev, rwq->core_qp.qpn, in, inlen);kvfree (in);if (!err)
include/linux/mlx5/mlx5_ifc.h +1 -1
@@ -5017,7 +5017,7 @@ struct mlx5_ifc_modify_rq_out_bits {enum {MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_VSD =1ULL <<1 , -MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_MODIFY_RQ_COUNTER_SET_ID =1ULL <<3 , +MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_RQ_COUNTER_SET_ID =1ULL <<3 , };struct mlx5_ifc_modify_rq_in_bits {
Signature · 6 lines
2.10.2 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): 20170118132510.4586-2-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org
Doug Ledford
AppliedRe: [PATCH rdma-next 2/2] IB/mlx5: Add port counter support for Receive WQs
Quoted 9 lines · Leon Romanovsky
From: Majd Dibbiny <majd-VPRAkNaXOzVWk0Htik3J/[email protected]>
Counters weren't updated due to Receive WQs' traffic since the counter-id was not associated with the RQ.
Added support for associating the q-counter-id with the Receive WQ. The attachment is done only when changing WQ's state from RESET to READY in modify-WQ command.
Quoted 5 lines
FW support is required for the above, without this support Receive WQ counters will not count.
Signed-off-by Leon Romanovsky <[email protected]>
Thanks, applied.
Signature · 4 lines
Doug Ledford <[email protected]> GPG KeyID: B826A3330E572FDD Key fingerprint = AE6B 1BDA 122B 23B4 265B 1274 B826 A333 0E57 2FDD
Doug Ledford
AppliedQuoted 10 lines · Leon Romanovsky
From: Kamal Heib <kamalh-VPRAkNaXOzVWk0Htik3J/[email protected]>
This patch modify the Q counters implementation, so each one of the three Q counters groups will be exposed by the driver only if they are
supported by the firmware.Signed-off-by Leon Romanovsky <[email protected]>
Thanks, applied.
Signature · 4 lines
Doug Ledford <[email protected]> GPG KeyID: B826A3330E572FDD Key fingerprint = AE6B 1BDA 122B 23B4 265B 1274 B826 A333 0E57 2FDD