summaryrefslogtreecommitdiff
path: root/sys/kern/kern_fork.c
diff options
context:
space:
mode:
authorVisa Hankala <visa@cvs.openbsd.org>2019-06-21 09:39:50 +0000
committerVisa Hankala <visa@cvs.openbsd.org>2019-06-21 09:39:50 +0000
commitf36079e076349e28aa988c7155e5d5dca320d8f7 (patch)
tree75b2a8f1fb017c3e8bf90644b9085cabd9ec0a65 /sys/kern/kern_fork.c
parent841259cd98c59028504e22d3e387f0ba49ec95a8 (diff)
Make resource limit access MP-safe. So far, the copy-on-write sharing
of resource limit structs has been done between processes. By applying copy-on-write also between threads, threads can read rlimits in a nearly lock-free manner. Inspired by code in DragonFly BSD and FreeBSD. OK mpi@, agreement from jmatthew@ and anton@
Diffstat (limited to 'sys/kern/kern_fork.c')
-rw-r--r--sys/kern/kern_fork.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 190c749720e..95180d9de31 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_fork.c,v 1.212 2019/06/01 14:11:17 mpi Exp $ */
+/* $OpenBSD: kern_fork.c,v 1.213 2019/06/21 09:39:48 visa Exp $ */
/* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */
/*
@@ -151,6 +151,7 @@ thread_new(struct proc *parent, vaddr_t uaddr)
p = pool_get(&proc_pool, PR_WAITOK);
p->p_stat = SIDL; /* protect against others */
p->p_flag = 0;
+ p->p_limit = NULL;
/*
* Make a proc table entry for the new process.
@@ -210,6 +211,8 @@ process_initialize(struct process *pr, struct proc *p)
LIST_INIT(&pr->ps_kqlist);
LIST_INIT(&pr->ps_sigiolst);
+ mtx_init(&pr->ps_mtx, IPL_MPFLOOR);
+
timeout_set(&pr->ps_realit_to, realitexpire, pr);
timeout_set(&pr->ps_rucheck_to, rucheck, pr);
}
@@ -237,12 +240,10 @@ process_new(struct proc *p, struct process *parent, int flags)
process_initialize(pr, p);
pr->ps_pid = allocpid();
+ lim_fork(parent, pr);
/* post-copy fixups */
pr->ps_pptr = parent;
- pr->ps_limit->pl_refcnt++;
- if (pr->ps_limit->pl_rlimit[RLIMIT_CPU].rlim_cur != RLIM_INFINITY)
- timeout_add_msec(&pr->ps_rucheck_to, RUCHECK_INTERVAL);
/* bump references to the text vnode (for sysctl) */
pr->ps_textvp = parent->ps_textvp;
@@ -373,7 +374,7 @@ fork1(struct proc *curp, int flags, void (*func)(void *), void *arg,
* Don't allow a nonprivileged user to exceed their current limit.
*/
count = chgproccnt(uid, 1);
- if (uid != 0 && count > curp->p_rlimit[RLIMIT_NPROC].rlim_cur) {
+ if (uid != 0 && count > lim_cur(RLIMIT_NPROC)) {
(void)chgproccnt(uid, -1);
nprocesses--;
nthreads--;