summaryrefslogtreecommitdiff
path: root/usr/src/uts/common
diff options
context:
space:
mode:
authorSurya Prakki <Surya.Prakki@Sun.COM>2009-07-15 00:07:13 -0700
committerSurya Prakki <Surya.Prakki@Sun.COM>2009-07-15 00:07:13 -0700
commitfb9b0aa8c76ff829a7069d38161a2cecc656b091 (patch)
treee37522fcc8f760240b049c073ab359eaf817c2e6 /usr/src/uts/common
parentc946faca5d4627284fb79c6b04e652b471034495 (diff)
downloadillumos-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.h7
-rw-r--r--usr/src/uts/common/syscall/pset.c63
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));