diff options
author | Surya Prakki <Surya.Prakki@Sun.COM> | 2009-07-15 00:07:13 -0700 |
---|---|---|
committer | Surya Prakki <Surya.Prakki@Sun.COM> | 2009-07-15 00:07:13 -0700 |
commit | fb9b0aa8c76ff829a7069d38161a2cecc656b091 (patch) | |
tree | e37522fcc8f760240b049c073ab359eaf817c2e6 /usr/src/uts/common | |
parent | c946faca5d4627284fb79c6b04e652b471034495 (diff) | |
download | illumos-joyent-fb9b0aa8c76ff829a7069d38161a2cecc656b091.tar.gz |
6757037 Zone-spawned LWP needs to be able to run on a processor set
Diffstat (limited to 'usr/src/uts/common')
-rw-r--r-- | usr/src/uts/common/sys/pset.h | 7 | ||||
-rw-r--r-- | usr/src/uts/common/syscall/pset.c | 63 |
2 files changed, 67 insertions, 3 deletions
diff --git a/usr/src/uts/common/sys/pset.h b/usr/src/uts/common/sys/pset.h index f98e327620..bf6562bb4e 100644 --- a/usr/src/uts/common/sys/pset.h +++ b/usr/src/uts/common/sys/pset.h @@ -19,15 +19,13 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_PSET_H #define _SYS_PSET_H -#pragma ident "%Z%%M% %I% %E% SMI" - #ifdef __cplusplus extern "C" { #endif @@ -60,6 +58,7 @@ extern int pset_destroy(psetid_t); extern int pset_assign(psetid_t, processorid_t, psetid_t *); extern int pset_info(psetid_t, int *, uint_t *, processorid_t *); extern int pset_bind(psetid_t, idtype_t, id_t, psetid_t *); +extern int pset_bind_lwp(psetid_t, id_t, pid_t, psetid_t *); extern int pset_getloadavg(psetid_t, double [], int); extern int pset_list(psetid_t *, uint_t *); extern int pset_setattr(psetid_t, uint_t); @@ -72,6 +71,7 @@ extern int pset_destroy(); extern int pset_assign(); extern int pset_info(); extern int pset_bind(); +extern int pset_bind_lwp(); extern int pset_getloadavg(); extern int pset_list(); extern int pset_setattr(); @@ -93,6 +93,7 @@ extern int pset_getattr(); #define PSET_SETATTR 7 #define PSET_GETATTR 8 #define PSET_ASSIGN_FORCED 9 +#define PSET_BIND_LWP 10 /* attribute bits */ #define PSET_NOESCAPE 0x0001 diff --git a/usr/src/uts/common/syscall/pset.c b/usr/src/uts/common/syscall/pset.c index 4c1aef27c5..ce49082d4d 100644 --- a/usr/src/uts/common/syscall/pset.c +++ b/usr/src/uts/common/syscall/pset.c @@ -470,6 +470,66 @@ pset_bind_contract(cont_process_t *ctp, psetid_t pset, psetid_t *oldpset, return (error); } +/* + * Bind the lwp:id of process:pid to processor set: pset + */ +static int +pset_bind_lwp(psetid_t pset, id_t id, pid_t pid, psetid_t *opset) +{ + kthread_t *tp; + proc_t *pp; + psetid_t oldpset; + void *projbuf, *zonebuf; + int error = 0; + + pool_lock(); + mutex_enter(&cpu_lock); + projbuf = fss_allocbuf(FSS_NPROJ_BUF, FSS_ALLOC_PROJ); + zonebuf = fss_allocbuf(FSS_NPROJ_BUF, FSS_ALLOC_ZONE); + + mutex_enter(&pidlock); + if ((pid == P_MYID && id == P_MYID) || + (pid == curproc->p_pid && id == P_MYID)) { + pp = curproc; + tp = curthread; + mutex_enter(&pp->p_lock); + } else { + if (pid == P_MYID) { + pp = curproc; + } else if ((pp = prfind(pid)) == NULL) { + error = ESRCH; + goto err; + } + if (pp != curproc && id == P_MYID) { + error = EINVAL; + goto err; + } + mutex_enter(&pp->p_lock); + if ((tp = idtot(pp, id)) == NULL) { + mutex_exit(&pp->p_lock); + error = ESRCH; + goto err; + } + } + + error = pset_bind_thread(tp, pset, &oldpset, projbuf, zonebuf); + mutex_exit(&pp->p_lock); +err: + mutex_exit(&pidlock); + + fss_freebuf(projbuf, FSS_ALLOC_PROJ); + fss_freebuf(zonebuf, FSS_ALLOC_ZONE); + mutex_exit(&cpu_lock); + pool_unlock(); + if (opset != NULL) { + if (copyout(&oldpset, opset, sizeof (psetid_t)) != 0) + return (set_errno(EFAULT)); + } + if (error != 0) + return (set_errno(error)); + return (0); +} + static int pset_bind(psetid_t pset, idtype_t idtype, id_t id, psetid_t *opset) { @@ -797,6 +857,9 @@ pset(int subcode, long arg1, long arg2, long arg3, long arg4) case PSET_BIND: return (pset_bind((psetid_t)arg1, (idtype_t)arg2, (id_t)arg3, (psetid_t *)arg4)); + case PSET_BIND_LWP: + return (pset_bind_lwp((psetid_t)arg1, (id_t)arg2, + (pid_t)arg3, (psetid_t *)arg4)); case PSET_GETLOADAVG: return (pset_getloadavg((psetid_t)arg1, (int *)arg2, (int)arg3)); |