Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 17 Jul 1999 15:00:02 +0200
From:      Peter Holm <peter@holm.cc>
To:        Freebsd-current@freebsd.org
Subject:   Out of swap handling
Message-ID:  <37907E52.7A257D9E@holm.cc>

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------2FD23224575AA298CF8FBAE3
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

I have tested out of swap handling in current. The situation is that the

system just lockes up, "looping" in vm_pageout_scan.

I have experimented with some modifications to vm_pageout.c that seems
to
improve the chances for a recovery drastically.
All tests were done on my 128Mb RAM / 256 Mb swap box.

The changes consists of:
*       Killing all running user processes when less than 1024 pages
swap left.
*       Sleeping after each kill to allow the user process to run.
*       Pausing the  vmdaemon when in kill mode.

I have tried different strategies for when to stop killing but only this
one seems
to guaranty recovery.

I have included my changes.

Regards,
--
Peter Holm | mailto:peter@holm.cc | http://login.dknet.dk/~pho/
  -[ Member of the BSD-Dk User Group / http://www.bsd-dk.dk/ ] -


--------------2FD23224575AA298CF8FBAE3
Content-Type: text/plain; charset=us-ascii;
 name="patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="patch"

*** sys/vm/vm_pageout.c~	Sun Jul  4 13:53:49 1999
--- sys/vm/vm_pageout.c	Sat Jul 17 13:51:39 1999
***************
*** 154,159 ****
--- 154,162 ----
  static int vm_swap_idle_enabled=0;
  #endif
  
+ static int kill_mode = 0;
+ static pid_t last_killed_pid = 0;
+ 
  SYSCTL_INT(_vm, VM_PAGEOUT_ALGORITHM, pageout_algorithm,
  	CTLFLAG_RW, &vm_pageout_algorithm_lru, 0, "LRU page mgmt");
  
***************
*** 204,209 ****
--- 207,213 ----
  #endif
  static void vm_pageout_page_stats(void);
  
+ 
  /*
   * vm_pageout_clean:
   *
***************
*** 1126,1175 ****
  	}
  
  	/*
! 	 * make sure that we have swap space -- if we are low on memory and
  	 * swap -- then kill the biggest process.
  	 */
! 	if ((vm_swap_size == 0 || swap_pager_full) &&
! 	    ((cnt.v_free_count + cnt.v_cache_count) < cnt.v_free_min)) {
! 		bigproc = NULL;
! 		bigsize = 0;
! 		for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
! 			/*
! 			 * if this is a system process, skip it
! 			 */
! 			if ((p->p_flag & P_SYSTEM) || (p->p_lock > 0) ||
! 			    (p->p_pid == 1) ||
! 			    ((p->p_pid < 48) && (vm_swap_size != 0))) {
! 				continue;
! 			}
! 			/*
! 			 * if the process is in a non-running type state,
! 			 * don't touch it.
! 			 */
! 			if (p->p_stat != SRUN && p->p_stat != SSLEEP) {
! 				continue;
  			}
! 			/*
! 			 * get the process size
! 			 */
! 			size = vmspace_resident_count(p->p_vmspace);
! 			/*
! 			 * if the this process is bigger than the biggest one
! 			 * remember it.
! 			 */
! 			if (size > bigsize) {
! 				bigproc = p;
! 				bigsize = size;
  			}
! 		}
! 		if (bigproc != NULL) {
! 			killproc(bigproc, "out of swap space");
! 			bigproc->p_estcpu = 0;
! 			bigproc->p_nice = PRIO_MIN;
! 			resetpriority(bigproc);
! 			wakeup(&cnt.v_free_count);
! 		}
! 	}
  	return force_wakeup;
  }
  
--- 1130,1196 ----
  	}
  
  	/*
! 	 * make sure that we have swap space -- if we are low on
  	 * swap -- then kill the biggest process.
  	 */
! #ifdef NO_SWAPPING
! 	if (kill_mode)
! 		kill_mode = ((cnt.v_free_count + cnt.v_cache_count) <
! 				3*cnt.v_free_min);
! 	else
! 		kill_mode = ((cnt.v_free_count + cnt.v_cache_count) <
! 				cnt.v_free_min);
! #else
! 	if (kill_mode)
! 		kill_mode = (vm_swap_size < 3072);
! 	else
! 		kill_mode = (vm_swap_size < 1024);
! #endif
! 		
! 	if (kill_mode) { /* Kill all running user procs, biggest first */
! 		do {
! 			bigproc = NULL;
! 			bigsize = 0;
! 			for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
! 				/*
! 				 * if this is a system process, skip it
! 				 */
! 				if ((p->p_flag & P_SYSTEM) || (p->p_lock > 0) ||
! 				    (p->p_pid == 1) ||
! 				    ((p->p_pid < 48) && (vm_swap_size != 0))) {
! 					continue;
! 				}
! 				/*
! 				 * if the process is in a non-running type state,
! 				 * don't touch it.
! 				 */
! 				if (p->p_stat != SRUN) continue;
! 				if (p->p_siglist & (SIGKILL | P_WEXIT)) continue;
! 				if (p->p_cred->p_ruid < 2) continue;
! 				if (p->p_pid == last_killed_pid) continue;
! 				/*
! 				 * get the process size
! 				 */
! 				size = vmspace_resident_count(p->p_vmspace);
! 				/*
! 				 * if the this process is bigger than the biggest one
! 				 * remember it.
! 				 */
! 				if (size > bigsize) {
! 					bigproc = p;
! 					bigsize = size;
! 				}
  			}
! 			if (bigproc != NULL) {
! 				killproc(bigproc, "out of swap space");
! 				last_killed_pid = bigproc->p_pid;
! 				s = splvm();
! 				tsleep(&vm_pages_needed, PVM, "psleep", hz/30);
! 				splx(s);
  			}
! 		} while (bigproc);
! 	} /* kill mode */
! 	wakeup(&cnt.v_free_count);
  	return force_wakeup;
  }
  
***************
*** 1404,1411 ****
--- 1425,1439 ----
  vm_daemon()
  {
  	struct proc *p;
+ 	int s;
  
  	while (TRUE) {
+ 		if (kill_mode) {
+                         /* Give killed user procs a chance to die */
+ 			s = splvm();
+ 			tsleep(&vm_pages_needed, PVM, "psleep", hz);
+ 			splx(s);
+ 		}
  		tsleep(&vm_daemon_needed, PPAUSE, "psleep", 0);
  		if (vm_pageout_req_swapout) {
  			swapout_procs(vm_pageout_req_swapout);
*** sys/vm/swap_pager.c~	Tue Jun 29 21:45:31 1999
--- sys/vm/swap_pager.c	Fri Jul 16 17:49:45 1999
***************
*** 214,220 ****
--- 214,222 ----
  {
  	if (vm_swap_size < nswap_lowat) {
  		if (swap_pager_almost_full == 0) {
+ #ifdef DISGNOSTIC
  			printf("swap_pager: out of swap space\n");
+ #endif
  			swap_pager_almost_full = 1;
  		}
  	} else {
***************
*** 470,476 ****
--- 472,480 ----
  
  	if ((blk = blist_alloc(swapblist, npages)) == SWAPBLK_NONE) {
  		if (swap_pager_full != 2) {
+ #ifdef DIAGNOSTIC
  			printf("swap_pager_getswapspace: failed\n");
+ #endif
  			swap_pager_full = 2;
  			swap_pager_almost_full = 1;
  		}

--------------2FD23224575AA298CF8FBAE3--



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?37907E52.7A257D9E>