If there are many establishments/teardowns, we need to make sure we do not consume too much system memory. Thus let on going session closing to finish before accepting new connection. In cma_ib_req_handler, the conn_id is newly created holding handler_mutex when call this function, and flush_workqueue wait for close_work to finish, in close_work rdma_destroy_id will be called, which will hold the handler_mutex, but they are mutex for different rdma_cm_id. To avoid circular locking lockdep warnings, disable lockdep around flush_workqueue in rtrs_rdma_connect, it's false positive. Inspired by commit 777dc82395de ("nvmet-rdma: occasionally flush ongoing controller teardown") Signed-off-by: Jack Wang <jinpu.wang@xxxxxxxxxxxxxxx> Reviewed-by: Guoqing Jiang <guoqing.jiang@xxxxxxxxxxxxxxx> --- drivers/infiniband/ulp/rtrs/rtrs-srv.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c index ed4628f032bb..eb7bb93884e7 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c +++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c @@ -1791,6 +1791,20 @@ static int rtrs_rdma_connect(struct rdma_cm_id *cm_id, err = -ENOMEM; goto reject_w_err; } + if (!cid) { + /* Let inflight session teardown complete * + * + * Avoid circular locking lockdep warnings. + * cma_ib_req_handler, the conn_id is newly created holding + * handler_mutex when call this function, and flush_workqueue + * wait for close_work to finish, in close_work rdma_destroy_id + * will be called, which will hold the handler_mutex, but they + * are mutex for different rdma_cm_id. + */ + lockdep_off(); + flush_workqueue(rtrs_wq); + lockdep_on(); + } mutex_lock(&srv->paths_mutex); sess = __find_sess(srv, &msg->sess_uuid); if (sess) { -- 2.25.1