Re: On the issue of low memory situations

From: Nicholas Vinen (hb@sonique.com)
Date: Sat Mar 18 2000 - 18:07:52 EST


On Sun, 19 Mar 2000, Chris Wedgwood wrote:

> On Fri, Mar 17, 2000 at 04:24:49PM -0800, Linda Walsh wrote:
>
> > I haven't read through this whole thread, so this may have been
> > suggested, but why not have a new signal "SIGNMEM". Can't be caught but
> > can be ignored. Default is to take the signal and terminate the program
> > that faulted. If ignored, put process to sleep until the memory request
> > can be satisfied. Then something like 'X' or apache could ignore, while
> > 'gcc' would just die.
>
> We've run out of non-rt signals. We could bump this up a bit and if
> we do decide to it should be done _now_ to minimize and ABI breakage
> later on (I've been looking at such a thing myself recently).
>
> The sticky part is -- I'm not sure how well this will work with glibc
> as it seems to have similar assumptions in there.
>
> I really hope that if we do even need to extend this, we don't end up
> with multiple signal system calls to maintain backwards
> compatibility, such a thing is horribly ugly IMO.

   Another libc issue. The way I see this working, you get SIGNMEM (or
whatever) then one of your options is to free some memory. However, when
you free() or delete [], pages are still allocated. A CLib call, similar
to "int flushheap()" will need to be implemented, which finds all pages in
the heap which are totally unallocated and uses some kind of syscall to
turn them back into COW pages (then returning the count, so you can tell
if you really managed to free any memory).

   This sounds like a pretty good idea to me though. Right now there's no
particularly good way to do such things. E.g. you allocate lots of small
blocks, free many of them. Then you go to allocate one large block.
There's no contiguous space large enough. Say you don't have enough pages
either - SIGNMEM happens - at which time you do flushheap() which returns
the fragmented memory (or at least some of it) to the page pool, thus
allowing you to brk() and actually allocate the memory - it was
effectively just defragmented by the memory page mapping scheme :)

   SIGNMEM should also set some kind of global variable (similar to errno)
like "memdeficit" which is how many more pages would need to be freed to
continue, letting you decide by flushheap()'s return value whether your
program can continue or not. Also, during SIGNMEM on SMP systems, all
other processors must sleep. Otherwise the memory situation may not be
stable across its execution.

   Finally, each process should have a "minimum free page" count that is
used to decide when it's time to call SIGNMEM. All processes can set this
up but you have to be root to set it down and it should be inherited.
Similarly there should be a value which is "memory priority". This will
let more important tasks take RAM from less important tasks when RAM
runs low - especially your low memory handler process. It can then check
the memory priority of all processes when SIGNMEMs start happening and
kill the biggest memory hog with lowest priority.

   Sound good? This kind of scheme seems like it should definately be an
improvement to me.

        Nicholas Vinen

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Mar 23 2000 - 21:00:26 EST