| From 13a925b4bacccb83cbd915d5ae396575cd7a3dc1 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 2 Sep 2020 11:17:08 +0300 |
| Subject: RDMA/core: Change how failing destroy is handled during uobj abort |
| |
| From: Jason Gunthorpe <jgg@nvidia.com> |
| |
| [ Upstream commit f553246f7f794675da1794ae7ee07d1f35e561ae ] |
| |
| 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> |
| --- |
| drivers/infiniband/core/rdma_core.c | 30 ++++++++++++++--------------- |
| include/rdma/ib_verbs.h | 5 ----- |
| 2 files changed, 15 insertions(+), 20 deletions(-) |
| |
| diff --git a/drivers/infiniband/core/rdma_core.c b/drivers/infiniband/core/rdma_core.c |
| index 6d3ed7c6e19eb..3962da54ffbf4 100644 |
| --- a/drivers/infiniband/core/rdma_core.c |
| +++ b/drivers/infiniband/core/rdma_core.c |
| @@ -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; |
| + |
| + 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); |
| diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h |
| index 5b4f0efc4241f..ef7b786b8675c 100644 |
| --- a/include/rdma/ib_verbs.h |
| +++ b/include/rdma/ib_verbs.h |
| @@ -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 { |
| -- |
| 2.27.0 |
| |