IB/uverbs: Hold the uobj write lock after allocate
authorJason Gunthorpe <jgg@mellanox.com>
Tue, 13 Feb 2018 10:18:36 +0000 (12:18 +0200)
committerJason Gunthorpe <jgg@mellanox.com>
Thu, 15 Feb 2018 21:59:46 +0000 (14:59 -0700)
This clarifies the design intention that time between allocate and
commit has the uobj exclusive to the caller. We already guarantee
this by delaying publishing the uobj pointer via idr_insert,
fd_install, list_add, etc.

Additionally holding the usecnt lock during this period provides
extra clarity and more protection against future mistakes.

Fixes: 3832125624b7 ("IB/core: Add support for idr types")
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/core/rdma_core.c

index 85b5ee4defa4bed1cabaeaa1fe0f1121bc91c242..3fe6035abde68d9289139c495d951d746e0c584a 100644 (file)
@@ -141,7 +141,12 @@ static struct ib_uobject *alloc_uobj(struct ib_ucontext *context,
         */
        uobj->context = context;
        uobj->type = type;
-       atomic_set(&uobj->usecnt, 0);
+       /*
+        * Allocated objects start out as write locked to deny any other
+        * syscalls from accessing them until they are committed. See
+        * rdma_alloc_commit_uobject
+        */
+       atomic_set(&uobj->usecnt, -1);
        kref_init(&uobj->ref);
 
        return uobj;
@@ -527,6 +532,10 @@ int rdma_alloc_commit_uobject(struct ib_uobject *uobj)
                return ret;
        }
 
+       /* matches atomic_set(-1) in alloc_uobj */
+       lockdep_check(uobj, true);
+       atomic_set(&uobj->usecnt, 0);
+
        uobj->type->type_class->alloc_commit(uobj);
        up_read(&uobj->context->cleanup_rwsem);