- 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.
This commit is contained in:
John Baldwin 2003-04-17 22:24:59 +00:00
parent 462f31bff0
commit bb0e8070fd
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=113628

View File

@ -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 @@ fork1(td, flags, pages, procp)
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 @@ fork1(td, flags, pages, procp)
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 @@ fork1(td, flags, pages, procp)
* 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 @@ fork1(td, flags, pages, procp)
/*
* Return child proc pointer to parent.
*/
mtx_unlock(&Giant);
*procp = p2;
return (0);
fail:
@ -745,6 +743,7 @@ fork1(td, flags, pages, procp)
PROC_UNLOCK(p1);
}
tsleep(&forksleep, PUSER, "fork", hz / 2);
mtx_unlock(&Giant);
return (error);
}