@@ -1468,8 +1468,21 @@ enum rdma_remove_reason {
RDMA_REMOVE_DRIVER_REMOVE,
/* Context is being cleaned-up, but commit was just completed */
RDMA_REMOVE_DURING_CLEANUP,
+ /* Driver is being hot-unplugged, retry may be called upon an
error */
+ RDMA_REMOVE_DRIVER_REMOVE_RELAX,
+ /* Context deletion, retry may be called upon an error */
+ RDMA_REMOVE_CLOSE_RELAX,
};
+static inline bool ib_is_remove_retry(enum rdma_remove_reason why)
+{
+ if (why == RDMA_REMOVE_DESTROY || why ==
RDMA_REMOVE_DRIVER_REMOVE_RELAX ||
+ why == RDMA_REMOVE_CLOSE_RELAX)
+ return true;
+
+ return false;
+}
+
// In the new algorithm below enums will be used instead of
//RDMA_REMOVE_DESTROY
@@ -700,7 +701,9 @@ void uverbs_cleanup_ucontext(struct ib_ucontext
*ucontext, bool device_removed)
*/
down_write(&ucontext->cleanup_rwsem);
while (!list_empty(&ucontext->uobjects))
- if (__uverbs_cleanup_ucontext(ucontext,
RDMA_REMOVE_DESTROY))
+ if (__uverbs_cleanup_ucontext(ucontext, device_removed ?
+ RDMA_REMOVE_DRIVER_REMOVE_RELAX :
+ RDMA_REMOVE_CLOSE_RELAX))
/* No entry was cleaned-up successfully during
this iteration */
break;
// Below logic will be replaced in all applicable places, I just put few
// of to demonstrate the solution.
@@ -44,7 +44,7 @@ static int uverbs_free_cq(struct ib_uobject *uobject,
int ret;
ret = ib_destroy_cq(cq);
- if (!ret || why != RDMA_REMOVE_DESTROY)
+ if (!ret || !ib_is_remove_retry(why))
ib_uverbs_release_ucq(uobject->context->ufile, ev_queue
? container_of(ev_queue, struct ib_uverbs_completion_event_file,