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>