kernel: Add a final p_lock wait loop before kfree'ing the process
authorYONETANI Tomokazu <y0netan1@dragonflybsd.org>
Mon, 6 Jun 2011 05:09:04 +0000 (14:09 +0900)
committerYONETANI Tomokazu <y0netan1@dragonflybsd.org>
Mon, 6 Jun 2011 05:09:04 +0000 (14:09 +0900)
Since p_lock can be acquired during the process removal, there
needs to be a final wait loop after the proc has been removed
from all queues, just before the kfree(p).  It will be a very
rare case but it definitely can still occur if e.g. the SYSCTL_OUT
code blocks on a VM fault or something like that.

Requested-by: dillon@
Dragonfly-bug: <http://bugs.dragonflybsd.org/issue1996>

sys/kern/kern_exit.c

index c5592c3..3ddbb96 100644 (file)
@@ -933,6 +933,16 @@ loop:
                        }
 
                        vm_waitproc(p);
+
+                       /*
+                        * Temporary refs may still have been acquired while
+                        * we removed the process, make sure they are all
+                        * gone before kfree()ing.  Now that the process has
+                        * been removed from all lists and all references to
+                        * it have gone away, no new refs can occur.
+                        */
+                       while (p->p_lock)
+                               tsleep(p, 0, "reap4", hz);
                        kfree(p, M_PROC);
                        nprocs--;
                        error = 0;