Introduce DEVX object and its DV APIs as of: create/modify/read/destroy. The DEVX general command API was added as well to enable reading CAPs directly from the firmware. Signed-off-by: Yishai Hadas <yishaih@xxxxxxxxxxxx> --- debian/ibverbs-providers.symbols | 5 ++ providers/mlx5/libmlx5.map | 5 ++ providers/mlx5/man/CMakeLists.txt | 7 ++ providers/mlx5/man/mlx5dv_devx_obj_create.3.md | 74 ++++++++++++++++++++ providers/mlx5/mlx5.h | 5 ++ providers/mlx5/mlx5dv.h | 12 ++++ providers/mlx5/verbs.c | 95 ++++++++++++++++++++++++++ 7 files changed, 203 insertions(+) create mode 100644 providers/mlx5/man/mlx5dv_devx_obj_create.3.md diff --git a/debian/ibverbs-providers.symbols b/debian/ibverbs-providers.symbols index 23b0bbf..acd1715 100644 --- a/debian/ibverbs-providers.symbols +++ b/debian/ibverbs-providers.symbols @@ -28,3 +28,8 @@ libmlx5.so.1 ibverbs-providers #MINVER# mlx5dv_create_flow_action_modify_header@MLX5_1.7 21 mlx5dv_create_flow_action_packet_reformat@MLX5_1.7 21 mlx5dv_open_device@MLX5_1.7 21 + mlx5dv_devx_general_cmd@MLX5_1.7 21 + mlx5dv_devx_obj_create@MLX5_1.7 21 + mlx5dv_devx_obj_destroy@MLX5_1.7 21 + mlx5dv_devx_obj_query@MLX5_1.7 21 + mlx5dv_devx_obj_modify@MLX5_1.7 21 diff --git a/providers/mlx5/libmlx5.map b/providers/mlx5/libmlx5.map index a178af6..91a7a32 100644 --- a/providers/mlx5/libmlx5.map +++ b/providers/mlx5/libmlx5.map @@ -46,4 +46,9 @@ MLX5_1.7 { mlx5dv_create_flow_action_modify_header; mlx5dv_create_flow_action_packet_reformat; mlx5dv_open_device; + mlx5dv_devx_general_cmd; + mlx5dv_devx_obj_create; + mlx5dv_devx_obj_destroy; + mlx5dv_devx_obj_query; + mlx5dv_devx_obj_modify; } MLX5_1.6; diff --git a/providers/mlx5/man/CMakeLists.txt b/providers/mlx5/man/CMakeLists.txt index e8405a2..8d5d8e2 100644 --- a/providers/mlx5/man/CMakeLists.txt +++ b/providers/mlx5/man/CMakeLists.txt @@ -4,6 +4,7 @@ rdma_man_pages( mlx5dv_create_flow_action_packet_reformat.3.md mlx5dv_create_flow_matcher.3.md mlx5dv_create_qp.3.md + mlx5dv_devx_obj_create.3.md mlx5dv_flow_action_esp.3.md mlx5dv_get_clock_info.3 mlx5dv_init_obj.3 @@ -12,3 +13,9 @@ rdma_man_pages( mlx5dv_ts_to_ns.3 mlx5dv.7 ) +rdma_alias_man_pages( + mlx5dv_devx_obj_create.3 mlx5dv_devx_general_cmd.3 + mlx5dv_devx_obj_create.3 mlx5dv_devx_obj_destroy.3 + mlx5dv_devx_obj_create.3 mlx5dv_devx_obj_query.3 + mlx5dv_devx_obj_create.3 mlx5dv_devx_obj_modify.3 +) diff --git a/providers/mlx5/man/mlx5dv_devx_obj_create.3.md b/providers/mlx5/man/mlx5dv_devx_obj_create.3.md new file mode 100644 index 0000000..320404a --- /dev/null +++ b/providers/mlx5/man/mlx5dv_devx_obj_create.3.md @@ -0,0 +1,74 @@ +--- +layout: page +title: mlx5dv_devx_obj_create / destroy / modify /query / general +section: 3 +tagline: Verbs +--- + +# NAME + +mlx5dv_devx_obj_create - Creates a devx object + +mlx5dv_devx_obj_destroy - Destroys a devx object + +mlx5dv_devx_obj_modify - Modifies a devx object + +mlx5dv_devx_obj_query - Queries a devx object + +mlx5dv_devx_general_cmd - Issues a general command over the devx interface + +# SYNOPSIS + +```c +#include <infiniband/mlx5dv.h> + +struct mlx5dv_devx_obj * +mlx5dv_devx_obj_create(struct ibv_context *context, const void *in, size_t inlen, + void *out, size_t outlen); +int mlx5dv_devx_obj_query(struct mlx5dv_devx_obj *obj, const void *in, size_t inlen, + void *out, size_t outlen); +int mlx5dv_devx_obj_modify(struct mlx5dv_devx_obj *obj, const void *in, size_t inlen, + void *out, size_t outlen); +int mlx5dv_devx_obj_destroy(struct mlx5dv_devx_obj *obj); +int mlx5dv_devx_general_cmd(struct ibv_context *context, const void *in, size_t inlen, + void *out, size_t outlen); +``` + +# DESCRIPTION + +Create / destroy / modify / query a devx object, issue a general command over the devx interface. + +# ARGUMENTS + +*context* +: RDMA device context to create the action on. + +*in* +: A buffer which contains the command's input data provided in a device specification format. + +*inlen* +: The size of *in* buffer in bytes. + +*out* +: A buffer which contains the command's output data according to the device specification format. + +*outlen* +: The size of *out* buffer in bytes. + +*obj* +: For query, modify, destroy: the devx object to work on. + +# RETURN VALUE + +Upon success *mlx5dv_devx_create_obj* will return a new *struct +mlx5dv_devx_obj* on error NULL will be returned and errno will be set. + +Upon success query, modify, destroy, general commands, 0 is returned or the value of errno on a failure. + +# SEE ALSO + +**mlx5dv_open_device** + +AUTHOR + +Yishai Hadas <yishaih@xxxxxxxxxxxx> diff --git a/providers/mlx5/mlx5.h b/providers/mlx5/mlx5.h index c5b9e6f..91fbc50 100644 --- a/providers/mlx5/mlx5.h +++ b/providers/mlx5/mlx5.h @@ -567,6 +567,11 @@ struct mlx5dv_flow_matcher { uint32_t handle; }; +struct mlx5dv_devx_obj { + struct ibv_context *context; + uint32_t handle; +}; + static inline int mlx5_ilog2(int n) { int t; diff --git a/providers/mlx5/mlx5dv.h b/providers/mlx5/mlx5dv.h index 28d68bc..662433b 100644 --- a/providers/mlx5/mlx5dv.h +++ b/providers/mlx5/mlx5dv.h @@ -1015,6 +1015,18 @@ struct mlx5dv_context_attr { struct ibv_context * mlx5dv_open_device(struct ibv_device *device, struct mlx5dv_context_attr *attr); +struct mlx5dv_devx_obj; + +struct mlx5dv_devx_obj * +mlx5dv_devx_obj_create(struct ibv_context *context, const void *in, size_t inlen, + void *out, size_t outlen); +int mlx5dv_devx_obj_query(struct mlx5dv_devx_obj *obj, const void *in, size_t inlen, + void *out, size_t outlen); +int mlx5dv_devx_obj_modify(struct mlx5dv_devx_obj *obj, const void *in, size_t inlen, + void *out, size_t outlen); +int mlx5dv_devx_obj_destroy(struct mlx5dv_devx_obj *obj); +int mlx5dv_devx_general_cmd(struct ibv_context *context, const void *in, size_t inlen, + void *out, size_t outlen); #ifdef __cplusplus } #endif diff --git a/providers/mlx5/verbs.c b/providers/mlx5/verbs.c index 9ebd742..f476bc5 100644 --- a/providers/mlx5/verbs.c +++ b/providers/mlx5/verbs.c @@ -3842,3 +3842,98 @@ err: free(mflow); return NULL; } + +struct mlx5dv_devx_obj * +mlx5dv_devx_obj_create(struct ibv_context *context, const void *in, size_t inlen, + void *out, size_t outlen) +{ + DECLARE_COMMAND_BUFFER(cmd, + MLX5_IB_OBJECT_DEVX_OBJ, + MLX5_IB_METHOD_DEVX_OBJ_CREATE, + 3); + struct ib_uverbs_attr *handle; + struct mlx5dv_devx_obj *obj; + int ret; + + obj = calloc(1, sizeof(*obj)); + if (!obj) { + errno = ENOMEM; + return NULL; + } + + handle = fill_attr_out_obj(cmd, MLX5_IB_ATTR_DEVX_OBJ_CREATE_HANDLE); + fill_attr_in(cmd, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN, in, inlen); + fill_attr_out(cmd, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT, out, outlen); + + ret = execute_ioctl(context, cmd); + if (ret) + goto err; + + obj->handle = read_attr_obj(MLX5_IB_ATTR_DEVX_OBJ_CREATE_HANDLE, handle); + obj->context = context; + return obj; +err: + free(obj); + return NULL; +} + +int mlx5dv_devx_obj_query(struct mlx5dv_devx_obj *obj, const void *in, size_t inlen, + void *out, size_t outlen) +{ + DECLARE_COMMAND_BUFFER(cmd, + MLX5_IB_OBJECT_DEVX_OBJ, + MLX5_IB_METHOD_DEVX_OBJ_QUERY, + 3); + + fill_attr_in_obj(cmd, MLX5_IB_ATTR_DEVX_OBJ_QUERY_HANDLE, obj->handle); + fill_attr_in(cmd, MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN, in, inlen); + fill_attr_out(cmd, MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT, out, outlen); + + return execute_ioctl(obj->context, cmd); +} + +int mlx5dv_devx_obj_modify(struct mlx5dv_devx_obj *obj, const void *in, size_t inlen, + void *out, size_t outlen) +{ + DECLARE_COMMAND_BUFFER(cmd, + MLX5_IB_OBJECT_DEVX_OBJ, + MLX5_IB_METHOD_DEVX_OBJ_MODIFY, + 3); + + fill_attr_in_obj(cmd, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_HANDLE, obj->handle); + fill_attr_in(cmd, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN, in, inlen); + fill_attr_out(cmd, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT, out, outlen); + + return execute_ioctl(obj->context, cmd); +} + +int mlx5dv_devx_obj_destroy(struct mlx5dv_devx_obj *obj) +{ + DECLARE_COMMAND_BUFFER(cmd, + MLX5_IB_OBJECT_DEVX_OBJ, + MLX5_IB_METHOD_DEVX_OBJ_DESTROY, + 1); + int ret; + + fill_attr_in_obj(cmd, MLX5_IB_ATTR_DEVX_OBJ_DESTROY_HANDLE, obj->handle); + ret = execute_ioctl(obj->context, cmd); + + if (ret) + return ret; + free(obj); + return 0; +} + +int mlx5dv_devx_general_cmd(struct ibv_context *context, const void *in, size_t inlen, + void *out, size_t outlen) +{ + DECLARE_COMMAND_BUFFER(cmd, + MLX5_IB_OBJECT_DEVX, + MLX5_IB_METHOD_DEVX_OTHER, + 2); + + fill_attr_in(cmd, MLX5_IB_ATTR_DEVX_OTHER_CMD_IN, in, inlen); + fill_attr_out(cmd, MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT, out, outlen); + + return execute_ioctl(context, cmd); +} -- 1.8.3.1