Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 20 Feb 1999 00:56:11 +1100
From:      Bruce Evans <bde@zeta.org.au>
To:        current@FreeBSD.ORG, semen@iclub.nsu.ru
Subject:   Re: swaper(?) bug (or feature) ?
Message-ID:  <199902191356.AAA31790@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>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




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