Merge branch 'akpm' (patches from Andrew)
Merge misc updates from Andrew Morton: "A few misc subsystems and some of MM. 175 patches. Subsystems affected by this patch series: ia64, kbuild, scripts, sh, ocfs2, kfifo, vfs, kernel/watchdog, and mm (slab-generic, slub, kmemleak, debug, pagecache, msync, gup, memremap, memcg, pagemap, mremap, dma, sparsemem, vmalloc, documentation, kasan, initialization, pagealloc, and memory-failure)" * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (175 commits) mm/memory-failure: unnecessary amount of unmapping mm/mmzone.h: fix existing kernel-doc comments and link them to core-api mm: page_alloc: ignore init_on_free=1 for debug_pagealloc=1 net: page_pool: use alloc_pages_bulk in refill code path net: page_pool: refactor dma_map into own function page_pool_dma_map SUNRPC: refresh rq_pages using a bulk page allocator SUNRPC: set rq_page_end differently mm/page_alloc: inline __rmqueue_pcplist mm/page_alloc: optimize code layout for __alloc_pages_bulk mm/page_alloc: add an array-based interface to the bulk page allocator mm/page_alloc: add a bulk page allocator mm/page_alloc: rename alloced to allocated mm/page_alloc: duplicate include linux/vmalloc.h mm, page_alloc: avoid page_to_pfn() in move_freepages() mm/Kconfig: remove default DISCONTIGMEM_MANUAL mm: page_alloc: dump migrate-failed pages mm/mempolicy: fix mpol_misplaced kernel-doc mm/mempolicy: rewrite alloc_pages_vma documentation mm/mempolicy: rewrite alloc_pages documentation mm/mempolicy: rename alloc_pages_current to alloc_pages ...
This commit is contained in:
@@ -19,12 +19,12 @@
|
||||
|
||||
|
||||
/*
|
||||
* Memory cgroup charging and vmstat data aggregation is performed using
|
||||
* percpu batches 32 pages big (look at MEMCG_CHARGE_BATCH). So the maximum
|
||||
* discrepancy between charge and vmstat entries is number of cpus multiplied
|
||||
* by 32 pages multiplied by 2.
|
||||
* Memory cgroup charging is performed using percpu batches 32 pages
|
||||
* big (look at MEMCG_CHARGE_BATCH), whereas memory.stat is exact. So
|
||||
* the maximum discrepancy between charge and vmstat entries is number
|
||||
* of cpus multiplied by 32 pages.
|
||||
*/
|
||||
#define MAX_VMSTAT_ERROR (4096 * 32 * 2 * get_nprocs())
|
||||
#define MAX_VMSTAT_ERROR (4096 * 32 * get_nprocs())
|
||||
|
||||
|
||||
static int alloc_dcache(const char *cgroup, void *arg)
|
||||
@@ -162,7 +162,7 @@ static int cg_run_in_subcgroups(const char *parent,
|
||||
*/
|
||||
static int test_kmem_memcg_deletion(const char *root)
|
||||
{
|
||||
long current, slab, anon, file, kernel_stack, sum;
|
||||
long current, slab, anon, file, kernel_stack, pagetables, percpu, sock, sum;
|
||||
int ret = KSFT_FAIL;
|
||||
char *parent;
|
||||
|
||||
@@ -184,11 +184,14 @@ static int test_kmem_memcg_deletion(const char *root)
|
||||
anon = cg_read_key_long(parent, "memory.stat", "anon ");
|
||||
file = cg_read_key_long(parent, "memory.stat", "file ");
|
||||
kernel_stack = cg_read_key_long(parent, "memory.stat", "kernel_stack ");
|
||||
pagetables = cg_read_key_long(parent, "memory.stat", "pagetables ");
|
||||
percpu = cg_read_key_long(parent, "memory.stat", "percpu ");
|
||||
sock = cg_read_key_long(parent, "memory.stat", "sock ");
|
||||
if (current < 0 || slab < 0 || anon < 0 || file < 0 ||
|
||||
kernel_stack < 0)
|
||||
kernel_stack < 0 || pagetables < 0 || percpu < 0 || sock < 0)
|
||||
goto cleanup;
|
||||
|
||||
sum = slab + anon + file + kernel_stack;
|
||||
sum = slab + anon + file + kernel_stack + pagetables + percpu + sock;
|
||||
if (abs(sum - current) < MAX_VMSTAT_ERROR) {
|
||||
ret = KSFT_PASS;
|
||||
} else {
|
||||
@@ -198,6 +201,9 @@ static int test_kmem_memcg_deletion(const char *root)
|
||||
printf("anon = %ld\n", anon);
|
||||
printf("file = %ld\n", file);
|
||||
printf("kernel_stack = %ld\n", kernel_stack);
|
||||
printf("pagetables = %ld\n", pagetables);
|
||||
printf("percpu = %ld\n", percpu);
|
||||
printf("sock = %ld\n", sock);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
||||
@@ -127,6 +127,57 @@ static void mremap_dontunmap_simple()
|
||||
"unable to unmap source mapping");
|
||||
}
|
||||
|
||||
// This test validates that MREMAP_DONTUNMAP on a shared mapping works as expected.
|
||||
static void mremap_dontunmap_simple_shmem()
|
||||
{
|
||||
unsigned long num_pages = 5;
|
||||
|
||||
int mem_fd = memfd_create("memfd", MFD_CLOEXEC);
|
||||
BUG_ON(mem_fd < 0, "memfd_create");
|
||||
|
||||
BUG_ON(ftruncate(mem_fd, num_pages * page_size) < 0,
|
||||
"ftruncate");
|
||||
|
||||
void *source_mapping =
|
||||
mmap(NULL, num_pages * page_size, PROT_READ | PROT_WRITE,
|
||||
MAP_FILE | MAP_SHARED, mem_fd, 0);
|
||||
BUG_ON(source_mapping == MAP_FAILED, "mmap");
|
||||
|
||||
BUG_ON(close(mem_fd) < 0, "close");
|
||||
|
||||
memset(source_mapping, 'a', num_pages * page_size);
|
||||
|
||||
// Try to just move the whole mapping anywhere (not fixed).
|
||||
void *dest_mapping =
|
||||
mremap(source_mapping, num_pages * page_size, num_pages * page_size,
|
||||
MREMAP_DONTUNMAP | MREMAP_MAYMOVE, NULL);
|
||||
if (dest_mapping == MAP_FAILED && errno == EINVAL) {
|
||||
// Old kernel which doesn't support MREMAP_DONTUNMAP on shmem.
|
||||
BUG_ON(munmap(source_mapping, num_pages * page_size) == -1,
|
||||
"unable to unmap source mapping");
|
||||
return;
|
||||
}
|
||||
|
||||
BUG_ON(dest_mapping == MAP_FAILED, "mremap");
|
||||
|
||||
// Validate that the pages have been moved, we know they were moved if
|
||||
// the dest_mapping contains a's.
|
||||
BUG_ON(check_region_contains_byte
|
||||
(dest_mapping, num_pages * page_size, 'a') != 0,
|
||||
"pages did not migrate");
|
||||
|
||||
// Because the region is backed by shmem, we will actually see the same
|
||||
// memory at the source location still.
|
||||
BUG_ON(check_region_contains_byte
|
||||
(source_mapping, num_pages * page_size, 'a') != 0,
|
||||
"source should have no ptes");
|
||||
|
||||
BUG_ON(munmap(dest_mapping, num_pages * page_size) == -1,
|
||||
"unable to unmap destination mapping");
|
||||
BUG_ON(munmap(source_mapping, num_pages * page_size) == -1,
|
||||
"unable to unmap source mapping");
|
||||
}
|
||||
|
||||
// This test validates MREMAP_DONTUNMAP will move page tables to a specific
|
||||
// destination using MREMAP_FIXED, also while validating that the source
|
||||
// remains intact.
|
||||
@@ -300,6 +351,7 @@ int main(void)
|
||||
BUG_ON(page_buffer == MAP_FAILED, "unable to mmap a page.");
|
||||
|
||||
mremap_dontunmap_simple();
|
||||
mremap_dontunmap_simple_shmem();
|
||||
mremap_dontunmap_simple_fixed();
|
||||
mremap_dontunmap_partial_mapping();
|
||||
mremap_dontunmap_partial_mapping_overwrite();
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
TEST_NAME="vmalloc"
|
||||
DRIVER="test_${TEST_NAME}"
|
||||
NUM_CPUS=`grep -c ^processor /proc/cpuinfo`
|
||||
|
||||
# 1 if fails
|
||||
exitcode=1
|
||||
@@ -22,9 +23,9 @@ ksft_skip=4
|
||||
# Static templates for performance, stressing and smoke tests.
|
||||
# Also it is possible to pass any supported parameters manualy.
|
||||
#
|
||||
PERF_PARAM="single_cpu_test=1 sequential_test_order=1 test_repeat_count=3"
|
||||
SMOKE_PARAM="single_cpu_test=1 test_loop_count=10000 test_repeat_count=10"
|
||||
STRESS_PARAM="test_repeat_count=20"
|
||||
PERF_PARAM="sequential_test_order=1 test_repeat_count=3"
|
||||
SMOKE_PARAM="test_loop_count=10000 test_repeat_count=10"
|
||||
STRESS_PARAM="nr_threads=$NUM_CPUS test_repeat_count=20"
|
||||
|
||||
check_test_requirements()
|
||||
{
|
||||
@@ -58,8 +59,8 @@ run_perfformance_check()
|
||||
|
||||
run_stability_check()
|
||||
{
|
||||
echo "Run stability tests. In order to stress vmalloc subsystem we run"
|
||||
echo "all available test cases on all available CPUs simultaneously."
|
||||
echo "Run stability tests. In order to stress vmalloc subsystem all"
|
||||
echo "available test cases are run by NUM_CPUS workers simultaneously."
|
||||
echo "It will take time, so be patient."
|
||||
|
||||
modprobe $DRIVER $STRESS_PARAM > /dev/null 2>&1
|
||||
@@ -92,17 +93,17 @@ usage()
|
||||
echo "# Shows help message"
|
||||
echo "./${DRIVER}.sh"
|
||||
echo
|
||||
echo "# Runs 1 test(id_1), repeats it 5 times on all online CPUs"
|
||||
echo "./${DRIVER}.sh run_test_mask=1 test_repeat_count=5"
|
||||
echo "# Runs 1 test(id_1), repeats it 5 times by NUM_CPUS workers"
|
||||
echo "./${DRIVER}.sh nr_threads=$NUM_CPUS run_test_mask=1 test_repeat_count=5"
|
||||
echo
|
||||
echo -n "# Runs 4 tests(id_1|id_2|id_4|id_16) on one CPU with "
|
||||
echo "sequential order"
|
||||
echo -n "./${DRIVER}.sh single_cpu_test=1 sequential_test_order=1 "
|
||||
echo -n "./${DRIVER}.sh sequential_test_order=1 "
|
||||
echo "run_test_mask=23"
|
||||
echo
|
||||
echo -n "# Runs all tests on all online CPUs, shuffled order, repeats "
|
||||
echo -n "# Runs all tests by NUM_CPUS workers, shuffled order, repeats "
|
||||
echo "20 times"
|
||||
echo "./${DRIVER}.sh test_repeat_count=20"
|
||||
echo "./${DRIVER}.sh nr_threads=$NUM_CPUS test_repeat_count=20"
|
||||
echo
|
||||
echo "# Performance analysis"
|
||||
echo "./${DRIVER}.sh performance"
|
||||
|
||||
Reference in New Issue
Block a user