Handle hugetlbfs file mapping
Hugetlbfs file mappings are handled differently than regular files: - pager_req_create will tell us the file is in a hugetlbfs - allocate memory upfront, we need to fail if not enough memory - the memory needs to be given again if another process maps the same file This implementation still has some hacks, in particular, the memory needs to be freed when all mappings are done and the file has been deleted/closed by all processes. We cannot know when the file is closed/unlinked easily, so clean up memory when all processes have exited. To test, install libhugetlbfs and link a program with the additional LDFLAGS += -B /usr/share/libhugetlbfs -Wl,--hugetlbfs-align Then run with HUGETLB_ELFMAP=RW set, you can check this works with HUGETLB_DEBUG=1 HUGETLB_VERBOSE=2 Change-Id: I327920ff06efd82e91b319b27319f41912169af1
This commit is contained in:
committed by
Masamichi Takagi
parent
3e3ccf377c
commit
39f9d7fdff
16
test/issues/1203/C1203.sh
Normal file
16
test/issues/1203/C1203.sh
Normal file
@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
. ../../common.sh
|
||||
|
||||
if "$MCEXEC" ./C1203T01; then
|
||||
echo "*** C1203T01: OK"
|
||||
else
|
||||
echo "*** C1203T01: NG"
|
||||
fi
|
||||
|
||||
# to run as user, chmod 1777 /dev/hugepages
|
||||
if sudo HUGETLB_VERBOSE=2 HUGETLB_ELFMAP=RW HUGETLB_DEBUG=1 "$MCEXEC" ./C1203T02; then
|
||||
echo "*** C1203T02: OK"
|
||||
else
|
||||
echo "*** C1203T02: NG"
|
||||
fi
|
||||
101
test/issues/1203/C1203T01.c
Normal file
101
test/issues/1203/C1203T01.c
Normal file
@ -0,0 +1,101 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define MAP_SIZE (2 * (2 * 1024 * 1024))
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int fd;
|
||||
long int *addr;
|
||||
pid_t pid;
|
||||
|
||||
|
||||
if ((fd = open("/dev/hugepages/foo", O_CREAT|O_RDWR, 0600)) < 0) {
|
||||
perror("open");
|
||||
return -1;
|
||||
}
|
||||
unlink("/dev/hugepages/foo");
|
||||
if ((pid = fork()) == 0) {
|
||||
if ((addr = mmap(NULL, MAP_SIZE, PROT_READ|PROT_WRITE,
|
||||
MAP_SHARED, fd, 0)) == MAP_FAILED) {
|
||||
perror("mmap");
|
||||
return -1;
|
||||
}
|
||||
for (int i = 0; i < MAP_SIZE / sizeof(long int); i++) {
|
||||
if (addr[i] != 0) {
|
||||
fprintf(stderr,
|
||||
"memory wasn't zeroed at offset %lx\n",
|
||||
i * sizeof(long int));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
addr[42] = 12;
|
||||
if (munmap(addr, MAP_SIZE) < 0) {
|
||||
perror("munmap");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (pid < 0) {
|
||||
perror("fork");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (waitpid(pid, NULL, 0) <= 0) {
|
||||
perror("waitpid");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* bigger extent: check what was set is still here and rest is zero */
|
||||
if ((addr = mmap(NULL, 2 * MAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED,
|
||||
fd, 0)) == MAP_FAILED) {
|
||||
perror("mmap, 2");
|
||||
return -1;
|
||||
}
|
||||
if (addr[42] != 12) {
|
||||
perror("unexpected content");
|
||||
return -1;
|
||||
}
|
||||
for (int i = 0; i < MAP_SIZE / sizeof(long int); i++) {
|
||||
if (addr[MAP_SIZE / sizeof(long int) + i] != 0) {
|
||||
fprintf(stderr, "memory wasn't zeroed at offset %lx\n",
|
||||
MAP_SIZE + i * sizeof(long int));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
addr[MAP_SIZE / sizeof(long int) + 17] = 42;
|
||||
if (munmap(addr, MAP_SIZE) < 0) {
|
||||
perror("munmap, 2");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* same with offset */
|
||||
if ((addr = mmap(NULL, 2 * MAP_SIZE, PROT_READ|PROT_EXEC,
|
||||
MAP_PRIVATE|MAP_NORESERVE, fd, MAP_SIZE))
|
||||
== MAP_FAILED) {
|
||||
perror("mmap, 2");
|
||||
return -1;
|
||||
}
|
||||
if (addr[17] != 42) {
|
||||
perror("unexpected content (2)");
|
||||
return -1;
|
||||
}
|
||||
for (int i = 0; i < MAP_SIZE / sizeof(long int); i++) {
|
||||
if (addr[MAP_SIZE / sizeof(long int) + i] != 0) {
|
||||
fprintf(stderr, "memory wasn't zeroed at offset %lx\n",
|
||||
2 * MAP_SIZE + i * sizeof(long int));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (munmap(addr, MAP_SIZE) < 0) {
|
||||
perror("munmap, 3");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
13
test/issues/1203/C1203T02.c
Normal file
13
test/issues/1203/C1203T02.c
Normal file
@ -0,0 +1,13 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#define __unused __attribute__((unused))
|
||||
|
||||
static __unused int data[1024*1024] = { 1, 0 };
|
||||
static __unused int data_zero[1024*1024] = { 0 };
|
||||
static __unused int const data_ro[1024*1024] = { 1, 0 };
|
||||
static __unused int const data_ro_zero[1024*1024] = { 0 };
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
12
test/issues/1203/Makefile
Normal file
12
test/issues/1203/Makefile
Normal file
@ -0,0 +1,12 @@
|
||||
TARGET = C1203T01 C1203T02
|
||||
SCRIPT = ./C1203.sh
|
||||
C1203T02: LDFLAGS = -B /usr/share/libhugetlbfs -Wl,--hugetlbfs-align
|
||||
CFLAGS = -Wall
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
test: all
|
||||
bash $(SCRIPT)
|
||||
|
||||
clean:
|
||||
rm -f $(TARGET) *.o
|
||||
Reference in New Issue
Block a user