qla2xxx: fix session free stall by using scst_unregister_session wait=0

Calling scst_unregister_session(wait=1) from qlt_free_session_done
blocks the qla2xxx_wq worker until session teardown completes, but
teardown requires the TM thread to process SCST_UNREG_SESS_TM while
the TM thread is blocked on scst_mutex held by concurrent session
teardown in the global management thread. Under load this stall
exceeds the hung-task timeout. Switch to wait=0 and wait on
fcport->unreg_done instead, matching the pattern in iscsi-scst.
This commit is contained in:
Brian M
2026-02-26 17:24:27 -08:00
committed by Gleb Chesnokov
parent 1e94a45bd3
commit 84a23a254b

View File

@@ -740,7 +740,23 @@ static void sqa_qla2xxx_free_session(struct fc_port *fcport)
DECLARE_COMPLETION_ONSTACK(c);
fcport->unreg_done = &c;
scst_unregister_session(scst_sess, 1, sqa_free_session_done);
/*
* Use wait=0 (async) to avoid a severe stall under concurrent
* session teardown. With wait=1 the workqueue thread blocks
* inside scst_unregister_session() until
* scst_free_session_callback() fires. That callback cannot be
* scheduled until the TM thread processes SCST_UNREG_SESS_TM,
* but the TM thread is blocked on scst_mutex which the global
* management thread holds during concurrent session teardown
* (scst_sess_free_tgt_devs -> synchronize_rcu()). Under load
* this stall exceeds the hung-task timeout. With wait=0 the
* workqueue thread is released immediately; we wait only on
* fcport->unreg_done, signalled by sqa_free_session_done() at
* a point where scst_mutex is not held.
* See also: iscsi-scst session_free() which carries a similar
* warning.
*/
scst_unregister_session(scst_sess, 0, sqa_free_session_done);
wait_for_completion(&c);
}