summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/os/lwp.c
diff options
context:
space:
mode:
authorJonathan Adams <Jonathan.Adams@Sun.COM>2009-12-09 16:02:00 -0800
committerJonathan Adams <Jonathan.Adams@Sun.COM>2009-12-09 16:02:00 -0800
commitd32efdadf99ffd25752922f91fe04ab04eda7f70 (patch)
tree14b10a1ddf2ab6166e0f073bb9235a425dcd3540 /usr/src/uts/common/os/lwp.c
parent2f172c55ef76964744bc62b4500ece87f3089b4d (diff)
downloadillumos-gate-d32efdadf99ffd25752922f91fe04ab04eda7f70.tar.gz
6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
6908270 Insufficient test for "segkp_fault: bad unlock" panic in segkp_fault()
Diffstat (limited to 'usr/src/uts/common/os/lwp.c')
-rw-r--r--usr/src/uts/common/os/lwp.c55
1 files changed, 39 insertions, 16 deletions
diff --git a/usr/src/uts/common/os/lwp.c b/usr/src/uts/common/os/lwp.c
index 091c4c4a21..229c3d1177 100644
--- a/usr/src/uts/common/os/lwp.c
+++ b/usr/src/uts/common/os/lwp.c
@@ -150,26 +150,25 @@ lwp_create(void (*proc)(), caddr_t arg, size_t len, proc_t *p,
mutex_exit(&p->p_zone->zone_nlwps_lock);
mutex_exit(&p->p_lock);
- if (CLASS_KERNEL(cid)) {
- curlwp = NULL; /* don't inherit from curlwp */
+ curlwp = ttolwp(curthread);
+ if (curlwp == NULL || (stksize = curlwp->lwp_childstksz) == 0)
stksize = lwp_default_stksize;
- } else {
- curlwp = ttolwp(curthread);
- if (curlwp == NULL || (stksize = curlwp->lwp_childstksz) == 0)
- stksize = lwp_default_stksize;
- }
- /*
- * For system threads, we sleep for our swap reservation, and the
- * thread stack can't be swapped.
- *
- * Otherwise, try to reclaim a <lwp,stack> from 'deathrow'
- */
if (CLASS_KERNEL(cid)) {
- lwpdata = (caddr_t)segkp_get(segkp, stksize,
- (KPD_NO_ANON | KPD_HASREDZONE | KPD_LOCKED));
+ /*
+ * Since we are creating an LWP in an SSYS process, we do not
+ * inherit anything from the current thread's LWP. We set
+ * stksize and lwpdata to 0 in order to let thread_create()
+ * allocate a regular kernel thread stack for this thread.
+ */
+ curlwp = NULL;
+ stksize = 0;
+ lwpdata = NULL;
} else if (stksize == lwp_default_stksize) {
+ /*
+ * Try to reuse an <lwp,stack> from the LWP deathrow.
+ */
if (lwp_reapcnt > 0) {
mutex_enter(&reaplock);
if ((t = lwp_deathrow) != NULL) {
@@ -223,7 +222,31 @@ lwp_create(void (*proc)(), caddr_t arg, size_t len, proc_t *p,
*/
t = thread_create(lwpdata, stksize, NULL, NULL, 0, p, TS_STOPPED, pri);
- t->t_swap = lwpdata; /* Start of page-able data */
+ /*
+ * If a non-NULL stack base is passed in, thread_create() assumes
+ * that the stack might be statically allocated (as opposed to being
+ * allocated from segkp), and so it does not set t_swap. Since
+ * the lwpdata was allocated from segkp, we must set t_swap to point
+ * to it ourselves.
+ *
+ * This would be less confusing if t_swap had a better name; it really
+ * indicates that the stack is allocated from segkp, regardless of
+ * whether or not it is swappable.
+ */
+ if (lwpdata != NULL) {
+ ASSERT(!CLASS_KERNEL(cid));
+ ASSERT(t->t_swap == NULL);
+ t->t_swap = lwpdata; /* Start of page-able data */
+ }
+
+ /*
+ * If the stack and lwp can be reused, mark the thread as such.
+ * When we get to reapq_add() from resume_from_zombie(), these
+ * threads will go onto lwp_deathrow instead of thread_deathrow.
+ */
+ if (!CLASS_KERNEL(cid) && stksize == lwp_default_stksize)
+ t->t_flag |= T_LWPREUSE;
+
if (lwp == NULL)
lwp = kmem_cache_alloc(lwp_cache, KM_SLEEP);
bzero(lwp, sizeof (*lwp));