From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 949FEA04B8; Tue, 5 May 2020 17:55:20 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 92BA31D657; Tue, 5 May 2020 17:55:14 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id E691B1D656 for ; Tue, 5 May 2020 17:55:12 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from matan@mellanox.com) with ESMTPS (AES256-SHA encrypted); 5 May 2020 18:55:07 +0300 Received: from pegasus25.mtr.labs.mlnx. (pegasus25.mtr.labs.mlnx [10.210.16.10]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 045Fstgm022938; Tue, 5 May 2020 18:55:07 +0300 From: Matan Azrad To: dev@dpdk.org Cc: Viacheslav Ovsiienko , Shahaf Shuler , Maxime Coquelin Date: Tue, 5 May 2020 15:54:42 +0000 Message-Id: <1588694084-381748-3-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1588694084-381748-1-git-send-email-matan@mellanox.com> References: <1585826793-28709-1-git-send-email-matan@mellanox.com> <1588694084-381748-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v2 2/4] common/mlx5: support DevX virtq stats operations X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add DevX API to create and query virtio queue statistics from the HW. The next counters are supported by the HW per virtio queue: received_desc. completed_desc. error_cqes. bad_desc_errors. exceed_max_chain. invalid_buffer. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/common/mlx5/mlx5_devx_cmds.c | 73 +++++++++++++++++++++++++ drivers/common/mlx5/mlx5_devx_cmds.h | 43 +++++++++++++++ drivers/common/mlx5/mlx5_prm.h | 26 ++++++++- drivers/common/mlx5/rte_common_mlx5_version.map | 7 +++ 4 files changed, 148 insertions(+), 1 deletion(-) diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c index 67c8a8c..c8fc4bb 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.c +++ b/drivers/common/mlx5/mlx5_devx_cmds.c @@ -460,6 +460,9 @@ struct mlx5_devx_obj * attr->vdpa.valid = !!(MLX5_GET64(cmd_hca_cap, hcattr, general_obj_types) & MLX5_GENERAL_OBJ_TYPES_CAP_VIRTQ_NET_Q); + attr->vdpa.queue_counters_valid = !!(MLX5_GET64(cmd_hca_cap, hcattr, + general_obj_types) & + MLX5_GENERAL_OBJ_TYPES_CAP_VIRTIO_Q_COUNTERS); if (attr->qos.sup) { MLX5_SET(query_hca_cap_in, in, op_mod, MLX5_GET_HCA_CAP_OP_MOD_QOS_CAP | @@ -1255,6 +1258,7 @@ struct mlx5_devx_obj * MLX5_SET(virtio_q, virtctx, umem_3_id, attr->umems[2].id); MLX5_SET(virtio_q, virtctx, umem_3_size, attr->umems[2].size); MLX5_SET64(virtio_q, virtctx, umem_3_offset, attr->umems[2].offset); + MLX5_SET(virtio_q, virtctx, counter_set_id, attr->counters_obj_id); MLX5_SET(virtio_net_q, virtq, tisn_or_qpn, attr->tis_id); virtq_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out)); @@ -1529,3 +1533,72 @@ struct mlx5_devx_obj * } return ret; } + +struct mlx5_devx_obj * +mlx5_devx_cmd_create_virtio_q_counters(void *ctx) +{ + uint32_t in[MLX5_ST_SZ_DW(create_virtio_q_counters_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; + struct mlx5_devx_obj *couners_obj = rte_zmalloc(__func__, + sizeof(*couners_obj), 0); + void *hdr = MLX5_ADDR_OF(create_virtio_q_counters_in, in, hdr); + + if (!couners_obj) { + DRV_LOG(ERR, "Failed to allocate virtio queue counters data."); + rte_errno = ENOMEM; + return NULL; + } + MLX5_SET(general_obj_in_cmd_hdr, hdr, opcode, + MLX5_CMD_OP_CREATE_GENERAL_OBJECT); + MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_type, + MLX5_GENERAL_OBJ_TYPE_VIRTIO_Q_COUNTERS); + couners_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, + sizeof(out)); + if (!couners_obj->obj) { + rte_errno = errno; + DRV_LOG(ERR, "Failed to create virtio queue counters Obj using" + " DevX."); + rte_free(couners_obj); + return NULL; + } + couners_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); + return couners_obj; +} + +int +mlx5_devx_cmd_query_virtio_q_counters(struct mlx5_devx_obj *couners_obj, + struct mlx5_devx_virtio_q_couners_attr *attr) +{ + uint32_t in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(query_virtio_q_counters_out)] = {0}; + void *hdr = MLX5_ADDR_OF(query_virtio_q_counters_out, in, hdr); + void *virtio_q_counters = MLX5_ADDR_OF(query_virtio_q_counters_out, out, + virtio_q_counters); + int ret; + + MLX5_SET(general_obj_in_cmd_hdr, hdr, opcode, + MLX5_CMD_OP_QUERY_GENERAL_OBJECT); + MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_type, + MLX5_GENERAL_OBJ_TYPE_VIRTIO_Q_COUNTERS); + MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_id, couners_obj->id); + ret = mlx5_glue->devx_obj_query(couners_obj->obj, in, sizeof(in), out, + sizeof(out)); + if (ret) { + DRV_LOG(ERR, "Failed to query virtio q counters using DevX."); + rte_errno = errno; + return -errno; + } + attr->received_desc = MLX5_GET64(virtio_q_counters, virtio_q_counters, + received_desc); + attr->completed_desc = MLX5_GET64(virtio_q_counters, virtio_q_counters, + completed_desc); + attr->error_cqes = MLX5_GET(virtio_q_counters, virtio_q_counters, + error_cqes); + attr->bad_desc_errors = MLX5_GET(virtio_q_counters, virtio_q_counters, + bad_desc_errors); + attr->exceed_max_chain = MLX5_GET(virtio_q_counters, virtio_q_counters, + exceed_max_chain); + attr->invalid_buffer = MLX5_GET(virtio_q_counters, virtio_q_counters, + invalid_buffer); + return ret; +} diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h index f7802e6..60db6da 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.h +++ b/drivers/common/mlx5/mlx5_devx_cmds.h @@ -64,6 +64,7 @@ struct mlx5_hca_vdpa_attr { uint32_t event_mode:3; uint32_t log_doorbell_stride:5; uint32_t log_doorbell_bar_size:5; + uint32_t queue_counters_valid:1; uint32_t max_num_virtio_queues; struct { uint32_t a; @@ -270,6 +271,7 @@ struct mlx5_devx_virtq_attr { uint32_t qp_id; uint32_t queue_index; uint32_t tis_id; + uint32_t counters_obj_id; uint64_t dirty_bitmap_addr; uint64_t type; uint64_t desc_addr; @@ -298,6 +300,15 @@ struct mlx5_devx_qp_attr { uint64_t wq_umem_offset; }; +struct mlx5_devx_virtio_q_couners_attr { + uint64_t received_desc; + uint64_t completed_desc; + uint32_t error_cqes; + uint32_t bad_desc_errors; + uint32_t exceed_max_chain; + uint32_t invalid_buffer; +}; + /* mlx5_devx_cmds.c */ struct mlx5_devx_obj *mlx5_devx_cmd_flow_counter_alloc(struct ibv_context *ctx, @@ -348,5 +359,37 @@ int mlx5_devx_cmd_modify_qp_state(struct mlx5_devx_obj *qp, uint32_t qp_st_mod_op, uint32_t remote_qp_id); int mlx5_devx_cmd_modify_rqt(struct mlx5_devx_obj *rqt, struct mlx5_devx_rqt_attr *rqt_attr); +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice + * + * Create virtio queue counters object DevX API. + * + * @param[in] ctx + * Device context. + + * @return + * The DevX object created, NULL otherwise and rte_errno is set. + */ +__rte_experimental +struct mlx5_devx_obj *mlx5_devx_cmd_create_virtio_q_counters(void *ctx); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice + * + * Query virtio queue counters object using DevX API. + * + * @param[in] couners_obj + * Pointer to virtq object structure. + * @param [in/out] attr + * Pointer to virtio queue counters attributes structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +__rte_experimental +int mlx5_devx_cmd_query_virtio_q_counters(struct mlx5_devx_obj *couners_obj, + struct mlx5_devx_virtio_q_couners_attr *attr); #endif /* RTE_PMD_MLX5_DEVX_CMDS_H_ */ diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h index 4ab1c75..eefaf26 100644 --- a/drivers/common/mlx5/mlx5_prm.h +++ b/drivers/common/mlx5/mlx5_prm.h @@ -947,6 +947,7 @@ enum { enum { MLX5_GENERAL_OBJ_TYPES_CAP_VIRTQ_NET_Q = (1ULL << 0xd), + MLX5_GENERAL_OBJ_TYPES_CAP_VIRTIO_Q_COUNTERS = (1ULL << 0x1c), }; enum { @@ -2003,6 +2004,7 @@ struct mlx5_ifc_create_cq_in_bits { enum { MLX5_GENERAL_OBJ_TYPE_VIRTQ = 0x000d, + MLX5_GENERAL_OBJ_TYPE_VIRTIO_Q_COUNTERS = 0x001c, }; struct mlx5_ifc_general_obj_in_cmd_hdr_bits { @@ -2021,6 +2023,27 @@ struct mlx5_ifc_general_obj_out_cmd_hdr_bits { u8 reserved_at_60[0x20]; }; +struct mlx5_ifc_virtio_q_counters_bits { + u8 modify_field_select[0x40]; + u8 reserved_at_40[0x40]; + u8 received_desc[0x40]; + u8 completed_desc[0x40]; + u8 error_cqes[0x20]; + u8 bad_desc_errors[0x20]; + u8 exceed_max_chain[0x20]; + u8 invalid_buffer[0x20]; + u8 reserved_at_180[0x50]; +}; + +struct mlx5_ifc_create_virtio_q_counters_in_bits { + struct mlx5_ifc_general_obj_in_cmd_hdr_bits hdr; + struct mlx5_ifc_virtio_q_counters_bits virtio_q_counters; +}; + +struct mlx5_ifc_query_virtio_q_counters_out_bits { + struct mlx5_ifc_general_obj_in_cmd_hdr_bits hdr; + struct mlx5_ifc_virtio_q_counters_bits virtio_q_counters; +}; enum { MLX5_VIRTQ_STATE_INIT = 0, MLX5_VIRTQ_STATE_RDY = 1, @@ -2061,7 +2084,8 @@ struct mlx5_ifc_virtio_q_bits { u8 umem_3_id[0x20]; u8 umem_3_size[0x20]; u8 umem_3_offset[0x40]; - u8 reserved_at_300[0x100]; + u8 counter_set_id[0x20]; + u8 reserved_at_320[0xe0]; }; struct mlx5_ifc_virtio_net_q_bits { diff --git a/drivers/common/mlx5/rte_common_mlx5_version.map b/drivers/common/mlx5/rte_common_mlx5_version.map index b58a378..8c2d224 100644 --- a/drivers/common/mlx5/rte_common_mlx5_version.map +++ b/drivers/common/mlx5/rte_common_mlx5_version.map @@ -76,3 +76,10 @@ EXPERIMENTAL { mlx5_mr_create_primary; mlx5_mr_flush_local_cache; }; + +EXPERIMENTAL { + global: + + mlx5_devx_cmd_create_virtio_q_counters; + mlx5_devx_cmd_query_virtio_q_counters; +}; -- 1.8.3.1