View Single Post
Old 04-15-09, 03:39 AM   #1
Adam Warner
Registered User
 
Join Date: Apr 2009
Posts: 5
Question Cannot overcommit memory when linking to Proprietary Nvidia OpenGL library

Hi all,

I've uncovered a crazy situation where mere linking to the OpenGL libraries stops mmap being able to overcommit memory. I've distilled this test case for Linux x86_64 (file is named mmap.c):
Code:
#include <assert.h>
#include <sys/mman.h>
#include <stdint.h>
#include <stdio.h>

int main() {
  void *mem=mmap(NULL, UINT64_C(1) << 46,
    PROT_READ | PROT_WRITE,
    MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
  assert (mem!=MAP_FAILED);
  return 0;
}
Now I compile the file and list its dependencies before executing it:
Code:
$ gcc mmap.c && ldd ./a.out && time ./a.out

linux-vdso.so.1 =>  (0x00007fff8d1ff000)
	libc.so.6 => /lib/libc.so.6 (0x00007f3484ae9000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f3484e3c000)

real	0m0.000s
user	0m0.000s
sys	0m0.000s
The memory allocation is virtually instantaneous, as it should be with the default value of /proc/sys/vm/overcommit_memory (0) combined with use of the MAP_NORESERVE flag.

Now I compile and run the same program with the OpenGL libraries linked in (note the -lGL flag):
Code:
$ gcc -lGL mmap.c && ldd ./a.out && time ./a.out

linux-vdso.so.1 =>  (0x00007fff493ff000)
	libGL.so.1 => /usr/lib/libGL.so.1 (0x00007fd440e16000)
	libc.so.6 => /lib/libc.so.6 (0x00007fd440ac3000)
	libGLcore.so.1 => /usr/lib/libGLcore.so.1 (0x00007fd43f7d9000)
	libnvidia-tls.so.1 => /usr/lib/tls/libnvidia-tls.so.1 (0x00007fd441104000)
	libm.so.6 => /lib/libm.so.6 (0x00007fd43f556000)
	libXext.so.6 => /usr/lib/libXext.so.6 (0x00007fd43f345000)
	libX11.so.6 => /usr/lib/libX11.so.6 (0x00007fd43f00a000)
	libdl.so.2 => /lib/libdl.so.2 (0x00007fd43ee06000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fd441008000)
	libXau.so.6 => /usr/lib/libXau.so.6 (0x00007fd43ec04000)
	libxcb.so.1 => /usr/lib/libxcb.so.1 (0x00007fd43e9e8000)
	libXdmcp.so.6 => /usr/lib/libXdmcp.so.6 (0x00007fd43e7e3000)
^C

real	0m24.904s
user	0m5.996s
sys	0m7.408s
The OS starts swapping madly as it tries to allocate 2^46 bytes of memory (half the user address space of current implementations of Linux x86_64). I have to press CTRL-C to regain a responsive OS.

Both 180.44 and 185.19 versions of the Nvidia driver exhibit this behaviour. I'm running Debian GNU/Linux 2.6.26-13lenny2 with the Nvidia drivers installed via the Nvidia installer.

Note: I am not experiencing this bug on a machine with integrated Intel graphics:

Code:
$ gcc -lGL mmap.c && ldd ./a.out && time ./a.out
	linux-vdso.so.1 =>  (0x00007ffff2bfe000)
	libGL.so.1 => /usr/lib/libGL.so.1 (0x00007f9cea708000)
	libc.so.6 => /lib/libc.so.6 (0x00007f9cea3b5000)
	libX11.so.6 => /usr/lib/libX11.so.6 (0x00007f9cea07a000)
	libXext.so.6 => /usr/lib/libXext.so.6 (0x00007f9ce9e69000)
	libXxf86vm.so.1 => /usr/lib/libXxf86vm.so.1 (0x00007f9ce9c64000)
	libXdamage.so.1 => /usr/lib/libXdamage.so.1 (0x00007f9ce9a62000)
	libXfixes.so.3 => /usr/lib/libXfixes.so.3 (0x00007f9ceaa7f000)
	libm.so.6 => /lib/libm.so.6 (0x00007f9ce97df000)
	libpthread.so.0 => /lib/libpthread.so.0 (0x00007f9ce95c4000)
	libdl.so.2 => /lib/libdl.so.2 (0x00007f9ce93c0000)
	libdrm.so.2 => /usr/lib/libdrm.so.2 (0x00007f9ce91b7000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f9cea986000)
	libxcb.so.1 => /usr/lib/libxcb.so.1 (0x00007f9ce8f9b000)
	libXau.so.6 => /usr/lib/libXau.so.6 (0x00007f9ce8d99000)
	libXdmcp.so.6 => /usr/lib/libXdmcp.so.6 (0x00007f9ce8b94000)

real	0m0.004s
user	0m0.000s
sys	0m0.004s
Regards,
Adam
Adam Warner is offline   Reply With Quote