Commit 7bd292e5 authored by Paul Dagnelie's avatar Paul Dagnelie Committed by Tony Hutter
Browse files

Fix cpu hotplug atomic sleep issue


We move the spinlock unlock before the thread creation. This should be
safe because the thread creation code doesn't actually manipulate any
taskq data structures; that's done by the thread once it's created.

We also remove the assertion that the maxthreads is the current threads
plus one; that assertion could fail if multiple hotplug events come in
quick succession, and the first new taskq thread hasn't had a chance to
start processing yet.
Reviewed-by: default avatarBrian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: default avatarMatthew Ahrens <mahrens@delphix.com>
eviewed-by: default avatarTony Nguyen <tony.nguyen@delphix.com>
Signed-off-by: default avatarPaul Dagnelie <pcd@delphix.com>
Closes #12714
Showing with 6 additions and 5 deletions
+6 -5
......@@ -1298,8 +1298,10 @@ spl_taskq_expand(unsigned int cpu, struct hlist_node *node)
ASSERT(tq);
spin_lock_irqsave_nested(&tq->tq_lock, flags, tq->tq_lock_class);
if (!(tq->tq_flags & TASKQ_ACTIVE))
goto out;
if (!(tq->tq_flags & TASKQ_ACTIVE)) {
spin_unlock_irqrestore(&tq->tq_lock, flags);
return (err);
}
ASSERT(tq->tq_flags & TASKQ_THREADS_CPU_PCT);
int nthreads = MIN(tq->tq_cpu_pct, 100);
......@@ -1308,13 +1310,12 @@ spl_taskq_expand(unsigned int cpu, struct hlist_node *node)
if (!((tq->tq_flags & TASKQ_DYNAMIC) && spl_taskq_thread_dynamic) &&
tq->tq_maxthreads > tq->tq_nthreads) {
ASSERT3U(tq->tq_maxthreads, ==, tq->tq_nthreads + 1);
spin_unlock_irqrestore(&tq->tq_lock, flags);
taskq_thread_t *tqt = taskq_thread_create(tq);
if (tqt == NULL)
err = -1;
return (err);
}
out:
spin_unlock_irqrestore(&tq->tq_lock, flags);
return (err);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment