0

my mmap fails with errno 12 when sizes > 1GB on linux 2.6.37.6.

Any ideas? I've got 64GB of ram

# swapon -s
Filename                Type        Size    Used    Priority
/dev/sda1                               partition   65537160    0   -1

and

# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 495694
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 495694
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

EDIT: added uname -a

#root@maverick-5:~# uname -a
Linux maverick-5 2.6.37.6 #5 SMP Fri Feb 14 16:21:40 PST 2014 x86_64 GNU/Linux

EDIT: added free

#free
         total       used       free     shared    buffers     cached
Mem:      63459224     317692   63141532          0      25800      36280
-/+ buffers/cache:     255612   63203612
Swap:     65537160          0   65537160

EDIT: Its a 64 bit system with 64GB RAM:

# cat /proc/meminfo
MemTotal:       63459224 kB    ...

EDIT: add mmap code

...
*fd = open(file_path, O_RDWR, 0644);
if (*fd==-1){
  printf("open file failed \n");
  exit();
}
system("ulimit -m -v");
mem = mmap(0,0x80000000,PROT_READ|PROT_WRITE,MAP_NORESERVE|MAP_PRIVATE,*fd,0);
if (mem == MAP_FAILED){
  printf("map failed failed %d %d\n", errno, mem);
  exit();
}
hlitz
  • 635
  • 6
  • 24

2 Answers2

1

You should always test the result of syscalls. Read mmap(2) so code

mem = mmap(0,size_of_segment, PROT_READ|PROT_WRITE, 
           MAP_NORESERVE|MAP_PRIVATE,*fd,0);
if (mem == MMAP_FAILED) 
     { perror("mmap size_of_segment"); exit(EXIT_FAILURE); };

We don't know what size_of_segment contains, and what is *fd. Actually, I'm not sure using MAP_NORESERVE when mmap-ing a file is a sensible thing to do. Either use MAP_NORESERVE with MAP_ANONYMOUS (to reserve address space without consuming swap space) or omit MAP_NORESERVE; an d if you want to access and modify the file, use MAP_SHARED :

mem = mmap(0,size_of_segment, PROT_READ|PROT_WRITE, 
           MAP_SHARED,*fd,0);
if (mem == MMAP_FAILED) 
     { fprintf (stderr, "mmap size_of_segment=%ld *fd=%d failed %s\n",
                (long)size_of_segment, *fd, strerror(errno));
       exit(EXIT_FAILURE); };

On my system ENOMEM is 12 then perror prints (or strerror gives) Cannot allocate memory which is quite self-explanatory. The mmap(2) man page tells:

   ENOMEM No memory is available, or the process's maximum number of
          mappings would have been exceeded.

But Posix mmap tells a different story; maybe you have too much memory mapping. Look into /proc/1234/maps for the process of pid 1234.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
1

The problem is that the per-process virtual memory limit will set to only 1GB (check with ulimit -a). ulimit -v can be used to set it to 60gb or so and then your mmap() call will succeed.

aditya dogra
  • 429
  • 4
  • 3