diff --git a/contrib/ofed/libmlx5/buf.c b/contrib/ofed/libmlx5/buf.c --- a/contrib/ofed/libmlx5/buf.c +++ b/contrib/ofed/libmlx5/buf.c @@ -320,6 +320,36 @@ mlx5_spin_unlock(&ctx->hugetlb_lock); } +void mlx5_free_buf_extern(struct mlx5_context *ctx, struct mlx5_buf *buf) +{ + ibv_dofork_range(buf->buf, buf->length); + ctx->extern_alloc.free(buf->buf, ctx->extern_alloc.data); +} + +int mlx5_alloc_buf_extern(struct mlx5_context *ctx, struct mlx5_buf *buf, + size_t size) +{ + void *addr; + + addr = ctx->extern_alloc.alloc(size, ctx->extern_alloc.data); + if (addr || size == 0) { + if (ibv_dontfork_range(addr, size)) { + mlx5_dbg(stderr, MLX5_DBG_CONTIG, + "External mode dontfork_range failed\n"); + ctx->extern_alloc.free(addr, + ctx->extern_alloc.data); + return -1; + } + buf->buf = addr; + buf->length = size; + buf->type = MLX5_ALLOC_TYPE_EXTERNAL; + return 0; + } + + mlx5_dbg(stderr, MLX5_DBG_CONTIG, "External alloc failed\n"); + return -1; +} + int mlx5_alloc_prefered_buf(struct mlx5_context *mctx, struct mlx5_buf *buf, size_t size, int page_size, @@ -362,6 +392,9 @@ "Contig allocation failed, fallback to default mode\n"); } + if (type == MLX5_ALLOC_TYPE_EXTERNAL) + return mlx5_alloc_buf_extern(mctx, buf, size); + return mlx5_alloc_buf(buf, size, page_size); } @@ -382,6 +415,11 @@ case MLX5_ALLOC_TYPE_CONTIG: mlx5_free_buf_contig(ctx, buf); break; + + case MLX5_ALLOC_TYPE_EXTERNAL: + mlx5_free_buf_extern(ctx, buf); + break; + default: fprintf(stderr, "Bad allocation type\n"); } @@ -414,7 +452,13 @@ return r; } -void mlx5_get_alloc_type(const char *component, +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, + const char *component, enum mlx5_alloc_type *alloc_type, enum mlx5_alloc_type default_type) @@ -422,6 +466,11 @@ char *env_value; char name[128]; + if (mlx5_is_extern_alloc(context)) { + *alloc_type = MLX5_ALLOC_TYPE_EXTERNAL; + return; + } + snprintf(name, sizeof(name), "%s_ALLOC_TYPE", component); *alloc_type = default_type; diff --git a/contrib/ofed/libmlx5/cq.c b/contrib/ofed/libmlx5/cq.c --- a/contrib/ofed/libmlx5/cq.c +++ b/contrib/ofed/libmlx5/cq.c @@ -1499,7 +1499,7 @@ if (mlx5_use_huge("HUGE_CQ")) default_type = MLX5_ALLOC_TYPE_HUGE; - mlx5_get_alloc_type(MLX5_CQ_PREFIX, &type, default_type); + mlx5_get_alloc_type(mctx, MLX5_CQ_PREFIX, &type, default_type); ret = mlx5_alloc_prefered_buf(mctx, buf, align(nent * cqe_sz, dev->page_size), diff --git a/contrib/ofed/libmlx5/dbrec.c b/contrib/ofed/libmlx5/dbrec.c --- a/contrib/ofed/libmlx5/dbrec.c +++ b/contrib/ofed/libmlx5/dbrec.c @@ -53,6 +53,7 @@ int pp; int i; int nlong; + int ret; pp = ps / context->cache_line_size; nlong = (pp + 8 * sizeof(long) - 1) / (8 * sizeof(long)); @@ -61,7 +62,11 @@ if (!page) return NULL; - if (mlx5_alloc_buf(&page->buf, ps, ps)) { + if (mlx5_is_extern_alloc(context)) + ret = mlx5_alloc_buf_extern(context, &page->buf, ps); + else + ret = mlx5_alloc_buf(&page->buf, ps, ps); + if (ret) { free(page); return NULL; } @@ -139,7 +144,11 @@ if (page->next) page->next->prev = page->prev; - mlx5_free_buf(&page->buf); + if (page->buf.type == MLX5_ALLOC_TYPE_EXTERNAL) + mlx5_free_buf_extern(context, &page->buf); + else + mlx5_free_buf(&page->buf); + free(page); } diff --git a/contrib/ofed/libmlx5/libmlx5.map b/contrib/ofed/libmlx5/libmlx5.map --- a/contrib/ofed/libmlx5/libmlx5.map +++ b/contrib/ofed/libmlx5/libmlx5.map @@ -14,4 +14,5 @@ MLX5_1.2 { global: mlx5dv_init_obj; + mlx5dv_set_context_attr; } MLX5_1.1; diff --git a/contrib/ofed/libmlx5/mlx5.h b/contrib/ofed/libmlx5/mlx5.h --- a/contrib/ofed/libmlx5/mlx5.h +++ b/contrib/ofed/libmlx5/mlx5.h @@ -162,6 +162,7 @@ MLX5_ALLOC_TYPE_CONTIG, MLX5_ALLOC_TYPE_PREFER_HUGE, MLX5_ALLOC_TYPE_PREFER_CONTIG, + MLX5_ALLOC_TYPE_EXTERNAL, MLX5_ALLOC_TYPE_ALL }; @@ -268,6 +269,7 @@ uint32_t uar_size; uint64_t vendor_cap_flags; /* Use enum mlx5_vendor_cap_flags */ struct mlx5dv_cqe_comp_caps cqe_comp_caps; + struct mlx5dv_ctx_allocators extern_alloc; }; struct mlx5_bitmap { @@ -558,10 +560,15 @@ enum mlx5_alloc_type alloc_type, const char *component); int mlx5_free_actual_buf(struct mlx5_context *ctx, struct mlx5_buf *buf); -void mlx5_get_alloc_type(const char *component, +void mlx5_get_alloc_type(struct mlx5_context *context, + 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_extern_alloc(struct mlx5_context *context); +int mlx5_alloc_buf_extern(struct mlx5_context *ctx, struct mlx5_buf *buf, + size_t size); +void mlx5_free_buf_extern(struct mlx5_context *ctx, struct mlx5_buf *buf); __be32 *mlx5_alloc_dbrec(struct mlx5_context *context); void mlx5_free_db(struct mlx5_context *context, __be32 *db); diff --git a/contrib/ofed/libmlx5/mlx5.c b/contrib/ofed/libmlx5/mlx5.c --- a/contrib/ofed/libmlx5/mlx5.c +++ b/contrib/ofed/libmlx5/mlx5.c @@ -736,6 +736,22 @@ return ret; } +int mlx5dv_set_context_attr(struct ibv_context *ibv_ctx, + enum mlx5dv_set_ctx_attr_type type, void *attr) +{ + struct mlx5_context *ctx = to_mctx(ibv_ctx); + + switch (type) { + case MLX5DV_CTX_ATTR_BUF_ALLOCATORS: + ctx->extern_alloc = *((struct mlx5dv_ctx_allocators *)attr); + break; + default: + return ENOTSUP; + } + + return 0; +} + static void adjust_uar_info(struct mlx5_device *mdev, struct mlx5_context *context, struct mlx5_alloc_ucontext_resp resp) diff --git a/contrib/ofed/libmlx5/mlx5dv.h b/contrib/ofed/libmlx5/mlx5dv.h --- a/contrib/ofed/libmlx5/mlx5dv.h +++ b/contrib/ofed/libmlx5/mlx5dv.h @@ -620,4 +620,24 @@ seg->inline_hdr_sz = htobe16(inline_hdr_sz); memcpy(seg->inline_hdr_start, inline_hdr_start, inline_hdr_sz); } + +enum mlx5dv_set_ctx_attr_type { + MLX5DV_CTX_ATTR_BUF_ALLOCATORS = 1, +}; + +struct mlx5dv_ctx_allocators { + void *(*alloc)(size_t size, void *priv_data); + void (*free)(void *ptr, void *priv_data); + void *data; +}; + +/* + * Generic context attributes set API + * + * Returns 0 on success, or the value of errno on failure + * (which indicates the failure reason). + */ +int mlx5dv_set_context_attr(struct ibv_context *context, + enum mlx5dv_set_ctx_attr_type type, void *attr); + #endif /* _MLX5DV_H_ */ diff --git a/contrib/ofed/libmlx5/verbs.c b/contrib/ofed/libmlx5/verbs.c --- a/contrib/ofed/libmlx5/verbs.c +++ b/contrib/ofed/libmlx5/verbs.c @@ -1077,7 +1077,7 @@ if (mlx5_use_huge(qp_huge_key)) default_alloc_type = MLX5_ALLOC_TYPE_HUGE; - mlx5_get_alloc_type(MLX5_QP_PREFIX, &alloc_type, + mlx5_get_alloc_type(to_mctx(context), MLX5_QP_PREFIX, &alloc_type, default_alloc_type); err = mlx5_alloc_prefered_buf(to_mctx(context), &qp->buf, @@ -2002,7 +2002,10 @@ int size) { int err; - enum mlx5_alloc_type default_alloc_type = MLX5_ALLOC_TYPE_PREFER_CONTIG; + enum mlx5_alloc_type alloc_type; + + mlx5_get_alloc_type(to_mctx(context), MLX5_RWQ_PREFIX, + &alloc_type, MLX5_ALLOC_TYPE_ANON); rwq->rq.wrid = malloc(rwq->rq.wqe_cnt * sizeof(uint64_t)); if (!rwq->rq.wrid) { @@ -2014,7 +2017,7 @@ align(rwq->buf_size, to_mdev (context->device)->page_size), to_mdev(context->device)->page_size, - default_alloc_type, + alloc_type, MLX5_RWQ_PREFIX); if (err) {