*BSD News Article 14133


Return to BSD News archive

Path: sserve!newshost.anu.edu.au!munnari.oz.au!ariel.ucs.unimelb.EDU.AU!werple.apana.org.au!news
From: andrew@werple.apana.org.au (Andrew Herbert)
Newsgroups: comp.os.386bsd.bugs
Subject: some fixes for vm/vm_object.c
Date: 7 Apr 1993 23:16:27 +1000
Organization: werple public-access unix, Melbourne
Lines: 116
Message-ID: <1puk7b$p5@werple.apana.org.au>
NNTP-Posting-Host: werple.apana.org.au

Here are some fixes I derived from the mach 3.0 VM system a couple of months
ago.  At the time, I was giving the memory object routines a good looking
at, trying to fix the long-standing problem where vm_object_collapse()
sometimes fails to collapse objects left over from the exit of a forked
child.  As bde has noted, the problem seems to occur when portions of the
parent are paged out.  These "lost" memory objects, which can eat up a huge
amount of swap space, are reclaimed when the parent responsible for the
fork()s is killed.  Here on werple, sendmail and innd (which forks nnrpds)
are the worst offenders, generally consuming about 10 MB of swap per day (as
measured by Kevin Lahey's excellent swapinfo program - thanks Kevin!).

I didn't manage to fix the problem, but I feel these patches are a move in
the right direction. :)

Andrew
--
*** /sys/vm/vm_object.c.unhacked	Wed Dec 25 09:24:23 1991
--- /sys/vm/vm_object.c	Mon Feb 15 11:39:00 1993
***************
*** 454,460 ****
  	while (!queue_end(&object->memq, (queue_entry_t) p)) {
  		next = (vm_page_t) queue_next(&p->listq);
  		vm_page_lock_queues();
! 		vm_page_deactivate(p);
  		vm_page_unlock_queues();
  		p = next;
  	}
--- 454,464 ----
  	while (!queue_end(&object->memq, (queue_entry_t) p)) {
  		next = (vm_page_t) queue_next(&p->listq);
  		vm_page_lock_queues();
! 		if (!p->busy)
! 			vm_page_deactivate(p);	/* optimisation from mach 3.0 -
! 						 * andrew@werple.apana.org.au,
! 						 * Feb '93
! 						 */
  		vm_page_unlock_queues();
  		p = next;
  	}
***************
*** 1141,1152 ****
--- 1145,1173 ----
  				    }
  				    else {
  					if (pp) {
+ #if 1
+ 					    /*
+ 					     *  This should never happen -- the
+ 					     *  parent cannot have ever had an
+ 					     *  external memory object, and thus
+ 					     *  cannot have absent pages.
+ 					     */
+ 					    panic("vm_object_collapse: bad case");
+ 					    /* andrew@werple.apana.org.au - from
+ 					       mach 3.0 VM */
+ #else
  					    /* may be someone waiting for it */
  					    PAGE_WAKEUP(pp);
  					    vm_page_lock_queues();
  					    vm_page_free(pp);
  					    vm_page_unlock_queues();
+ #endif
  					}
+ 					/*
+ 					 *	Parent now has no page.
+ 					 *	Move the backing object's page
+ 					 *	up.
+ 					 */
  					vm_page_rename(p, object, new_offset);
  				    }
  				}
***************
*** 1161,1167 ****
--- 1182,1202 ----
  			 */
  
  			object->pager = backing_object->pager;
+ #if 1
+ 			/* Mach 3.0 code */
+ 			/* andrew@werple.apana.org.au, 12 Feb 1993 */
+ 
+ 			/*
+ 			 * If there is no pager, leave paging-offset alone.
+ 			 */
+ 			if (object->pager)
+ 				object->paging_offset =
+ 					backing_object->paging_offset +
+ 						backing_offset;
+ #else
+ 			/* old VM 2.5 version */
  			object->paging_offset += backing_offset;
+ #endif
  
  			backing_object->pager = NULL;
  
***************
*** 1259,1264 ****
--- 1294,1311 ----
  
  			vm_object_reference(object->shadow = backing_object->shadow);
  			object->shadow_offset += backing_object->shadow_offset;
+ 
+ #if 1
+ 			/* Mach 3.0 code */
+ 			/* andrew@werple.apana.org.au, 12 Feb 1993 */
+ 
+ 			/*
+ 			 *      Backing object might have had a copy pointer
+ 			 *      to us.  If it did, clear it.
+ 			 */
+ 			 if (backing_object->copy == object)
+ 				backing_object->copy = NULL;
+ #endif
  
  			/*	Drop the reference count on backing_object.
  			 *	Since its ref_count was at least 2, it