aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYishai Hadas <yishaih@mellanox.com>2018-06-17 06:00:04 -0400
committerJason Gunthorpe <jgg@mellanox.com>2018-06-19 12:53:02 -0400
commitaeae94579caf77406a8a235ea33fdb67abe9a57e (patch)
tree27e16ea1a1840d95801afd339355c759f17c7b2f
parent7c043e908a74ae0a935037cdd984d0cb89b2b970 (diff)
IB/mlx5: Add DEVX support for memory registration
Add support to register a memory with the firmware via the DEVX interface. The driver translates a given user address to ib_umem then it will register the physical addresses with the firmware and get a unique id for this registration to be used for this virtual address. Signed-off-by: Yishai Hadas <yishaih@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
-rw-r--r--drivers/infiniband/hw/mlx5/devx.c199
-rw-r--r--include/linux/mlx5/mlx5_ifc.h1
-rw-r--r--include/uapi/rdma/mlx5_user_ioctl_cmds.h18
3 files changed, 217 insertions, 1 deletions
diff --git a/drivers/infiniband/hw/mlx5/devx.c b/drivers/infiniband/hw/mlx5/devx.c
index 9b1804eb9924..162321f486eb 100644
--- a/drivers/infiniband/hw/mlx5/devx.c
+++ b/drivers/infiniband/hw/mlx5/devx.c
@@ -24,6 +24,22 @@ struct devx_obj {
24 u32 dinbox[MLX5_MAX_DESTROY_INBOX_SIZE_DW]; 24 u32 dinbox[MLX5_MAX_DESTROY_INBOX_SIZE_DW];
25}; 25};
26 26
27struct devx_umem {
28 struct mlx5_core_dev *mdev;
29 struct ib_umem *umem;
30 u32 page_offset;
31 int page_shift;
32 int ncont;
33 u32 dinlen;
34 u32 dinbox[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)];
35};
36
37struct devx_umem_reg_cmd {
38 void *in;
39 u32 inlen;
40 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
41};
42
27static struct mlx5_ib_ucontext *devx_ufile2uctx(struct ib_uverbs_file *file) 43static struct mlx5_ib_ucontext *devx_ufile2uctx(struct ib_uverbs_file *file)
28{ 44{
29 return to_mucontext(ib_uverbs_get_ucontext(file)); 45 return to_mucontext(ib_uverbs_get_ucontext(file));
@@ -788,6 +804,181 @@ other_cmd_free:
788 return err; 804 return err;
789} 805}
790 806
807static int devx_umem_get(struct mlx5_ib_dev *dev, struct ib_ucontext *ucontext,
808 struct uverbs_attr_bundle *attrs,
809 struct devx_umem *obj)
810{
811 u64 addr;
812 size_t size;
813 int access;
814 int npages;
815 int err;
816 u32 page_mask;
817
818 if (uverbs_copy_from(&addr, attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_ADDR) ||
819 uverbs_copy_from(&size, attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_LEN) ||
820 uverbs_copy_from(&access, attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_ACCESS))
821 return -EFAULT;
822
823 err = ib_check_mr_access(access);
824 if (err)
825 return err;
826
827 obj->umem = ib_umem_get(ucontext, addr, size, access, 0);
828 if (IS_ERR(obj->umem))
829 return PTR_ERR(obj->umem);
830
831 mlx5_ib_cont_pages(obj->umem, obj->umem->address,
832 MLX5_MKEY_PAGE_SHIFT_MASK, &npages,
833 &obj->page_shift, &obj->ncont, NULL);
834
835 if (!npages) {
836 ib_umem_release(obj->umem);
837 return -EINVAL;
838 }
839
840 page_mask = (1 << obj->page_shift) - 1;
841 obj->page_offset = obj->umem->address & page_mask;
842
843 return 0;
844}
845
846static int devx_umem_reg_cmd_alloc(struct devx_umem *obj,
847 struct devx_umem_reg_cmd *cmd)
848{
849 cmd->inlen = MLX5_ST_SZ_BYTES(create_umem_in) +
850 (MLX5_ST_SZ_BYTES(mtt) * obj->ncont);
851 cmd->in = kvzalloc(cmd->inlen, GFP_KERNEL);
852 return cmd->in ? 0 : -ENOMEM;
853}
854
855static void devx_umem_reg_cmd_free(struct devx_umem_reg_cmd *cmd)
856{
857 kvfree(cmd->in);
858}
859
860static void devx_umem_reg_cmd_build(struct mlx5_ib_dev *dev,
861 struct devx_umem *obj,
862 struct devx_umem_reg_cmd *cmd)
863{
864 void *umem;
865 __be64 *mtt;
866
867 umem = MLX5_ADDR_OF(create_umem_in, cmd->in, umem);
868 mtt = (__be64 *)MLX5_ADDR_OF(umem, umem, mtt);
869
870 MLX5_SET(general_obj_in_cmd_hdr, cmd->in, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
871 MLX5_SET(general_obj_in_cmd_hdr, cmd->in, obj_type, MLX5_OBJ_TYPE_UMEM);
872 MLX5_SET64(umem, umem, num_of_mtt, obj->ncont);
873 MLX5_SET(umem, umem, log_page_size, obj->page_shift -
874 MLX5_ADAPTER_PAGE_SHIFT);
875 MLX5_SET(umem, umem, page_offset, obj->page_offset);
876 mlx5_ib_populate_pas(dev, obj->umem, obj->page_shift, mtt,
877 (obj->umem->writable ? MLX5_IB_MTT_WRITE : 0) |
878 MLX5_IB_MTT_READ);
879}
880
881static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_UMEM_REG)(struct ib_device *ib_dev,
882 struct ib_uverbs_file *file,
883 struct uverbs_attr_bundle *attrs)
884{
885 struct mlx5_ib_ucontext *c = devx_ufile2uctx(file);
886 struct mlx5_ib_dev *dev = to_mdev(ib_dev);
887 struct devx_umem_reg_cmd cmd;
888 struct devx_umem *obj;
889 struct ib_uobject *uobj;
890 u32 obj_id;
891 int err;
892
893 if (!c->devx_uid)
894 return -EPERM;
895
896 uobj = uverbs_attr_get_uobject(attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_HANDLE);
897 obj = kzalloc(sizeof(struct devx_umem), GFP_KERNEL);
898 if (!obj)
899 return -ENOMEM;
900
901 err = devx_umem_get(dev, &c->ibucontext, attrs, obj);
902 if (err)
903 goto err_obj_free;
904
905 err = devx_umem_reg_cmd_alloc(obj, &cmd);
906 if (err)
907 goto err_umem_release;
908
909 devx_umem_reg_cmd_build(dev, obj, &cmd);
910
911 MLX5_SET(general_obj_in_cmd_hdr, cmd.in, uid, c->devx_uid);
912 err = mlx5_cmd_exec(dev->mdev, cmd.in, cmd.inlen, cmd.out,
913 sizeof(cmd.out));
914 if (err)
915 goto err_umem_reg_cmd_free;
916
917 obj->mdev = dev->mdev;
918 uobj->object = obj;
919 devx_obj_build_destroy_cmd(cmd.in, cmd.out, obj->dinbox, &obj->dinlen, &obj_id);
920 err = uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_OUT_ID, &obj_id, sizeof(obj_id));
921 if (err)
922 goto err_umem_destroy;
923
924 devx_umem_reg_cmd_free(&cmd);
925
926 return 0;
927
928err_umem_destroy:
929 mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, cmd.out, sizeof(cmd.out));
930err_umem_reg_cmd_free:
931 devx_umem_reg_cmd_free(&cmd);
932err_umem_release:
933 ib_umem_release(obj->umem);
934err_obj_free:
935 kfree(obj);
936 return err;
937}
938
939static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_UMEM_DEREG)(struct ib_device *ib_dev,
940 struct ib_uverbs_file *file,
941 struct uverbs_attr_bundle *attrs)
942{
943 return 0;
944}
945
946static int devx_umem_cleanup(struct ib_uobject *uobject,
947 enum rdma_remove_reason why)
948{
949 struct devx_umem *obj = uobject->object;
950 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
951 int err;
952
953 err = mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out, sizeof(out));
954 if (err && why == RDMA_REMOVE_DESTROY)
955 return err;
956
957 ib_umem_release(obj->umem);
958 kfree(obj);
959 return 0;
960}
961
962static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_UMEM_REG,
963 &UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_UMEM_REG_HANDLE,
964 MLX5_IB_OBJECT_DEVX_UMEM,
965 UVERBS_ACCESS_NEW,
966 UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
967 &UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_UMEM_REG_ADDR, UVERBS_ATTR_TYPE(u64),
968 UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
969 &UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_UMEM_REG_LEN, UVERBS_ATTR_TYPE(u64),
970 UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
971 &UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_UMEM_REG_ACCESS, UVERBS_ATTR_TYPE(u32),
972 UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
973 &UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_DEVX_UMEM_REG_OUT_ID, UVERBS_ATTR_TYPE(u32),
974 UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)));
975
976static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_UMEM_DEREG,
977 &UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_UMEM_DEREG_HANDLE,
978 MLX5_IB_OBJECT_DEVX_UMEM,
979 UVERBS_ACCESS_DESTROY,
980 UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)));
981
791static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_QUERY_UAR, 982static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_QUERY_UAR,
792 &UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_QUERY_UAR_USER_IDX, UVERBS_ATTR_TYPE(u32), 983 &UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_QUERY_UAR_USER_IDX, UVERBS_ATTR_TYPE(u32),
793 UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)), 984 UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
@@ -868,6 +1059,12 @@ static DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_DEVX_OBJ,
868 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_MODIFY), 1059 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_MODIFY),
869 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_QUERY)); 1060 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_QUERY));
870 1061
1062static DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_DEVX_UMEM,
1063 &UVERBS_TYPE_ALLOC_IDR(0, devx_umem_cleanup),
1064 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_UMEM_REG),
1065 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_UMEM_DEREG));
1066
871static DECLARE_UVERBS_OBJECT_TREE(devx_objects, 1067static DECLARE_UVERBS_OBJECT_TREE(devx_objects,
872 &UVERBS_OBJECT(MLX5_IB_OBJECT_DEVX), 1068 &UVERBS_OBJECT(MLX5_IB_OBJECT_DEVX),
873 &UVERBS_OBJECT(MLX5_IB_OBJECT_DEVX_OBJ)); 1069 &UVERBS_OBJECT(MLX5_IB_OBJECT_DEVX_OBJ),
1070 &UVERBS_OBJECT(MLX5_IB_OBJECT_DEVX_UMEM));
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index ac24ed87c67e..00b539303f5d 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -82,6 +82,7 @@ enum {
82 82
83enum { 83enum {
84 MLX5_OBJ_TYPE_UCTX = 0x0004, 84 MLX5_OBJ_TYPE_UCTX = 0x0004,
85 MLX5_OBJ_TYPE_UMEM = 0x0005,
85}; 86};
86 87
87enum { 88enum {
diff --git a/include/uapi/rdma/mlx5_user_ioctl_cmds.h b/include/uapi/rdma/mlx5_user_ioctl_cmds.h
index 1252695cd94b..dbc549a7bf50 100644
--- a/include/uapi/rdma/mlx5_user_ioctl_cmds.h
+++ b/include/uapi/rdma/mlx5_user_ioctl_cmds.h
@@ -89,9 +89,27 @@ enum mlx5_ib_devx_obj_methods {
89 MLX5_IB_METHOD_DEVX_OBJ_QUERY, 89 MLX5_IB_METHOD_DEVX_OBJ_QUERY,
90}; 90};
91 91
92enum mlx5_ib_devx_umem_reg_attrs {
93 MLX5_IB_ATTR_DEVX_UMEM_REG_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
94 MLX5_IB_ATTR_DEVX_UMEM_REG_ADDR,
95 MLX5_IB_ATTR_DEVX_UMEM_REG_LEN,
96 MLX5_IB_ATTR_DEVX_UMEM_REG_ACCESS,
97 MLX5_IB_ATTR_DEVX_UMEM_REG_OUT_ID,
98};
99
100enum mlx5_ib_devx_umem_dereg_attrs {
101 MLX5_IB_ATTR_DEVX_UMEM_DEREG_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
102};
103
104enum mlx5_ib_devx_umem_methods {
105 MLX5_IB_METHOD_DEVX_UMEM_REG = (1U << UVERBS_ID_NS_SHIFT),
106 MLX5_IB_METHOD_DEVX_UMEM_DEREG,
107};
108
92enum mlx5_ib_devx_objects { 109enum mlx5_ib_devx_objects {
93 MLX5_IB_OBJECT_DEVX = (1U << UVERBS_ID_NS_SHIFT), 110 MLX5_IB_OBJECT_DEVX = (1U << UVERBS_ID_NS_SHIFT),
94 MLX5_IB_OBJECT_DEVX_OBJ, 111 MLX5_IB_OBJECT_DEVX_OBJ,
112 MLX5_IB_OBJECT_DEVX_UMEM,
95}; 113};
96 114
97#endif 115#endif