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 
>                                           <dil...@backplane.com>
> 
> 

 Brian Feldman                _ __ ___ ____  ___ ___ ___  
 gr...@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 majord...@freebsd.org
with "unsubscribe freebsd-current" in the body of the message

Reply via email to