aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/rdma_core.c
diff options
context:
space:
mode:
authorJason Gunthorpe <jgg@mellanox.com>2018-07-25 21:40:11 -0600
committerJason Gunthorpe <jgg@mellanox.com>2018-08-01 14:55:48 -0600
commit32ed5c00ac5fdea49058fd49bf8707e101dc3dfe (patch)
treee8e6c3e38713d9693556786ac56bff9bcc20ebea /drivers/infiniband/core/rdma_core.c
parentIB/uverbs: Remove rdma_explicit_destroy() from the ioctl methods (diff)
downloadlinux-dev-32ed5c00ac5fdea49058fd49bf8707e101dc3dfe.tar.xz
linux-dev-32ed5c00ac5fdea49058fd49bf8707e101dc3dfe.zip
IB/uverbs: Make the write path destroy methods use the same flow as ioctl
The ridiculous dance with uobj_remove_commit() is not needed, the write path can follow the same flow as ioctl - lock and destroy the HW object then use the data left over in the uobject to form the response to userspace. Two helpers are introduced to make this flow straightforward for the caller. Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Diffstat (limited to 'drivers/infiniband/core/rdma_core.c')
-rw-r--r--drivers/infiniband/core/rdma_core.c53
1 files changed, 29 insertions, 24 deletions
diff --git a/drivers/infiniband/core/rdma_core.c b/drivers/infiniband/core/rdma_core.c
index 9e84ded6d3be..7db75d784070 100644
--- a/drivers/infiniband/core/rdma_core.c
+++ b/drivers/infiniband/core/rdma_core.c
@@ -130,24 +130,44 @@ static int uverbs_try_lock_object(struct ib_uobject *uobj, bool exclusive)
}
/*
- * Does both rdma_lookup_get_uobject() and rdma_remove_commit_uobject(), then
- * returns success_res on success (negative errno on failure). For use by
- * callers that do not need the uobj.
+ * uobj_get_destroy destroys the HW object and returns a handle to the uobj
+ * with a NULL object pointer. The caller must pair this with
+ * uverbs_put_destroy.
*/
-int __uobj_perform_destroy(const struct uverbs_obj_type *type, u32 id,
- struct ib_uverbs_file *ufile, int success_res)
+struct ib_uobject *__uobj_get_destroy(const struct uverbs_obj_type *type,
+ u32 id, struct ib_uverbs_file *ufile)
{
struct ib_uobject *uobj;
int ret;
uobj = rdma_lookup_get_uobject(type, ufile, id, true);
if (IS_ERR(uobj))
- return PTR_ERR(uobj);
+ return uobj;
- ret = rdma_remove_commit_uobject(uobj);
- if (ret)
- return ret;
+ ret = rdma_explicit_destroy(uobj);
+ if (ret) {
+ rdma_lookup_put_uobject(uobj, true);
+ return ERR_PTR(ret);
+ }
+
+ return uobj;
+}
+/*
+ * Does both uobj_get_destroy() and uobj_put_destroy(). Returns success_res
+ * on success (negative errno on failure). For use by callers that do not need
+ * the uobj.
+ */
+int __uobj_perform_destroy(const struct uverbs_obj_type *type, u32 id,
+ struct ib_uverbs_file *ufile, int success_res)
+{
+ struct ib_uobject *uobj;
+
+ uobj = __uobj_get_destroy(type, id, ufile);
+ if (IS_ERR(uobj))
+ return PTR_ERR(uobj);
+
+ rdma_lookup_put_uobject(uobj, true);
return success_res;
}
@@ -449,21 +469,6 @@ static int __must_check _rdma_remove_commit_uobject(struct ib_uobject *uobj,
return ret;
}
-/* This is called only for user requested DESTROY reasons
- * rdma_lookup_get_uobject(exclusive=true) must have been called to get uobj,
- * and after this returns the corresponding put has been done, and the kref
- * for uobj has been consumed.
- */
-int __must_check rdma_remove_commit_uobject(struct ib_uobject *uobj)
-{
- int ret;
-
- ret = rdma_explicit_destroy(uobj);
- /* Pairs with the lookup_get done by the caller */
- rdma_lookup_put_uobject(uobj, true);
- return ret;
-}
-
int rdma_explicit_destroy(struct ib_uobject *uobject)
{
int ret;