diff --git a/scst/include/scst.h b/scst/include/scst.h index 20e2c6685..9f10f9fa7 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -1965,6 +1965,7 @@ struct scst_cmd_threads { int io_context_refcnt; bool io_context_ready; + wait_queue_head_t io_context_wait; /* io_context_mutex protects io_context and io_context_refcnt. */ struct mutex io_context_mutex; diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index 669cafdb7..1b17d3828 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -4331,13 +4331,7 @@ found: t->acg_dev->acg->acg_io_grouping_type); } else { res = t; - if (!*(volatile bool *)&res->active_cmd_threads->io_context_ready) { - TRACE_DBG("IO context for t %p not yet " - "initialized, waiting...", t); - msleep(100); - goto found; - } - smp_rmb(); + scst_wait_ioctx(res->active_cmd_threads); TRACE_DBG("Going to share IO context %p (res %p, ini %s, " "dev %s, cmd_threads %p, grouping type %d)", res->active_cmd_threads->io_context, res, diff --git a/scst/src/scst_main.c b/scst/src/scst_main.c index 3992b2d50..05a5d87e1 100644 --- a/scst/src/scst_main.c +++ b/scst/src/scst_main.c @@ -1930,12 +1930,7 @@ out_wait: * Wait for io_context gets initialized to avoid possible races * for it from the sharing it tgt_devs. */ - while (!*(volatile bool *)&cmd_threads->io_context_ready) { - TRACE_DBG("Waiting for io_context for cmd_threads %p " - "initialized", cmd_threads); - msleep(50); - } - smp_rmb(); + scst_wait_ioctx(cmd_threads); } if (res != 0) @@ -2193,6 +2188,7 @@ void scst_init_threads(struct scst_cmd_threads *cmd_threads) INIT_LIST_HEAD(&cmd_threads->threads_list); mutex_init(&cmd_threads->io_context_mutex); spin_lock_init(&cmd_threads->thr_lock); + init_waitqueue_head(&cmd_threads->io_context_wait); mutex_lock(&scst_cmd_threads_mutex); list_add_tail(&cmd_threads->lists_list_entry, diff --git a/scst/src/scst_priv.h b/scst/src/scst_priv.h index 5f016fb08..28ec3c1e4 100644 --- a/scst/src/scst_priv.h +++ b/scst/src/scst_priv.h @@ -214,6 +214,8 @@ struct scst_cmd_thread_t { bool being_stopped; }; +void scst_wait_ioctx(struct scst_cmd_threads *tp); + static inline bool scst_set_io_context(struct scst_cmd *cmd, struct io_context **old) { diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index 2bb613b5c..deb8af02f 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -4650,6 +4650,20 @@ int scst_init_thread(void *arg) return 0; } +/** + * scst_wait_ioctx_timeout() - wait until an I/O context becomes available + * @tp: Thread pool to wait on. + * + * Returns the number of jiffies remaining if the I/O context became available + * in time and zero if the I/O context did not become available in time. + */ +void scst_wait_ioctx(struct scst_cmd_threads *tp) +{ + wait_event(tp->io_context_wait, + *(volatile bool *)&tp->io_context_ready); + smp_rmb(); +} + /** * scst_ioctx_get() - Associate an I/O context with a thread. * @@ -4717,7 +4731,8 @@ See "http://lkml.org/lkml/2012/7/17/515" for more details. smp_wmb(); p_cmd_threads->io_context_ready = true; - return; + + wake_up_all(&p_cmd_threads->io_context_wait); } /**