diff options
author | jhb <jhb@FreeBSD.org> | 2003-04-17 22:24:59 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2003-04-17 22:24:59 +0000 |
commit | ab40c1468e69d8fda6ba05450835eadb678218b6 (patch) | |
tree | 8c730107712041b890befceb46362c91ce79ff6a /sys/kern/kern_fork.c | |
parent | b09e86b5014747623ce8b347ba032a51ebc04af9 (diff) | |
download | FreeBSD-src-ab40c1468e69d8fda6ba05450835eadb678218b6.zip FreeBSD-src-ab40c1468e69d8fda6ba05450835eadb678218b6.tar.gz |
- Push Giant down into the fork1() function a small bit.
- Set p_acflag earlier while already hold the proc lock in fork1().
- Mark the realitexpire() callout MPSAFE for new processes. It was already
marked safe for proc0 a long while ago.
Diffstat (limited to 'sys/kern/kern_fork.c')
-rw-r--r-- | sys/kern/kern_fork.c | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 8ca68f5..6be5da9 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -97,13 +97,11 @@ fork(td, uap) int error; struct proc *p2; - mtx_lock(&Giant); error = fork1(td, RFFDG | RFPROC, 0, &p2); if (error == 0) { td->td_retval[0] = p2->p_pid; td->td_retval[1] = 0; } - mtx_unlock(&Giant); return error; } @@ -119,13 +117,11 @@ vfork(td, uap) int error; struct proc *p2; - mtx_lock(&Giant); error = fork1(td, RFFDG | RFPROC | RFPPWAIT | RFMEM, 0, &p2); if (error == 0) { td->td_retval[0] = p2->p_pid; td->td_retval[1] = 0; } - mtx_unlock(&Giant); return error; } @@ -150,13 +146,11 @@ rfork(td, uap) if ((uap->flags & (RFPROC | RFTHREAD | RFFDG | RFCFDG)) == RFPROC) return(EINVAL); - mtx_lock(&Giant); error = fork1(td, uap->flags, 0, &p2); if (error == 0) { td->td_retval[0] = p2 ? p2->p_pid : 0; td->td_retval[1] = 0; } - mtx_unlock(&Giant); return error; } @@ -223,12 +217,11 @@ fork1(td, flags, pages, procp) struct procsig *newprocsig; int error; - GIANT_REQUIRED; - /* Can't copy and clear */ if ((flags & (RFFDG|RFCFDG)) == (RFFDG|RFCFDG)) return (EINVAL); + mtx_lock(&Giant); /* * Here we don't create a new process, but we divorce * certain parts of a process from itself. @@ -261,6 +254,7 @@ fork1(td, flags, pages, procp) } else FILEDESC_UNLOCK(p1->p_fd); } + mtx_unlock(&Giant); *procp = NULL; return (0); } @@ -283,6 +277,7 @@ fork1(td, flags, pages, procp) if (thread_single(SINGLE_NO_EXIT)) { /* Abort.. someone else is single threading before us */ PROC_UNLOCK(p1); + mtx_unlock(&Giant); return (ERESTART); } PROC_UNLOCK(p1); @@ -600,7 +595,7 @@ again: PGRP_UNLOCK(p1->p_pgrp); LIST_INIT(&p2->p_children); - callout_init(&p2->p_itcallout, 0); + callout_init(&p2->p_itcallout, 1); #ifdef KTRACE /* @@ -649,9 +644,12 @@ again: pptr = p1; p2->p_pptr = pptr; LIST_INSERT_HEAD(&pptr->p_children, p2, p_sibling); - PROC_UNLOCK(p2); sx_xunlock(&proctree_lock); + /* Inform accounting that we have forked. */ + p2->p_acflag = AFORK; + PROC_UNLOCK(p2); + KASSERT(newprocsig == NULL, ("unused newprocsig")); if (newsigacts != NULL) FREE(newsigacts, M_SUBPROC); @@ -691,7 +689,6 @@ again: * run queue. */ microtime(&(p2->p_stats->p_start)); - p2->p_acflag = AFORK; if ((flags & RFSTOPPED) == 0) { mtx_lock_spin(&sched_lock); p2->p_state = PRS_NORMAL; @@ -734,6 +731,7 @@ again: /* * Return child proc pointer to parent. */ + mtx_unlock(&Giant); *procp = p2; return (0); fail: @@ -745,6 +743,7 @@ fail: PROC_UNLOCK(p1); } tsleep(&forksleep, PUSER, "fork", hz / 2); + mtx_unlock(&Giant); return (error); } |