@@ -31,6 +31,7 @@
*/
#include <rdma/uverbs_ioctl_cmd.h>
+#include <rdma/ib_user_verbs.h>
#include <linux/bug.h>
#define IB_UVERBS_VENDOR_FLAG 0x8000
@@ -55,3 +56,42 @@ int uverbs_action_std_handle(struct ib_device *ib_dev,
return priv->handler(ib_dev, ucontext, &ctx[0], &ctx[1], priv->priv);
}
+
+DECLARE_UVERBS_ATTR_CHAIN_SPEC(
+ uverbs_create_qp_spec,
+ UVERBS_ATTR_PTR_IN(CREATE_QP_CMD, sizeof(struct rdma_ioctl_create_qp)),
+ UVERBS_ATTR_PTR_OUT(CREATE_QP_RESP, sizeof(struct ib_uverbs_create_qp_resp)),
+ UVERBS_ATTR_IDR_IN(CREATE_QP_QP, UVERBS_TYPE_QP,
+ UVERBS_IDR_ACCESS_NEW),
+ UVERBS_ATTR_IDR_IN(CREATE_QP_PD, UVERBS_TYPE_PD,
+ UVERBS_IDR_ACCESS_READ),
+ UVERBS_ATTR_IDR_IN(CREATE_QP_RECV_CQ, UVERBS_TYPE_CQ,
+ UVERBS_IDR_ACCESS_READ),
+ UVERBS_ATTR_IDR_IN(CREATE_QP_SEND_CQ, UVERBS_TYPE_CQ,
+ UVERBS_IDR_ACCESS_READ));
+
+DECLARE_UVERBS_ATTR_CHAIN_SPEC(
+ uverbs_destroy_qp_spec,
+ UVERBS_ATTR_PTR_OUT(DESTROY_QP_RESP, sizeof(struct ib_uverbs_destroy_qp_resp)),
+ UVERBS_ATTR_IDR_IN(DESTROY_QP_QP, UVERBS_TYPE_QP,
+ UVERBS_IDR_ACCESS_DESTROY));
+
+DECLARE_UVERBS_ATTR_CHAIN_SPEC(
+ uverbs_create_cq_spec,
+ UVERBS_ATTR_PTR_IN(CREATE_CQ_CMD, sizeof(struct rdma_create_cq)),
+ UVERBS_ATTR_PTR_OUT(CREATE_CQ_RESP, sizeof(struct ib_uverbs_create_cq_resp)));
+
+
+int uverbs_destroy_qp_handler(struct ib_device *ib_dev,
+ struct ib_ucontext *ucontext,
+ struct uverbs_attr_array *common,
+ struct uverbs_attr_array *vendor,
+ void *priv)
+{
+ /*
+ * Implementation:
+ * 1. Serialize to kAPI
+ * 2. Call ib_dev with @vendor as vendor specific data
+ */
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,119 @@
+/* Vendor demo */
+
+#include <rdma/uverbs_ioctl_cmd.h>
+
+/*
+ * Vendor could have its own object model as well
+ * enum {
+ * MLX5_VENDOR_TYPE_OBJ
+ * };
+ */
+
+struct mlx5_ib_create_qp_vendor_cmd {
+ __u64 buf_addr;
+ __u64 db_addr;
+ __u32 sq_wqe_count;
+ __u32 rq_wqe_count;
+ __u32 rq_wqe_shift;
+ __u32 flags;
+ __u32 uidx;
+ __u32 reserved0;
+ __u64 sq_buf_addr;
+};
+
+struct mlx5_ib_create_qp_vendor_resp {
+ __u32 uuar_index;
+};
+
+struct mlx5_ib_create_cq_vendor_cmd {
+ __u64 buf_addr;
+ __u64 db_addr;
+ __u32 cqe_size;
+ __u32 reserved;
+};
+
+struct mlx5_ib_create_cq_vendor_resp {
+ __u32 cqn;
+ __u32 reserved;
+};
+
+/* Could be per vendor handler */
+static int create_qp_handler(struct ib_device *ib_dev,
+ struct ib_ucontext *ucontext,
+ struct uverbs_attr_array *common,
+ struct uverbs_attr_array *vendor,
+ void *priv)
+{
+ /* Some smart things here */
+ return 0;
+}
+
+/* Could be per vendor handler */
+static int create_cq_handler(struct ib_device *ib_dev,
+ struct ib_ucontext *ucontext,
+ struct uverbs_attr_array *common,
+ struct uverbs_attr_array *vendor,
+ void *priv)
+{
+ /* Some smart things here */
+ return 0;
+}
+
+enum mlx5_qp_commands {
+ MLX5_QP_COMMAND_CREATE,
+ MLX5_QP_COMMAND_DESTROY
+ /* TODO: Other commands */
+};
+
+enum mlx5_cq_commands {
+ MLX5_CQ_COMMAND_CREATE,
+};
+
+enum mlx5_qp_create {
+ MLX5_CREATE_QP_VENDOR_CMD = IB_UVERBS_VENDOR_FLAG,
+ MLX5_CREATE_QP_VENDOR_RESP,
+};
+
+DECLARE_UVERBS_TYPE(mlx5_ib_qp,
+ UVERBS_ACTION(
+ MLX5_QP_COMMAND_CREATE, create_qp_handler, NULL, &uverbs_create_qp_spec,
+ &UVERBS_ATTR_CHAIN_SPEC(
+ UVERBS_ATTR_PTR_IN(MLX5_CREATE_QP_VENDOR_CMD,
+ sizeof(struct mlx5_ib_create_qp_vendor_cmd)),
+ UVERBS_ATTR_PTR_OUT(MLX5_CREATE_QP_VENDOR_RESP,
+ sizeof(struct mlx5_ib_create_qp_vendor_resp)),
+ /*
+ * User could have its own objects and IDRs
+ * UVERBS_ATTR_IDR_IN(MLX_CREATE_QP_VENDOR_OBJ,
+ * UVERBS_COMMON_TYPE_QP, 0)
+ */
+ ),
+ ),
+ UVERBS_ACTION(MLX5_QP_COMMAND_DESTROY, uverbs_destroy_qp_handler, NULL,
+ &uverbs_destroy_qp_spec),
+);
+
+enum mlx5_cq_create {
+ MLX5_CREATE_CQ_VENDOR_CMD = IB_UVERBS_VENDOR_FLAG,
+ MLX5_CREATE_CQ_VENDOR_RESP,
+};
+
+struct uverbs_types objects = UVERBS_TYPES(
+ /* Decalre types by pointer */
+ UVERBS_TYPE(UVERBS_TYPE_QP, mlx5_ib_qp),
+ /* Types could only declared in-lined */
+ UVERBS_TYPE_ACTIONS(
+ UVERBS_TYPE_CQ,
+ UVERBS_ACTION(
+ MLX5_CQ_COMMAND_CREATE, create_cq_handler, NULL,
+ &uverbs_create_cq_spec,
+ &UVERBS_ATTR_CHAIN_SPEC(
+ UVERBS_ATTR_PTR_IN(MLX5_CREATE_CQ_VENDOR_CMD,
+ sizeof(struct mlx5_ib_create_cq_vendor_cmd)),
+ UVERBS_ATTR_PTR_OUT(MLX5_CREATE_QP_VENDOR_RESP,
+ sizeof(struct mlx5_ib_create_cq_vendor_resp)),
+ ),
+ ),
+ )
+);
+
@@ -49,5 +49,40 @@ struct uverbs_action_std_handler {
void *priv);
void *priv;
};
+
+enum uverbs_common_types {
+ UVERBS_TYPE_PD,
+ UVERBS_TYPE_CQ,
+ UVERBS_TYPE_QP,
+};
+
+enum uverbs_create_qp_cmd_attr {
+ CREATE_QP_CMD,
+ CREATE_QP_RESP,
+ CREATE_QP_QP,
+ CREATE_QP_PD,
+ CREATE_QP_RECV_CQ,
+ CREATE_QP_SEND_CQ,
+};
+
+enum uverbs_destroy_qp_cmd_attr {
+ DESTROY_QP_RESP,
+ DESTROY_QP_QP,
+};
+
+enum uverbs_create_cq_cmd_attr {
+ CREATE_CQ_CMD,
+ CREATE_CQ_RESP,
+};
+
+extern const struct uverbs_attr_chain_spec uverbs_create_qp_spec;
+extern const struct uverbs_attr_chain_spec uverbs_destroy_qp_spec;
+extern const struct uverbs_attr_chain_spec uverbs_create_cq_spec;
+
+int uverbs_destroy_qp_handler(struct ib_device *ib_dev,
+ struct ib_ucontext *ucontext,
+ struct uverbs_attr_array *common,
+ struct uverbs_attr_array *vendor,
+ void *priv);
#endif
@@ -368,6 +368,14 @@ struct ib_uverbs_ex_create_cq {
__u32 reserved;
};
+struct rdma_create_cq {
+ __u64 user_handle;
+ __u32 cqe;
+ __u32 comp_vector;
+ __s32 comp_channel;
+ __u32 flags;
+};
+
struct ib_uverbs_create_cq_resp {
__u32 cq_handle;
__u32 cqe;
@@ -518,6 +526,17 @@ struct ib_uverbs_create_qp {
__u64 driver_data[0];
};
+struct rdma_ioctl_create_qp
+{
+ __u32 max_send_wr;
+ __u32 max_recv_wr;
+ __u32 max_send_sge;
+ __u32 max_recv_sge;
+ __u32 max_inline_data;
+ __u8 sq_sig_all;
+ __u8 qp_type;
+};
+
struct ib_uverbs_ex_create_qp {
__u64 user_handle;
__u32 pd_handle;