On Tue, May 26, 2020 at 05:24:46PM +0200, Vlastimil Babka wrote: > On 4/22/20 10:47 PM, Roman Gushchin wrote: > > Add some tests to cover the kernel memory accounting functionality. > > These are covering some issues (and changes) we had recently. > > > > 1) A test which allocates a lot of negative dentries, checks memcg > > slab statistics, creates memory pressure by setting memory.max > > to some low value and checks that some number of slabs was reclaimed. > > > > 2) A test which covers side effects of memcg destruction: it creates > > and destroys a large number of sub-cgroups, each containing a > > multi-threaded workload which allocates and releases some kernel > > memory. Then it checks that the charge ans memory.stats do add up > > on the parent level. > > > > 3) A test which reads /proc/kpagecgroup and implicitly checks that it > > doesn't crash the system. > > > > 4) A test which spawns a large number of threads and checks that > > the kernel stacks accounting works as expected. > > > > 5) A test which checks that living charged slab objects are not > > preventing the memory cgroup from being released after being deleted > > by a user. > > > > Signed-off-by: Roman Gushchin <guro@xxxxxx> > > --- > > tools/testing/selftests/cgroup/.gitignore | 1 + > > tools/testing/selftests/cgroup/Makefile | 2 + > > tools/testing/selftests/cgroup/test_kmem.c | 382 +++++++++++++++++++++ > > 3 files changed, 385 insertions(+) > > create mode 100644 tools/testing/selftests/cgroup/test_kmem.c > > > > diff --git a/tools/testing/selftests/cgroup/.gitignore b/tools/testing/selftests/cgroup/.gitignore > > index aa6de65b0838..84cfcabea838 100644 > > --- a/tools/testing/selftests/cgroup/.gitignore > > +++ b/tools/testing/selftests/cgroup/.gitignore > > @@ -2,3 +2,4 @@ > > test_memcontrol > > test_core > > test_freezer > > +test_kmem > > \ No newline at end of file > > diff --git a/tools/testing/selftests/cgroup/Makefile b/tools/testing/selftests/cgroup/Makefile > > index 967f268fde74..4794844a228e 100644 > > --- a/tools/testing/selftests/cgroup/Makefile > > +++ b/tools/testing/selftests/cgroup/Makefile > > @@ -6,11 +6,13 @@ all: > > TEST_FILES := with_stress.sh > > TEST_PROGS := test_stress.sh > > TEST_GEN_PROGS = test_memcontrol > > +TEST_GEN_PROGS = test_kmem > > Should be += > > > TEST_GEN_PROGS += test_core > > TEST_GEN_PROGS += test_freezer > > > > include ../lib.mk > > > > $(OUTPUT)/test_memcontrol: cgroup_util.c ../clone3/clone3_selftests.h > > +$(OUTPUT)/test_kmem: cgroup_util.c ../clone3/clone3_selftests.h > > $(OUTPUT)/test_core: cgroup_util.c ../clone3/clone3_selftests.h > > $(OUTPUT)/test_freezer: cgroup_util.c ../clone3/clone3_selftests.h > > diff --git a/tools/testing/selftests/cgroup/test_kmem.c b/tools/testing/selftests/cgroup/test_kmem.c > > new file mode 100644 > > index 000000000000..5bc1132fec6b > > --- /dev/null > > +++ b/tools/testing/selftests/cgroup/test_kmem.c > > @@ -0,0 +1,382 @@ > ... > > +/* > > + * This test allocates 100000 of negative dentries with long names. > > + * Then it checks that "slab" in memory.stat is larger than 1M. > > + * Then it sets memory.high to 1M and checks that at least 1/2 > > + * of slab memory has been reclaimed. > > + */ > > +static int test_kmem_basic(const char *root) > > +{ > > + int ret = KSFT_FAIL; > > + char *cg = NULL; > > + long slab0, slab1, current; > > + > > + cg = cg_name(root, "kmem_basic_test"); > > + if (!cg) > > + goto cleanup; > > + > > + if (cg_create(cg)) > > + goto cleanup; > > + > > + if (cg_run(cg, alloc_dcache, (void *)100000)) > > + goto cleanup; > > + > > + slab0 = cg_read_key_long(cg, "memory.stat", "slab "); > > + if (slab0 < (1 >> 20)) > > 1 << 20 ? > > Anyway I was getting this: > not ok 1 test_kmem_basic > ok 2 test_kmem_memcg_deletion > ok 3 test_kmem_proc_kpagecgroup > not ok 4 test_kmem_kernel_stacks > ok 5 test_kmem_dead_cgroups > > Adding some debugging into kmem_basic I found I get memory.stat == 0 at this > point thus it fails the fixed test (otherwise it was failing the <= 0 test after > writing to memory.high). But it's just a VM spinned by virtme which has a very > simple init, so perhaps things are not as initialized as expected. Hm, it's strange, do you have any values in memory.stat::slab for any cgroups? Or can you send me your config (and kvm setup), I'll take a look. Btw, thank you very much for reviewing the series! I appreciate it. I'll integrate your feedback into the next version, which I'm working on right now. Thanks!