Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 11 Apr 1999 21:11:08 -0400 (EDT)
From:      Brian Feldman <green@unixhelp.org>
To:        Matthew Dillon <dillon@apollo.backplane.com>
Cc:        current@FreeBSD.ORG
Subject:   Re: swap-related problems
Message-ID:  <Pine.BSF.4.05.9904112100260.35407-100000@janus.syracuse.net>
In-Reply-To: <199904120004.RAA08629@apollo.backplane.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, 11 Apr 1999, Matthew Dillon wrote:

> :It seems that something has broken the good ol' swap behavior. For instance,
> :I have my user-limits set to unlimited and I run something which uses up
> :all RAM. Mallocing never FAILS in the program, as brk() doesn't fail, as etc
> :etc etc. But mallocing continues, all swap space gets used, and both the
> :runaway process and the next biggest gets killed (XF86, of course).
> :  Matt, perhaps you can shed light on
> :	a. why mallocs still succeed after
> :swap_pager: out of swap space
> :swap_pager_getswapspace: failed
> :	   is displayed
> :	b. why the process continues and gets killed TWICE, or two different
> :		processes get killed
> :?
> :
> : Brian Feldman                _ __ ___ ____  ___ ___ ___  
> 
>     The thing with the processes getting killed twice or two different
>     processes being killed is due to the latency between sending the signal
>     to kill the process and the process actually going away.  In order to be
>     killed, the process must be woken up and allowed to run.

Then let's make sure the kill waits before it does that.

> 
>     malloc() still succeeds because it isn't actually touching the new memory,
>     and so the system doesn't actually reserve the memory as of the time of
>     the system call.  That is done by the user program later on after malloc()
>     returns.  malloc()'s limitations are based on the process resources, not
>     available memory.

I use the memory as soon as it's malloced. If it reserves a page, then
pagefaults it into existence, the VM system knows that that page is now
allocated. When I malloc the last available page for user use, the VM
system knows that it's the last page. I dirty it, and there are none
free. If I malloc(), I want to know that there is no more memory, not
have my process killed. This is POMA.

Previously, the POLA, a NULL getting returned, WORKED CORRECTLY. It did this
for a long time. My little test program always showed this, and shows
that now something was broken. I'll attach it to the end.

> 
>     It would not be appropriate to make malloc() fail in this situation because
>     this would result in N random programs getting malloc() failures rather
>     then one or two processes getting killed.  Having N random processes get
>     malloc() failures can lead to serious instability with processes.

Only bad code doesn't check return values of malloc().

> 
>     What might help in a situation like this would a way to flag certain
>     processes as being 'very important' ... that should only be killed as
>     a last resort, even if they have a relatively large RSS.

Yes, I was thinking of something like this for the X server.

> 
> 					    -Matt
> 					    Matthew Dillon 
> 					    <dillon@backplane.com>
> 
> 

 Brian Feldman                _ __ ___ ____  ___ ___ ___  
 green@unixhelp.org                _ __ ___ | _ ) __|   \ 
     FreeBSD: The Power to Serve!      _ __ | _ \__ \ |) |
         http://www.freebsd.org           _ |___/___/___/ 


ts=4

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 1024*1024

#ifdef OTHER_VER
const unsigned int junk[] = {
	0xdeadbeef,
	0xbeeff00d,
	0x133751ff,
	0xf33db34f
};
#endif

void
main(void) {
	int count, yep = 0;
	void *stfu[SIZE];
	void *mem;

	for (count = 0; count < SIZE; count++) {
		if ((mem = stfu[count] = malloc(1024))) {
			int where;
			printf("%p (%i) malloc'd\n", stfu[count], count);
			for (where = 0; where < (1024 / sizeof(unsigned)); where++)
				((unsigned *)mem)[where] =
#ifdef OTHER_VER
										 	junk[
#endif
													where
#ifdef OTHER_VER
															% 4]
#endif
																;
			yep++;
		}	
		else
			break;
	}
/*	free(stfu[yep--]); */
	for (count = 0; count < yep; count++) {
		int where;

		mem = stfu[count];
		for (where = 0; where < (1024 / sizeof(unsigned)); where++)
				if (((unsigned *)mem)[where] !=
#ifdef OTHER_VER
										 	junk[
#endif
													where
#ifdef OTHER_VER
															% 4]
#endif
																) {
					fprintf(stderr, "memory check failed at %i of %i:\n"
							"%#x != %#x\n", count, yep,
							((unsigned *)mem)[where],
#ifdef OTHER_VER
														junk[
#endif
															where
#ifdef OTHER_VER
																	% 4]
#endif
																		);
					exit(2);
				}
		free(stfu[count]);
		printf("%i free'd\n", count);
	}
	if (yep != SIZE) {
		printf("mallocs failed at %i\n", yep);
		exit (1);
	}
	else
		exit (0);
}




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?Pine.BSF.4.05.9904112100260.35407-100000>