Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F108593984
D41128.id125092.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D41128.id125092.diff
View Options
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -862,7 +862,7 @@
static int curfail;
static struct timeval lastfail;
int flags, pages;
- bool killsx_locked;
+ bool killsx_locked, singlethreaded;
flags = fr->fr_flags;
pages = fr->fr_pages;
@@ -920,6 +920,7 @@
newproc = NULL;
vm2 = NULL;
killsx_locked = false;
+ singlethreaded = false;
/*
* Increment the nprocs resource before allocations occur.
@@ -954,10 +955,25 @@
* a signal to our process group until the child is visible.
*/
pg = p1->p_pgrp;
- if (sx_slock_sig(&pg->pg_killsx) != 0) {
+ if (p1->p_numthreads > 1) {
+ if (sx_try_slock(&pg->pg_killsx) != 0) {
+ killsx_locked = true;
+ } else {
+ PROC_LOCK(p1);
+ if (thread_single(p1, SINGLE_BOUNDARY)) {
+ PROC_UNLOCK(p1);
+ error = ERESTART;
+ goto fail2;
+ }
+ PROC_UNLOCK(p1);
+ singlethreaded = true;
+ }
+ }
+ if (!killsx_locked && sx_slock_sig(&pg->pg_killsx) != 0) {
error = ERESTART;
goto fail2;
- } else if (__predict_false(p1->p_pgrp != pg || sig_intr() != 0)) {
+ }
+ if (__predict_false(p1->p_pgrp != pg || sig_intr() != 0)) {
/*
* Either the process was moved to other process
* group, or there is pending signal. sx_slock_sig()
@@ -1062,8 +1078,8 @@
}
do_fork(td, fr, newproc, td2, vm2, fp_procdesc);
- sx_sunlock(&pg->pg_killsx);
- return (0);
+ error = 0;
+ goto cleanup;
fail0:
error = EAGAIN;
#ifdef MAC
@@ -1081,9 +1097,16 @@
fdrop(fp_procdesc, td);
}
atomic_add_int(&nprocs, -1);
+cleanup:
if (killsx_locked)
sx_sunlock(&pg->pg_killsx);
- pause("fork", hz / 2);
+ if (singlethreaded) {
+ PROC_LOCK(p1);
+ thread_single_end(p1, SINGLE_BOUNDARY);
+ PROC_UNLOCK(p1);
+ }
+ if (error != 0)
+ pause("fork", hz / 2);
return (error);
}
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -2158,14 +2158,18 @@
if (curproc == p && !SIGISMEMBER(curthread->td_sigmask, sig) &&
(!fast_sigblock || curthread->td_sigblock_val == 0))
return (curthread);
+
+ /* Find a non-stopped thread that does not mask the signal. */
signal_td = NULL;
FOREACH_THREAD_IN_PROC(p, td) {
if (!SIGISMEMBER(td->td_sigmask, sig) && (!fast_sigblock ||
- td != curthread || td->td_sigblock_val == 0)) {
+ td != curthread || td->td_sigblock_val == 0) &&
+ (td->td_flags & TDF_BOUNDARY) == 0) {
signal_td = td;
break;
}
}
+ /* Select random (first) thread if no better match was found. */
if (signal_td == NULL)
signal_td = FIRST_THREAD_IN_PROC(p);
return (signal_td);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Jan 27, 6:14 PM (5 h, 27 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16203451
Default Alt Text
D41128.id125092.diff (2 KB)
Attached To
Mode
D41128: Different fix for the killpg race, part2
Attached
Detach File
Event Timeline
Log In to Comment