37 #include <sys/cdefs.h>
40 #include "opt_compat.h"
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/sysproto.h>
46 #include <sys/kernel.h>
48 #include <sys/malloc.h>
49 #include <sys/mutex.h>
52 #include <sys/refcount.h>
53 #include <sys/racct.h>
54 #include <sys/resourcevar.h>
55 #include <sys/rwlock.h>
56 #include <sys/sched.h>
58 #include <sys/syscallsubr.h>
59 #include <sys/sysctl.h>
60 #include <sys/sysent.h>
65 #include <vm/vm_param.h>
67 #include <vm/vm_map.h>
70 static MALLOC_DEFINE(M_PLIMIT,
"plimit",
"plimit structures");
71 static MALLOC_DEFINE(M_UIDINFO,
"uidinfo",
"uidinfo structures");
72 #define UIHASH(uid) (&uihashtbl[(uid) & uihash])
77 static void calcru1(
struct proc *p,
struct rusage_ext *ruxp,
78 struct timeval *up,
struct timeval *sp);
79 static int donice(
struct thread *td,
struct proc *chgp,
int n);
80 static struct uidinfo *
uilookup(uid_t uid);
81 static void ruxagg_locked(
struct rusage_ext *rux,
struct thread *td);
86 #ifndef _SYS_SYSPROTO_H_
87 struct getpriority_args {
95 register struct getpriority_args *uap;
103 switch (uap->which) {
107 low = td->td_proc->p_nice;
121 pg = td->td_proc->p_pgrp;
131 LIST_FOREACH(p, &pg->pg_members, p_pglist) {
133 if (p->p_state == PRS_NORMAL &&
145 uap->who = td->td_ucred->cr_uid;
147 FOREACH_PROC_IN_SYSTEM(p) {
149 if (p->p_state == PRS_NORMAL &&
151 p->p_ucred->cr_uid == uap->who) {
164 if (low == PRIO_MAX + 1 && error == 0)
166 td->td_retval[0] = low;
170 #ifndef _SYS_SYSPROTO_H_
182 struct proc *curp, *p;
184 int found = 0, error = 0;
187 switch (uap->
which) {
218 LIST_FOREACH(p, &pg->pg_members, p_pglist) {
220 if (p->p_state == PRS_NORMAL &&
232 uap->
who = td->td_ucred->cr_uid;
234 FOREACH_PROC_IN_SYSTEM(p) {
236 if (p->p_state == PRS_NORMAL &&
237 p->p_ucred->cr_uid == uap->
who &&
251 if (found == 0 && error == 0)
260 donice(
struct thread *td,
struct proc *p,
int n)
264 PROC_LOCK_ASSERT(p, MA_OWNED);
271 if (n < p->p_nice &&
priv_check(td, PRIV_SCHED_SETPRIORITY) != 0)
284 #ifndef _SYS_SYSPROTO_H_
301 cierror = copyin(uap->
rtp, &rtp,
sizeof(
struct rtprio));
305 if (uap->
lwpid == 0 || uap->
lwpid == td->td_tid) {
323 return (copyout(&rtp, uap->
rtp,
sizeof(
struct rtprio)));
325 if ((error =
p_cansched(td, p)) || (error = cierror))
346 if (RTP_PRIO_BASE(rtp.type) == RTP_PRIO_REALTIME ||
347 (RTP_PRIO_BASE(rtp.type) == RTP_PRIO_IDLE &&
366 #ifndef _SYS_SYSPROTO_H_
384 if (uap->function == RTP_SET)
385 cierror = copyin(uap->rtp, &rtp,
sizeof(
struct rtprio));
398 switch (uap->function) {
415 rtp.type = RTP_PRIO_IDLE;
416 rtp.prio = RTP_PRIO_MAX;
417 FOREACH_THREAD_IN_PROC(p, tdp) {
419 if (rtp2.type < rtp.type ||
420 (rtp2.type == rtp.type &&
421 rtp2.prio < rtp.prio)) {
422 rtp.type = rtp2.type;
423 rtp.prio = rtp2.prio;
428 return (copyout(&rtp, uap->rtp,
sizeof(
struct rtprio)));
430 if ((error =
p_cansched(td, p)) || (error = cierror))
438 if (RTP_PRIO_BASE(rtp.type) == RTP_PRIO_REALTIME ||
439 (RTP_PRIO_BASE(rtp.type) == RTP_PRIO_IDLE &&
455 FOREACH_THREAD_IN_PROC(p, td) {
475 switch (RTP_PRIO_BASE(rtp->type)) {
476 case RTP_PRIO_REALTIME:
477 if (rtp->prio > RTP_PRIO_MAX)
479 newpri = PRI_MIN_REALTIME + rtp->prio;
481 case RTP_PRIO_NORMAL:
482 if (rtp->prio > (PRI_MAX_TIMESHARE - PRI_MIN_TIMESHARE))
484 newpri = PRI_MIN_TIMESHARE + rtp->prio;
487 if (rtp->prio > RTP_PRIO_MAX)
489 newpri = PRI_MIN_IDLE + rtp->prio;
497 oldpri = td->td_user_pri;
499 if (td->td_user_pri != oldpri && (td == curthread ||
500 td->td_priority == oldpri || td->td_user_pri <= PRI_MAX_REALTIME))
502 if (TD_ON_UPILOCK(td) && oldpri != newpri) {
517 switch (PRI_BASE(td->td_pri_class)) {
519 rtp->prio = td->td_base_user_pri - PRI_MIN_REALTIME;
522 rtp->prio = td->td_base_user_pri - PRI_MIN_TIMESHARE;
525 rtp->prio = td->td_base_user_pri - PRI_MIN_IDLE;
530 rtp->type = td->td_pri_class;
534 #if defined(COMPAT_43)
535 #ifndef _SYS_SYSPROTO_H_
536 struct osetrlimit_args {
544 register struct osetrlimit_args *uap;
550 if ((error = copyin(uap->rlp, &olim,
sizeof(
struct orlimit))))
552 lim.rlim_cur = olim.rlim_cur;
553 lim.rlim_max = olim.rlim_max;
558 #ifndef _SYS_SYSPROTO_H_
559 struct ogetrlimit_args {
567 register struct ogetrlimit_args *uap;
574 if (uap->which >= RLIM_NLIMITS)
590 olim.rlim_cur = rl.rlim_cur > 0x7fffffff ? 0x7fffffff : rl.rlim_cur;
591 olim.rlim_max = rl.rlim_max > 0x7fffffff ? 0x7fffffff : rl.rlim_max;
592 error = copyout(&olim, uap->rlp,
sizeof(olim));
597 #ifndef _SYS_SYSPROTO_H_
611 if ((error = copyin(uap->rlp, &alim,
sizeof(
struct rlimit))))
625 PROC_LOCK_ASSERT(p, MA_OWNED);
630 if (p->p_cpulimit == RLIM_INFINITY)
633 FOREACH_THREAD_IN_PROC(p, td) {
637 if (p->p_rux.rux_runtime > p->p_cpulimit *
cpu_tickrate()) {
639 if (p->p_rux.rux_runtime >= rlim.rlim_max *
cpu_tickrate()) {
640 killproc(p,
"exceeded maximum CPU limit");
642 if (p->p_cpulimit < rlim.rlim_max)
647 if ((p->p_flag & P_WEXIT) == 0)
648 callout_reset(&p->p_limco,
hz,
lim_cb, p);
662 struct plimit *newlim, *oldlim;
663 register struct rlimit *alimp;
664 struct rlimit oldssiz;
667 if (which >= RLIM_NLIMITS)
673 if (limp->rlim_cur < 0)
674 limp->rlim_cur = RLIM_INFINITY;
675 if (limp->rlim_max < 0)
676 limp->rlim_max = RLIM_INFINITY;
678 oldssiz.rlim_cur = 0;
682 alimp = &oldlim->pl_rlimit[which];
683 if (limp->rlim_cur > alimp->rlim_max ||
684 limp->rlim_max > alimp->rlim_max)
685 if ((error =
priv_check(td, PRIV_PROC_SETRLIMIT))) {
690 if (limp->rlim_cur > limp->rlim_max)
691 limp->rlim_cur = limp->rlim_max;
693 alimp = &newlim->pl_rlimit[which];
698 if (limp->rlim_cur != RLIM_INFINITY &&
699 p->p_cpulimit == RLIM_INFINITY)
700 callout_reset(&p->p_limco,
hz,
lim_cb, p);
701 p->p_cpulimit = limp->rlim_cur;
716 if (p->p_sysent->sv_fixlimit != NULL)
717 p->p_sysent->sv_fixlimit(&oldssiz,
733 if (limp->rlim_cur < 1)
735 if (limp->rlim_max < 1)
739 if (p->p_sysent->sv_fixlimit != NULL)
740 p->p_sysent->sv_fixlimit(limp, which);
746 if (which == RLIMIT_STACK) {
752 if (limp->rlim_cur != oldssiz.rlim_cur) {
757 if (limp->rlim_cur > oldssiz.rlim_cur) {
758 prot = p->p_sysent->sv_stackprot;
759 size = limp->rlim_cur - oldssiz.rlim_cur;
760 addr = p->p_sysent->sv_usrstack -
764 size = oldssiz.rlim_cur - limp->rlim_cur;
765 addr = p->p_sysent->sv_usrstack -
768 addr = trunc_page(addr);
769 size = round_page(size);
770 (void)vm_map_protect(&p->p_vmspace->vm_map,
771 addr, addr + size, prot, FALSE);
778 #ifndef _SYS_SYSPROTO_H_
794 if (uap->which >= RLIM_NLIMITS)
800 error = copyout(&rlim, uap->rlp,
sizeof(
struct rlimit));
815 PROC_LOCK_ASSERT(p, MA_OWNED);
816 calcru1(p, &p->p_crux, up, sp);
825 calcru(
struct proc *p,
struct timeval *up,
struct timeval *sp)
830 PROC_LOCK_ASSERT(p, MA_OWNED);
831 PROC_SLOCK_ASSERT(p, MA_OWNED);
839 if (td->td_proc == p) {
841 runtime = u - PCPU_GET(switchtime);
842 td->td_runtime += runtime;
843 td->td_incruntime += runtime;
844 PCPU_SET(switchtime, u);
847 FOREACH_THREAD_IN_PROC(p, td) {
848 if (td->td_incruntime == 0)
863 PROC_SLOCK_ASSERT(p, MA_OWNED);
864 THREAD_LOCK_ASSERT(td, MA_OWNED);
871 if (td == curthread) {
873 runtime = u - PCPU_GET(switchtime);
874 td->td_runtime += runtime;
875 td->td_incruntime += runtime;
876 PCPU_SET(switchtime, u);
880 calcru1(p, &td->td_rux, &ru->ru_utime, &ru->ru_stime);
884 calcru1(
struct proc *p,
struct rusage_ext *ruxp,
struct timeval *up,
888 uint64_t ut, uu, st, su, it, tt, tu;
890 ut = ruxp->rux_uticks;
891 st = ruxp->rux_sticks;
892 it = ruxp->rux_iticks;
900 if ((int64_t)tu < 0) {
902 printf(
"calcru: negative runtime of %jd usec for pid %d (%s)\n",
903 (intmax_t)tu, p->p_pid, p->p_comm);
907 if (tu >= ruxp->rux_tu) {
913 if (uu < ruxp->rux_uu)
916 if (su < ruxp->rux_su)
918 }
else if (tu + 3 > ruxp->rux_tu || 101 * tu > 100 * ruxp->rux_tu) {
940 printf(
"calcru: runtime went backwards from %ju usec "
941 "to %ju usec for pid %d (%s)\n",
942 (uintmax_t)ruxp->rux_tu, (uintmax_t)tu,
943 p->p_pid, p->p_comm);
952 up->tv_sec = uu / 1000000;
953 up->tv_usec = uu % 1000000;
954 sp->tv_sec = su / 1000000;
955 sp->tv_usec = su % 1000000;
958 #ifndef _SYS_SYSPROTO_H_
966 register struct thread *td;
974 error = copyout(&ru, uap->rusage,
sizeof(
struct rusage));
993 case RUSAGE_CHILDREN:
994 *rup = p->p_stats->p_cru;
995 calccru(p, &rup->ru_utime, &rup->ru_stime);
1019 if (ru->ru_maxrss < ru2->ru_maxrss)
1020 ru->ru_maxrss = ru2->ru_maxrss;
1022 ip2 = &ru2->ru_first;
1023 for (i = &ru->ru_last - &ru->ru_first; i >= 0; i--)
1028 ruadd(
struct rusage *ru,
struct rusage_ext *rux,
struct rusage *ru2,
1029 struct rusage_ext *rux2)
1032 rux->rux_runtime += rux2->rux_runtime;
1033 rux->rux_uticks += rux2->rux_uticks;
1034 rux->rux_sticks += rux2->rux_sticks;
1035 rux->rux_iticks += rux2->rux_iticks;
1036 rux->rux_uu += rux2->rux_uu;
1037 rux->rux_su += rux2->rux_su;
1038 rux->rux_tu += rux2->rux_tu;
1049 THREAD_LOCK_ASSERT(td, MA_OWNED);
1050 PROC_SLOCK_ASSERT(td->td_proc, MA_OWNED);
1051 rux->rux_runtime += td->td_incruntime;
1052 rux->rux_uticks += td->td_uticks;
1053 rux->rux_sticks += td->td_sticks;
1054 rux->rux_iticks += td->td_iticks;
1064 td->td_incruntime = 0;
1080 PROC_SLOCK_ASSERT(p, MA_OWNED);
1083 if (p->p_numthreads > 0) {
1084 FOREACH_THREAD_IN_PROC(p, td) {
1114 struct plimit *limp;
1116 limp =
malloc(
sizeof(
struct plimit), M_PLIMIT, M_WAITOK);
1117 refcount_init(&limp->pl_refcnt, 1);
1123 struct plimit *limp;
1126 refcount_acquire(&limp->pl_refcnt);
1133 p2->p_limit =
lim_hold(p1->p_limit);
1134 callout_init_mtx(&p2->p_limco, &p2->p_mtx, 0);
1135 if (p1->p_cpulimit != RLIM_INFINITY)
1136 callout_reset(&p2->p_limco,
hz,
lim_cb, p2);
1141 struct plimit *limp;
1144 KASSERT(limp->pl_refcnt > 0, (
"plimit refcnt underflow"));
1145 if (refcount_release(&limp->pl_refcnt))
1146 free((
void *)limp, M_PLIMIT);
1155 struct plimit *dst, *src;
1158 KASSERT(dst->pl_refcnt == 1, (
"lim_copy to shared limit"));
1159 bcopy(src->pl_rlimit, dst->pl_rlimit,
sizeof(src->pl_rlimit));
1172 return (rl.rlim_max);
1185 return (rl.rlim_cur);
1196 PROC_LOCK_ASSERT(p, MA_OWNED);
1197 KASSERT(which >= 0 && which < RLIM_NLIMITS,
1198 (
"request for invalid resource limit"));
1199 *rlp = p->p_limit->pl_rlimit[which];
1200 if (p->p_sysent->sv_fixlimit != NULL)
1201 p->p_sysent->sv_fixlimit(rlp, which);
1216 static struct uidinfo *
1220 struct uihashhead *uipp;
1221 struct uidinfo *uip;
1225 LIST_FOREACH(uip, uipp, ui_hash)
1226 if (uip->ui_uid == uid)
1241 struct uidinfo *old_uip, *uip;
1247 uip =
malloc(
sizeof(*uip), M_UIDINFO, M_WAITOK | M_ZERO);
1255 if ((old_uip =
uilookup(uid)) != NULL) {
1258 free(uip, M_UIDINFO);
1261 refcount_init(&uip->ui_ref, 0);
1263 mtx_init(&uip->ui_vmsize_mtx,
"ui_vmsize", NULL,
1265 LIST_INSERT_HEAD(
UIHASH(uid), uip, ui_hash);
1278 struct uidinfo *uip;
1281 refcount_acquire(&uip->ui_ref);
1301 struct uidinfo *uip;
1307 if (old > 1 && atomic_cmpset_int(&uip->ui_ref, old, old - 1))
1312 if (refcount_release(&uip->ui_ref)) {
1314 LIST_REMOVE(uip, ui_hash);
1316 if (uip->ui_sbsize != 0)
1317 printf(
"freeing uidinfo: uid = %d, sbsize = %ld\n",
1318 uip->ui_uid, uip->ui_sbsize);
1319 if (uip->ui_proccnt != 0)
1320 printf(
"freeing uidinfo: uid = %d, proccnt = %ld\n",
1321 uip->ui_uid, uip->ui_proccnt);
1322 if (uip->ui_vmsize != 0)
1323 printf(
"freeing uidinfo: uid = %d, swapuse = %lld\n",
1324 uip->ui_uid, (
unsigned long long)uip->ui_vmsize);
1326 free(uip, M_UIDINFO);
1338 void *arg2,
void *arg3),
void *arg2,
void *arg3)
1340 struct uidinfo *uip;
1341 struct uihashhead *uih;
1344 for (uih = &uihashtbl[uihash]; uih >= uihashtbl; uih--) {
1345 LIST_FOREACH(uip, uih, ui_hash) {
1346 (
callback)(uip->ui_racct, arg2, arg3);
1358 struct uidinfo *uip;
1364 if (diff > 0 && max != 0) {
1365 if (atomic_fetchadd_long(&uip->ui_proccnt, (
long)diff) + diff > max) {
1366 atomic_subtract_long(&uip->ui_proccnt, (
long)diff);
1370 atomic_add_long(&uip->ui_proccnt, (
long)diff);
1371 if (uip->ui_proccnt < 0)
1372 printf(
"negative proccnt for uid = %d\n", uip->ui_uid);
1382 struct uidinfo *uip;
1391 if (atomic_fetchadd_long(&uip->ui_sbsize, (
long)diff) + diff > max) {
1392 atomic_subtract_long(&uip->ui_sbsize, (
long)diff);
1396 atomic_add_long(&uip->ui_sbsize, (
long)diff);
1397 if (uip->ui_sbsize < 0)
1398 printf(
"negative sbsize for uid = %d\n", uip->ui_uid);
1410 struct uidinfo *uip;
1416 if (diff > 0 && max != 0) {
1417 if (atomic_fetchadd_long(&uip->ui_ptscnt, (
long)diff) + diff > max) {
1418 atomic_subtract_long(&uip->ui_ptscnt, (
long)diff);
1422 atomic_add_long(&uip->ui_ptscnt, (
long)diff);
1423 if (uip->ui_ptscnt < 0)
1424 printf(
"negative ptscnt for uid = %d\n", uip->ui_uid);
rlim_t lim_max(struct proc *p, int which)
void umtx_pi_adjust(struct thread *td, u_char oldpri)
static void lim_cb(void *arg)
static MALLOC_DEFINE(M_PLIMIT,"plimit","plimit structures")
int sys_rtprio(struct thread *td, struct rtprio_args *uap)
void killproc(struct proc *p, char *why)
int sys_getrusage(struct thread *td, struct getrusage_args *uap)
void rufetch(struct proc *p, struct rusage *ru)
SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_idprio, CTLFLAG_RW,&unprivileged_idprio, 0,"Allow non-root users to set an idle priority")
static void ruxagg_locked(struct rusage_ext *rux, struct thread *td)
int chgsbsize(struct uidinfo *uip, u_int *hiwat, u_int to, rlim_t max)
void sched_prio(struct thread *td, u_char prio)
rlim_t lim_cur(struct proc *p, int which)
void * hashinit(int elements, struct malloc_type *type, u_long *hashmask)
static int donice(struct thread *td, struct proc *p, int n)
void uifree(struct uidinfo *uip)
int kern_getrusage(struct thread *td, int who, struct rusage *rup)
void * malloc(unsigned long size, struct malloc_type *mtp, int flags)
struct uidinfo * uifind(uid_t uid)
void sched_nice(struct proc *p, int nice)
int sys_setrlimit(struct thread *td, struct __setrlimit_args *uap)
void lim_copy(struct plimit *dst, struct plimit *src)
linker_function_name_callback_t callback
void kern_psignal(struct proc *p, int sig)
void uihold(struct uidinfo *uip)
struct plimit * lim_alloc()
int sys_setpriority(struct thread *td, struct setpriority_args *uap)
int priv_check(struct thread *td, int priv)
struct proc * pfind(pid_t pid)
void calccru(struct proc *p, struct timeval *up, struct timeval *sp)
static struct rwlock uihashtbl_lock
int rtp_to_pri(struct rtprio *rtp, struct thread *td)
uint64_t cputick2usec(uint64_t tick)
void rucollect(struct rusage *ru, struct rusage *ru2)
void sched_class(struct thread *td, int class)
void rufetchcalc(struct proc *p, struct rusage *ru, struct timeval *up, struct timeval *sp)
void lim_fork(struct proc *p1, struct proc *p2)
int chgproccnt(struct uidinfo *uip, int diff, rlim_t max)
void ruxagg(struct proc *p, struct thread *td)
struct plimit * lim_hold(struct plimit *limp)
static void calcru1(struct proc *p, struct rusage_ext *ruxp, struct timeval *up, struct timeval *sp)
static LIST_HEAD(uihashhead, uidinfo)
struct pgrp * pgfind(pid_t pgid)
void lim_rlimit(struct proc *p, int which, struct rlimit *rlp)
void racct_destroy(struct racct **racctp)
int sys_getrlimit(struct thread *td, struct __getrlimit_args *uap)
int sys_getpriority(struct thread *td, struct getpriority_args *uap)
void rufetchtd(struct thread *td, struct rusage *ru)
void free(void *addr, struct malloc_type *mtp)
int printf(const char *fmt,...)
void sched_user_prio(struct thread *td, u_char prio)
void mtx_init(struct mtx *m, const char *name, const char *type, int opts)
int kern_proc_setrlimit(struct thread *td, struct proc *p, u_int which, struct rlimit *limp)
uint64_t cpu_tickrate(void)
int sys_rtprio_thread(struct thread *td, struct rtprio_thread_args *uap)
struct thread * tdfind(lwpid_t tid, pid_t pid)
void pri_to_rtp(struct thread *td, struct rtprio *rtp)
int chgptscnt(struct uidinfo *uip, int diff, rlim_t max)
void ui_racct_foreach(void(*callback)(struct racct *racct, void *arg2, void *arg3), void *arg2, void *arg3)
void lim_free(struct plimit *limp)
void calcru(struct proc *p, struct timeval *up, struct timeval *sp)
void mtx_destroy(struct mtx *m)
void racct_create(struct racct **racctp)
static struct uidinfo * uilookup(uid_t uid)
int p_cansee(struct thread *td, struct proc *p)
void ruadd(struct rusage *ru, struct rusage_ext *rux, struct rusage *ru2, struct rusage_ext *rux2)
void critical_enter(void)
int p_cansched(struct thread *td, struct proc *p)
static int unprivileged_idprio
int kern_setrlimit(struct thread *td, u_int which, struct rlimit *limp)