diff options
author | Mike Rapoport <rppt@linux.vnet.ibm.com> | 2018-05-15 12:05:53 -0400 |
---|---|---|
committer | Shuah Khan (Samsung OSG) <shuah@kernel.org> | 2018-05-30 17:29:07 -0400 |
commit | 478b27844e9ee5660f4d4fa477e85514c51fc6d8 (patch) | |
tree | f7a4572220ee251de9487e1129c8d3a813b7cc04 /tools | |
parent | 84092dbcf90176fcc258d74ad6ae8bb28d7df31a (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.c | 16 | ||||
-rw-r--r-- | tools/testing/selftests/cgroup/cgroup_util.h | 1 | ||||
-rw-r--r-- | tools/testing/selftests/cgroup/test_memcontrol.c | 91 |
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 | |||
319 | int 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, | |||
38 | extern int get_temp_fd(void); | 38 | extern int get_temp_fd(void); |
39 | extern int alloc_pagecache(int fd, size_t size); | 39 | extern int alloc_pagecache(int fd, size_t size); |
40 | extern int alloc_anon(const char *cgroup, void *arg); | 40 | extern int alloc_anon(const char *cgroup, void *arg); |
41 | extern 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 | ||
641 | static 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; | ||
663 | cleanup: | ||
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 | */ | ||
672 | static 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 | |||
724 | cleanup: | ||
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 | ||