summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorGordon Ross <gwr@nexenta.com>2015-04-21 21:30:02 -0400
committerGordon Ross <gwr@nexenta.com>2015-04-27 20:49:40 -0400
commite548823371e6dfbf1717dabbe24870fec98c6051 (patch)
treee9d1139f2fc6c2b58ad8b3e90442e051729efeff /usr/src
parentee637354acf5da3e4a5853a500f444e3aec1a76e (diff)
downloadillumos-joyent-e548823371e6dfbf1717dabbe24870fec98c6051.tar.gz
1501 taskq_create_proc ... TQ_DYNAMIC puts tasks in p0 (take 2)
Reviewed by: Garrett D'Amore <garrett@damore.org> Reviewed by: Dan McDonald <danmcd@omniti.com> Reviewed by: Robert Mustacchi <rm@joyent.com> Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com> Approved by: Albert Lee <trisk@omniti.com>
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/os/taskq.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/usr/src/uts/common/os/taskq.c b/usr/src/uts/common/os/taskq.c
index 26e7b952d7..f761490b92 100644
--- a/usr/src/uts/common/os/taskq.c
+++ b/usr/src/uts/common/os/taskq.c
@@ -24,7 +24,7 @@
*/
/*
- * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -1435,12 +1435,19 @@ taskq_thread_create(taskq_t *tq)
tq->tq_active++;
mutex_exit(&tq->tq_lock);
- if (tq->tq_proc != &p0) {
+ /*
+ * With TASKQ_DUTY_CYCLE the new thread must have an LWP
+ * as explained in ../disp/sysdc.c (for the msacct data).
+ * Otherwise simple kthreads are preferred.
+ */
+ if ((tq->tq_flags & TASKQ_DUTY_CYCLE) != 0) {
+ /* Enforced in taskq_create_common */
+ ASSERT3P(tq->tq_proc, !=, &p0);
t = lwp_kernel_create(tq->tq_proc, taskq_thread, tq, TS_RUN,
tq->tq_pri);
} else {
- t = thread_create(NULL, 0, taskq_thread, tq, 0, &p0, TS_RUN,
- tq->tq_pri);
+ t = thread_create(NULL, 0, taskq_thread, tq, 0, tq->tq_proc,
+ TS_RUN, tq->tq_pri);
}
if (!first) {
@@ -1867,7 +1874,10 @@ taskq_create_common(const char *name, int instance, int nthreads, pri_t pri,
IMPLY((flags & TASKQ_DYNAMIC), !(flags & TASKQ_THREADS_CPU_PCT));
IMPLY((flags & TASKQ_CPR_SAFE), !(flags & TASKQ_THREADS_CPU_PCT));
- /* Cannot have DUTY_CYCLE without a non-p0 kernel process */
+ /* Cannot have DYNAMIC with DUTY_CYCLE */
+ IMPLY((flags & TASKQ_DYNAMIC), !(flags & TASKQ_DUTY_CYCLE));
+
+ /* Cannot have DUTY_CYCLE with a p0 kernel process */
IMPLY((flags & TASKQ_DUTY_CYCLE), proc != &p0);
/* Cannot have DC_BATCH without DUTY_CYCLE */
@@ -1945,6 +1955,14 @@ taskq_create_common(const char *name, int instance, int nthreads, pri_t pri,
}
/*
+ * Before we start creating threads for this taskq, take a
+ * zone hold so the zone can't go away before taskq_destroy
+ * makes sure all the taskq threads are gone. This hold is
+ * similar in purpose to those taken by zthread_create().
+ */
+ zone_hold(tq->tq_proc->p_zone);
+
+ /*
* Create the first thread, which will create any other threads
* necessary. taskq_thread_create will not return until we have
* enough threads to be able to process requests.
@@ -2122,6 +2140,12 @@ taskq_destroy(taskq_t *tq)
ASSERT(!(tq->tq_flags & TASKQ_DYNAMIC));
}
+ /*
+ * Now that all the taskq threads are gone, we can
+ * drop the zone hold taken in taskq_create_common
+ */
+ zone_rele(tq->tq_proc->p_zone);
+
tq->tq_threads_ncpus_pct = 0;
tq->tq_totaltime = 0;
tq->tq_tasks = 0;
@@ -2183,7 +2207,7 @@ taskq_bucket_extend(void *arg)
* created, place the entry on the free list and start the thread.
*/
tqe->tqent_thread = thread_create(NULL, 0, taskq_d_thread, tqe,
- 0, &p0, TS_STOPPED, tq->tq_pri);
+ 0, tq->tq_proc, TS_STOPPED, tq->tq_pri);
/*
* Once the entry is ready, link it to the the bucket free list.