mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-25 06:03:36 -04:00
Merge branch 'akpm' (patches from Andrew)
Merge updates from Andrew Morton: - misc fixes - ocfs2 updates - most of MM * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (118 commits) mm: remove PG_highmem description tools, vm: new option to specify kpageflags file mm/swap.c: make functions and their kernel-doc agree mm, memory_hotplug: fix memmap initialization mm: correct comments regarding do_fault_around() mm: numa: do not trap faults on shared data section pages. hugetlb, mbind: fall back to default policy if vma is NULL hugetlb, mempolicy: fix the mbind hugetlb migration mm, hugetlb: further simplify hugetlb allocation API mm, hugetlb: get rid of surplus page accounting tricks mm, hugetlb: do not rely on overcommit limit during migration mm, hugetlb: integrate giga hugetlb more naturally to the allocation path mm, hugetlb: unify core page allocation accounting and initialization mm/memcontrol.c: try harder to decrease [memory,memsw].limit_in_bytes mm/memcontrol.c: make local symbol static mm/hmm: fix uninitialized use of 'entry' in hmm_vma_walk_pmd() include/linux/mmzone.h: fix explanation of lower bits in the SPARSEMEM mem_map pointer mm/compaction.c: fix comment for try_to_compact_pages() mm/page_ext.c: make page_ext_init a noop when CONFIG_PAGE_EXTENSION but nothing uses it zsmalloc: use U suffix for negative literals being shifted ...
This commit is contained in:
commit
73da9e1a9f
118 changed files with 2607 additions and 1863 deletions
|
|
@ -12,3 +12,8 @@ fuse_mnt.o: CFLAGS += $(shell pkg-config fuse --cflags)
|
|||
include ../lib.mk
|
||||
|
||||
$(OUTPUT)/fuse_mnt: LDLIBS += $(shell pkg-config fuse --libs)
|
||||
|
||||
$(OUTPUT)/memfd_test: memfd_test.c common.o
|
||||
$(OUTPUT)/fuse_test: fuse_test.c common.o
|
||||
|
||||
EXTRA_CLEAN = common.o
|
||||
|
|
|
|||
46
tools/testing/selftests/memfd/common.c
Normal file
46
tools/testing/selftests/memfd/common.c
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#define _GNU_SOURCE
|
||||
#define __EXPORTED_HEADERS__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/memfd.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
int hugetlbfs_test = 0;
|
||||
|
||||
/*
|
||||
* Copied from mlock2-tests.c
|
||||
*/
|
||||
unsigned long default_huge_page_size(void)
|
||||
{
|
||||
unsigned long hps = 0;
|
||||
char *line = NULL;
|
||||
size_t linelen = 0;
|
||||
FILE *f = fopen("/proc/meminfo", "r");
|
||||
|
||||
if (!f)
|
||||
return 0;
|
||||
while (getline(&line, &linelen, f) > 0) {
|
||||
if (sscanf(line, "Hugepagesize: %lu kB", &hps) == 1) {
|
||||
hps <<= 10;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(line);
|
||||
fclose(f);
|
||||
return hps;
|
||||
}
|
||||
|
||||
int sys_memfd_create(const char *name, unsigned int flags)
|
||||
{
|
||||
if (hugetlbfs_test)
|
||||
flags |= MFD_HUGETLB;
|
||||
|
||||
return syscall(__NR_memfd_create, name, flags);
|
||||
}
|
||||
9
tools/testing/selftests/memfd/common.h
Normal file
9
tools/testing/selftests/memfd/common.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef COMMON_H_
|
||||
#define COMMON_H_
|
||||
|
||||
extern int hugetlbfs_test;
|
||||
|
||||
unsigned long default_huge_page_size(void);
|
||||
int sys_memfd_create(const char *name, unsigned int flags);
|
||||
|
||||
#endif
|
||||
|
|
@ -33,14 +33,12 @@
|
|||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define MFD_DEF_SIZE 8192
|
||||
#define STACK_SIZE 65536
|
||||
|
||||
static int sys_memfd_create(const char *name,
|
||||
unsigned int flags)
|
||||
{
|
||||
return syscall(__NR_memfd_create, name, flags);
|
||||
}
|
||||
static size_t mfd_def_size = MFD_DEF_SIZE;
|
||||
|
||||
static int mfd_assert_new(const char *name, loff_t sz, unsigned int flags)
|
||||
{
|
||||
|
|
@ -127,7 +125,7 @@ static void *mfd_assert_mmap_shared(int fd)
|
|||
void *p;
|
||||
|
||||
p = mmap(NULL,
|
||||
MFD_DEF_SIZE,
|
||||
mfd_def_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
fd,
|
||||
|
|
@ -145,7 +143,7 @@ static void *mfd_assert_mmap_private(int fd)
|
|||
void *p;
|
||||
|
||||
p = mmap(NULL,
|
||||
MFD_DEF_SIZE,
|
||||
mfd_def_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE,
|
||||
fd,
|
||||
|
|
@ -178,7 +176,7 @@ static int sealing_thread_fn(void *arg)
|
|||
usleep(200000);
|
||||
|
||||
/* unmount mapping before sealing to avoid i_mmap_writable failures */
|
||||
munmap(global_p, MFD_DEF_SIZE);
|
||||
munmap(global_p, mfd_def_size);
|
||||
|
||||
/* Try sealing the global file; expect EBUSY or success. Current
|
||||
* kernels will never succeed, but in the future, kernels might
|
||||
|
|
@ -228,7 +226,7 @@ static void join_sealing_thread(pid_t pid)
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
static const char zero[MFD_DEF_SIZE];
|
||||
char *zero;
|
||||
int fd, mfd, r;
|
||||
void *p;
|
||||
int was_sealed;
|
||||
|
|
@ -239,6 +237,25 @@ int main(int argc, char **argv)
|
|||
abort();
|
||||
}
|
||||
|
||||
if (argc >= 3) {
|
||||
if (!strcmp(argv[2], "hugetlbfs")) {
|
||||
unsigned long hpage_size = default_huge_page_size();
|
||||
|
||||
if (!hpage_size) {
|
||||
printf("Unable to determine huge page size\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
hugetlbfs_test = 1;
|
||||
mfd_def_size = hpage_size * 2;
|
||||
} else {
|
||||
printf("Unknown option: %s\n", argv[2]);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
zero = calloc(sizeof(*zero), mfd_def_size);
|
||||
|
||||
/* open FUSE memfd file for GUP testing */
|
||||
printf("opening: %s\n", argv[1]);
|
||||
fd = open(argv[1], O_RDONLY | O_CLOEXEC);
|
||||
|
|
@ -249,7 +266,7 @@ int main(int argc, char **argv)
|
|||
|
||||
/* create new memfd-object */
|
||||
mfd = mfd_assert_new("kern_memfd_fuse",
|
||||
MFD_DEF_SIZE,
|
||||
mfd_def_size,
|
||||
MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
||||
|
||||
/* mmap memfd-object for writing */
|
||||
|
|
@ -268,7 +285,7 @@ int main(int argc, char **argv)
|
|||
* This guarantees that the receive-buffer is pinned for 1s until the
|
||||
* data is written into it. The racing ADD_SEALS should thus fail as
|
||||
* the pages are still pinned. */
|
||||
r = read(fd, p, MFD_DEF_SIZE);
|
||||
r = read(fd, p, mfd_def_size);
|
||||
if (r < 0) {
|
||||
printf("read() failed: %m\n");
|
||||
abort();
|
||||
|
|
@ -295,10 +312,10 @@ int main(int argc, char **argv)
|
|||
* enough to avoid any in-flight writes. */
|
||||
|
||||
p = mfd_assert_mmap_private(mfd);
|
||||
if (was_sealed && memcmp(p, zero, MFD_DEF_SIZE)) {
|
||||
if (was_sealed && memcmp(p, zero, mfd_def_size)) {
|
||||
printf("memfd sealed during read() but data not discarded\n");
|
||||
abort();
|
||||
} else if (!was_sealed && !memcmp(p, zero, MFD_DEF_SIZE)) {
|
||||
} else if (!was_sealed && !memcmp(p, zero, mfd_def_size)) {
|
||||
printf("memfd sealed after read() but data discarded\n");
|
||||
abort();
|
||||
}
|
||||
|
|
@ -307,6 +324,7 @@ int main(int argc, char **argv)
|
|||
close(fd);
|
||||
|
||||
printf("fuse: DONE\n");
|
||||
free(zero);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,10 @@
|
|||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define MEMFD_STR "memfd:"
|
||||
#define MEMFD_HUGE_STR "memfd-hugetlb:"
|
||||
#define SHARED_FT_STR "(shared file-table)"
|
||||
|
||||
#define MFD_DEF_SIZE 8192
|
||||
|
|
@ -28,41 +31,8 @@
|
|||
/*
|
||||
* Default is not to test hugetlbfs
|
||||
*/
|
||||
static int hugetlbfs_test;
|
||||
static size_t mfd_def_size = MFD_DEF_SIZE;
|
||||
|
||||
/*
|
||||
* Copied from mlock2-tests.c
|
||||
*/
|
||||
static unsigned long default_huge_page_size(void)
|
||||
{
|
||||
unsigned long hps = 0;
|
||||
char *line = NULL;
|
||||
size_t linelen = 0;
|
||||
FILE *f = fopen("/proc/meminfo", "r");
|
||||
|
||||
if (!f)
|
||||
return 0;
|
||||
while (getline(&line, &linelen, f) > 0) {
|
||||
if (sscanf(line, "Hugepagesize: %lu kB", &hps) == 1) {
|
||||
hps <<= 10;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(line);
|
||||
fclose(f);
|
||||
return hps;
|
||||
}
|
||||
|
||||
static int sys_memfd_create(const char *name,
|
||||
unsigned int flags)
|
||||
{
|
||||
if (hugetlbfs_test)
|
||||
flags |= MFD_HUGETLB;
|
||||
|
||||
return syscall(__NR_memfd_create, name, flags);
|
||||
}
|
||||
static const char *memfd_str = MEMFD_STR;
|
||||
|
||||
static int mfd_assert_new(const char *name, loff_t sz, unsigned int flags)
|
||||
{
|
||||
|
|
@ -513,6 +483,10 @@ static void mfd_assert_grow_write(int fd)
|
|||
static char *buf;
|
||||
ssize_t l;
|
||||
|
||||
/* hugetlbfs does not support write */
|
||||
if (hugetlbfs_test)
|
||||
return;
|
||||
|
||||
buf = malloc(mfd_def_size * 8);
|
||||
if (!buf) {
|
||||
printf("malloc(%zu) failed: %m\n", mfd_def_size * 8);
|
||||
|
|
@ -533,6 +507,10 @@ static void mfd_fail_grow_write(int fd)
|
|||
static char *buf;
|
||||
ssize_t l;
|
||||
|
||||
/* hugetlbfs does not support write */
|
||||
if (hugetlbfs_test)
|
||||
return;
|
||||
|
||||
buf = malloc(mfd_def_size * 8);
|
||||
if (!buf) {
|
||||
printf("malloc(%zu) failed: %m\n", mfd_def_size * 8);
|
||||
|
|
@ -598,7 +576,7 @@ static void test_create(void)
|
|||
char buf[2048];
|
||||
int fd;
|
||||
|
||||
printf("%s CREATE\n", MEMFD_STR);
|
||||
printf("%s CREATE\n", memfd_str);
|
||||
|
||||
/* test NULL name */
|
||||
mfd_fail_new(NULL, 0);
|
||||
|
|
@ -627,18 +605,13 @@ static void test_create(void)
|
|||
fd = mfd_assert_new("", 0, MFD_CLOEXEC);
|
||||
close(fd);
|
||||
|
||||
if (!hugetlbfs_test) {
|
||||
/* verify MFD_ALLOW_SEALING is allowed */
|
||||
fd = mfd_assert_new("", 0, MFD_ALLOW_SEALING);
|
||||
close(fd);
|
||||
/* verify MFD_ALLOW_SEALING is allowed */
|
||||
fd = mfd_assert_new("", 0, MFD_ALLOW_SEALING);
|
||||
close(fd);
|
||||
|
||||
/* verify MFD_ALLOW_SEALING | MFD_CLOEXEC is allowed */
|
||||
fd = mfd_assert_new("", 0, MFD_ALLOW_SEALING | MFD_CLOEXEC);
|
||||
close(fd);
|
||||
} else {
|
||||
/* sealing is not supported on hugetlbfs */
|
||||
mfd_fail_new("", MFD_ALLOW_SEALING);
|
||||
}
|
||||
/* verify MFD_ALLOW_SEALING | MFD_CLOEXEC is allowed */
|
||||
fd = mfd_assert_new("", 0, MFD_ALLOW_SEALING | MFD_CLOEXEC);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -649,11 +622,7 @@ static void test_basic(void)
|
|||
{
|
||||
int fd;
|
||||
|
||||
/* hugetlbfs does not contain sealing support */
|
||||
if (hugetlbfs_test)
|
||||
return;
|
||||
|
||||
printf("%s BASIC\n", MEMFD_STR);
|
||||
printf("%s BASIC\n", memfd_str);
|
||||
|
||||
fd = mfd_assert_new("kern_memfd_basic",
|
||||
mfd_def_size,
|
||||
|
|
@ -697,28 +666,6 @@ static void test_basic(void)
|
|||
close(fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* hugetlbfs doesn't support seals or write, so just verify grow and shrink
|
||||
* on a hugetlbfs file created via memfd_create.
|
||||
*/
|
||||
static void test_hugetlbfs_grow_shrink(void)
|
||||
{
|
||||
int fd;
|
||||
|
||||
printf("%s HUGETLBFS-GROW-SHRINK\n", MEMFD_STR);
|
||||
|
||||
fd = mfd_assert_new("kern_memfd_seal_write",
|
||||
mfd_def_size,
|
||||
MFD_CLOEXEC);
|
||||
|
||||
mfd_assert_read(fd);
|
||||
mfd_assert_write(fd);
|
||||
mfd_assert_shrink(fd);
|
||||
mfd_assert_grow(fd);
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test SEAL_WRITE
|
||||
* Test whether SEAL_WRITE actually prevents modifications.
|
||||
|
|
@ -727,14 +674,7 @@ static void test_seal_write(void)
|
|||
{
|
||||
int fd;
|
||||
|
||||
/*
|
||||
* hugetlbfs does not contain sealing or write support. Just test
|
||||
* basic grow and shrink via test_hugetlbfs_grow_shrink.
|
||||
*/
|
||||
if (hugetlbfs_test)
|
||||
return test_hugetlbfs_grow_shrink();
|
||||
|
||||
printf("%s SEAL-WRITE\n", MEMFD_STR);
|
||||
printf("%s SEAL-WRITE\n", memfd_str);
|
||||
|
||||
fd = mfd_assert_new("kern_memfd_seal_write",
|
||||
mfd_def_size,
|
||||
|
|
@ -760,11 +700,7 @@ static void test_seal_shrink(void)
|
|||
{
|
||||
int fd;
|
||||
|
||||
/* hugetlbfs does not contain sealing support */
|
||||
if (hugetlbfs_test)
|
||||
return;
|
||||
|
||||
printf("%s SEAL-SHRINK\n", MEMFD_STR);
|
||||
printf("%s SEAL-SHRINK\n", memfd_str);
|
||||
|
||||
fd = mfd_assert_new("kern_memfd_seal_shrink",
|
||||
mfd_def_size,
|
||||
|
|
@ -790,11 +726,7 @@ static void test_seal_grow(void)
|
|||
{
|
||||
int fd;
|
||||
|
||||
/* hugetlbfs does not contain sealing support */
|
||||
if (hugetlbfs_test)
|
||||
return;
|
||||
|
||||
printf("%s SEAL-GROW\n", MEMFD_STR);
|
||||
printf("%s SEAL-GROW\n", memfd_str);
|
||||
|
||||
fd = mfd_assert_new("kern_memfd_seal_grow",
|
||||
mfd_def_size,
|
||||
|
|
@ -820,11 +752,7 @@ static void test_seal_resize(void)
|
|||
{
|
||||
int fd;
|
||||
|
||||
/* hugetlbfs does not contain sealing support */
|
||||
if (hugetlbfs_test)
|
||||
return;
|
||||
|
||||
printf("%s SEAL-RESIZE\n", MEMFD_STR);
|
||||
printf("%s SEAL-RESIZE\n", memfd_str);
|
||||
|
||||
fd = mfd_assert_new("kern_memfd_seal_resize",
|
||||
mfd_def_size,
|
||||
|
|
@ -842,32 +770,6 @@ static void test_seal_resize(void)
|
|||
close(fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* hugetlbfs does not support seals. Basic test to dup the memfd created
|
||||
* fd and perform some basic operations on it.
|
||||
*/
|
||||
static void hugetlbfs_dup(char *b_suffix)
|
||||
{
|
||||
int fd, fd2;
|
||||
|
||||
printf("%s HUGETLBFS-DUP %s\n", MEMFD_STR, b_suffix);
|
||||
|
||||
fd = mfd_assert_new("kern_memfd_share_dup",
|
||||
mfd_def_size,
|
||||
MFD_CLOEXEC);
|
||||
|
||||
fd2 = mfd_assert_dup(fd);
|
||||
|
||||
mfd_assert_read(fd);
|
||||
mfd_assert_write(fd);
|
||||
|
||||
mfd_assert_shrink(fd2);
|
||||
mfd_assert_grow(fd2);
|
||||
|
||||
close(fd2);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test sharing via dup()
|
||||
* Test that seals are shared between dupped FDs and they're all equal.
|
||||
|
|
@ -876,16 +778,7 @@ static void test_share_dup(char *banner, char *b_suffix)
|
|||
{
|
||||
int fd, fd2;
|
||||
|
||||
/*
|
||||
* hugetlbfs does not contain sealing support. Perform some
|
||||
* basic testing on dup'ed fd instead via hugetlbfs_dup.
|
||||
*/
|
||||
if (hugetlbfs_test) {
|
||||
hugetlbfs_dup(b_suffix);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("%s %s %s\n", MEMFD_STR, banner, b_suffix);
|
||||
printf("%s %s %s\n", memfd_str, banner, b_suffix);
|
||||
|
||||
fd = mfd_assert_new("kern_memfd_share_dup",
|
||||
mfd_def_size,
|
||||
|
|
@ -927,11 +820,7 @@ static void test_share_mmap(char *banner, char *b_suffix)
|
|||
int fd;
|
||||
void *p;
|
||||
|
||||
/* hugetlbfs does not contain sealing support */
|
||||
if (hugetlbfs_test)
|
||||
return;
|
||||
|
||||
printf("%s %s %s\n", MEMFD_STR, banner, b_suffix);
|
||||
printf("%s %s %s\n", memfd_str, banner, b_suffix);
|
||||
|
||||
fd = mfd_assert_new("kern_memfd_share_mmap",
|
||||
mfd_def_size,
|
||||
|
|
@ -955,32 +844,6 @@ static void test_share_mmap(char *banner, char *b_suffix)
|
|||
close(fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Basic test to make sure we can open the hugetlbfs fd via /proc and
|
||||
* perform some simple operations on it.
|
||||
*/
|
||||
static void hugetlbfs_proc_open(char *b_suffix)
|
||||
{
|
||||
int fd, fd2;
|
||||
|
||||
printf("%s HUGETLBFS-PROC-OPEN %s\n", MEMFD_STR, b_suffix);
|
||||
|
||||
fd = mfd_assert_new("kern_memfd_share_open",
|
||||
mfd_def_size,
|
||||
MFD_CLOEXEC);
|
||||
|
||||
fd2 = mfd_assert_open(fd, O_RDWR, 0);
|
||||
|
||||
mfd_assert_read(fd);
|
||||
mfd_assert_write(fd);
|
||||
|
||||
mfd_assert_shrink(fd2);
|
||||
mfd_assert_grow(fd2);
|
||||
|
||||
close(fd2);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test sealing with open(/proc/self/fd/%d)
|
||||
* Via /proc we can get access to a separate file-context for the same memfd.
|
||||
|
|
@ -991,16 +854,7 @@ static void test_share_open(char *banner, char *b_suffix)
|
|||
{
|
||||
int fd, fd2;
|
||||
|
||||
/*
|
||||
* hugetlbfs does not contain sealing support. So test basic
|
||||
* functionality of using /proc fd via hugetlbfs_proc_open
|
||||
*/
|
||||
if (hugetlbfs_test) {
|
||||
hugetlbfs_proc_open(b_suffix);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("%s %s %s\n", MEMFD_STR, banner, b_suffix);
|
||||
printf("%s %s %s\n", memfd_str, banner, b_suffix);
|
||||
|
||||
fd = mfd_assert_new("kern_memfd_share_open",
|
||||
mfd_def_size,
|
||||
|
|
@ -1043,11 +897,7 @@ static void test_share_fork(char *banner, char *b_suffix)
|
|||
int fd;
|
||||
pid_t pid;
|
||||
|
||||
/* hugetlbfs does not contain sealing support */
|
||||
if (hugetlbfs_test)
|
||||
return;
|
||||
|
||||
printf("%s %s %s\n", MEMFD_STR, banner, b_suffix);
|
||||
printf("%s %s %s\n", memfd_str, banner, b_suffix);
|
||||
|
||||
fd = mfd_assert_new("kern_memfd_share_fork",
|
||||
mfd_def_size,
|
||||
|
|
@ -1083,7 +933,11 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
hugetlbfs_test = 1;
|
||||
memfd_str = MEMFD_HUGE_STR;
|
||||
mfd_def_size = hpage_size * 2;
|
||||
} else {
|
||||
printf("Unknown option: %s\n", argv[1]);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,6 @@ set -e
|
|||
|
||||
mkdir mnt
|
||||
./fuse_mnt ./mnt
|
||||
./fuse_test ./mnt/memfd
|
||||
./fuse_test ./mnt/memfd $@
|
||||
fusermount -u ./mnt
|
||||
rmdir ./mnt
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ fi
|
|||
# Run the hugetlbfs test
|
||||
#
|
||||
./memfd_test hugetlbfs
|
||||
./run_fuse_test.sh hugetlbfs
|
||||
|
||||
#
|
||||
# Give back any huge pages allocated for the test
|
||||
|
|
|
|||
|
|
@ -8,17 +8,18 @@ endif
|
|||
CFLAGS = -Wall -I ../../../../usr/include $(EXTRA_CFLAGS)
|
||||
LDLIBS = -lrt
|
||||
TEST_GEN_FILES = compaction_test
|
||||
TEST_GEN_FILES += gup_benchmark
|
||||
TEST_GEN_FILES += hugepage-mmap
|
||||
TEST_GEN_FILES += hugepage-shm
|
||||
TEST_GEN_FILES += map_hugetlb
|
||||
TEST_GEN_FILES += mlock-random-test
|
||||
TEST_GEN_FILES += mlock2-tests
|
||||
TEST_GEN_FILES += on-fault-limit
|
||||
TEST_GEN_FILES += thuge-gen
|
||||
TEST_GEN_FILES += transhuge-stress
|
||||
TEST_GEN_FILES += userfaultfd
|
||||
TEST_GEN_FILES += mlock-random-test
|
||||
TEST_GEN_FILES += va_128TBswitch
|
||||
TEST_GEN_FILES += virtual_address_range
|
||||
TEST_GEN_FILES += gup_benchmark
|
||||
|
||||
TEST_PROGS := run_vmtests
|
||||
|
||||
|
|
|
|||
|
|
@ -177,4 +177,15 @@ else
|
|||
echo "[PASS]"
|
||||
fi
|
||||
|
||||
echo "-----------------------------"
|
||||
echo "running virtual address 128TB switch test"
|
||||
echo "-----------------------------"
|
||||
./va_128TBswitch
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "[FAIL]"
|
||||
exitcode=1
|
||||
else
|
||||
echo "[PASS]"
|
||||
fi
|
||||
|
||||
exit $exitcode
|
||||
|
|
|
|||
297
tools/testing/selftests/vm/va_128TBswitch.c
Normal file
297
tools/testing/selftests/vm/va_128TBswitch.c
Normal file
|
|
@ -0,0 +1,297 @@
|
|||
/*
|
||||
*
|
||||
* Authors: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
|
||||
* Authors: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License, version 2, as
|
||||
* published by the Free Software Foundation.
|
||||
|
||||
* This program is distributed in the hope that it would be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
|
||||
#ifdef __powerpc64__
|
||||
#define PAGE_SIZE (64 << 10)
|
||||
/*
|
||||
* This will work with 16M and 2M hugepage size
|
||||
*/
|
||||
#define HUGETLB_SIZE (16 << 20)
|
||||
#else
|
||||
#define PAGE_SIZE (4 << 10)
|
||||
#define HUGETLB_SIZE (2 << 20)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* >= 128TB is the hint addr value we used to select
|
||||
* large address space.
|
||||
*/
|
||||
#define ADDR_SWITCH_HINT (1UL << 47)
|
||||
#define LOW_ADDR ((void *) (1UL << 30))
|
||||
#define HIGH_ADDR ((void *) (1UL << 48))
|
||||
|
||||
struct testcase {
|
||||
void *addr;
|
||||
unsigned long size;
|
||||
unsigned long flags;
|
||||
const char *msg;
|
||||
unsigned int low_addr_required:1;
|
||||
unsigned int keep_mapped:1;
|
||||
};
|
||||
|
||||
static struct testcase testcases[] = {
|
||||
{
|
||||
/*
|
||||
* If stack is moved, we could possibly allocate
|
||||
* this at the requested address.
|
||||
*/
|
||||
.addr = ((void *)(ADDR_SWITCH_HINT - PAGE_SIZE)),
|
||||
.size = PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE, PAGE_SIZE)",
|
||||
.low_addr_required = 1,
|
||||
},
|
||||
{
|
||||
/*
|
||||
* We should never allocate at the requested address or above it
|
||||
* The len cross the 128TB boundary. Without MAP_FIXED
|
||||
* we will always search in the lower address space.
|
||||
*/
|
||||
.addr = ((void *)(ADDR_SWITCH_HINT - PAGE_SIZE)),
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE, (2 * PAGE_SIZE))",
|
||||
.low_addr_required = 1,
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Exact mapping at 128TB, the area is free we should get that
|
||||
* even without MAP_FIXED.
|
||||
*/
|
||||
.addr = ((void *)(ADDR_SWITCH_HINT)),
|
||||
.size = PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(ADDR_SWITCH_HINT, PAGE_SIZE)",
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = (void *)(ADDR_SWITCH_HINT),
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
|
||||
.msg = "mmap(ADDR_SWITCH_HINT, 2 * PAGE_SIZE, MAP_FIXED)",
|
||||
},
|
||||
{
|
||||
.addr = NULL,
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(NULL)",
|
||||
.low_addr_required = 1,
|
||||
},
|
||||
{
|
||||
.addr = LOW_ADDR,
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(LOW_ADDR)",
|
||||
.low_addr_required = 1,
|
||||
},
|
||||
{
|
||||
.addr = HIGH_ADDR,
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(HIGH_ADDR)",
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = HIGH_ADDR,
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(HIGH_ADDR) again",
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = HIGH_ADDR,
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
|
||||
.msg = "mmap(HIGH_ADDR, MAP_FIXED)",
|
||||
},
|
||||
{
|
||||
.addr = (void *) -1,
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(-1)",
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = (void *) -1,
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(-1) again",
|
||||
},
|
||||
{
|
||||
.addr = ((void *)(ADDR_SWITCH_HINT - PAGE_SIZE)),
|
||||
.size = PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE, PAGE_SIZE)",
|
||||
.low_addr_required = 1,
|
||||
},
|
||||
{
|
||||
.addr = (void *)(ADDR_SWITCH_HINT - PAGE_SIZE),
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE, 2 * PAGE_SIZE)",
|
||||
.low_addr_required = 1,
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = (void *)(ADDR_SWITCH_HINT - PAGE_SIZE / 2),
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE/2 , 2 * PAGE_SIZE)",
|
||||
.low_addr_required = 1,
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = ((void *)(ADDR_SWITCH_HINT)),
|
||||
.size = PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(ADDR_SWITCH_HINT, PAGE_SIZE)",
|
||||
},
|
||||
{
|
||||
.addr = (void *)(ADDR_SWITCH_HINT),
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
|
||||
.msg = "mmap(ADDR_SWITCH_HINT, 2 * PAGE_SIZE, MAP_FIXED)",
|
||||
},
|
||||
};
|
||||
|
||||
static struct testcase hugetlb_testcases[] = {
|
||||
{
|
||||
.addr = NULL,
|
||||
.size = HUGETLB_SIZE,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(NULL, MAP_HUGETLB)",
|
||||
.low_addr_required = 1,
|
||||
},
|
||||
{
|
||||
.addr = LOW_ADDR,
|
||||
.size = HUGETLB_SIZE,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(LOW_ADDR, MAP_HUGETLB)",
|
||||
.low_addr_required = 1,
|
||||
},
|
||||
{
|
||||
.addr = HIGH_ADDR,
|
||||
.size = HUGETLB_SIZE,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(HIGH_ADDR, MAP_HUGETLB)",
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = HIGH_ADDR,
|
||||
.size = HUGETLB_SIZE,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(HIGH_ADDR, MAP_HUGETLB) again",
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = HIGH_ADDR,
|
||||
.size = HUGETLB_SIZE,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
|
||||
.msg = "mmap(HIGH_ADDR, MAP_FIXED | MAP_HUGETLB)",
|
||||
},
|
||||
{
|
||||
.addr = (void *) -1,
|
||||
.size = HUGETLB_SIZE,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(-1, MAP_HUGETLB)",
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = (void *) -1,
|
||||
.size = HUGETLB_SIZE,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(-1, MAP_HUGETLB) again",
|
||||
},
|
||||
{
|
||||
.addr = (void *)(ADDR_SWITCH_HINT - PAGE_SIZE),
|
||||
.size = 2 * HUGETLB_SIZE,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE, 2*HUGETLB_SIZE, MAP_HUGETLB)",
|
||||
.low_addr_required = 1,
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = (void *)(ADDR_SWITCH_HINT),
|
||||
.size = 2 * HUGETLB_SIZE,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
|
||||
.msg = "mmap(ADDR_SWITCH_HINT , 2*HUGETLB_SIZE, MAP_FIXED | MAP_HUGETLB)",
|
||||
},
|
||||
};
|
||||
|
||||
static int run_test(struct testcase *test, int count)
|
||||
{
|
||||
void *p;
|
||||
int i, ret = 0;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
struct testcase *t = test + i;
|
||||
|
||||
p = mmap(t->addr, t->size, PROT_READ | PROT_WRITE, t->flags, -1, 0);
|
||||
|
||||
printf("%s: %p - ", t->msg, p);
|
||||
|
||||
if (p == MAP_FAILED) {
|
||||
printf("FAILED\n");
|
||||
ret = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (t->low_addr_required && p >= (void *)(ADDR_SWITCH_HINT)) {
|
||||
printf("FAILED\n");
|
||||
ret = 1;
|
||||
} else {
|
||||
/*
|
||||
* Do a dereference of the address returned so that we catch
|
||||
* bugs in page fault handling
|
||||
*/
|
||||
memset(p, 0, t->size);
|
||||
printf("OK\n");
|
||||
}
|
||||
if (!t->keep_mapped)
|
||||
munmap(p, t->size);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int supported_arch(void)
|
||||
{
|
||||
#if defined(__powerpc64__)
|
||||
return 1;
|
||||
#elif defined(__x86_64__)
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!supported_arch())
|
||||
return 0;
|
||||
|
||||
ret = run_test(testcases, ARRAY_SIZE(testcases));
|
||||
if (argc == 2 && !strcmp(argv[1], "--run-hugetlb"))
|
||||
ret = run_test(hugetlb_testcases, ARRAY_SIZE(hugetlb_testcases));
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1,177 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
|
||||
#define PAGE_SIZE 4096
|
||||
#define LOW_ADDR ((void *) (1UL << 30))
|
||||
#define HIGH_ADDR ((void *) (1UL << 50))
|
||||
|
||||
struct testcase {
|
||||
void *addr;
|
||||
unsigned long size;
|
||||
unsigned long flags;
|
||||
const char *msg;
|
||||
unsigned int low_addr_required:1;
|
||||
unsigned int keep_mapped:1;
|
||||
};
|
||||
|
||||
static struct testcase testcases[] = {
|
||||
{
|
||||
.addr = NULL,
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(NULL)",
|
||||
.low_addr_required = 1,
|
||||
},
|
||||
{
|
||||
.addr = LOW_ADDR,
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(LOW_ADDR)",
|
||||
.low_addr_required = 1,
|
||||
},
|
||||
{
|
||||
.addr = HIGH_ADDR,
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(HIGH_ADDR)",
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = HIGH_ADDR,
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(HIGH_ADDR) again",
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = HIGH_ADDR,
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
|
||||
.msg = "mmap(HIGH_ADDR, MAP_FIXED)",
|
||||
},
|
||||
{
|
||||
.addr = (void*) -1,
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(-1)",
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = (void*) -1,
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(-1) again",
|
||||
},
|
||||
{
|
||||
.addr = (void *)((1UL << 47) - PAGE_SIZE),
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap((1UL << 47), 2 * PAGE_SIZE)",
|
||||
.low_addr_required = 1,
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = (void *)((1UL << 47) - PAGE_SIZE / 2),
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap((1UL << 47), 2 * PAGE_SIZE / 2)",
|
||||
.low_addr_required = 1,
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = (void *)((1UL << 47) - PAGE_SIZE),
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
|
||||
.msg = "mmap((1UL << 47) - PAGE_SIZE, 2 * PAGE_SIZE, MAP_FIXED)",
|
||||
},
|
||||
{
|
||||
.addr = NULL,
|
||||
.size = 2UL << 20,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(NULL, MAP_HUGETLB)",
|
||||
.low_addr_required = 1,
|
||||
},
|
||||
{
|
||||
.addr = LOW_ADDR,
|
||||
.size = 2UL << 20,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(LOW_ADDR, MAP_HUGETLB)",
|
||||
.low_addr_required = 1,
|
||||
},
|
||||
{
|
||||
.addr = HIGH_ADDR,
|
||||
.size = 2UL << 20,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(HIGH_ADDR, MAP_HUGETLB)",
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = HIGH_ADDR,
|
||||
.size = 2UL << 20,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(HIGH_ADDR, MAP_HUGETLB) again",
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = HIGH_ADDR,
|
||||
.size = 2UL << 20,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
|
||||
.msg = "mmap(HIGH_ADDR, MAP_FIXED | MAP_HUGETLB)",
|
||||
},
|
||||
{
|
||||
.addr = (void*) -1,
|
||||
.size = 2UL << 20,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(-1, MAP_HUGETLB)",
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = (void*) -1,
|
||||
.size = 2UL << 20,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(-1, MAP_HUGETLB) again",
|
||||
},
|
||||
{
|
||||
.addr = (void *)((1UL << 47) - PAGE_SIZE),
|
||||
.size = 4UL << 20,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap((1UL << 47), 4UL << 20, MAP_HUGETLB)",
|
||||
.low_addr_required = 1,
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = (void *)((1UL << 47) - (2UL << 20)),
|
||||
.size = 4UL << 20,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
|
||||
.msg = "mmap((1UL << 47) - (2UL << 20), 4UL << 20, MAP_FIXED | MAP_HUGETLB)",
|
||||
},
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
void *p;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(testcases); i++) {
|
||||
struct testcase *t = testcases + i;
|
||||
|
||||
p = mmap(t->addr, t->size, PROT_NONE, t->flags, -1, 0);
|
||||
|
||||
printf("%s: %p - ", t->msg, p);
|
||||
|
||||
if (p == MAP_FAILED) {
|
||||
printf("FAILED\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (t->low_addr_required && p >= (void *)(1UL << 47))
|
||||
printf("FAILED\n");
|
||||
else
|
||||
printf("OK\n");
|
||||
if (!t->keep_mapped)
|
||||
munmap(p, t->size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in a new issue