[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Swap overdraft

H C Lai wrote:
> Thanks for all the replies so far. The impression I get is that
> Linux does support the 'over-commitment' mode. Kernel 2.0.0 definitely
> does not support this. I have a ~10 lines of small fortran test
> programme which basically creates a HUGE array in a common block and
> then tries to use a small part of it. It failed with segmentation
> fault on elf. But succeeds by just putting in more swap !!

Hmm, don't know how Fortran handles this sort of thing.  Below is a
very quick & dirty C program I've used to test Linux's handling of at
least some cases of swap overcommitment.  A long time ago (kernel 1.0,
I think) running enough copies of this to cause overcommitment locked
the system up to the point of requiring a hardware reset.  I just tried
it on 2.0.25 and the program dies with a "Bus error" signal.

In case it's not obvious what's going on here, what the program does is
malloc() 20000K and then proceed to dirty (write to) each page.  Linux
will allow a program to allocate more virtual memory than exists -- all
that happens is that the process's address space is marked as usable and
mapped to a page of zeros, copy-on-write.  This allows (for example)
allocating a very large array that the programmer knows will be used only
very sparsely.

When a page is dirtied, real memory must be allocated and mapped in; if
this is done enough, something needs to be swapped out.  If all available
swap space is full, something needs to give.  Apparently, in 2.0 a process
is chosen and killed when it attempts to commit virtual memory beyond
some threshold.  (I'm just guessing here, I haven't tracked this down in
the kernel source.)

Here's my <EM>quick and dirty</EM> C program.  I have 24M RAM and 24M swap
space.  Running under X, I typically have just under 40M total VM available
(counting buffers as "free") so running one copy of this succeeds, after
much swap activity, and running two copies causes the aforementioned "bus
error" signal to kill at least one.

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#define NK 20000

int main(int argc, char **argv)
	char *p = malloc(NK * 1024L);
	int i;

	for (i = 0; i < NK; i += 4) {
		printf("\r%d", i);
		p[i * 1024] = 1;
	return 0;

Bill Roman  (roman@songdog.eskimo.com / roman@songdog.uucp)   running linux

TO UNSUBSCRIBE FROM THIS MAILING LIST: e-mail the word "unsubscribe" to
debian-user-REQUEST@lists.debian.org . Trouble? e-mail to Bruce@Pixar.com

Reply to: