sched_setparam: fix the case when incorrect (according to the class)
in-kernel priority is used. Reported by <drochner>. Minor fixes for scheduling calls to conform the POSIX: - If pid is equal to zero, use the calling process; - In case of permission problem, return EPERM instead of EACESS; - sched_setscheduler() should return previously used policy; - pthread_* calls should return the error code or zero; Should fix the namespace problems (and builds of some packages): - Move cpuset_t defintion from pset.h to sched.h; - Remove the #include of pset.h in pthread.h;
This commit is contained in:
parent
ef515ac1dc
commit
b5e9addd22
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: sysconf.c,v 1.26 2008/01/15 03:37:14 rmind Exp $ */
|
/* $NetBSD: sysconf.c,v 1.27 2008/01/26 17:55:30 rmind Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1993
|
* Copyright (c) 1993
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
#if 0
|
#if 0
|
||||||
static char sccsid[] = "@(#)sysconf.c 8.2 (Berkeley) 3/20/94";
|
static char sccsid[] = "@(#)sysconf.c 8.2 (Berkeley) 3/20/94";
|
||||||
#else
|
#else
|
||||||
__RCSID("$NetBSD: sysconf.c,v 1.26 2008/01/15 03:37:14 rmind Exp $");
|
__RCSID("$NetBSD: sysconf.c,v 1.27 2008/01/26 17:55:30 rmind Exp $");
|
||||||
#endif
|
#endif
|
||||||
#endif /* LIBC_SCCS and not lint */
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
|
||||||
|
@ -357,7 +357,7 @@ yesno: if (sysctl(mib, mib_len, &value, &len, NULL, 0) == -1)
|
||||||
|
|
||||||
/* Native */
|
/* Native */
|
||||||
case _SC_SCHED_RT_TS:
|
case _SC_SCHED_RT_TS:
|
||||||
if (sysctlgetmibinfo("kern.sched.rt_ts", &mib[0], &mib_len,
|
if (sysctlgetmibinfo("kern.sched.rtts", &mib[0], &mib_len,
|
||||||
NULL, NULL, NULL, SYSCTL_VERSION))
|
NULL, NULL, NULL, SYSCTL_VERSION))
|
||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: pthread.h,v 1.27 2008/01/19 16:05:34 christos Exp $ */
|
/* $NetBSD: pthread.h,v 1.28 2008/01/26 17:55:30 rmind Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||||
|
@ -44,9 +44,6 @@
|
||||||
#include <time.h> /* For timespec */
|
#include <time.h> /* For timespec */
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <sys/featuretest.h>
|
#include <sys/featuretest.h>
|
||||||
#ifdef _NETBSD_SOURCE
|
|
||||||
#include <sys/pset.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <pthread_types.h>
|
#include <pthread_types.h>
|
||||||
|
|
||||||
|
@ -190,13 +187,14 @@ int pthread_barrierattr_destroy(pthread_barrierattr_t *);
|
||||||
int pthread_getschedparam(pthread_t, int * __restrict,
|
int pthread_getschedparam(pthread_t, int * __restrict,
|
||||||
struct sched_param * __restrict);
|
struct sched_param * __restrict);
|
||||||
int pthread_setschedparam(pthread_t, int, const struct sched_param *);
|
int pthread_setschedparam(pthread_t, int, const struct sched_param *);
|
||||||
int pthread_getaffinity_np(pthread_t, size_t, cpuset_t *);
|
|
||||||
int pthread_setaffinity_np(pthread_t, size_t, cpuset_t *);
|
|
||||||
int pthread_setschedprio(pthread_t, int);
|
int pthread_setschedprio(pthread_t, int);
|
||||||
|
|
||||||
int *pthread__errno(void);
|
int *pthread__errno(void);
|
||||||
|
|
||||||
#if defined(_NETBSD_SOURCE)
|
#if defined(_NETBSD_SOURCE)
|
||||||
|
int pthread_getaffinity_np(pthread_t, size_t, cpuset_t *);
|
||||||
|
int pthread_setaffinity_np(pthread_t, size_t, cpuset_t *);
|
||||||
|
|
||||||
int pthread_mutex_held_np(pthread_mutex_t *);
|
int pthread_mutex_held_np(pthread_mutex_t *);
|
||||||
pthread_t pthread_mutex_owner_np(pthread_mutex_t *);
|
pthread_t pthread_mutex_owner_np(pthread_mutex_t *);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: pthread_misc.c,v 1.4 2008/01/15 03:37:14 rmind Exp $ */
|
/* $NetBSD: pthread_misc.c,v 1.5 2008/01/26 17:55:30 rmind Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
|
* Copyright (c) 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__RCSID("$NetBSD: pthread_misc.c,v 1.4 2008/01/15 03:37:14 rmind Exp $");
|
__RCSID("$NetBSD: pthread_misc.c,v 1.5 2008/01/26 17:55:30 rmind Exp $");
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -68,15 +68,15 @@ __strong_alias(__libc_thr_yield,pthread__sched_yield)
|
||||||
int
|
int
|
||||||
pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param)
|
pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param)
|
||||||
{
|
{
|
||||||
int error;
|
|
||||||
|
|
||||||
if (pthread__find(thread) != 0)
|
if (pthread__find(thread) != 0)
|
||||||
return ESRCH;
|
return ESRCH;
|
||||||
|
|
||||||
error = _sched_getparam(getpid(), thread->pt_lid, param);
|
if (_sched_getparam(getpid(), thread->pt_lid, param) < 0)
|
||||||
if (error == 0)
|
return errno;
|
||||||
*policy = param->sched_class;
|
|
||||||
return error;
|
*policy = param->sched_class;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -90,7 +90,10 @@ pthread_setschedparam(pthread_t thread, int policy,
|
||||||
|
|
||||||
memcpy(&sp, param, sizeof(struct sched_param));
|
memcpy(&sp, param, sizeof(struct sched_param));
|
||||||
sp.sched_class = policy;
|
sp.sched_class = policy;
|
||||||
return _sched_setparam(getpid(), thread->pt_lid, &sp);
|
if (_sched_setparam(getpid(), thread->pt_lid, &sp) < 0)
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -100,7 +103,10 @@ pthread_getaffinity_np(pthread_t thread, size_t size, cpuset_t *cpuset)
|
||||||
if (pthread__find(thread) != 0)
|
if (pthread__find(thread) != 0)
|
||||||
return ESRCH;
|
return ESRCH;
|
||||||
|
|
||||||
return _sched_getaffinity(getpid(), thread->pt_lid, size, cpuset);
|
if (_sched_getaffinity(getpid(), thread->pt_lid, size, cpuset) < 0)
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -110,7 +116,10 @@ pthread_setaffinity_np(pthread_t thread, size_t size, cpuset_t *cpuset)
|
||||||
if (pthread__find(thread) != 0)
|
if (pthread__find(thread) != 0)
|
||||||
return ESRCH;
|
return ESRCH;
|
||||||
|
|
||||||
return _sched_setaffinity(getpid(), thread->pt_lid, size, cpuset);
|
if (_sched_setaffinity(getpid(), thread->pt_lid, size, cpuset) < 0)
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -123,7 +132,10 @@ pthread_setschedprio(pthread_t thread, int prio)
|
||||||
|
|
||||||
sp.sched_class = SCHED_NONE;
|
sp.sched_class = SCHED_NONE;
|
||||||
sp.sched_priority = prio;
|
sp.sched_priority = prio;
|
||||||
return _sched_setparam(getpid(), thread->pt_lid, &sp);
|
if (_sched_setparam(getpid(), thread->pt_lid, &sp) < 0)
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: sched.c,v 1.1 2008/01/15 03:37:15 rmind Exp $ */
|
/* $NetBSD: sched.c,v 1.2 2008/01/26 17:55:30 rmind Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, Mindaugas Rasiukevicius <rmind at NetBSD org>
|
* Copyright (c) 2008, Mindaugas Rasiukevicius <rmind at NetBSD org>
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__RCSID("$NetBSD: sched.c,v 1.1 2008/01/15 03:37:15 rmind Exp $");
|
__RCSID("$NetBSD: sched.c,v 1.2 2008/01/26 17:55:30 rmind Exp $");
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -37,6 +37,9 @@ __RCSID("$NetBSD: sched.c,v 1.1 2008/01/15 03:37:15 rmind Exp $");
|
||||||
#include <sys/pset.h>
|
#include <sys/pset.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
/* All LWPs in the process */
|
||||||
|
#define P_ALL_LWPS 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scheduling parameters.
|
* Scheduling parameters.
|
||||||
*/
|
*/
|
||||||
|
@ -44,36 +47,51 @@ __RCSID("$NetBSD: sched.c,v 1.1 2008/01/15 03:37:15 rmind Exp $");
|
||||||
int
|
int
|
||||||
sched_setparam(pid_t pid, const struct sched_param *param)
|
sched_setparam(pid_t pid, const struct sched_param *param)
|
||||||
{
|
{
|
||||||
|
struct sched_param sp;
|
||||||
|
|
||||||
return _sched_setparam(pid, 0, param);
|
memset(&sp, 0, sizeof(struct sched_param));
|
||||||
|
sp.sched_priority = param->sched_priority;
|
||||||
|
sp.sched_class = SCHED_NONE;
|
||||||
|
return _sched_setparam(pid, P_ALL_LWPS, &sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sched_getparam(pid_t pid, struct sched_param *param)
|
sched_getparam(pid_t pid, struct sched_param *param)
|
||||||
{
|
{
|
||||||
|
|
||||||
return _sched_getparam(pid, 0, param);
|
return _sched_getparam(pid, P_ALL_LWPS, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sched_setscheduler(pid_t pid, int policy, const struct sched_param *param)
|
sched_setscheduler(pid_t pid, int policy, const struct sched_param *param)
|
||||||
{
|
{
|
||||||
struct sched_param sp;
|
struct sched_param sp;
|
||||||
|
int ret, old_policy;
|
||||||
|
|
||||||
memcpy(&sp, param, sizeof(struct sched_param));
|
ret = _sched_getparam(pid, P_ALL_LWPS, &sp);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
old_policy = sp.sched_class;
|
||||||
|
|
||||||
|
memset(&sp, 0, sizeof(struct sched_param));
|
||||||
|
sp.sched_priority = param->sched_priority;
|
||||||
sp.sched_class = policy;
|
sp.sched_class = policy;
|
||||||
return _sched_setparam(pid, 0, &sp);
|
ret = _sched_setparam(pid, P_ALL_LWPS, &sp);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return old_policy;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sched_getscheduler(pid_t pid)
|
sched_getscheduler(pid_t pid)
|
||||||
{
|
{
|
||||||
struct sched_param sp;
|
struct sched_param sp;
|
||||||
int error;
|
int ret;
|
||||||
|
|
||||||
error = _sched_getparam(pid, 0, &sp);
|
ret = _sched_getparam(pid, P_ALL_LWPS, &sp);
|
||||||
if (error)
|
if (ret < 0)
|
||||||
return error;
|
return ret;
|
||||||
|
|
||||||
return sp.sched_class;
|
return sp.sched_class;
|
||||||
}
|
}
|
||||||
|
@ -86,6 +104,10 @@ int
|
||||||
sched_get_priority_max(int policy)
|
sched_get_priority_max(int policy)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (policy < SCHED_OTHER || policy > SCHED_RR) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return sysconf(_SC_SCHED_PRI_MAX);
|
return sysconf(_SC_SCHED_PRI_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,6 +115,10 @@ int
|
||||||
sched_get_priority_min(int policy)
|
sched_get_priority_min(int policy)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (policy < SCHED_OTHER || policy > SCHED_RR) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return sysconf(_SC_SCHED_PRI_MIN);
|
return sysconf(_SC_SCHED_PRI_MIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,5 +139,5 @@ int
|
||||||
pset_bind(psetid_t psid, idtype_t idtype, id_t id, psetid_t *opsid)
|
pset_bind(psetid_t psid, idtype_t idtype, id_t id, psetid_t *opsid)
|
||||||
{
|
{
|
||||||
|
|
||||||
return _pset_bind(idtype, id, 0, psid, opsid);
|
return _pset_bind(idtype, id, P_ALL_LWPS, psid, opsid);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: sys_sched.c,v 1.6 2008/01/24 14:41:12 rmind Exp $ */
|
/* $NetBSD: sys_sched.c,v 1.7 2008/01/26 17:55:29 rmind Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, Mindaugas Rasiukevicius <rmind at NetBSD org>
|
* Copyright (c) 2008, Mindaugas Rasiukevicius <rmind at NetBSD org>
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: sys_sched.c,v 1.6 2008/01/24 14:41:12 rmind Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: sys_sched.c,v 1.7 2008/01/26 17:55:29 rmind Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
|
||||||
|
@ -51,6 +51,51 @@ __KERNEL_RCSID(0, "$NetBSD: sys_sched.c,v 1.6 2008/01/24 14:41:12 rmind Exp $");
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/unistd.h>
|
#include <sys/unistd.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert user priority or the in-kernel priority or convert the current
|
||||||
|
* priority to the appropriate range according to the policy change.
|
||||||
|
*/
|
||||||
|
static pri_t
|
||||||
|
convert_pri(lwp_t *l, int policy, pri_t pri)
|
||||||
|
{
|
||||||
|
int delta = 0;
|
||||||
|
|
||||||
|
if (policy == SCHED_NONE)
|
||||||
|
policy = l->l_class;
|
||||||
|
|
||||||
|
switch (policy) {
|
||||||
|
case SCHED_OTHER:
|
||||||
|
delta = PRI_USER;
|
||||||
|
break;
|
||||||
|
case SCHED_FIFO:
|
||||||
|
case SCHED_RR:
|
||||||
|
delta = PRI_USER_RT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
panic("upri_to_kpri");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pri != PRI_NONE) {
|
||||||
|
/* Convert user priority to the in-kernel */
|
||||||
|
KASSERT(pri >= SCHED_PRI_MIN && pri <= SCHED_PRI_MAX);
|
||||||
|
return pri + delta;
|
||||||
|
}
|
||||||
|
if (l->l_class == policy)
|
||||||
|
return l->l_priority;
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
if (policy == SCHED_OTHER) {
|
||||||
|
KASSERT(l->l_class == SCHED_FIFO || l->l_class == SCHED_RR);
|
||||||
|
return l->l_priority - delta;
|
||||||
|
}
|
||||||
|
KASSERT(l->l_class != SCHED_OTHER && policy != SCHED_OTHER);
|
||||||
|
return l->l_class;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set scheduling parameters.
|
* Set scheduling parameters.
|
||||||
*/
|
*/
|
||||||
|
@ -66,103 +111,87 @@ sys__sched_setparam(struct lwp *l, const struct sys__sched_setparam_args *uap,
|
||||||
struct sched_param *sp;
|
struct sched_param *sp;
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
struct lwp *t;
|
struct lwp *t;
|
||||||
pid_t pid;
|
|
||||||
lwpid_t lid;
|
lwpid_t lid;
|
||||||
u_int lcnt;
|
u_int lcnt;
|
||||||
|
int policy;
|
||||||
pri_t pri;
|
pri_t pri;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
/* Available only for super-user */
|
/* Available only for super-user */
|
||||||
if (kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER, NULL))
|
if (kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER, NULL))
|
||||||
return EACCES;
|
return EPERM;
|
||||||
|
|
||||||
/* Get the parameters from the user-space */
|
/* Get the parameters from the user-space */
|
||||||
sp = kmem_zalloc(sizeof(struct sched_param), KM_SLEEP);
|
sp = kmem_zalloc(sizeof(struct sched_param), KM_SLEEP);
|
||||||
error = copyin(SCARG(uap, params), sp, sizeof(struct sched_param));
|
error = copyin(SCARG(uap, params), sp, sizeof(struct sched_param));
|
||||||
if (error)
|
if (error) {
|
||||||
goto error;
|
kmem_free(sp, sizeof(struct sched_param));
|
||||||
|
return error;
|
||||||
/*
|
}
|
||||||
* Validate scheduling class and priority.
|
|
||||||
* Convert the user priority to the in-kernel value.
|
|
||||||
*/
|
|
||||||
pri = sp->sched_priority;
|
pri = sp->sched_priority;
|
||||||
if (pri != PRI_NONE && (pri < SCHED_PRI_MIN || pri > SCHED_PRI_MAX)) {
|
policy = sp->sched_class;
|
||||||
error = EINVAL;
|
kmem_free(sp, sizeof(struct sched_param));
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
switch (sp->sched_class) {
|
|
||||||
case SCHED_OTHER:
|
|
||||||
if (pri == PRI_NONE)
|
|
||||||
pri = PRI_USER;
|
|
||||||
else
|
|
||||||
pri += PRI_USER;
|
|
||||||
break;
|
|
||||||
case SCHED_RR:
|
|
||||||
case SCHED_FIFO:
|
|
||||||
if (pri == PRI_NONE)
|
|
||||||
pri = PRI_USER_RT;
|
|
||||||
else
|
|
||||||
pri += PRI_USER_RT;
|
|
||||||
break;
|
|
||||||
case SCHED_NONE:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
error = EINVAL;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the process */
|
/* If no parameters specified, just return (this should not happen) */
|
||||||
pid = SCARG(uap, pid);
|
if (pri == PRI_NONE && policy == SCHED_NONE)
|
||||||
p = p_find(pid, PFIND_UNLOCK_FAIL);
|
return 0;
|
||||||
if (p == NULL) {
|
|
||||||
error = ESRCH;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
mutex_enter(&p->p_smutex);
|
|
||||||
mutex_exit(&proclist_lock);
|
|
||||||
|
|
||||||
/* Disallow modification of system processes */
|
/* Validate scheduling class */
|
||||||
if (p->p_flag & PK_SYSTEM) {
|
if (policy != SCHED_NONE && (policy < SCHED_OTHER || policy > SCHED_RR))
|
||||||
mutex_exit(&p->p_smutex);
|
return EINVAL;
|
||||||
error = EACCES;
|
|
||||||
goto error;
|
/* Validate priority */
|
||||||
|
if (pri != PRI_NONE && (pri < SCHED_PRI_MIN || pri > SCHED_PRI_MAX))
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
if (SCARG(uap, pid) != 0) {
|
||||||
|
/* Find the process */
|
||||||
|
p = p_find(SCARG(uap, pid), PFIND_UNLOCK_FAIL);
|
||||||
|
if (p == NULL)
|
||||||
|
return ESRCH;
|
||||||
|
mutex_enter(&p->p_smutex);
|
||||||
|
mutex_exit(&proclist_lock);
|
||||||
|
/* Disallow modification of system processes */
|
||||||
|
if (p->p_flag & PK_SYSTEM) {
|
||||||
|
mutex_exit(&p->p_smutex);
|
||||||
|
return EPERM;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Use the calling process */
|
||||||
|
p = l->l_proc;
|
||||||
|
mutex_enter(&p->p_smutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the LWP(s) */
|
/* Find the LWP(s) */
|
||||||
lcnt = 0;
|
lcnt = 0;
|
||||||
lid = SCARG(uap, lid);
|
lid = SCARG(uap, lid);
|
||||||
LIST_FOREACH(t, &p->p_lwps, l_sibling) {
|
LIST_FOREACH(t, &p->p_lwps, l_sibling) {
|
||||||
bool chpri;
|
pri_t kpri;
|
||||||
|
|
||||||
if (lid && lid != t->l_lid)
|
if (lid && lid != t->l_lid)
|
||||||
continue;
|
continue;
|
||||||
|
KASSERT(pri != PRI_NONE || policy != SCHED_NONE);
|
||||||
|
lwp_lock(t);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that, priority may need to be changed to get into
|
||||||
|
* the correct priority range of the new scheduling class.
|
||||||
|
*/
|
||||||
|
kpri = convert_pri(t, policy, pri);
|
||||||
|
|
||||||
/* Set the scheduling class */
|
/* Set the scheduling class */
|
||||||
lwp_lock(t);
|
if (policy != SCHED_NONE)
|
||||||
if (sp->sched_class != SCHED_NONE) {
|
t->l_class = policy;
|
||||||
/*
|
|
||||||
* Priority must be changed to get into the correct
|
|
||||||
* priority range of the new scheduling class.
|
|
||||||
*/
|
|
||||||
chpri = (t->l_class != sp->sched_class);
|
|
||||||
t->l_class = sp->sched_class;
|
|
||||||
} else
|
|
||||||
chpri = false;
|
|
||||||
|
|
||||||
/* Change the priority */
|
/* Change the priority */
|
||||||
if (sp->sched_priority != PRI_NONE || chpri)
|
if (t->l_priority != kpri)
|
||||||
lwp_changepri(t, pri);
|
lwp_changepri(t, kpri);
|
||||||
|
|
||||||
lwp_unlock(t);
|
lwp_unlock(t);
|
||||||
lcnt++;
|
lcnt++;
|
||||||
}
|
}
|
||||||
mutex_exit(&p->p_smutex);
|
mutex_exit(&p->p_smutex);
|
||||||
if (lcnt == 0)
|
return (lcnt == 0) ? ESRCH : error;
|
||||||
error = ESRCH;
|
|
||||||
error:
|
|
||||||
kmem_free(sp, sizeof(struct sched_param));
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -179,12 +208,26 @@ sys__sched_getparam(struct lwp *l, const struct sys__sched_getparam_args *uap,
|
||||||
} */
|
} */
|
||||||
struct sched_param *sp;
|
struct sched_param *sp;
|
||||||
struct lwp *t;
|
struct lwp *t;
|
||||||
|
lwpid_t lid;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
sp = kmem_zalloc(sizeof(struct sched_param), KM_SLEEP);
|
sp = kmem_zalloc(sizeof(struct sched_param), KM_SLEEP);
|
||||||
|
|
||||||
/* Locks the LWP */
|
/* If not specified, use the first LWP */
|
||||||
t = lwp_find2(SCARG(uap, pid), SCARG(uap, lid));
|
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);
|
||||||
|
}
|
||||||
if (t == NULL) {
|
if (t == NULL) {
|
||||||
kmem_free(sp, sizeof(struct sched_param));
|
kmem_free(sp, sizeof(struct sched_param));
|
||||||
return ESRCH;
|
return ESRCH;
|
||||||
|
@ -231,7 +274,7 @@ sys__sched_setaffinity(struct lwp *l,
|
||||||
|
|
||||||
/* Available only for super-user */
|
/* Available only for super-user */
|
||||||
if (kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER, NULL))
|
if (kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER, NULL))
|
||||||
return EACCES;
|
return EPERM;
|
||||||
|
|
||||||
if (SCARG(uap, size) <= 0)
|
if (SCARG(uap, size) <= 0)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
@ -253,19 +296,25 @@ sys__sched_setaffinity(struct lwp *l,
|
||||||
cpuset = NULL;
|
cpuset = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the process */
|
if (SCARG(uap, pid) != 0) {
|
||||||
p = p_find(SCARG(uap, pid), PFIND_UNLOCK_FAIL);
|
/* Find the process */
|
||||||
if (p == NULL) {
|
p = p_find(SCARG(uap, pid), PFIND_UNLOCK_FAIL);
|
||||||
error = ESRCH;
|
if (p == NULL) {
|
||||||
goto error;
|
error = ESRCH;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
mutex_enter(&p->p_smutex);
|
||||||
|
mutex_exit(&proclist_lock);
|
||||||
|
} else {
|
||||||
|
/* Use the calling process */
|
||||||
|
p = l->l_proc;
|
||||||
|
mutex_enter(&p->p_smutex);
|
||||||
}
|
}
|
||||||
mutex_enter(&p->p_smutex);
|
|
||||||
mutex_exit(&proclist_lock);
|
|
||||||
|
|
||||||
/* Disallow modification of system processes */
|
/* Disallow modification of system processes */
|
||||||
if (p->p_flag & PK_SYSTEM) {
|
if (p->p_flag & PK_SYSTEM) {
|
||||||
mutex_exit(&p->p_smutex);
|
mutex_exit(&p->p_smutex);
|
||||||
error = EACCES;
|
error = EPERM;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,6 +362,7 @@ sys__sched_getaffinity(struct lwp *l,
|
||||||
} */
|
} */
|
||||||
struct lwp *t;
|
struct lwp *t;
|
||||||
void *cpuset;
|
void *cpuset;
|
||||||
|
lwpid_t lid;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (SCARG(uap, size) <= 0)
|
if (SCARG(uap, size) <= 0)
|
||||||
|
@ -320,8 +370,21 @@ sys__sched_getaffinity(struct lwp *l,
|
||||||
|
|
||||||
cpuset = kmem_zalloc(sizeof(cpuset_t), KM_SLEEP);
|
cpuset = kmem_zalloc(sizeof(cpuset_t), KM_SLEEP);
|
||||||
|
|
||||||
/* Locks the LWP */
|
/* If not specified, use the first LWP */
|
||||||
t = lwp_find2(SCARG(uap, pid), SCARG(uap, lid));
|
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);
|
||||||
|
}
|
||||||
if (t == NULL) {
|
if (t == NULL) {
|
||||||
kmem_free(cpuset, sizeof(cpuset_t));
|
kmem_free(cpuset, sizeof(cpuset_t));
|
||||||
return ESRCH;
|
return ESRCH;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: lwp.h,v 1.77 2008/01/15 03:37:12 rmind Exp $ */
|
/* $NetBSD: lwp.h,v 1.78 2008/01/26 17:55:29 rmind Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2001, 2006, 2007 The NetBSD Foundation, Inc.
|
* Copyright (c) 2001, 2006, 2007 The NetBSD Foundation, Inc.
|
||||||
|
@ -46,6 +46,7 @@
|
||||||
#include <sys/condvar.h>
|
#include <sys/condvar.h>
|
||||||
#include <sys/pset.h>
|
#include <sys/pset.h>
|
||||||
#include <sys/signalvar.h>
|
#include <sys/signalvar.h>
|
||||||
|
#include <sys/sched.h>
|
||||||
#include <sys/specificdata.h>
|
#include <sys/specificdata.h>
|
||||||
#include <sys/syncobj.h>
|
#include <sys/syncobj.h>
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: pset.h,v 1.1 2008/01/15 03:41:50 rmind Exp $ */
|
/* $NetBSD: pset.h,v 1.2 2008/01/26 17:55:29 rmind Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, Mindaugas Rasiukevicius <rmind at NetBSD org>
|
* Copyright (c) 2008, Mindaugas Rasiukevicius <rmind at NetBSD org>
|
||||||
|
@ -52,32 +52,6 @@ int pset_create(psetid_t *);
|
||||||
int pset_destroy(psetid_t);
|
int pset_destroy(psetid_t);
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
/* Size of the CPU set bitmap */
|
|
||||||
#define CPUSET_SHIFT 5
|
|
||||||
#define CPUSET_MASK 31
|
|
||||||
#if MAXCPUS > 32
|
|
||||||
#define CPUSET_SIZE (MAXCPUS >> CPUSET_SHIFT)
|
|
||||||
#else
|
|
||||||
#define CPUSET_SIZE 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Bitmap of the CPUs */
|
|
||||||
typedef struct {
|
|
||||||
uint32_t bits[CPUSET_SIZE];
|
|
||||||
} cpuset_t;
|
|
||||||
|
|
||||||
#define CPU_ZERO(c) \
|
|
||||||
(memset(c, 0, sizeof(cpuset_t)))
|
|
||||||
|
|
||||||
#define CPU_ISSET(i, c) \
|
|
||||||
((1 << (i & CPUSET_MASK)) & (c)->bits[i >> CPUSET_SHIFT])
|
|
||||||
|
|
||||||
#define CPU_SET(i, c) \
|
|
||||||
((c)->bits[i >> CPUSET_SHIFT] |= 1 << (i & CPUSET_MASK))
|
|
||||||
|
|
||||||
#define CPU_CLR(i, c) \
|
|
||||||
((c)->bits[i >> CPUSET_SHIFT] &= ~(1 << (i & CPUSET_MASK)))
|
|
||||||
|
|
||||||
#ifdef _NETBSD_SOURCE
|
#ifdef _NETBSD_SOURCE
|
||||||
int _pset_bind(idtype_t, id_t, id_t, psetid_t, psetid_t *);
|
int _pset_bind(idtype_t, id_t, id_t, psetid_t, psetid_t *);
|
||||||
#endif /* _NETBSD_SOURCE */
|
#endif /* _NETBSD_SOURCE */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: sched.h,v 1.45 2008/01/15 03:37:12 rmind Exp $ */
|
/* $NetBSD: sched.h,v 1.46 2008/01/26 17:55:29 rmind Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1999, 2000, 2001, 2002, 2007 The NetBSD Foundation, Inc.
|
* Copyright (c) 1999, 2000, 2001, 2002, 2007 The NetBSD Foundation, Inc.
|
||||||
|
@ -101,6 +101,32 @@ struct sched_param {
|
||||||
|
|
||||||
#if defined(_NETBSD_SOURCE)
|
#if defined(_NETBSD_SOURCE)
|
||||||
|
|
||||||
|
/* XXX: Size of the CPU set bitmap */
|
||||||
|
#define CPUSET_SHIFT 5
|
||||||
|
#define CPUSET_MASK 31
|
||||||
|
#if MAXCPUS > 32
|
||||||
|
#define CPUSET_SIZE (MAXCPUS >> CPUSET_SHIFT)
|
||||||
|
#else
|
||||||
|
#define CPUSET_SIZE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Bitmap of the CPUs */
|
||||||
|
typedef struct {
|
||||||
|
uint32_t bits[CPUSET_SIZE];
|
||||||
|
} cpuset_t;
|
||||||
|
|
||||||
|
#define CPU_ZERO(c) \
|
||||||
|
(memset(c, 0, sizeof(cpuset_t)))
|
||||||
|
|
||||||
|
#define CPU_ISSET(i, c) \
|
||||||
|
((1 << (i & CPUSET_MASK)) & (c)->bits[i >> CPUSET_SHIFT])
|
||||||
|
|
||||||
|
#define CPU_SET(i, c) \
|
||||||
|
((c)->bits[i >> CPUSET_SHIFT] |= 1 << (i & CPUSET_MASK))
|
||||||
|
|
||||||
|
#define CPU_CLR(i, c) \
|
||||||
|
((c)->bits[i >> CPUSET_SHIFT] &= ~(1 << (i & CPUSET_MASK)))
|
||||||
|
|
||||||
int _sched_getaffinity(pid_t, lwpid_t, size_t, void *);
|
int _sched_getaffinity(pid_t, lwpid_t, size_t, void *);
|
||||||
int _sched_setaffinity(pid_t, lwpid_t, size_t, void *);
|
int _sched_setaffinity(pid_t, lwpid_t, size_t, void *);
|
||||||
int _sched_getparam(pid_t, lwpid_t, struct sched_param *);
|
int _sched_getparam(pid_t, lwpid_t, struct sched_param *);
|
||||||
|
|
Loading…
Reference in New Issue