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: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Matthew Ahrens <mahrens@delphix.com> eviewed-by: Tony Nguyen <tony.nguyen@delphix.com> Signed-off-by: Paul Dagnelie <pcd@delphix.com> Closes #12714
This commit is contained in:
parent
321c1b6f39
commit
58bf6afd3f
|
@ -1298,8 +1298,10 @@ spl_taskq_expand(unsigned int cpu, struct hlist_node *node)
|
||||||
ASSERT(tq);
|
ASSERT(tq);
|
||||||
spin_lock_irqsave_nested(&tq->tq_lock, flags, tq->tq_lock_class);
|
spin_lock_irqsave_nested(&tq->tq_lock, flags, tq->tq_lock_class);
|
||||||
|
|
||||||
if (!(tq->tq_flags & TASKQ_ACTIVE))
|
if (!(tq->tq_flags & TASKQ_ACTIVE)) {
|
||||||
goto out;
|
spin_unlock_irqrestore(&tq->tq_lock, flags);
|
||||||
|
return (err);
|
||||||
|
}
|
||||||
|
|
||||||
ASSERT(tq->tq_flags & TASKQ_THREADS_CPU_PCT);
|
ASSERT(tq->tq_flags & TASKQ_THREADS_CPU_PCT);
|
||||||
int nthreads = MIN(tq->tq_cpu_pct, 100);
|
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) &&
|
if (!((tq->tq_flags & TASKQ_DYNAMIC) && spl_taskq_thread_dynamic) &&
|
||||||
tq->tq_maxthreads > tq->tq_nthreads) {
|
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);
|
taskq_thread_t *tqt = taskq_thread_create(tq);
|
||||||
if (tqt == NULL)
|
if (tqt == NULL)
|
||||||
err = -1;
|
err = -1;
|
||||||
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
|
||||||
spin_unlock_irqrestore(&tq->tq_lock, flags);
|
spin_unlock_irqrestore(&tq->tq_lock, flags);
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue