mlx5: Implement ibv_alloc_buf/ibv_free_buf ops

Implement mlx5_alloc_buf_op()/mlx5_free_buf_op() using the existing
struct mlx5_buf based allocation infrastructure.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
diff --git a/providers/mlx5/buf.c b/providers/mlx5/buf.c
index 1a6b6cd..9fc7d44 100644
--- a/providers/mlx5/buf.c
+++ b/providers/mlx5/buf.c
@@ -613,9 +613,9 @@
 int mlx5_alloc_buf(struct mlx5_buf *buf, size_t size, int page_size,
 		   struct ibv_pd *pd)
 {
+	size_t al_size;
 	void *addr;
 	int ret;
-	int al_size;
 
 	al_size = align(size, page_size);
 	ret = posix_memalign(&addr, page_size, al_size);
diff --git a/providers/mlx5/mlx5.c b/providers/mlx5/mlx5.c
index 8cc9ad6..22daff3 100644
--- a/providers/mlx5/mlx5.c
+++ b/providers/mlx5/mlx5.c
@@ -133,6 +133,8 @@
 	.alloc_dm = mlx5_alloc_dm,
 	.alloc_parent_domain = mlx5_alloc_parent_domain,
 	.alloc_td = mlx5_alloc_td,
+	.alloc_buf = mlx5_alloc_buf_op,
+	.free_buf = mlx5_free_buf_op,
 	.attach_counters_point_flow = mlx5_attach_counters_point_flow,
 	.close_xrcd = mlx5_close_xrcd,
 	.create_counters = mlx5_create_counters,
diff --git a/providers/mlx5/mlx5.h b/providers/mlx5/mlx5.h
index 585133d..0803b8f 100644
--- a/providers/mlx5/mlx5.h
+++ b/providers/mlx5/mlx5.h
@@ -1308,6 +1308,8 @@
 
 struct ibv_pd *mlx5_alloc_parent_domain(struct ibv_context *context,
 					struct ibv_parent_domain_init_attr *attr);
+void *mlx5_alloc_buf_op(struct ibv_pd *pd, size_t size, struct ibv_buf **buf);
+void mlx5_free_buf_op(struct ibv_buf *buf);
 
 struct ibv_dmah *mlx5_alloc_dmah(struct ibv_context *context,
 				 struct ibv_dmah_init_attr *attr);
diff --git a/providers/mlx5/verbs.c b/providers/mlx5/verbs.c
index 3aa8584..6b14672 100644
--- a/providers/mlx5/verbs.c
+++ b/providers/mlx5/verbs.c
@@ -622,6 +622,49 @@
 	return 0;
 }
 
+void *mlx5_alloc_buf_op(struct ibv_pd *pd, size_t size, struct ibv_buf **ibv_buf)
+{
+	struct mlx5_context *mctx = to_mctx(pd->context);
+	enum mlx5_alloc_type alloc_type;
+	struct mlx5_buf *buf;
+
+	if (size == 0) {
+		errno = EINVAL;
+		return NULL;
+	}
+
+	buf = calloc(1, sizeof(*buf));
+	if (!buf) {
+		errno = ENOMEM;
+		return NULL;
+	}
+
+	mlx5_get_alloc_type(mctx, pd, MLX5_MR_PREFIX, &alloc_type,
+			    MLX5_ALLOC_TYPE_ANON);
+
+	buf->req_alignment = to_mdev(pd->context->device)->page_size;
+
+	if (mlx5_alloc_prefered_buf(mctx, buf, size,
+				    to_mdev(pd->context->device)->page_size,
+				    alloc_type, MLX5_MR_PREFIX, pd)) {
+		free(buf);
+		errno = ENOMEM;
+		return NULL;
+	}
+
+	*ibv_buf = &buf->ibv_buf;
+	return buf->ibv_buf.addr;
+}
+
+void mlx5_free_buf_op(struct ibv_buf *ibv_buf)
+{
+	struct mlx5_buf *buf;
+
+	buf = container_of(ibv_buf, struct mlx5_buf, ibv_buf);
+	mlx5_free_actual_buf(to_mctx(ibv_buf->pd->context), buf);
+	free(buf);
+}
+
 static int _mlx5_free_pd(struct ibv_pd *pd, bool unimport)
 {
 	int ret;