summaryrefslogtreecommitdiffstats
path: root/sys/compat
diff options
context:
space:
mode:
authorbdrewery <bdrewery@FreeBSD.org>2015-10-07 19:10:38 +0000
committerbdrewery <bdrewery@FreeBSD.org>2015-10-07 19:10:38 +0000
commit923a85693e40a7db7ed3eeceedfcfebb993bd639 (patch)
tree2684641cdd9b65d0f3d3860f87f48e362dc9f543 /sys/compat
parent9b1033cdad0d2f3ced950ee53780ba9c3b3c2819 (diff)
downloadFreeBSD-src-923a85693e40a7db7ed3eeceedfcfebb993bd639.zip
FreeBSD-src-923a85693e40a7db7ed3eeceedfcfebb993bd639.tar.gz
Remove redundant RFFPWAIT/vfork(2) handling in Linux fork(2) and clone(2) wrappers.
r161611 added some of the code from sys_vfork() directly into the Linux module wrappers since they use RFSTOPPED. In r232240, the RFFPWAIT handling was moved to syscallret(), thus this code in the Linux module is no longer needed as it will be called later. This also allows the Linux wrappers to benefit from the fix in r275616 for threads not getting suspended if their vforked child is stopped while they wait on them. Reviewed by: jhb, kib MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D3828
Diffstat (limited to 'sys/compat')
-rw-r--r--sys/compat/linux/linux_fork.c33
1 files changed, 5 insertions, 28 deletions
diff --git a/sys/compat/linux/linux_fork.c b/sys/compat/linux/linux_fork.c
index dd3b894..d0f73ad 100644
--- a/sys/compat/linux/linux_fork.c
+++ b/sys/compat/linux/linux_fork.c
@@ -106,20 +106,14 @@ linux_vfork(struct thread *td, struct linux_vfork_args *args)
printf(ARGS(vfork, ""));
#endif
- /* Exclude RFPPWAIT */
- if ((error = fork1(td, RFFDG | RFPROC | RFMEM | RFSTOPPED, 0, &p2,
- NULL, 0, NULL)) != 0)
+ if ((error = fork1(td, RFFDG | RFPROC | RFMEM | RFPPWAIT | RFSTOPPED,
+ 0, &p2, NULL, 0, NULL)) != 0)
return (error);
-
td2 = FIRST_THREAD_IN_PROC(p2);
linux_proc_init(td, td2, 0);
- PROC_LOCK(p2);
- p2->p_flag |= P_PPWAIT;
- PROC_UNLOCK(p2);
-
td->td_retval[0] = p2->p_pid;
/*
@@ -130,12 +124,6 @@ linux_vfork(struct thread *td, struct linux_vfork_args *args)
sched_add(td2, SRQ_BORING);
thread_unlock(td2);
- /* wait for the children to exit, ie. emulate vfork */
- PROC_LOCK(p2);
- while (p2->p_flag & P_PPWAIT)
- cv_wait(&p2->p_pwait, &p2->p_mtx);
- PROC_UNLOCK(p2);
-
return (0);
}
@@ -179,6 +167,9 @@ linux_clone_proc(struct thread *td, struct linux_clone_args *args)
if (args->parent_tidptr == NULL)
return (EINVAL);
+ if (args->flags & LINUX_CLONE_VFORK)
+ ff |= RFPPWAIT;
+
error = fork1(td, ff, 0, &p2, NULL, 0, NULL);
if (error)
return (error);
@@ -228,12 +219,6 @@ linux_clone_proc(struct thread *td, struct linux_clone_args *args)
exit_signal);
#endif
- if (args->flags & LINUX_CLONE_VFORK) {
- PROC_LOCK(p2);
- p2->p_flag |= P_PPWAIT;
- PROC_UNLOCK(p2);
- }
-
/*
* Make this runnable after we are finished with it.
*/
@@ -244,14 +229,6 @@ linux_clone_proc(struct thread *td, struct linux_clone_args *args)
td->td_retval[0] = p2->p_pid;
- if (args->flags & LINUX_CLONE_VFORK) {
- /* wait for the children to exit, ie. emulate vfork */
- PROC_LOCK(p2);
- while (p2->p_flag & P_PPWAIT)
- cv_wait(&p2->p_pwait, &p2->p_mtx);
- PROC_UNLOCK(p2);
- }
-
return (0);
}
OpenPOWER on IntegriCloud