Skip to content

Commit

Permalink
RDMA/core: Change how failing destroy is handled during uobj abort
Browse files Browse the repository at this point in the history
[ Upstream commit f553246 ]

Currently it triggers a WARN_ON and then goes ahead and destroys the
uobject anyhow, leaking any driver memory.

The only place that leaks driver memory should be during FD close() in
uverbs_destroy_ufile_hw().

Drivers are only allowed to fail destroy uobjects if they guarantee
destroy will eventually succeed. uverbs_destroy_ufile_hw() provides the
loop to give the driver that chance.

Link: https://lore.kernel.org/r/20200902081708.746631-1-leon@kernel.org
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
jgunthorpe authored and gregkh committed Nov 5, 2020
1 parent d4ddc5a commit 44c1c8c
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 20 deletions.
30 changes: 15 additions & 15 deletions drivers/infiniband/core/rdma_core.c
Expand Up @@ -130,17 +130,6 @@ static int uverbs_destroy_uobject(struct ib_uobject *uobj,
lockdep_assert_held(&ufile->hw_destroy_rwsem);
assert_uverbs_usecnt(uobj, UVERBS_LOOKUP_WRITE);

if (reason == RDMA_REMOVE_ABORT_HWOBJ) {
reason = RDMA_REMOVE_ABORT;
ret = uobj->uapi_object->type_class->destroy_hw(uobj, reason,
attrs);
/*
* Drivers are not permitted to ignore RDMA_REMOVE_ABORT, see
* ib_is_destroy_retryable, cleanup_retryable == false here.
*/
WARN_ON(ret);
}

if (reason == RDMA_REMOVE_ABORT) {
WARN_ON(!list_empty(&uobj->list));
WARN_ON(!uobj->context);
Expand Down Expand Up @@ -674,11 +663,22 @@ void rdma_alloc_abort_uobject(struct ib_uobject *uobj,
bool hw_obj_valid)
{
struct ib_uverbs_file *ufile = uobj->ufile;
int ret;

if (hw_obj_valid) {
ret = uobj->uapi_object->type_class->destroy_hw(
uobj, RDMA_REMOVE_ABORT, attrs);
/*
* If the driver couldn't destroy the object then go ahead and
* commit it. Leaking objects that can't be destroyed is only
* done during FD close after the driver has a few more tries to
* destroy it.
*/
if (WARN_ON(ret))
return rdma_alloc_commit_uobject(uobj, attrs);
}

uverbs_destroy_uobject(uobj,
hw_obj_valid ? RDMA_REMOVE_ABORT_HWOBJ :
RDMA_REMOVE_ABORT,
attrs);
uverbs_destroy_uobject(uobj, RDMA_REMOVE_ABORT, attrs);

/* Matches the down_read in rdma_alloc_begin_uobject */
up_read(&ufile->hw_destroy_rwsem);
Expand Down
5 changes: 0 additions & 5 deletions include/rdma/ib_verbs.h
Expand Up @@ -1463,11 +1463,6 @@ enum rdma_remove_reason {
RDMA_REMOVE_DRIVER_REMOVE,
/* uobj is being cleaned-up before being committed */
RDMA_REMOVE_ABORT,
/*
* uobj has been fully created, with the uobj->object set, but is being
* cleaned up before being comitted
*/
RDMA_REMOVE_ABORT_HWOBJ,
};

struct ib_rdmacg_object {
Expand Down

0 comments on commit 44c1c8c

Please sign in to comment.