summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_fork.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2008-07-07 09:30:11 +0000
committerkib <kib@FreeBSD.org>2008-07-07 09:30:11 +0000
commitd39c6bcffb3f54fc335949c08670e703eb9cc996 (patch)
treead819a13e4319b489ad70ca457daa6a8a0bf96ad /sys/kern/kern_fork.c
parentea93f8d5f82a12b7726b10658ac4190373e54559 (diff)
downloadFreeBSD-src-d39c6bcffb3f54fc335949c08670e703eb9cc996.zip
FreeBSD-src-d39c6bcffb3f54fc335949c08670e703eb9cc996.tar.gz
The kqueue_register() function assumes that it is called from the top of
the syscall code and acquires various event subsystem locks as needed. The handling of the NOTE_TRACK for EVFILT_PROC is currently done by calling the kqueue_register() from filt_proc() filter, causing recursive entrance of the kqueue code. This results in the LORs and recursive acquisition of the locks. Implement the variant of the knote() function designed to only handle the fork() event. It mostly copies the knote() body, but also handles the NOTE_TRACK, removing the handling from the filt_proc(), where it causes problems described above. The function is called from the fork1() instead of knote(). When encountering NOTE_TRACK knote, it marks the knote as influx and drops the knlist and kqueue lock. In this context call to kqueue_register is safe from the problems. An error from the kqueue_register() is reported to the observer as NOTE_TRACKERR fflag. PR: 108201 Reviewed by: jhb, Pramod Srinivasan <pramod juniper net> (previous version) Discussed with: jmg Tested by: pho MFC after: 2 weeks
Diffstat (limited to 'sys/kern/kern_fork.c')
-rw-r--r--sys/kern/kern_fork.c6
1 files changed, 2 insertions, 4 deletions
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 8387532..6da07d4 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -728,14 +728,12 @@ again:
*/
PROC_LOCK(p1);
_PRELE(p1);
+ PROC_UNLOCK(p1);
/*
* Tell any interested parties about the new process.
*/
- KNOTE_LOCKED(&p1->p_klist, NOTE_FORK | p2->p_pid);
-
- PROC_UNLOCK(p1);
-
+ knote_fork(&p1->p_klist, p2->p_pid);
SDT_PROBE(proc, kernel, , create, p2, p1, flags, 0, 0);
/*
OpenPOWER on IntegriCloud