rsc_event_notifier() takes a reference on the resource via
mlx5_get_rsc() before dispatching to the registered .event callback, and
documents that the callback owns releasing it:
qp->event(qp, event_type);
/* Need to put resource in event handler */
return NOTIFY_OK;
mlx5_ib_qp_event() honors this, either releasing the reference
immediately when it has no work to do or handing it off to its deferred
workqueue callback. mlx5_ib_wq_event(), registered as the .event
callback for standalone RQ/WQ resources, never released it on any path.
Every MLX5_EVENT_TYPE_WQ_CATAS_ERROR (or any other event reaching this
callback) therefore leaked one reference on dev->qp_table's tracked
resource. Once leaked enough times, or even just once, the resource's
refcount can never reach zero, so destroy_resource_common()'s
wait_for_completion(&qp->common.free) hangs forever when the WQ is later
destroyed.
Add the missing mlx5_core_res_put() on every exit path.
Fixes: 350d0e4c7e4b ("IB/mlx5: Track asynchronous events on a receive work queue")
Signed-off-by: Yishai Hadas <yishaih@nvidia.com>
---
drivers/infiniband/hw/mlx5/qp.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 0d4f8b109ad2..d4d439ebb595 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -5344,11 +5344,13 @@ static void mlx5_ib_wq_event(struct mlx5_core_qp *core_qp, int type)
break;
default:
mlx5_ib_warn(dev, "Unexpected event type %d on WQ %06x\n", type, core_qp->qpn);
- return;
+ goto out;
}
rwq->ibwq.event_handler(&event, rwq->ibwq.wq_context);
}
+out:
+ mlx5_core_res_put(&core_qp->common);
}
static int set_delay_drop(struct mlx5_ib_dev *dev)
--
2.18.1