diff options
author | John Levon <john.levon@joyent.com> | 2018-09-07 19:18:13 +0000 |
---|---|---|
committer | John Levon <john.levon@joyent.com> | 2018-09-07 19:19:13 +0000 |
commit | 78b5ec13e46ab3b58f3ef9d6501c98dc7e278d69 (patch) | |
tree | 0fa0751333745e0c22fc24d73855a25e0d66ae7d /usr/src | |
parent | e58cbadf52334f540974293063eec8df9cb5a0da (diff) | |
download | illumos-joyent-78b5ec13e46ab3b58f3ef9d6501c98dc7e278d69.tar.gz |
OS-7222 thread_create() should ensure ->t_cpu is set
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Approved by: Robert Mustacchi <rm@joyent.com>
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/disp/thread.c | 57 |
1 files changed, 27 insertions, 30 deletions
diff --git a/usr/src/uts/common/disp/thread.c b/usr/src/uts/common/disp/thread.c index c923ba5d1a..aece8faaff 100644 --- a/usr/src/uts/common/disp/thread.c +++ b/usr/src/uts/common/disp/thread.c @@ -479,15 +479,9 @@ thread_create( curthread->t_prev = t; /* - * Threads should never have a NULL t_cpu pointer so assign it - * here. If the thread is being created with state TS_RUN a - * better CPU may be chosen when it is placed on the run queue. - * - * We need to keep kernel preemption disabled when setting all - * three fields to keep them in sync. Also, always create in - * the default partition since that's where kernel threads go - * (if this isn't a kernel thread, t_cpupart will be changed - * in lwp_create before setting the thread runnable). + * We'll always create in the default partition since that's where + * kernel threads go (we'll change this later if needed, in + * lwp_create()). */ t->t_cpupart = &cp_default; @@ -496,20 +490,23 @@ thread_create( * Since the kernel does not (presently) allocate its memory * in a locality aware fashion, the root is an appropriate home. * If this thread is later associated with an lwp, it will have - * it's lgroup re-assigned at that time. + * its lgroup re-assigned at that time. */ lgrp_move_thread(t, &cp_default.cp_lgrploads[LGRP_ROOTID], 1); /* - * Inherit the current cpu. If this cpu isn't part of the chosen - * lgroup, a new cpu will be chosen by cpu_choose when the thread - * is ready to run. + * If the current CPU is in the default cpupart, use it. Otherwise, + * pick one that is; before entering the dispatcher code, we'll + * make sure to keep the invariant that ->t_cpu is set. (In fact, we + * rely on this, in ht_should_run(), in the call tree of + * disp_lowpri_cpu().) */ - if (CPU->cpu_part == &cp_default) + if (CPU->cpu_part == &cp_default) { t->t_cpu = CPU; - else - t->t_cpu = disp_lowpri_cpu(cp_default.cp_cpulist, t, - t->t_pri); + } else { + t->t_cpu = cp_default.cp_cpulist; + t->t_cpu = disp_lowpri_cpu(t->t_cpu, t, t->t_pri); + } t->t_disp_queue = t->t_cpu->cpu_disp; kpreempt_enable(); @@ -865,12 +862,12 @@ thread_zone_destroy(zoneid_t zoneid, void *unused) /* * Guard against race condition in mutex_owner_running: - * thread=owner(mutex) - * <interrupt> - * thread exits mutex - * thread exits - * thread reaped - * thread struct freed + * thread=owner(mutex) + * <interrupt> + * thread exits mutex + * thread exits + * thread reaped + * thread struct freed * cpu = thread->t_cpu <- BAD POINTER DEREFERENCE. * A cross call to all cpus will cause the interrupt handler * to reset the PC if it is in mutex_owner_running, refreshing @@ -927,12 +924,12 @@ thread_reaper() /* * Guard against race condition in mutex_owner_running: - * thread=owner(mutex) - * <interrupt> - * thread exits mutex - * thread exits - * thread reaped - * thread struct freed + * thread=owner(mutex) + * <interrupt> + * thread exits mutex + * thread exits + * thread reaped + * thread struct freed * cpu = thread->t_cpu <- BAD POINTER DEREFERENCE. * A cross call to all cpus will cause the interrupt handler * to reset the PC if it is in mutex_owner_running, refreshing @@ -1521,7 +1518,7 @@ thread_create_intr(struct cpu *cp) static kmutex_t tsd_mutex; /* linked list spin lock */ static uint_t tsd_nkeys; /* size of destructor array */ /* per-key destructor funcs */ -static void (**tsd_destructor)(void *); +static void (**tsd_destructor)(void *); /* list of tsd_thread's */ static struct tsd_thread *tsd_list; |