summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_fork.c
diff options
context:
space:
mode:
authordas <das@FreeBSD.org>2004-10-01 05:01:29 +0000
committerdas <das@FreeBSD.org>2004-10-01 05:01:29 +0000
commite399d76f1b87f09aa09947ccc8853979d1ba34c3 (patch)
tree0f18ea11b1bf77da8cd270aed4856db2614d81d5 /sys/kern/kern_fork.c
parent9d2cf40e6309c36b8bd2cf35e45478f451dd1f19 (diff)
downloadFreeBSD-src-e399d76f1b87f09aa09947ccc8853979d1ba34c3.zip
FreeBSD-src-e399d76f1b87f09aa09947ccc8853979d1ba34c3.tar.gz
Avoid calling _PHOLD(p1) with p2's lock held, since _PHOLD()
may block to swap in p1. Instead, call _PHOLD earlier, at a point where the only lock held happens to be p1's.
Diffstat (limited to 'sys/kern/kern_fork.c')
-rw-r--r--sys/kern/kern_fork.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 714a1af..6e47e26 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -533,8 +533,14 @@ again:
* p_limit is copy-on-write. Bump its refcount.
*/
p2->p_limit = lim_hold(p1->p_limit);
- PROC_UNLOCK(p1);
+
+ /*
+ * We don't need to prevent the parent from being swapped out just yet,
+ * but this is a convenient point to block to swap it in if needed.
+ */
PROC_UNLOCK(p2);
+ _PHOLD(p1);
+ PROC_UNLOCK(p1);
/* Bump references to the text vnode (for procfs) */
if (p2->p_textvp)
@@ -629,9 +635,8 @@ again:
/*
* This begins the section where we must prevent the parent
- * from being swapped.
+ * from being swapped. We already got a hold on the parent earlier.
*/
- _PHOLD(p1);
PROC_UNLOCK(p1);
/*
OpenPOWER on IntegriCloud