aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorMike Rapoport <rppt@linux.vnet.ibm.com>2018-05-15 12:05:53 -0400
committerShuah Khan (Samsung OSG) <shuah@kernel.org>2018-05-30 17:29:07 -0400
commit478b27844e9ee5660f4d4fa477e85514c51fc6d8 (patch)
treef7a4572220ee251de9487e1129c8d3a813b7cc04 /tools
parent84092dbcf90176fcc258d74ad6ae8bb28d7df31a (diff)
selftests: cgroup/memcontrol: add basic test for swap controls
The new test verifies that memory.swap.max and memory.swap.current behave as expected for simple allocation scenarios Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com> Acked-by: Tejun Heo <tj@kernel.org> Acked-by: Roman Gushchin <guro@fb.com> Signed-off-by: Shuah Khan (Samsung OSG) <shuah@kernel.org>
Diffstat (limited to 'tools')
-rw-r--r--tools/testing/selftests/cgroup/cgroup_util.c16
-rw-r--r--tools/testing/selftests/cgroup/cgroup_util.h1
-rw-r--r--tools/testing/selftests/cgroup/test_memcontrol.c91
3 files changed, 108 insertions, 0 deletions
diff --git a/tools/testing/selftests/cgroup/cgroup_util.c b/tools/testing/selftests/cgroup/cgroup_util.c
index a938b6c8b55a..41cc3b5e5be1 100644
--- a/tools/testing/selftests/cgroup/cgroup_util.c
+++ b/tools/testing/selftests/cgroup/cgroup_util.c
@@ -315,3 +315,19 @@ int alloc_anon(const char *cgroup, void *arg)
315 free(buf); 315 free(buf);
316 return 0; 316 return 0;
317} 317}
318
319int is_swap_enabled(void)
320{
321 char buf[PAGE_SIZE];
322 const char delim[] = "\n";
323 int cnt = 0;
324 char *line;
325
326 if (read_text("/proc/swaps", buf, sizeof(buf)) <= 0)
327 return -1;
328
329 for (line = strtok(buf, delim); line; line = strtok(NULL, delim))
330 cnt++;
331
332 return cnt > 1;
333}
diff --git a/tools/testing/selftests/cgroup/cgroup_util.h b/tools/testing/selftests/cgroup/cgroup_util.h
index 000de075d3d8..fe82a297d4e0 100644
--- a/tools/testing/selftests/cgroup/cgroup_util.h
+++ b/tools/testing/selftests/cgroup/cgroup_util.h
@@ -38,3 +38,4 @@ extern int cg_run_nowait(const char *cgroup,
38extern int get_temp_fd(void); 38extern int get_temp_fd(void);
39extern int alloc_pagecache(int fd, size_t size); 39extern int alloc_pagecache(int fd, size_t size);
40extern int alloc_anon(const char *cgroup, void *arg); 40extern int alloc_anon(const char *cgroup, void *arg);
41extern int is_swap_enabled(void);
diff --git a/tools/testing/selftests/cgroup/test_memcontrol.c b/tools/testing/selftests/cgroup/test_memcontrol.c
index c92a21f3c806..beae06c9c899 100644
--- a/tools/testing/selftests/cgroup/test_memcontrol.c
+++ b/tools/testing/selftests/cgroup/test_memcontrol.c
@@ -638,6 +638,96 @@ cleanup:
638 return ret; 638 return ret;
639} 639}
640 640
641static int alloc_anon_50M_check_swap(const char *cgroup, void *arg)
642{
643 long mem_max = (long)arg;
644 size_t size = MB(50);
645 char *buf, *ptr;
646 long mem_current, swap_current;
647 int ret = -1;
648
649 buf = malloc(size);
650 for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
651 *ptr = 0;
652
653 mem_current = cg_read_long(cgroup, "memory.current");
654 if (!mem_current || !values_close(mem_current, mem_max, 3))
655 goto cleanup;
656
657 swap_current = cg_read_long(cgroup, "memory.swap.current");
658 if (!swap_current ||
659 !values_close(mem_current + swap_current, size, 3))
660 goto cleanup;
661
662 ret = 0;
663cleanup:
664 free(buf);
665 return ret;
666}
667
668/*
669 * This test checks that memory.swap.max limits the amount of
670 * anonymous memory which can be swapped out.
671 */
672static int test_memcg_swap_max(const char *root)
673{
674 int ret = KSFT_FAIL;
675 char *memcg;
676 long max;
677
678 if (!is_swap_enabled())
679 return KSFT_SKIP;
680
681 memcg = cg_name(root, "memcg_test");
682 if (!memcg)
683 goto cleanup;
684
685 if (cg_create(memcg))
686 goto cleanup;
687
688 if (cg_read_long(memcg, "memory.swap.current")) {
689 ret = KSFT_SKIP;
690 goto cleanup;
691 }
692
693 if (cg_read_strcmp(memcg, "memory.max", "max\n"))
694 goto cleanup;
695
696 if (cg_read_strcmp(memcg, "memory.swap.max", "max\n"))
697 goto cleanup;
698
699 if (cg_write(memcg, "memory.swap.max", "30M"))
700 goto cleanup;
701
702 if (cg_write(memcg, "memory.max", "30M"))
703 goto cleanup;
704
705 /* Should be killed by OOM killer */
706 if (!cg_run(memcg, alloc_anon, (void *)MB(100)))
707 goto cleanup;
708
709 if (cg_read_key_long(memcg, "memory.events", "oom ") != 1)
710 goto cleanup;
711
712 if (cg_read_key_long(memcg, "memory.events", "oom_kill ") != 1)
713 goto cleanup;
714
715 if (cg_run(memcg, alloc_anon_50M_check_swap, (void *)MB(30)))
716 goto cleanup;
717
718 max = cg_read_key_long(memcg, "memory.events", "max ");
719 if (max <= 0)
720 goto cleanup;
721
722 ret = KSFT_PASS;
723
724cleanup:
725 cg_destroy(memcg);
726 free(memcg);
727
728 return ret;
729}
730
641/* 731/*
642 * This test disables swapping and tries to allocate anonymous memory 732 * This test disables swapping and tries to allocate anonymous memory
643 * up to OOM. Then it checks for oom and oom_kill events in 733 * up to OOM. Then it checks for oom and oom_kill events in
@@ -694,6 +784,7 @@ struct memcg_test {
694 T(test_memcg_high), 784 T(test_memcg_high),
695 T(test_memcg_max), 785 T(test_memcg_max),
696 T(test_memcg_oom_events), 786 T(test_memcg_oom_events),
787 T(test_memcg_swap_max),
697}; 788};
698#undef T 789#undef T
699 790