Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 2 Jun 2001 21:45:29 -0700 (PDT)
From:      Matt Dillon <dillon@earth.backplane.com>
To:        hackers@FreeBSD.ORG
Cc:        Alfred Perlstein <bright@rush.net>
Subject:   Patch to fix code that kills procs when swap runs out (stable)
Message-ID:  <200106030445.f534jTA07246@earth.backplane.com>

next in thread | raw e-mail | index | archive | help
    I'll probably commit something similar to this to -current on sunday,
    and -stable next weekend.  This patch should fix the process killing
    part of the VM system.  It fixes two things:

    (1) It starts killing processes a little earlier, before the machine
	truely hoses itself.  This should avoid the deadlocks.

    (2) It locates the largest process by counting the approximate amount
	of swap used as well as the RSS.  Before it was just counting the
	RSS which resulted in it choosing the wrong process (often choosing
	small processes instead of large processes).

    Alfred, I'm cc'ing you.  If you have some time, could you check the
    vmspace_swap_count() routine?  What do I need to mutex it for -current?
    For -stable I don't think there's an issue since VM objects are not
    instantiated/destroyed by interrupts.

    All suggestions are welcome.

    --

    On another note, I am MFCing the O_DIRECT patches I did a weekend or two
    ago to -stable now.

						-Matt

Index: vm/vm_map.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/vm_map.c,v
retrieving revision 1.187.2.8
diff -u -r1.187.2.8 vm_map.c
--- vm/vm_map.c	2001/03/14 07:05:05	1.187.2.8
+++ vm/vm_map.c	2001/06/03 04:22:03
@@ -220,6 +220,41 @@
 }
 
 /*
+ * vmspace_swap_count() - count the approximate swap useage in pages for a
+ *			  vmspace.
+ *
+ *	Swap useage is determined by taking the proportional swap used by
+ *	VM objects backing the VM map.  To make up for fractional losses,
+ *	if the VM object has any swap use at all the associated map entries
+ *	count for at least 1 swap page.
+ */
+int
+vmspace_swap_count(struct vmspace *vmspace)
+{
+    vm_map_t map = &vmspace->vm_map;
+    vm_map_entry_t cur;
+    int count = 0;
+
+    for (cur = map->header.next; cur != &map->header; cur = cur->next) {
+	vm_object_t object;
+
+	if ((cur->eflags & MAP_ENTRY_IS_SUB_MAP) == 0 &&
+	    (object = cur->object.vm_object) != NULL &&
+	    object->type == OBJT_SWAP
+	) {
+	    int n = (cur->end - cur->start) / PAGE_SIZE;
+
+	    if (object->un_pager.swp.swp_bcount) {
+		count += object->un_pager.swp.swp_bcount * SWAP_META_PAGES * n /
+			object->size + 1;
+	    }
+	}
+    }
+    return(count);
+}
+
+
+/*
  *	vm_map_create:
  *
  *	Creates and returns a new empty VM map with
Index: vm/vm_map.h
===================================================================
RCS file: /home/ncvs/src/sys/vm/vm_map.h,v
retrieving revision 1.54.2.1
diff -u -r1.54.2.1 vm_map.h
--- vm/vm_map.h	2001/03/14 07:05:06	1.54.2.1
+++ vm/vm_map.h	2001/06/03 03:58:51
@@ -375,6 +375,7 @@
 void vm_freeze_copyopts __P((vm_object_t, vm_pindex_t, vm_pindex_t));
 int vm_map_stack __P((vm_map_t, vm_offset_t, vm_size_t, vm_prot_t, vm_prot_t, int));
 int vm_map_growstack __P((struct proc *p, vm_offset_t addr));
+int vmspace_swap_count __P((struct vmspace *vmspace));
 
 #endif
 #endif				/* _VM_MAP_ */
Index: vm/vm_pageout.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/vm_pageout.c,v
retrieving revision 1.151.2.7
diff -u -r1.151.2.7 vm_pageout.c
--- vm/vm_pageout.c	2000/12/30 01:51:12	1.151.2.7
+++ vm/vm_pageout.c	2001/06/03 04:12:27
@@ -1094,10 +1094,14 @@
 	}
 
 	/*
-	 * make sure that we have swap space -- if we are low on memory and
-	 * swap -- then kill the biggest process.
+	 * If we are out of swap and were not able to reach our paging
+	 * target, kill the largest process.
 	 */
+	if ((vm_swap_size < 64 && vm_page_count_min()) ||
+	    (swap_pager_full && vm_paging_target() > 0)) {
+#if 0
 	if ((vm_swap_size < 64 || swap_pager_full) && vm_page_count_min()) {
+#endif
 		bigproc = NULL;
 		bigsize = 0;
 		for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
@@ -1119,7 +1123,8 @@
 			/*
 			 * get the process size
 			 */
-			size = vmspace_resident_count(p->p_vmspace);
+			size = vmspace_resident_count(p->p_vmspace) +
+				vmspace_swap_count(p->p_vmspace);
 			/*
 			 * if the this process is bigger than the biggest one
 			 * remember it.

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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200106030445.f534jTA07246>