*BSD News Article 13562


Return to BSD News archive

Path: sserve!newshost.anu.edu.au!munnari.oz.au!ariel.ucs.unimelb.EDU.AU!werple.apana.org.au!news
From: andrew@werple.apana.org.au (Andrew Herbert)
Newsgroups: comp.os.386bsd.bugs
Subject: Re: kmem_map overflow with 0.2.2 kernel (a fix)
Date: 29 Mar 1993 12:12:41 +1000
Organization: werple public-access unix, Melbourne
Lines: 82
Message-ID: <1p5lup$osq@werple.apana.org.au>
References: <C4Kw3q.C6M@sugar.neosoft.com> <f0#VeOr@quack.kfu.com> <CGD.93Mar28094535@erewhon.CS.Berkeley.EDU>
NNTP-Posting-Host: werple.apana.org.au

cgd@erewhon.CS.Berkeley.EDU (Chris G. Demetriou) writes:

>i'm not sure (i'm in the process of tracking it down),
>but there's either something *awfully* kernel-malloc-intensive someplace
>in the disk usage code, or (more likely in my opinion),
>there's a memory leak some place or other...

I solved this problem by ensuring that the buffer cache, which likes doing
malloc(x, M_TEMP) calls and turns out to be by far the main user (spacewise)
of kmem_map, is never able to consume all of the memory available in this
map.  vmstat was invaluable in tracking it down - I'm surprised this program
still hasn't made it into the patchkit.

On my 16MB machine, I set NKMEMCLUSTERS to (3072*1024/CLBYTES) in
/sys/i386/include/param.h and changed wfj's /sys/i386/i386/machdep.c
bufpages fix from:

	bufpages = min(NKMEMCLUSTERS/2, bufpages);
to
	bufpages = min(NKMEMCLUSTERS*2/5, bufpages);

No doubt this is more conservative than is required to avoid the panics, but
it certainly works 100% for me.  I'm certainly looking forward to 386bsd 0.2
which I hear solves this properly with a unified buffer-cache/vm system. :)

It may also help to apply the following mods to /sys/vm/vm_kern.c - the
vm_map_simplify()s should prevent fragmentation.  (vm_map_simplify() lines
courtesy of John Dyson - formerly dyson@ref.tfs.com :(

Andrew

*** vm_kern.c.unhacked	Mon Oct  5 19:28:21 1992
--- vm_kern.c	Tue Feb  2 21:18:29 1993
***************
*** 214,219 ****
--- 214,220 ----
  	vm_size_t		size;
  {
  	(void) vm_map_remove(map, trunc_page(addr), round_page(addr + size));
+ 	vm_map_simplify(map, addr);
  }
  
  /*
***************
*** 369,377 ****
  
  	if (vm_map_find(map, NULL, (vm_offset_t)0,
  			&addr, size, TRUE) != KERN_SUCCESS) {
! 		if (canwait)
! 			panic("kmem_malloc: kmem_map too small");
! 		return(0);
  	}
  
  	/*
--- 370,386 ----
  
  	if (vm_map_find(map, NULL, (vm_offset_t)0,
  			&addr, size, TRUE) != KERN_SUCCESS) {
! 		if (!canwait) {
! 			if (map == kmem_map)
! 				panic("kmem_malloc: kmem_map too small");
! #if 0
! 			else if (map == mb_map)
! 				printf("kmem_malloc: mb_map too small (can't wait)\n");
! 			else if (map == buffer_map)
! 				printf("kmem_malloc: buffer_map too small (can't wait)\n");
! #endif
! 		}
! 		return 0;
  	}
  
  	/*
***************
*** 576,581 ****
--- 585,591 ----
  	(void) vm_map_delete(map, trunc_page(addr), round_page(addr + size));
  	thread_wakeup((int)map);
  	vm_map_unlock(map);
+ 	vm_map_simplify(map, addr);
  }
  
  /*