RDMA/core: Change how failing destroy is handled during uobj abort
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>
This commit is contained in:
parent
00b3c11879
commit
f553246f7f
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
uverbs_destroy_uobject(uobj,
|
||||
hw_obj_valid ? RDMA_REMOVE_ABORT_HWOBJ :
|
||||
RDMA_REMOVE_ABORT,
|
||||
attrs);
|
||||
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, RDMA_REMOVE_ABORT, attrs);
|
||||
|
||||
/* Matches the down_read in rdma_alloc_begin_uobject */
|
||||
up_read(&ufile->hw_destroy_rwsem);
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue