Subject: port-i386/3404: paging values may be too low
To: None <gnats-bugs@gnats.netbsd.org>
From: George Navas <navas@bayarea.net>
List: netbsd-bugs
Date: 03/28/1997 17:05:48
>Number:         3404
>Category:       port-i386
>Synopsis:       paging values may be too low
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Fri Mar 28 17:20:01 1997
>Last-Modified:
>Originator:     George Navas
>Organization:
Bayarea Internet Solutions

George E. Navas   		navas@bayarea.net
Voice: (408)260-5000  		Fax:(408)260-5003 	http://www.bayarea.net
>Release:        NetBSD baygate 1.2C, March 8, 1997
>Environment:
	
System: NetBSD baygate 1.2C NetBSD 1.2C (ANCHOR) #6: Thu Mar 27 21:04:49 PST 1997 navas@shell2:/usr/src.12cmar8/sys/arch/i386/compile/ANCHOR i386


>Description:

Not quite sure if this a bug, but perhaps the following values need to be revisited now that
is not uncommon for a netbsd machine to have 128 megabytes of memory. From my humble 
understanding of how the code is working, it appears that the certian values in vm_pageout.c 
may be very low. The current values are set as follows:   

	 vm_page_free_min_min = 16 * 1024;
	 vm_page_free_min_max = 256 * 1024;

If my understanding is correct, as a result of the vm_page_free_min_min the cnt.v_free_min
is used in vm_page.c as one of the determinations of when to start reclaiming pages. This 
algorithm seems to work well if all is resident in main memory and activity is low. However, if all 
of a sudden  a high demand of memory is requested such as starting numerous pids at a given moment, 
the system does not free enough pages fast enough to keep up with the demand. This translates 
into what appears to be a system hung condition, and eventually if you give enough time 
it may recover based on the demand. However, it appears that from the preliminary tests that
we have conducted in our production environment and our test environment, that a much higher 
value such as in the megabyte ranges allows the system to operate a lot more smoothly since
it allows it to maintain a larger size of available memory. This does mean that you 
increase your paging activity slightly since you will start reclaiming pages earlier, but overall
it give the interactive/active users a smoother performance of the system. 

Please note that the above scenario is apparent when we run a few hundred pids on the system, 
and can be recreated using the simple program included below. Perhaps this could be 
made into an option or an algorithm that is calculated based on the amount of real memory since
running on a 16meg machine this may be quite adequate, but running on a 128 meg machine and 
very soon on a 256 meg machine, a value of only 16k for  vm_page_free_min_min may be way too
small for the type of burst-load that it can generate. 

>How-To-Repeat:

/*
 * Program to exercise the number of tasks and memory
 *
 * usage:    forks -f children -m memory_per_child [-v]  [-s sleeptime]
 *		where children is the number of children
 *		memory_per_child is memory allocated
 *		-v for verbose
 */

#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>

extern char     *optarg;
extern int      optind;

main(int argc, char **argv)
{
	char	*ptr, c;
	int	i, j, pid, cpuloop;
	int	vflag=0;
	int	children=10;
	int	memsize= 102400;
	int	sleeptime= 60;


        /*
         * Default
	 * 	-f 10 
	 *      -m 102400
	 *      -s 60     
         */
        while ((c = getopt(argc, argv, "s:vf:m:")) != -1)
                switch (c) {
                  case 'f': children = atoi(optarg); break;
                  case 'm': memsize= atoi(optarg); break;
                  case 's': sleeptime = atoi(optarg); break;
                  case 'v': vflag++; break;
                  default:
                  case '?':  
			printf ("Usage %s -f children -m memsize \n");
			return(1);
                }


	for ( j = 0; j < children; j++){
		if ( (pid = fork() ) == 0 ){

				if ( (ptr = (char *) malloc(memsize) )== NULL ){
					printf("Memory allocation failed for %d \n", memsize);
					return(0);
				}
				memset(ptr, 1,  memsize);
				sleep(sleeptime);
				if ( vflag) 
					printf("%d bytes zapped\n", memsize );
				return(0);
			
		}
		if ( pid == -1 ){
			perror("fork failed ");
		}
		if ( pid ) {
			printf(" pid %d started with pid number = %d\n", j, pid);
			
		}
	}
}
>Fix:
	Increase the values based on the amount of real memory you have
>Audit-Trail:
>Unformatted: