From 66bc7b861842190b139e176a0c25242593a7f797 Mon Sep 17 00:00:00 2001 From: Shay Drory Date: Thu, 4 Jun 2020 18:02:12 +0300 Subject: [PATCH] mlx5: Enable non page aligned QP ring buffer allocation HCA supports non page aligned ring buffer allocation for QP. Currently even for a QP which requires small amount of ring buffer (e.g. 320 bytes) a page aligned buffer size allocation is requested. This results in system memory wastage on an embedded platform where custom allocator has very small ring buffer memory budget. To make efficient use of custom allocator memory, request only needed amount of memory instead of page aligned memory. Note: The external custom allocator is responsible to consider fork() in case it's applicable for his case, as defined by the man page. Signed-off-by: Shay Drory Reviewed-by: Parav Pandit Signed-off-by: Yishai Hadas --- providers/mlx5/mlx5_ifc.h | 5 +++++ providers/mlx5/verbs.c | 29 ++++++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/providers/mlx5/mlx5_ifc.h b/providers/mlx5/mlx5_ifc.h index 86a19560a..186e84142 100644 --- a/providers/mlx5/mlx5_ifc.h +++ b/providers/mlx5/mlx5_ifc.h @@ -2550,4 +2550,9 @@ enum { MLX5_DR_ACTION_MDFY_HW_HDR_L4_TCP = 0x1, MLX5_DR_ACTION_MDFY_HW_HDR_L4_UDP = 0x2, }; + +enum { + MLX5_QPC_PAGE_OFFSET_QUANTA = 64, +}; + #endif /* MLX5_IFC_H */ diff --git a/providers/mlx5/verbs.c b/providers/mlx5/verbs.c index 2fa265543..ee11bee51 100644 --- a/providers/mlx5/verbs.c +++ b/providers/mlx5/verbs.c @@ -1781,6 +1781,26 @@ static const char *qptype2key(enum ibv_qp_type type) } } +static size_t mlx5_set_custom_qp_alignment(struct ibv_context *context, + struct mlx5_qp *qp) +{ + uint32_t max_stride; + uint32_t buf_page; + + /* The main QP buffer alignment requirement is QP_PAGE_SIZE / + * MLX5_QPC_PAGE_OFFSET_QUANTA. In case the buffer is contig, then + * QP_PAGE_SIZE is the buffer size align to system page_size roundup to + * the next pow of two. + */ + buf_page = roundup_pow_of_two(align(qp->buf_size, + to_mdev(context->device)->page_size)); + /* Another QP buffer alignment requirement is to consider send wqe and + * receive wqe strides. + */ + max_stride = max((1 << qp->sq.wqe_shift), (1 << qp->rq.wqe_shift)); + return max(max_stride, buf_page / MLX5_QPC_PAGE_OFFSET_QUANTA); +} + static int mlx5_alloc_qp_buf(struct ibv_context *context, struct ibv_qp_init_attr_ex *attr, struct mlx5_qp *qp, @@ -1790,6 +1810,7 @@ static int mlx5_alloc_qp_buf(struct ibv_context *context, enum mlx5_alloc_type alloc_type; enum mlx5_alloc_type default_alloc_type = MLX5_ALLOC_TYPE_ANON; const char *qp_huge_key; + size_t req_align = to_mdev(context->device)->page_size; if (qp->sq.wqe_cnt) { qp->sq.wrid = malloc(qp->sq.wqe_cnt * sizeof(*qp->sq.wrid)); @@ -1833,13 +1854,15 @@ static int mlx5_alloc_qp_buf(struct ibv_context *context, if (alloc_type == MLX5_ALLOC_TYPE_CUSTOM) { qp->buf.mparent_domain = to_mparent_domain(attr->pd); - qp->buf.req_alignment = to_mdev(context->device)->page_size; + if (attr->qp_type != IBV_QPT_RAW_PACKET && + !(qp->flags & MLX5_QP_FLAGS_USE_UNDERLAY)) + req_align = mlx5_set_custom_qp_alignment(context, qp); + qp->buf.req_alignment = req_align; qp->buf.resource_type = MLX5DV_RES_TYPE_QP; } err = mlx5_alloc_prefered_buf(to_mctx(context), &qp->buf, - align(qp->buf_size, to_mdev - (context->device)->page_size), + align(qp->buf_size, req_align), to_mdev(context->device)->page_size, alloc_type, MLX5_QP_PREFIX);