Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 04 Jan 2002 20:14:47 +0300
From:      "Vladimir B.Grebenschikov" <vova@sw.ru>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/33542: a few of swapping completly freeze system with large number of processes
Message-ID:  <E16MXvb-0001s1-00@vbook.express.ru>

next in thread | raw e-mail | index | archive | help

>Number:         33542
>Category:       kern
>Synopsis:       a few of swapping completly freeze system with large number of processes
>Confidential:   no
>Severity:       critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Jan 04 09:20:01 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Vladimir B. Grebenschikov
>Release:        FreeBSD 4.4-RELEASE i386
>Organization:
SWsoft
>Environment:
System: FreeBSD vbook.express.ru 4.4-RELEASE FreeBSD
>Description:
vmdaemon process (function vm_daemon() in kernel) runs through list of
processes and looks at all nested memory objects.

Kernel spends too long time ( 20-30 secs per cycle on system with 1000-2000 processes )
running through processes list in vm_daemon() (pageouting processes)
 and system seems to be completly freezed (only network interrupts is servering) when
vm_daemon does not asleep.
>How-To-Repeat:
run large number of processes and reach end of real memory (until swapping begins)
>Fix:
This patch is far of ideal. But system responds on commands and seems
workable while pageout with it.

There are two sysctl variables to control pageout cycle:
vm.pageout_run_ticks  - how long vmdaemon runs at once (in ticks)
vm.pageout_skip_ticks - how long vmdaemon sleeps before continue run through processes list (in ticks)
                        but vmdaemon will be awaken if new wakeup() called.

patch related to RELENG_4

--- sys/vm/vm_pageout.c.orig	Wed Dec 26 04:28:12 2001
+++ sys/vm/vm_pageout.c	Fri Jan  4 19:49:04 2002
@@ -143,6 +143,9 @@
 static int defer_swap_pageouts=0;
 static int disable_swap_pageouts=0;
 
+static int pageout_run_ticks=50;
+static int pageout_skip_ticks=50;
+
 #if defined(NO_SWAPPING)
 static int vm_swap_enabled=0;
 static int vm_swap_idle_enabled=0;
@@ -191,6 +194,12 @@
 SYSCTL_INT(_vm, OID_AUTO, pageout_lock_miss,
 	CTLFLAG_RD, &pageout_lock_miss, 0, "vget() lock misses during pageout");
 
+SYSCTL_INT(_vm, OID_AUTO, pageout_run_ticks,
+	CTLFLAG_RW, &pageout_run_ticks, 0, "Pageout maximail run on single awake in ticks");
+
+SYSCTL_INT(_vm, OID_AUTO, pageout_skip_ticks,
+	CTLFLAG_RW, &pageout_skip_ticks, 0, "Pageout skip ticks after single run");
+
 #define VM_PAGEOUT_PAGE_COUNT 16
 int vm_pageout_page_count = VM_PAGEOUT_PAGE_COUNT;
 
@@ -1433,10 +1442,13 @@
 static void
 vm_daemon()
 {
+	static int pid = 0;
 	struct proc *p;
+	int timo = 0;
+	int cycleticks;		
 
 	while (TRUE) {
-		tsleep(&vm_daemon_needed, PPAUSE, "psleep", 0);
+		tsleep(&vm_daemon_needed, PPAUSE, "psleep", timo);
 		if (vm_pageout_req_swapout) {
 			swapout_procs(vm_pageout_req_swapout);
 			vm_pageout_req_swapout = 0;
@@ -1446,7 +1458,28 @@
 		 * process is swapped out -- deactivate pages
 		 */
 
-		for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
+		cycleticks = ticks;
+
+		if (pid == 0)
+		  p = allproc.lh_first;
+		else {
+		  p = pfind(pid);
+		  if (p) {
+		    p = p->p_list.le_next;
+		    if (!p) p = allproc.lh_first;
+		  }
+		}
+		
+		if (!p)
+		  for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
+		    if (p->p_pid < pid)
+		      break;
+		  }
+
+		if (!p)
+		  p = allproc.lh_first;
+
+		for (; p != 0; p = p->p_list.le_next) {
 			vm_pindex_t limit, size;
 
 			/*
@@ -1479,11 +1512,26 @@
 				limit = 0;	/* XXX */
 
 			size = vmspace_resident_count(p->p_vmspace);
+
+			if (ticks - cycleticks > pageout_run_ticks)
+				break;
+			
 			if (limit >= 0 && size >= limit) {
 				vm_pageout_map_deactivate_pages(
 				    &p->p_vmspace->vm_map, limit);
 			}
 		}
+
+                if (vm_page_count_target()) {
+                       pid = (p) ? p->p_pid : 0;
+                       /* sleep a bit - to give system possibility to do somet
+                       timo = pageout_skip_ticks;                        
+                } else {
+                       pid = 0;
+                       /* sleep until awake */
+                       timo = 0;
+                }
+                		
 	}
 }
 #endif
>Release-Note:
>Audit-Trail:
>Unformatted:

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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?E16MXvb-0001s1-00>