Skip to content

Commit

Permalink
mlx5: Enable non page aligned QP ring buffer allocation
Browse files Browse the repository at this point in the history
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 <shayd@mellanox.com>
Reviewed-by: Parav Pandit <parav@mellanox.com>
Signed-off-by: Yishai Hadas <yishaih@mellanox.com>
  • Loading branch information
shayshd authored and yishaih committed Jul 26, 2020
1 parent f0b2d01 commit 66bc7b8
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 3 deletions.
5 changes: 5 additions & 0 deletions providers/mlx5/mlx5_ifc.h
Expand Up @@ -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 */
29 changes: 26 additions & 3 deletions providers/mlx5/verbs.c
Expand Up @@ -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,
Expand All @@ -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));
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 66bc7b8

Please sign in to comment.