mmap() > phys mem problem

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

 



I asked the following question on linux-mm. I tried a patch they suggested on the latest kernel and increasing /proc/sys/vm/min_free_kbytes without any luck. They suggested asking this question on linux-net. -Ron

---------- Forwarded message ----------
Date: Tue, 25 May 2004 15:40:56 -0700 (PDT)
From: Ron Maeder <rlm@orionmulti.com>
To: linux-mm@kvack.org
Subject: mmap() > phys mem problem

I have a diskless x86 box running the 2.6.5rc3 kernel.  I ran a program
which mmap()'d a file that was larger than physical memory over NFS and
then began to write values to it.  The process grew until it was near the
size of phys mem, and then grinded to a halt and other programs, including
daemons, were exiting when they should have stayed running.

If I run the program on a system that has some swap space, it completes
without any issue.

It seems as if the OS will not write any dirty pages back to the mmap()'d
file, and then eventually runs out of memory.

Is this an "undocumented feature" or is this a linux error?  I would
expect pages of the mmap()'d file would get paged back to the original
file. I know this won't be fast, but the performance is not an issue for
this application.

Below is an example that reproduces the problem on a machine without swap.
If I do an occasional synchronous msync(MS_SYNC) (compiling -DNEVER), the
test case completes fine, while if I use an msync(MS_ASYNC) then other
programs exit as if I did no msync().

Many thanks,

Ron
---------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/sysinfo.h>

#define MAX_UNSIGNED	((unsigned) (~0))
#define	FILE_MODE	(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)

unsigned
total_ram()
{
    struct sysinfo	info;
    double		my_total_ram;

    if (sysinfo(&info) != 0) {
	perror("sysinfo");
	exit(1);
    }
    my_total_ram = ((double) info.totalram * (double) info.mem_unit);
    if (my_total_ram > (double) MAX_UNSIGNED) {
	fprintf(stderr, "'my_total_ram' too large for 'unsigned' type.");
	exit(1);
    }
    return((unsigned) my_total_ram);
}

int
main()
{
    unsigned	i;
    unsigned	addr_size;
    unsigned	mem_size;
    unsigned	*mem;
    char	swap_filename[20] = "thrash_swap";
    int		swap_filedes;

    mem_size = total_ram();
    mem_size -= (mem_size % sizeof(unsigned));	/* align to 'unsigned' size */
    /* compute the size of the address for 'unsigned' memory accesses */
    addr_size = ((mem_size / sizeof(unsigned)) - 1);

    (void) unlink(swap_filename);
    if ((swap_filedes = open(swap_filename, O_RDWR | O_CREAT | O_TRUNC,
			     FILE_MODE)) == -1) {
	perror("open: Can't open for writing");
	exit(1);
    }
    /* Set size of swap file */
    if (lseek(swap_filedes, (mem_size - 1), SEEK_SET) == (off_t) -1) {
	perror("lseek");
	exit(1);
    }
    if (write(swap_filedes, "", 1) != 1) {
	perror("write");
	exit(1);
    }
    if ((mem = (unsigned *) mmap(0, mem_size, PROT_READ | PROT_WRITE,
				 MAP_FILE | MAP_SHARED, swap_filedes, 0))
	== (unsigned *) -1) {
	perror("mmap");
	exit(1);
    }
    /* for this example just dirty each page. */
    for (i = 0; i < addr_size; i += 1024) {
	mem[i] = 0;
	if ((i & 0xfffff) == 0) {
#ifdef NEVER
	    if (msync(mem, mem_size, MS_SYNC) != 0) {
		perror("msync");
		exit(1);
	    }
#endif
	    printf(".");
	    fflush(stdout);
	}
    }
    if (munmap(mem, mem_size) != 0) {
	perror("munmap");
	exit(1);
    }
    if (close(swap_filedes) != 0) {
	perror("close");
	exit(1);
    }
    if (unlink(swap_filename) != 0) {
	perror("unlink");
	exit(1);
    }
    printf("\n");
    fflush(stdout);
    return(0);
}



--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"aart@kvack.org";> aart@kvack.org </a>
-
: send the line "unsubscribe linux-net" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux