@@ -3875,6 +3875,15 @@ static void ib_uverbs_clone_ib_pd(union ib_uverbs_import_fr_fd_resp *resp,
resp->alloc_pd.pd_handle = handle;
}
+static void ib_uverbs_clone_ib_mr(union ib_uverbs_import_fr_fd_resp *resp,
+ struct ib_mr *mr,
+ __u32 handle)
+{
+ resp->reg_mr.lkey = mr->lkey;
+ resp->reg_mr.rkey = mr->rkey;
+ resp->reg_mr.mr_handle = handle;
+}
+
static int ib_uverbs_import_ib_pd(struct uverbs_attr_bundle *attrs)
{
union ib_uverbs_import_fr_fd_resp resp = {0};
@@ -3941,6 +3950,74 @@ static int ib_uverbs_import_ib_pd(struct uverbs_attr_bundle *attrs)
return ret;
}
+static int ib_uverbs_import_ib_mr(struct uverbs_attr_bundle *attrs)
+{
+ union ib_uverbs_import_fr_fd_resp resp = {0};
+ struct ib_uobject *src_uobj = NULL;
+ struct ib_uobject *dst_uobj = NULL;
+ struct ib_uverbs_import_fr_fd cmd;
+ struct ib_uverbs_file *src_file;
+ struct ib_device *ibdev;
+ struct ib_mr *mr;
+ struct file *filep;
+ int ret;
+
+ ret = uverbs_request(attrs, &cmd, sizeof(cmd));
+ if (ret)
+ return ret;
+
+ ret = ib_uverbs_import_lock(attrs, cmd.fd, UVERBS_OBJECT_MR,
+ cmd.handle, &src_uobj, &filep,
+ &src_file);
+ if (ret)
+ return ret;
+
+ mr = src_uobj->object;
+
+ dst_uobj = uobj_alloc(UVERBS_OBJECT_MR, attrs, &ibdev);
+ if (IS_ERR(dst_uobj)) {
+ ret = -ENOMEM;
+ goto uobj;
+ }
+
+ if (!ibdev->ops.clone_ib_mr) {
+ ret = -EINVAL;
+ goto uobj;
+ }
+
+ dst_uobj->object = src_uobj->object;
+ dst_uobj->refcnt = src_uobj->refcnt;
+
+ if (WARN_ON(!atomic_inc_not_zero(src_uobj->refcnt))) {
+ ret = -EINVAL;
+ goto uobj;
+ }
+
+ ret = ibdev->ops.clone_ib_mr(&attrs->driver_udata, mr);
+ if (ret)
+ goto uobj;
+
+ ib_uverbs_clone_ib_mr(&resp, dst_uobj->object, dst_uobj->id);
+
+ ret = uverbs_response(attrs, &resp, sizeof(resp));
+ if (ret)
+ goto uobj;
+
+ ret = uobj_alloc_commit(dst_uobj, attrs);
+
+ ib_uverbs_import_unlock(src_uobj, filep);
+
+ return ret;
+
+uobj:
+ ib_uverbs_import_unlock(src_uobj, filep);
+
+ if (!IS_ERR_OR_NULL(dst_uobj))
+ uobj_alloc_abort(dst_uobj, attrs);
+
+ return ret;
+}
+
static int ib_uverbs_import_fr_fd(struct uverbs_attr_bundle *attrs)
{
struct ib_uverbs_import_fr_fd cmd;
@@ -3953,6 +4030,8 @@ static int ib_uverbs_import_fr_fd(struct uverbs_attr_bundle *attrs)
switch (cmd.type) {
case UVERBS_OBJECT_PD:
return ib_uverbs_import_ib_pd(attrs);
+ case UVERBS_OBJECT_MR:
+ return ib_uverbs_import_ib_mr(attrs);
}
return -EINVAL;
@@ -1311,6 +1311,7 @@ struct ib_uverbs_import_fr_fd {
union ib_uverbs_import_fr_fd_resp {
struct ib_uverbs_alloc_pd_resp alloc_pd;
+ struct ib_uverbs_reg_mr_resp reg_mr;
};
#define IB_DEVICE_NAME_MAX 64
Implementation of new verb which enable to import ib_mr object. Signed-off-by: Yuval Shaia <yuval.shaia@oracle.com> --- drivers/infiniband/core/uverbs_cmd.c | 79 ++++++++++++++++++++++++++++ include/uapi/rdma/ib_user_verbs.h | 1 + 2 files changed, 80 insertions(+)