diff options
author | Jonathan Adams <Jonathan.Adams@Sun.COM> | 2009-11-23 15:29:44 -0800 |
---|---|---|
committer | Jonathan Adams <Jonathan.Adams@Sun.COM> | 2009-11-23 15:29:44 -0800 |
commit | 35a5a3587fd94b666239c157d3722745250ccbd7 (patch) | |
tree | 5b1d8a35d4b4129747989cd4857cdd21d5a223aa /usr/src/uts/common/os/lwp.c | |
parent | 023e71de9e5670cebc23dd51162833661d3d2d3b (diff) | |
download | illumos-gate-35a5a3587fd94b666239c157d3722745250ccbd7.tar.gz |
6881015 ZFS write activity prevents other threads from running in a timely manner
6899867 mstate_thread_onproc_time() doesn't account for runnable time correctly
PSARC/2009/615 System Duty Cycle Scheduling Class and ZFS IO Observability
Diffstat (limited to 'usr/src/uts/common/os/lwp.c')
-rw-r--r-- | usr/src/uts/common/os/lwp.c | 64 |
1 files changed, 55 insertions, 9 deletions
diff --git a/usr/src/uts/common/os/lwp.c b/usr/src/uts/common/os/lwp.c index 45eaff29ef..1bb5b36828 100644 --- a/usr/src/uts/common/os/lwp.c +++ b/usr/src/uts/common/os/lwp.c @@ -68,6 +68,24 @@ extern void reapq_move_lq_to_tq(kthread_t *); extern void freectx_ctx(struct ctxop *); /* + * Create a kernel thread associated with a particular system process. Give + * it an LWP so that microstate accounting will be available for it. + */ +kthread_t * +lwp_kernel_create(proc_t *p, void (*proc)(), void *arg, int state, pri_t pri) +{ + klwp_t *lwp; + + VERIFY((p->p_flag & SSYS) != 0); + + lwp = lwp_create(proc, arg, 0, p, state, pri, &t0.t_hold, syscid, 0); + + VERIFY(lwp != NULL); + + return (lwptot(lwp)); +} + +/* * Create a thread that appears to be stopped at sys_rtt. */ klwp_t * @@ -84,7 +102,7 @@ lwp_create(void (*proc)(), caddr_t arg, size_t len, proc_t *p, int err = 0; kproject_t *oldkpj, *newkpj; void *bufp = NULL; - klwp_t *curlwp = ttolwp(curthread); + klwp_t *curlwp; lwpent_t *lep; lwpdir_t *old_dir = NULL; uint_t old_dirsz = 0; @@ -96,12 +114,16 @@ lwp_create(void (*proc)(), caddr_t arg, size_t len, proc_t *p, boolean_t branded = 0; struct ctxop *ctx = NULL; + ASSERT(cid != sysdccid); /* system threads must start in SYS */ + + ASSERT(p != &p0); /* No new LWPs in p0. */ + mutex_enter(&p->p_lock); mutex_enter(&p->p_zone->zone_nlwps_lock); /* * don't enforce rctl limits on system processes */ - if (cid != syscid) { + if (!CLASS_KERNEL(cid)) { if (p->p_task->tk_nlwps >= p->p_task->tk_nlwps_ctl) if (rctl_test(rc_task_lwps, p->p_task->tk_rctls, p, 1, 0) & RCT_DENY) @@ -128,13 +150,26 @@ 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 (curlwp == NULL || (stksize = curlwp->lwp_childstksz) == 0) + if (CLASS_KERNEL(cid)) { + curlwp = NULL; /* don't inherit from curlwp */ stksize = lwp_default_stksize; + } else { + curlwp = ttolwp(curthread); + if (curlwp == NULL || (stksize = curlwp->lwp_childstksz) == 0) + stksize = lwp_default_stksize; + } /* - * Try to reclaim a <lwp,stack> from 'deathrow' + * 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 (stksize == lwp_default_stksize) { + if (CLASS_KERNEL(cid)) { + lwpdata = (caddr_t)segkp_get(segkp, stksize, + (KPD_NO_ANON | KPD_HASREDZONE | KPD_LOCKED)); + + } else if (stksize == lwp_default_stksize) { if (lwp_reapcnt > 0) { mutex_enter(&reaplock); if ((t = lwp_deathrow) != NULL) { @@ -434,11 +469,15 @@ grow: kpreempt_disable(); /* can't grab cpu_lock here */ /* - * Inherit processor and processor set bindings from curthread, - * unless we're creating a new kernel process, in which case - * clear all bindings. + * Inherit processor and processor set bindings from curthread. + * + * For kernel LWPs, we do not inherit processor set bindings at + * process creation time (i.e. when p != curproc). After the + * kernel process is created, any subsequent LWPs must be created + * by threads in the kernel process, at which point we *will* + * inherit processor set bindings. */ - if (cid == syscid) { + if (CLASS_KERNEL(cid) && p != curproc) { t->t_bind_cpu = binding = PBIND_NONE; t->t_cpupart = oldpart = &cp_default; t->t_bind_pset = PS_NONE; @@ -658,6 +697,13 @@ grow: error: if (err) { + if (CLASS_KERNEL(cid)) { + /* + * This should only happen if a system process runs + * out of lwpids, which shouldn't occur. + */ + panic("Failed to create a system LWP"); + } /* * We have failed to create an lwp, so decrement the number * of lwps in the task and let the lgroup load averages know |