RDMA/ucma: Do not use file->mut to lock destroying
The only reader of destroying is inside a handler under the handler_mutex, so directly use the handler_mutex when setting it instead of the larger file->mut. As the refcount could be zero here, and the cm_id already freed, and additional refcount grab around the locking is required to touch the cm_id. Link: https://lore.kernel.org/r/20200818120526.702120-8-leon@kernel.org Signed-off-by: Leon Romanovsky <leonro@mellanox.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
@@ -602,9 +602,17 @@ static int ucma_free_ctx(struct ucma_context *ctx)
|
|||||||
|
|
||||||
static int __destroy_id(struct ucma_context *ctx)
|
static int __destroy_id(struct ucma_context *ctx)
|
||||||
{
|
{
|
||||||
mutex_lock(&ctx->file->mut);
|
/*
|
||||||
ctx->destroying = 1;
|
* If the refcount is already 0 then ucma_close_id() has already
|
||||||
mutex_unlock(&ctx->file->mut);
|
* destroyed the cm_id, otherwise holding the refcount keeps cm_id
|
||||||
|
* valid. Prevent queue_work() from being called.
|
||||||
|
*/
|
||||||
|
if (refcount_inc_not_zero(&ctx->ref)) {
|
||||||
|
rdma_lock_handler(ctx->cm_id);
|
||||||
|
ctx->destroying = 1;
|
||||||
|
rdma_unlock_handler(ctx->cm_id);
|
||||||
|
ucma_put_ctx(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
flush_workqueue(ctx->file->close_wq);
|
flush_workqueue(ctx->file->close_wq);
|
||||||
/* At this point it's guaranteed that there is no inflight closing task */
|
/* At this point it's guaranteed that there is no inflight closing task */
|
||||||
|
|||||||
Reference in New Issue
Block a user