mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-23 05:31:28 +00:00
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:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user