I ran the program with root priviledge but it keeps complaining that mmap cannot allocate memory. Code snippet is below:
#define PROTECTION (PROT_READ | PROT_WRITE)
#define LENGTH (4*1024)
#ifndef MAP_HUGETLB
#define MAP_HUGETLB 0x40000
#endif
#define ADDR (void *) (0x0UL)
#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB)
int main (int argc, char *argv[]){
...
// allocate a buffer with the same size as the LLC using huge pages
buf = mmap(ADDR, LENGTH, PROTECTION, FLAGS, 0, 0);
if (buf == MAP_FAILED) {
perror("mmap");
exit(1);
}
...}
Hardware: I have 8G RAM. Processor is ivybridge
Uname output:
Linux mymachine 3.13.0-43-generic #72-Ubuntu SMP Mon Dec 8 19:35:06 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
EDIT 1: The output of perror
mmap: Cannot allocate memory
Also added one line to print errno
printf("something is wrong: %d\n", errno);
But the output is:
something is wrong: 12
EDIT 2: The huge tlb related information from /proc/meminfo
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
mmap() is a system call that can be used by a user process to ask the operating system kernel to map either files or devices into the memory (i.e., address space) of that process. The mmap() system call can also be used to allocate memory (an anonymous mapping).
The mmap() function will fail if: [EACCES] The fildes argument is not open for read, regardless of the protection specified, or fildes is not open for write and PROT_WRITE was specified for a MAP_SHARED type mapping. [EAGAIN]
By default, any process can be killed at any moment when the system runs out of memory. In kernels before 2.6. 7, the MAP_POPULATE flag has effect only if prot is specified as PROT_NONE. SUSv3 specifies that mmap() should fail if length is 0.
In computing, mmap(2) is a POSIX-compliant Unix system call that maps files or devices into memory. It is a method of memory-mapped file I/O. It implements demand paging because file contents are not read from disk directly and initially do not use physical RAM at all.
Well, as Documentation/vm/hugetlspage.txt suggested, do
echo 20 > /proc/sys/vm/nr_hugepages
solved the problem. Tested on ubuntu 14.04. Check Why I can't map memory with mmap also.
When you use MAP_HUGETLB
, the mmap(2) call can fail (e.g. if your system does not have huge pages configured, or if some resource is exhausted), so you almost always should call mmap
without MAP_HUGETLB
as a fail back. Also, you should not define MAP_HUGETLB
. If it is not defined (by system headers internal to <sys/mman.h>
; it might be different according to architectures or kernel versions), don't use it!
// allocate a buffer with the same size as the LLC using huge pages
buf = mmap(NULL, LENGTH, PROTECTION,
#ifdef MAP_HUGETLB
MAP_HUGETLB |
#endif
MAP_PRIVATE | MAP_ANONYMOUS,
0, 0);
#ifdef MAP_HUGETLB
if (buf == MAP_FAILED) {
// try again without huge pages:
buf = mmap(NULL, LENGTH, PROTECTION,
MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
};
#endif
if (buf == MAP_FAILED) {
perror("mmap");
exit(EXIT_FAILURE);
}
The kernel's Documentation/vm/hugetlspage.txt mention that huge pages are -or may be- limited (e.g. if you pass hugepages=N
to the kernel, or if you do things thru /proc/
or /sys/
, or if this was not configured in the kernel, etc...). So you are not sure to get them. And using huge pages for a small mapping of only 4Kbytes is a mistake (or perhaps a failure). Huge pages are worthwhile only when asking many megabytes (e.g. a gigabyte or more) and are always an optimization (e.g. you would want your application to be able to run on a kernel without them).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With