Commit 104f268d authored by Jason Gunthorpe's avatar Jason Gunthorpe

IB/uverbs: Improve lockdep_check

This is really being used as an assert that the expected usecnt
is being held and implicitly that the usecnt is valid. Rename it to
assert_uverbs_usecnt and tighten the checks to only accept valid
values of usecnt (eg 0 and < -1 are invalid).

The tigher checkes make the assertion cover more cases and is more
likely to find bugs via syzkaller/etc.

Fixes: 38321256 ("IB/core: Add support for idr types")
Signed-off-by: default avatarLeon Romanovsky <leon@kernel.org>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent 6623e3e3
...@@ -412,13 +412,13 @@ static int __must_check remove_commit_fd_uobject(struct ib_uobject *uobj, ...@@ -412,13 +412,13 @@ static int __must_check remove_commit_fd_uobject(struct ib_uobject *uobj,
return ret; return ret;
} }
static void lockdep_check(struct ib_uobject *uobj, bool exclusive) static void assert_uverbs_usecnt(struct ib_uobject *uobj, bool exclusive)
{ {
#ifdef CONFIG_LOCKDEP #ifdef CONFIG_LOCKDEP
if (exclusive) if (exclusive)
WARN_ON(atomic_read(&uobj->usecnt) > 0); WARN_ON(atomic_read(&uobj->usecnt) != -1);
else else
WARN_ON(atomic_read(&uobj->usecnt) == -1); WARN_ON(atomic_read(&uobj->usecnt) <= 0);
#endif #endif
} }
...@@ -457,7 +457,7 @@ int __must_check rdma_remove_commit_uobject(struct ib_uobject *uobj) ...@@ -457,7 +457,7 @@ int __must_check rdma_remove_commit_uobject(struct ib_uobject *uobj)
WARN(true, "ib_uverbs: Cleanup is running while removing an uobject\n"); WARN(true, "ib_uverbs: Cleanup is running while removing an uobject\n");
return 0; return 0;
} }
lockdep_check(uobj, true); assert_uverbs_usecnt(uobj, true);
ret = _rdma_remove_commit_uobject(uobj, RDMA_REMOVE_DESTROY); ret = _rdma_remove_commit_uobject(uobj, RDMA_REMOVE_DESTROY);
up_read(&ucontext->cleanup_rwsem); up_read(&ucontext->cleanup_rwsem);
...@@ -487,7 +487,7 @@ int rdma_explicit_destroy(struct ib_uobject *uobject) ...@@ -487,7 +487,7 @@ int rdma_explicit_destroy(struct ib_uobject *uobject)
WARN(true, "ib_uverbs: Cleanup is running while removing an uobject\n"); WARN(true, "ib_uverbs: Cleanup is running while removing an uobject\n");
return 0; return 0;
} }
lockdep_check(uobject, true); assert_uverbs_usecnt(uobject, true);
ret = uobject->type->type_class->remove_commit(uobject, ret = uobject->type->type_class->remove_commit(uobject,
RDMA_REMOVE_DESTROY); RDMA_REMOVE_DESTROY);
if (ret) if (ret)
...@@ -541,7 +541,7 @@ int rdma_alloc_commit_uobject(struct ib_uobject *uobj) ...@@ -541,7 +541,7 @@ int rdma_alloc_commit_uobject(struct ib_uobject *uobj)
} }
/* matches atomic_set(-1) in alloc_uobj */ /* matches atomic_set(-1) in alloc_uobj */
lockdep_check(uobj, true); assert_uverbs_usecnt(uobj, true);
atomic_set(&uobj->usecnt, 0); atomic_set(&uobj->usecnt, 0);
uobj->type->type_class->alloc_commit(uobj); uobj->type->type_class->alloc_commit(uobj);
...@@ -578,7 +578,7 @@ static void lookup_put_fd_uobject(struct ib_uobject *uobj, bool exclusive) ...@@ -578,7 +578,7 @@ static void lookup_put_fd_uobject(struct ib_uobject *uobj, bool exclusive)
void rdma_lookup_put_uobject(struct ib_uobject *uobj, bool exclusive) void rdma_lookup_put_uobject(struct ib_uobject *uobj, bool exclusive)
{ {
lockdep_check(uobj, exclusive); assert_uverbs_usecnt(uobj, exclusive);
uobj->type->type_class->lookup_put(uobj, exclusive); uobj->type->type_class->lookup_put(uobj, exclusive);
/* /*
* In order to unlock an object, either decrease its usecnt for * In order to unlock an object, either decrease its usecnt for
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment