Merge branch 'akpm' (patches from Andrew)
Merge more updates from Andrew Morton: - most of the rest of MM (memcg, hugetlb, vmscan, proc, compaction, mempolicy, oom-kill, hugetlbfs, migration, thp, cma, util, memory-hotplug, cleanups, uaccess, migration, gup, pagemap), - various other subsystems (alpha, misc, sparse, bitmap, lib, bitops, checkpatch, autofs, minix, nilfs, ufs, fat, signals, kmod, coredump, exec, kdump, rapidio, panic, kcov, kgdb, ipc). * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (164 commits) mm/gup: remove task_struct pointer for all gup code mm: clean up the last pieces of page fault accountings mm/xtensa: use general page fault accounting mm/x86: use general page fault accounting mm/sparc64: use general page fault accounting mm/sparc32: use general page fault accounting mm/sh: use general page fault accounting mm/s390: use general page fault accounting mm/riscv: use general page fault accounting mm/powerpc: use general page fault accounting mm/parisc: use general page fault accounting mm/openrisc: use general page fault accounting mm/nios2: use general page fault accounting mm/nds32: use general page fault accounting mm/mips: use general page fault accounting mm/microblaze: use general page fault accounting mm/m68k: use general page fault accounting mm/ia64: use general page fault accounting mm/hexagon: use general page fault accounting mm/csky: use general page fault accounting ...
This commit is contained in:
@@ -18,6 +18,15 @@
|
||||
#include "cgroup_util.h"
|
||||
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#define MAX_VMSTAT_ERROR (4096 * 32 * 2 * get_nprocs())
|
||||
|
||||
|
||||
static int alloc_dcache(const char *cgroup, void *arg)
|
||||
{
|
||||
unsigned long i;
|
||||
@@ -180,7 +189,7 @@ static int test_kmem_memcg_deletion(const char *root)
|
||||
goto cleanup;
|
||||
|
||||
sum = slab + anon + file + kernel_stack;
|
||||
if (abs(sum - current) < 4096 * 32 * 2 * get_nprocs()) {
|
||||
if (abs(sum - current) < MAX_VMSTAT_ERROR) {
|
||||
ret = KSFT_PASS;
|
||||
} else {
|
||||
printf("memory.current = %ld\n", current);
|
||||
@@ -331,6 +340,64 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This test creates a sub-tree with 1000 memory cgroups.
|
||||
* Then it checks that the memory.current on the parent level
|
||||
* is greater than 0 and approximates matches the percpu value
|
||||
* from memory.stat.
|
||||
*/
|
||||
static int test_percpu_basic(const char *root)
|
||||
{
|
||||
int ret = KSFT_FAIL;
|
||||
char *parent, *child;
|
||||
long current, percpu;
|
||||
int i;
|
||||
|
||||
parent = cg_name(root, "percpu_basic_test");
|
||||
if (!parent)
|
||||
goto cleanup;
|
||||
|
||||
if (cg_create(parent))
|
||||
goto cleanup;
|
||||
|
||||
if (cg_write(parent, "cgroup.subtree_control", "+memory"))
|
||||
goto cleanup;
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
child = cg_name_indexed(parent, "child", i);
|
||||
if (!child)
|
||||
return -1;
|
||||
|
||||
if (cg_create(child))
|
||||
goto cleanup_children;
|
||||
|
||||
free(child);
|
||||
}
|
||||
|
||||
current = cg_read_long(parent, "memory.current");
|
||||
percpu = cg_read_key_long(parent, "memory.stat", "percpu ");
|
||||
|
||||
if (current > 0 && percpu > 0 && abs(current - percpu) <
|
||||
MAX_VMSTAT_ERROR)
|
||||
ret = KSFT_PASS;
|
||||
else
|
||||
printf("memory.current %ld\npercpu %ld\n",
|
||||
current, percpu);
|
||||
|
||||
cleanup_children:
|
||||
for (i = 0; i < 1000; i++) {
|
||||
child = cg_name_indexed(parent, "child", i);
|
||||
cg_destroy(child);
|
||||
free(child);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
cg_destroy(parent);
|
||||
free(parent);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define T(x) { x, #x }
|
||||
struct kmem_test {
|
||||
int (*fn)(const char *root);
|
||||
@@ -341,6 +408,7 @@ struct kmem_test {
|
||||
T(test_kmem_proc_kpagecgroup),
|
||||
T(test_kmem_kernel_stacks),
|
||||
T(test_kmem_dead_cgroups),
|
||||
T(test_percpu_basic),
|
||||
};
|
||||
#undef T
|
||||
|
||||
|
@@ -343,7 +343,7 @@ kmod_test_0001_driver()
|
||||
|
||||
kmod_defaults_driver
|
||||
config_num_threads 1
|
||||
printf '\000' >"$DIR"/config_test_driver
|
||||
printf $NAME >"$DIR"/config_test_driver
|
||||
config_trigger ${FUNCNAME[0]}
|
||||
config_expect_result ${FUNCNAME[0]} MODULE_NOT_FOUND
|
||||
}
|
||||
@@ -354,7 +354,7 @@ kmod_test_0001_fs()
|
||||
|
||||
kmod_defaults_fs
|
||||
config_num_threads 1
|
||||
printf '\000' >"$DIR"/config_test_fs
|
||||
printf $NAME >"$DIR"/config_test_fs
|
||||
config_trigger ${FUNCNAME[0]}
|
||||
config_expect_result ${FUNCNAME[0]} -EINVAL
|
||||
}
|
||||
|
@@ -941,6 +941,41 @@ TEST_F(hmm, migrate_fault)
|
||||
hmm_buffer_free(buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
* Migrate anonymous shared memory to device private memory.
|
||||
*/
|
||||
TEST_F(hmm, migrate_shared)
|
||||
{
|
||||
struct hmm_buffer *buffer;
|
||||
unsigned long npages;
|
||||
unsigned long size;
|
||||
int ret;
|
||||
|
||||
npages = ALIGN(HMM_BUFFER_SIZE, self->page_size) >> self->page_shift;
|
||||
ASSERT_NE(npages, 0);
|
||||
size = npages << self->page_shift;
|
||||
|
||||
buffer = malloc(sizeof(*buffer));
|
||||
ASSERT_NE(buffer, NULL);
|
||||
|
||||
buffer->fd = -1;
|
||||
buffer->size = size;
|
||||
buffer->mirror = malloc(size);
|
||||
ASSERT_NE(buffer->mirror, NULL);
|
||||
|
||||
buffer->ptr = mmap(NULL, size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED | MAP_ANONYMOUS,
|
||||
buffer->fd, 0);
|
||||
ASSERT_NE(buffer->ptr, MAP_FAILED);
|
||||
|
||||
/* Migrate memory to device. */
|
||||
ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_MIGRATE, buffer, npages);
|
||||
ASSERT_EQ(ret, -ENOENT);
|
||||
|
||||
hmm_buffer_free(buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to migrate various memory types to device private memory.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user