Whoop.  Ok, here's a new patch.  I think this covers all the cases.
    I've done some testing and it appears to do the right thing, please
    look it over (the last patch had type-o's and didn't cover the correct
    cases).

                                                -Matt

Index: kern/kern_exit.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_exit.c,v
retrieving revision 1.187
diff -u -r1.187 kern_exit.c
--- kern/kern_exit.c    10 Dec 2002 02:33:44 -0000      1.187
+++ kern/kern_exit.c    15 Dec 2002 01:45:15 -0000
@@ -287,7 +287,15 @@
         * Need to do this early enough that we can still sleep.
         * Can't free the entire vmspace as the kernel stack
         * may be mapped within that space also.
+        *
+        * Processes sharing the same vmspace may exit in one order, and
+        * get cleaned up by vmspace_exit() in a different order.  The
+        * last exiting process to reach this point releases as much of
+        * the environment as it can, and the last process cleaned up
+        * by vmspace_exit() (which decrements exitingcnt) cleans up the
+        * remainder.
         */
+       ++vm->vm_exitingcnt;
        if (--vm->vm_refcnt == 0) {
                if (vm->vm_shm)
                        shmexit(p);
@@ -297,7 +305,6 @@
                vm_page_unlock_queues();
                (void) vm_map_remove(&vm->vm_map, vm_map_min(&vm->vm_map),
                    vm_map_max(&vm->vm_map));
-               vm->vm_freer = p;
        }
 
        sx_xlock(&proctree_lock);
Index: vm/vm_map.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/vm_map.c,v
retrieving revision 1.273
diff -u -r1.273 vm_map.c
--- vm/vm_map.c 1 Dec 2002 18:57:56 -0000       1.273
+++ vm/vm_map.c 15 Dec 2002 02:05:13 -0000
@@ -258,7 +258,7 @@
        vm->vm_map.pmap = vmspace_pmap(vm);             /* XXX */
        vm->vm_refcnt = 1;
        vm->vm_shm = NULL;
-       vm->vm_freer = NULL;
+       vm->vm_exitingcnt = 0;
        return (vm);
 }
 
@@ -304,7 +304,7 @@
        if (vm->vm_refcnt == 0)
                panic("vmspace_free: attempt to free already freed vmspace");
 
-       if (--vm->vm_refcnt == 0)
+       if (--vm->vm_refcnt == 0 && vm->vm_exitingcnt == 0)
                vmspace_dofree(vm);
 }
 
@@ -314,11 +314,22 @@
        struct vmspace *vm;
 
        GIANT_REQUIRED;
-       if (p == p->p_vmspace->vm_freer) {
-               vm = p->p_vmspace;
-               p->p_vmspace = NULL;
+       vm = p->p_vmspace;
+       p->p_vmspace = NULL;
+
+       /*
+        * cleanup by parent process wait()ing on exiting child.  vm_refcnt
+        * may not be 0 (e.g. fork() and child exits without exec()ing).
+        * exitingcnt may increment above 0 and drop back down to zero
+        * several times while vm_refcnt is held non-zero.  vm_refcnt
+        * may also increment above 0 and drop back down to zero several 
+        * times while vm_exitingcnt is held non-zero.
+        * 
+        * The last wait on the exiting child's vmspace will clean up 
+        * the remainder of the vmspace.
+        */
+       if (--vm->vm_exitingcnt == 0 && vm->vm_refcnt == 0)
                vmspace_dofree(vm);
-       }
 }
 
 /*
Index: vm/vm_map.h
===================================================================
RCS file: /home/ncvs/src/sys/vm/vm_map.h,v
retrieving revision 1.92
diff -u -r1.92 vm_map.h
--- vm/vm_map.h 22 Sep 2002 04:33:43 -0000      1.92
+++ vm/vm_map.h 15 Dec 2002 01:47:49 -0000
@@ -218,8 +218,8 @@
        caddr_t vm_taddr;       /* (c) user virtual address of text */
        caddr_t vm_daddr;       /* (c) user virtual address of data */
        caddr_t vm_maxsaddr;    /* user VA at max stack growth */
-#define        vm_endcopy vm_freer
-       struct proc *vm_freer;  /* vm freed on whose behalf */
+#define        vm_endcopy vm_exitingcnt
+       int     vm_exitingcnt;  /* several processes zombied in exit1  */
 };
 
 #ifdef _KERNEL

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to