diff --git a/scst/src/scst_main.c b/scst/src/scst_main.c index b5b3851e9..6bd731c80 100644 --- a/scst/src/scst_main.c +++ b/scst/src/scst_main.c @@ -593,16 +593,6 @@ out_free_tgt: } EXPORT_SYMBOL(scst_register_target); -static inline int test_sess_list(struct scst_tgt *tgt) -{ - int res; - - mutex_lock(&scst_mutex); - res = list_empty(&tgt->sysfs_sess_list); - mutex_unlock(&scst_mutex); - return res; -} - /** * scst_unregister_target() - unregister target. * @@ -655,8 +645,20 @@ again: mutex_unlock(&scst_mutex); #endif + /* + * Testing tgt->sysfs_sess_list below without holding scst_mutex + * is safe, because: + * + * - On the init path no attempts to create new sessions for this + * target can be done in a race with this function (see above) + * + * - On the shutdown path 'tgt' won't disappear until scst_free_tgt() + * is called below and because the mutex_lock(&scst_mutex) call below + * waits until scst_free_session() has finished accessing the 'tgt' + * object. + */ TRACE_DBG("%s", "Waiting for sessions shutdown"); - wait_event(tgt->unreg_waitQ, test_sess_list(tgt)); + wait_event(tgt->unreg_waitQ, list_empty(&tgt->sysfs_sess_list)); TRACE_DBG("%s", "wait_event() returned"); scst_suspend_activity(SCST_SUSPEND_TIMEOUT_UNLIMITED);