scst_main: Fix wait_event() call in scst_unregister_target()

Avoid that the following kernel warning gets triggered:

WARNING: CPU: 3 PID: 12967 at kernel/sched/core.c:7287 __might_sleep+0x7a/0x90()
do not call blocking ops when !TASK_RUNNING; state=2 set at [<ffffffff81097cfe>] prepare_to_wait_event+0x5e/0xf0
CPU: 3 PID: 12967 Comm: scst_uid Tainted: G           O    4.0.0-debug+ #1
Call Trace:
 [<ffffffff815f11cb>] dump_stack+0x4c/0x65
 [<ffffffff81053930>] warn_slowpath_common+0x80/0xc0
 [<ffffffff810539b1>] warn_slowpath_fmt+0x41/0x50
 [<ffffffff81079c1a>] __might_sleep+0x7a/0x90
 [<ffffffff815f5d4a>] mutex_lock_nested+0x2a/0x4d0
 [<ffffffffa035330a>] test_sess_list+0x1a/0x40 [scst]
 [<ffffffffa0355b1e>] scst_unregister_target+0x26e/0x380 [scst]
 [<ffffffffa01f6c86>] __scst_local_remove_target+0xc6/0x160 [scst_local]
 [<ffffffffa01f6ddc>] scst_local_sysfs_del_target+0xbc/0x1b0 [scst_local]
 [<ffffffffa038b315>] scst_process_tgtt_mgmt_store+0x205/0x300 [scst]
 [<ffffffffa038b424>] scst_tgtt_mgmt_store_work_fn+0x14/0x20 [scst]
 [<ffffffffa038cc1d>] scst_process_sysfs_works+0xbd/0x1f0 [scst]
 [<ffffffffa038ce0d>] sysfs_work_thread_fn+0xbd/0x310 [scst]
 [<ffffffff81073d33>] kthread+0xf3/0x110
 [<ffffffff815faf18>] ret_from_fork+0x58/0x90


git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6724 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Bart Van Assche
2015-12-09 19:18:01 +00:00
parent 82d831be80
commit 08b774f643
+8 -11
View File
@@ -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,15 @@ again:
mutex_unlock(&scst_mutex);
#endif
/*
* Testing tgt->sysfs_sess_list below without holding scst_mutex
* is safe because '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);