Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/kern/sys_sched.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/kern/sys_sched.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.15 retrieving revision 1.15.6.2 diff -u -p -r1.15 -r1.15.6.2 --- src/sys/kern/sys_sched.c 2008/02/19 19:38:18 1.15 +++ src/sys/kern/sys_sched.c 2008/06/02 13:24:12 1.15.6.2 @@ -1,4 +1,4 @@ -/* $NetBSD: sys_sched.c,v 1.15 2008/02/19 19:38:18 drochner Exp $ */ +/* $NetBSD: sys_sched.c,v 1.15.6.2 2008/06/02 13:24:12 mjf Exp $ */ /* * Copyright (c) 2008, Mindaugas Rasiukevicius @@ -13,27 +13,29 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ /* + * System calls relating to the scheduler. + * * TODO: * - Handle pthread_setschedprio() as defined by POSIX; * - Handle sched_yield() case for SCHED_FIFO as defined by POSIX; */ #include -__KERNEL_RCSID(0, "$NetBSD: sys_sched.c,v 1.15 2008/02/19 19:38:18 drochner Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sys_sched.c,v 1.15.6.2 2008/06/02 13:24:12 mjf Exp $"); #include @@ -83,7 +85,7 @@ convert_pri(lwp_t *l, int policy, pri_t /* Change the current priority to the appropriate range */ if (l->l_class == SCHED_OTHER) { KASSERT(policy == SCHED_FIFO || policy == SCHED_RR); - return l->l_priority + delta; + return delta; } if (policy == SCHED_OTHER) { KASSERT(l->l_class == SCHED_FIFO || l->l_class == SCHED_RR); @@ -93,35 +95,19 @@ convert_pri(lwp_t *l, int policy, pri_t return l->l_class; } -/* - * Set scheduling parameters. - */ int -sys__sched_setparam(struct lwp *l, const struct sys__sched_setparam_args *uap, - register_t *retval) +do_sched_setparam(pid_t pid, lwpid_t lid, int policy, + const struct sched_param *params) { - /* { - syscallarg(pid_t) pid; - syscallarg(lwpid_t) lid; - syscallarg(int) policy; - syscallarg(const struct sched_param *) params; - } */ - struct sched_param param; struct proc *p; struct lwp *t; - lwpid_t lid; - u_int lcnt; - int policy; pri_t pri; + u_int lcnt; int error; - /* Get the parameters from the user-space */ - error = copyin(SCARG(uap, params), ¶m, sizeof(param)); - if (error) { - return error; - } - pri = param.sched_priority; - policy = SCARG(uap, policy); + error = 0; + + pri = params->sched_priority; /* If no parameters specified, just return (this should not happen) */ if (pri == PRI_NONE && policy == SCHED_NONE) @@ -135,27 +121,29 @@ sys__sched_setparam(struct lwp *l, const if (pri != PRI_NONE && (pri < SCHED_PRI_MIN || pri > SCHED_PRI_MAX)) return EINVAL; - if (SCARG(uap, pid) != 0) { + if (pid != 0) { /* Find the process */ - p = p_find(SCARG(uap, pid), PFIND_UNLOCK_FAIL); - if (p == NULL) + mutex_enter(proc_lock); + p = p_find(pid, PFIND_LOCKED); + if (p == NULL) { + mutex_exit(proc_lock); return ESRCH; - mutex_enter(&p->p_smutex); - mutex_exit(&proclist_lock); + } + mutex_enter(p->p_lock); + mutex_exit(proc_lock); /* Disallow modification of system processes */ - if (p->p_flag & PK_SYSTEM) { - mutex_exit(&p->p_smutex); + if ((p->p_flag & PK_SYSTEM) != 0) { + mutex_exit(p->p_lock); return EPERM; } } else { /* Use the calling process */ - p = l->l_proc; - mutex_enter(&p->p_smutex); + p = curlwp->l_proc; + mutex_enter(p->p_lock); } /* Find the LWP(s) */ lcnt = 0; - lid = SCARG(uap, lid); LIST_FOREACH(t, &p->p_lwps, l_sibling) { pri_t kpri; int lpolicy; @@ -178,7 +166,7 @@ sys__sched_setparam(struct lwp *l, const kpri = convert_pri(t, lpolicy, pri); /* Check the permission */ - error = kauth_authorize_process(l->l_cred, + error = kauth_authorize_process(kauth_cred_get(), KAUTH_PROCESS_SCHEDULER_SETPARAM, p, t, KAUTH_ARG(lpolicy), KAUTH_ARG(kpri)); if (error) { @@ -196,74 +184,111 @@ sys__sched_setparam(struct lwp *l, const lwp_unlock(t); } - mutex_exit(&p->p_smutex); + mutex_exit(p->p_lock); return (lcnt == 0) ? ESRCH : error; } /* - * Get scheduling parameters. + * Set scheduling parameters. */ int -sys__sched_getparam(struct lwp *l, const struct sys__sched_getparam_args *uap, +sys__sched_setparam(struct lwp *l, const struct sys__sched_setparam_args *uap, register_t *retval) { /* { syscallarg(pid_t) pid; syscallarg(lwpid_t) lid; - syscallarg(int *) policy; - syscallarg(struct sched_param *) params; + syscallarg(int) policy; + syscallarg(const struct sched_param *) params; } */ - struct sched_param param; - struct lwp *t; - lwpid_t lid; - int error, policy; + struct sched_param params; + int error; - /* If not specified, use the first LWP */ - lid = SCARG(uap, lid) == 0 ? 1 : SCARG(uap, lid); + /* Get the parameters from the user-space */ + error = copyin(SCARG(uap, params), ¶ms, sizeof(params)); + if (error) + goto out; - if (SCARG(uap, pid) != 0) { - /* Locks the LWP */ - t = lwp_find2(SCARG(uap, pid), lid); - } else { - struct proc *p = l->l_proc; - /* Use the calling process */ - mutex_enter(&p->p_smutex); - t = lwp_find(p, lid); - if (t != NULL) - lwp_lock(t); - mutex_exit(&p->p_smutex); - } - if (t == NULL) { - error = ESRCH; - goto error; - } + error = do_sched_setparam(SCARG(uap, pid), SCARG(uap, lid), + SCARG(uap, policy), ¶ms); + + out: + return (error); +} + +int +do_sched_getparam(pid_t pid, lwpid_t lid, int *policy, + struct sched_param *params) +{ + struct sched_param lparams; + struct lwp *t; + int error, lpolicy; + + /* Locks the LWP */ + t = lwp_find2(pid, lid); + if (t == NULL) + return ESRCH; /* Check the permission */ - error = kauth_authorize_process(l->l_cred, + error = kauth_authorize_process(kauth_cred_get(), KAUTH_PROCESS_SCHEDULER_GETPARAM, t->l_proc, NULL, NULL, NULL); if (error != 0) { - lwp_unlock(t); - goto error; + mutex_exit(t->l_proc->p_lock); + return error; } - param.sched_priority = t->l_priority; - policy = t->l_class; - lwp_unlock(t); + lwp_lock(t); + lparams.sched_priority = t->l_priority; + lpolicy = t->l_class; - switch (policy) { + switch (lpolicy) { case SCHED_OTHER: - param.sched_priority -= PRI_USER; + lparams.sched_priority -= PRI_USER; break; case SCHED_RR: case SCHED_FIFO: - param.sched_priority -= PRI_USER_RT; + lparams.sched_priority -= PRI_USER_RT; break; } - error = copyout(¶m, SCARG(uap, params), sizeof(param)); + + if (policy != NULL) + *policy = lpolicy; + + if (params != NULL) + *params = lparams; + + lwp_unlock(t); + mutex_exit(t->l_proc->p_lock); + return error; +} + +/* + * Get scheduling parameters. + */ +int +sys__sched_getparam(struct lwp *l, const struct sys__sched_getparam_args *uap, + register_t *retval) +{ + /* { + syscallarg(pid_t) pid; + syscallarg(lwpid_t) lid; + syscallarg(int *) policy; + syscallarg(struct sched_param *) params; + } */ + struct sched_param params; + int error, policy; + + error = do_sched_getparam(SCARG(uap, pid), SCARG(uap, lid), &policy, + ¶ms); + if (error) + goto out; + + error = copyout(¶ms, SCARG(uap, params), sizeof(params)); if (error == 0 && SCARG(uap, policy) != NULL) error = copyout(&policy, SCARG(uap, policy), sizeof(int)); -error: - return error; + + out: + return (error); } /* @@ -307,32 +332,34 @@ sys__sched_setaffinity(struct lwp *l, if (SCARG(uap, pid) != 0) { /* Find the process */ - p = p_find(SCARG(uap, pid), PFIND_UNLOCK_FAIL); + mutex_enter(proc_lock); + p = p_find(SCARG(uap, pid), PFIND_LOCKED); if (p == NULL) { + mutex_exit(proc_lock); error = ESRCH; goto error; } - mutex_enter(&p->p_smutex); - mutex_exit(&proclist_lock); + mutex_enter(p->p_lock); + mutex_exit(proc_lock); + /* Disallow modification of system processes. */ + if ((p->p_flag & PK_SYSTEM) != 0) { + mutex_exit(p->p_lock); + error = EPERM; + goto error; + } } else { /* Use the calling process */ p = l->l_proc; - mutex_enter(&p->p_smutex); + mutex_enter(p->p_lock); } /* * Check the permission. - * Disallow modification of system processes. */ error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_SCHEDULER_SETAFFINITY, p, NULL, NULL, NULL); if (error != 0) { - mutex_exit(&p->p_smutex); - goto error; - } - if ((p->p_flag & PK_SYSTEM) != 0) { - mutex_exit(&p->p_smutex); - error = EPERM; + mutex_exit(p->p_lock); goto error; } @@ -356,7 +383,7 @@ sys__sched_setaffinity(struct lwp *l, } lcnt++; } - mutex_exit(&p->p_smutex); + mutex_exit(p->p_lock); if (lcnt == 0) error = ESRCH; error: @@ -380,28 +407,14 @@ sys__sched_getaffinity(struct lwp *l, } */ struct lwp *t; void *cpuset; - lwpid_t lid; int error; if (SCARG(uap, size) <= 0) return EINVAL; cpuset = kmem_zalloc(sizeof(cpuset_t), KM_SLEEP); - /* If not specified, use the first LWP */ - lid = SCARG(uap, lid) == 0 ? 1 : SCARG(uap, lid); - - if (SCARG(uap, pid) != 0) { - /* Locks the LWP */ - t = lwp_find2(SCARG(uap, pid), lid); - } else { - struct proc *p = l->l_proc; - /* Use the calling process */ - mutex_enter(&p->p_smutex); - t = lwp_find(p, lid); - if (t != NULL) - lwp_lock(t); - mutex_exit(&p->p_smutex); - } + /* Locks the LWP */ + t = lwp_find2(SCARG(uap, pid), SCARG(uap, lid)); if (t == NULL) { kmem_free(cpuset, sizeof(cpuset_t)); return ESRCH; @@ -409,13 +422,15 @@ sys__sched_getaffinity(struct lwp *l, /* Check the permission */ if (kauth_authorize_process(l->l_cred, KAUTH_PROCESS_SCHEDULER_GETAFFINITY, t->l_proc, NULL, NULL, NULL)) { - lwp_unlock(t); + mutex_exit(t->l_proc->p_lock); kmem_free(cpuset, sizeof(cpuset_t)); return EPERM; } + lwp_lock(t); if (t->l_flag & LW_AFFINITY) memcpy(cpuset, &t->l_affinity, sizeof(cpuset_t)); lwp_unlock(t); + mutex_exit(t->l_proc->p_lock); error = copyout(cpuset, SCARG(uap, cpuset), min(SCARG(uap, size), sizeof(cpuset_t))); @@ -474,7 +489,7 @@ SYSCTL_SETUP(sysctl_sched_setup, "sysctl sysctl_createv(clog, 0, &node, NULL, CTLFLAG_PERMANENT | CTLFLAG_IMMEDIATE, CTLTYPE_INT, "pri_max", - SYSCTL_DESCR("Minimal POSIX real-time priority"), + SYSCTL_DESCR("Maximal POSIX real-time priority"), NULL, SCHED_PRI_MAX, NULL, 0, CTL_CREATE, CTL_EOL); }