Add custom allocation support for QP and RWQ buffers by extending the internal allocation flows to consider this option. Signed-off-by: Yishai Hadas <yishaih@xxxxxxxxxxxx> --- providers/mlx5/buf.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ providers/mlx5/cq.c | 2 +- providers/mlx5/mlx5.h | 6 +++++ providers/mlx5/mlx5dv.h | 4 ++++ providers/mlx5/verbs.c | 34 +++++++++++++++++++++++----- 5 files changed, 98 insertions(+), 7 deletions(-) diff --git a/providers/mlx5/buf.c b/providers/mlx5/buf.c index aa2fe02..b5cf391 100644 --- a/providers/mlx5/buf.c +++ b/providers/mlx5/buf.c @@ -356,6 +356,40 @@ int mlx5_alloc_buf_extern(struct mlx5_context *ctx, struct mlx5_buf *buf, return -1; } +static void mlx5_free_buf_custom(struct mlx5_context *ctx, + struct mlx5_buf *buf) +{ + struct mlx5_parent_domain *mparent_domain = buf->mparent_domain; + + mparent_domain->free(&mparent_domain->mpd.ibv_pd, + mparent_domain->pd_context, + buf->buf, + buf->resource_type); +} + +static int mlx5_alloc_buf_custom(struct mlx5_context *ctx, + struct mlx5_buf *buf, size_t size) +{ + struct mlx5_parent_domain *mparent_domain = buf->mparent_domain; + void *addr; + + addr = mparent_domain->alloc(&mparent_domain->mpd.ibv_pd, + mparent_domain->pd_context, size, + buf->req_alignment, + buf->resource_type); + if (addr == IBV_ALLOCATOR_USE_DEFAULT) + return 1; + + if (addr || size == 0) { + buf->buf = addr; + buf->length = size; + buf->type = MLX5_ALLOC_TYPE_CUSTOM; + return 0; + } + + return -1; +} + int mlx5_alloc_prefered_buf(struct mlx5_context *mctx, struct mlx5_buf *buf, size_t size, int page_size, @@ -364,6 +398,14 @@ int mlx5_alloc_prefered_buf(struct mlx5_context *mctx, { int ret; + if (type == MLX5_ALLOC_TYPE_CUSTOM) { + ret = mlx5_alloc_buf_custom(mctx, buf, size); + if (ret <= 0) + return ret; + + /* Fallback - default allocation is required */ + } + /* * Fallback mechanism priority: * huge pages @@ -426,6 +468,10 @@ int mlx5_free_actual_buf(struct mlx5_context *ctx, struct mlx5_buf *buf) mlx5_free_buf_extern(ctx, buf); break; + case MLX5_ALLOC_TYPE_CUSTOM: + mlx5_free_buf_custom(ctx, buf); + break; + default: fprintf(stderr, "Bad allocation type\n"); } @@ -458,12 +504,20 @@ static uint32_t mlx5_get_block_order(uint32_t v) return r; } +bool mlx5_is_custom_alloc(struct ibv_pd *pd) +{ + struct mlx5_parent_domain *mparent_domain = to_mparent_domain(pd); + + return (mparent_domain && mparent_domain->alloc && mparent_domain->free); +} + bool mlx5_is_extern_alloc(struct mlx5_context *context) { return context->extern_alloc.alloc && context->extern_alloc.free; } void mlx5_get_alloc_type(struct mlx5_context *context, + struct ibv_pd *pd, const char *component, enum mlx5_alloc_type *alloc_type, enum mlx5_alloc_type default_type) @@ -472,6 +526,11 @@ void mlx5_get_alloc_type(struct mlx5_context *context, char *env_value; char name[128]; + if (mlx5_is_custom_alloc(pd)) { + *alloc_type = MLX5_ALLOC_TYPE_CUSTOM; + return; + } + if (mlx5_is_extern_alloc(context)) { *alloc_type = MLX5_ALLOC_TYPE_EXTERNAL; return; diff --git a/providers/mlx5/cq.c b/providers/mlx5/cq.c index b9b47df..26edd86 100644 --- a/providers/mlx5/cq.c +++ b/providers/mlx5/cq.c @@ -1861,7 +1861,7 @@ int mlx5_alloc_cq_buf(struct mlx5_context *mctx, struct mlx5_cq *cq, if (mlx5_use_huge("HUGE_CQ")) default_type = MLX5_ALLOC_TYPE_HUGE; - mlx5_get_alloc_type(mctx, MLX5_CQ_PREFIX, &type, default_type); + mlx5_get_alloc_type(mctx, NULL, MLX5_CQ_PREFIX, &type, default_type); ret = mlx5_alloc_prefered_buf(mctx, buf, align(nent * cqe_sz, dev->page_size), diff --git a/providers/mlx5/mlx5.h b/providers/mlx5/mlx5.h index e960e6f..1c13390 100644 --- a/providers/mlx5/mlx5.h +++ b/providers/mlx5/mlx5.h @@ -173,6 +173,7 @@ enum mlx5_alloc_type { MLX5_ALLOC_TYPE_PREFER_HUGE, MLX5_ALLOC_TYPE_PREFER_CONTIG, MLX5_ALLOC_TYPE_EXTERNAL, + MLX5_ALLOC_TYPE_CUSTOM, MLX5_ALLOC_TYPE_ALL }; @@ -334,6 +335,9 @@ struct mlx5_buf { int base; struct mlx5_hugetlb_mem *hmem; enum mlx5_alloc_type type; + uint64_t resource_type; + size_t req_alignment; + struct mlx5_parent_domain *mparent_domain; }; struct mlx5_td { @@ -780,10 +784,12 @@ int mlx5_alloc_prefered_buf(struct mlx5_context *mctx, const char *component); int mlx5_free_actual_buf(struct mlx5_context *ctx, struct mlx5_buf *buf); void mlx5_get_alloc_type(struct mlx5_context *context, + struct ibv_pd *pd, const char *component, enum mlx5_alloc_type *alloc_type, enum mlx5_alloc_type default_alloc_type); int mlx5_use_huge(const char *key); +bool mlx5_is_custom_alloc(struct ibv_pd *pd); bool mlx5_is_extern_alloc(struct mlx5_context *context); int mlx5_alloc_buf_extern(struct mlx5_context *ctx, struct mlx5_buf *buf, size_t size); diff --git a/providers/mlx5/mlx5dv.h b/providers/mlx5/mlx5dv.h index d5e8e0c..0ad9768 100644 --- a/providers/mlx5/mlx5dv.h +++ b/providers/mlx5/mlx5dv.h @@ -59,6 +59,10 @@ extern "C" { #define MLX5DV_ALWAYS_INLINE inline #endif + +#define MLX5DV_RES_TYPE_QP ((uint64_t)RDMA_DRIVER_MLX5 << 32 | 1) +#define MLX5DV_RES_TYPE_RWQ ((uint64_t)RDMA_DRIVER_MLX5 << 32 | 2) + enum { MLX5_RCV_DBR = 0, MLX5_SND_DBR = 1, diff --git a/providers/mlx5/verbs.c b/providers/mlx5/verbs.c index 166ea4f..513af5e 100644 --- a/providers/mlx5/verbs.c +++ b/providers/mlx5/verbs.c @@ -1554,8 +1554,14 @@ static int mlx5_alloc_qp_buf(struct ibv_context *context, if (mlx5_use_huge(qp_huge_key)) default_alloc_type = MLX5_ALLOC_TYPE_HUGE; - mlx5_get_alloc_type(to_mctx(context), MLX5_QP_PREFIX, &alloc_type, - default_alloc_type); + mlx5_get_alloc_type(to_mctx(context), attr->pd, MLX5_QP_PREFIX, + &alloc_type, default_alloc_type); + + 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; + qp->buf.resource_type = MLX5DV_RES_TYPE_QP; + } err = mlx5_alloc_prefered_buf(to_mctx(context), &qp->buf, align(qp->buf_size, to_mdev @@ -1569,12 +1575,20 @@ static int mlx5_alloc_qp_buf(struct ibv_context *context, goto ex_wrid; } - memset(qp->buf.buf, 0, qp->buf_size); + if (qp->buf.type != MLX5_ALLOC_TYPE_CUSTOM) + memset(qp->buf.buf, 0, qp->buf_size); if (attr->qp_type == IBV_QPT_RAW_PACKET || qp->flags & MLX5_QP_FLAGS_USE_UNDERLAY) { size_t aligned_sq_buf_size = align(qp->sq_buf_size, to_mdev(context->device)->page_size); + + if (alloc_type == MLX5_ALLOC_TYPE_CUSTOM) { + qp->sq_buf.mparent_domain = to_mparent_domain(attr->pd); + qp->sq_buf.req_alignment = to_mdev(context->device)->page_size; + qp->sq_buf.resource_type = MLX5DV_RES_TYPE_QP; + } + /* For Raw Packet QP, allocate a separate buffer for the SQ */ err = mlx5_alloc_prefered_buf(to_mctx(context), &qp->sq_buf, aligned_sq_buf_size, @@ -1586,7 +1600,8 @@ static int mlx5_alloc_qp_buf(struct ibv_context *context, goto rq_buf; } - memset(qp->sq_buf.buf, 0, aligned_sq_buf_size); + if (qp->sq_buf.type != MLX5_ALLOC_TYPE_CUSTOM) + memset(qp->sq_buf.buf, 0, aligned_sq_buf_size); } return 0; @@ -3121,13 +3136,14 @@ static void mlx5_free_rwq_buf(struct mlx5_rwq *rwq, struct ibv_context *context) } static int mlx5_alloc_rwq_buf(struct ibv_context *context, + struct ibv_pd *pd, struct mlx5_rwq *rwq, int size) { int err; enum mlx5_alloc_type alloc_type; - mlx5_get_alloc_type(to_mctx(context), MLX5_RWQ_PREFIX, + mlx5_get_alloc_type(to_mctx(context), pd, MLX5_RWQ_PREFIX, &alloc_type, MLX5_ALLOC_TYPE_ANON); rwq->rq.wrid = malloc(rwq->rq.wqe_cnt * sizeof(uint64_t)); @@ -3136,6 +3152,12 @@ static int mlx5_alloc_rwq_buf(struct ibv_context *context, return -1; } + if (alloc_type == MLX5_ALLOC_TYPE_CUSTOM) { + rwq->buf.mparent_domain = to_mparent_domain(pd); + rwq->buf.req_alignment = to_mdev(context->device)->page_size; + rwq->buf.resource_type = MLX5DV_RES_TYPE_RWQ; + } + err = mlx5_alloc_prefered_buf(to_mctx(context), &rwq->buf, align(rwq->buf_size, to_mdev (context->device)->page_size), @@ -3186,7 +3208,7 @@ static struct ibv_wq *create_wq(struct ibv_context *context, } rwq->buf_size = ret; - if (mlx5_alloc_rwq_buf(context, rwq, ret)) + if (mlx5_alloc_rwq_buf(context, attr->pd, rwq, ret)) goto err; mlx5_init_rwq_indices(rwq); -- 1.8.3.1