From owner-freebsd-current Fri Feb 19 5:56:19 1999 Delivered-To: freebsd-current@freebsd.org Received: from godzilla.zeta.org.au (godzilla.zeta.org.au [203.26.10.9]) by hub.freebsd.org (Postfix) with ESMTP id 45DC711684 for ; Fri, 19 Feb 1999 05:56:12 -0800 (PST) (envelope-from bde@godzilla.zeta.org.au) Received: (from bde@localhost) by godzilla.zeta.org.au (8.8.7/8.8.7) id AAA31790; Sat, 20 Feb 1999 00:56:11 +1100 Date: Sat, 20 Feb 1999 00:56:11 +1100 From: Bruce Evans Message-Id: <199902191356.AAA31790@godzilla.zeta.org.au> To: current@FreeBSD.ORG, semen@iclub.nsu.ru Subject: Re: swaper(?) bug (or feature) ? Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG >running 4.0-current from late january i've got folloing: >top tells: > >... >Mem: 11M Active, 952K Inact, 5712K Wired, 640K Cache, 3348K Buf, 11M Free >Swap: 106M Total, 106M Used, 232K Free, 99% Inuse >... > >regardless 11M Free, almost all programs fail: > ># cat >cat: Cannot allocate memory This bug is more obvious when there is no swap. I use the following quick fix for part of it: --- diff -c2 vm_unix.c~ vm_unix.c *** vm_unix.c~ Fri Feb 12 19:56:24 1999 --- vm_unix.c Fri Feb 12 19:56:27 1999 *************** *** 94,100 **** if (new > old) { vm_size_t diff; ! if (swap_pager_full) { ! return (ENOMEM); ! } diff = new - old; rv = vm_map_find(&vm->vm_map, NULL, 0, &old, diff, FALSE, --- 94,98 ---- if (new > old) { vm_size_t diff; ! diff = new - old; rv = vm_map_find(&vm->vm_map, NULL, 0, &old, diff, FALSE, --- The orginal of the above code (in obreak()) is rather silly. It gives up very easily, although the swapper may be in the process of freeing some memory and all (?) other parts of the system just wait for memory to become free. The behaviour is silliest when there is no swap. Then swap_pager_full is never cleared, because the high watermark for free swap is > 0 which can never be exceeded when there is no swap. Things apparently worked better in 3.0 because the code corresponding to the following in swap_pager.c didn't spew messages or set swap_pager_full, at least in the no-swap-at-all case: ! if ((blk = blist_alloc(swapblist, npages)) == SWAPBLK_NONE) { ! if (swap_pager_full != 2) { ! printf("swap_pager_getswapspace: failed\n"); ! swap_pager_full = 2; ! } ! } else { ! vm_swap_size -= npages; ! swp_sizecheck(); ! } Normally, when there is no free swap, free memory is found somewhere else on return from the above code, and obreak() has no problems using that memory if it tries. >luck is that kill works :-) after i kill the process eating all swap >space all went OK. The swap watermarks are apparently breaking the automatic killing of the biggest process. They are supposed to be just to control the spew from the above printf, but since swap_pager_full is used in obreak() and for killing the biggest process, setting it to control the spew has bad side effects. Bruce To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message