Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests: cgroup: update per-memcg zswap writeback selftest

The memcg-zswap self test is updated to adjust to the behavior change
implemented by commit 87730b165089 ("zswap: make shrinking memcg-aware"),
where zswap performs writeback for specific memcg.

Link: https://lkml.kernel.org/r/20231130194023.4102148-6-nphamcs@gmail.com
Signed-off-by: Domenico Cerasuolo <cerasuolodomenico@gmail.com>
Signed-off-by: Nhat Pham <nphamcs@gmail.com>
Tested-by: Bagas Sanjaya <bagasdotme@gmail.com>
Acked-by: Chris Li <chrisl@kernel.org> (Google)
Cc: Dan Streetman <ddstreet@ieee.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Seth Jennings <sjenning@redhat.com>
Cc: Shakeel Butt <shakeelb@google.com>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Vitaly Wool <vitaly.wool@konsulko.com>
Cc: Yosry Ahmed <yosryahmed@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Domenico Cerasuolo and committed by
Andrew Morton
a697dc2b 7108cc3f

+51 -25
+51 -25
tools/testing/selftests/cgroup/test_zswap.c
··· 50 50 return read_int("/sys/kernel/debug/zswap/stored_pages", value); 51 51 } 52 52 53 - static int get_zswap_written_back_pages(size_t *value) 53 + static int get_cg_wb_count(const char *cg) 54 54 { 55 - return read_int("/sys/kernel/debug/zswap/written_back_pages", value); 55 + return cg_read_key_long(cg, "memory.stat", "zswp_wb"); 56 56 } 57 57 58 58 static long get_zswpout(const char *cgroup) ··· 71 71 mem[i] = 'a'; 72 72 free(mem); 73 73 return 0; 74 + } 75 + 76 + static char *setup_test_group_1M(const char *root, const char *name) 77 + { 78 + char *group_name = cg_name(root, name); 79 + 80 + if (!group_name) 81 + return NULL; 82 + if (cg_create(group_name)) 83 + goto fail; 84 + if (cg_write(group_name, "memory.max", "1M")) { 85 + cg_destroy(group_name); 86 + goto fail; 87 + } 88 + return group_name; 89 + fail: 90 + free(group_name); 91 + return NULL; 74 92 } 75 93 76 94 /* ··· 135 117 136 118 /* 137 119 * When trying to store a memcg page in zswap, if the memcg hits its memory 138 - * limit in zswap, writeback should not be triggered. 139 - * 140 - * This was fixed with commit 0bdf0efa180a("zswap: do not shrink if cgroup may 141 - * not zswap"). Needs to be revised when a per memcg writeback mechanism is 142 - * implemented. 120 + * limit in zswap, writeback should affect only the zswapped pages of that 121 + * memcg. 143 122 */ 144 123 static int test_no_invasive_cgroup_shrink(const char *root) 145 124 { 146 - size_t written_back_before, written_back_after; 147 125 int ret = KSFT_FAIL; 148 - char *test_group; 126 + size_t control_allocation_size = MB(10); 127 + char *control_allocation, *wb_group = NULL, *control_group = NULL; 149 128 150 129 /* Set up */ 151 - test_group = cg_name(root, "no_shrink_test"); 152 - if (!test_group) 130 + wb_group = setup_test_group_1M(root, "per_memcg_wb_test1"); 131 + if (!wb_group) 132 + return KSFT_FAIL; 133 + if (cg_write(wb_group, "memory.zswap.max", "10K")) 153 134 goto out; 154 - if (cg_create(test_group)) 155 - goto out; 156 - if (cg_write(test_group, "memory.max", "1M")) 157 - goto out; 158 - if (cg_write(test_group, "memory.zswap.max", "10K")) 159 - goto out; 160 - if (get_zswap_written_back_pages(&written_back_before)) 135 + control_group = setup_test_group_1M(root, "per_memcg_wb_test2"); 136 + if (!control_group) 161 137 goto out; 162 138 163 - /* Allocate 10x memory.max to push memory into zswap */ 164 - if (cg_run(test_group, allocate_bytes, (void *)MB(10))) 139 + /* Push some test_group2 memory into zswap */ 140 + if (cg_enter_current(control_group)) 141 + goto out; 142 + control_allocation = malloc(control_allocation_size); 143 + for (int i = 0; i < control_allocation_size; i += 4095) 144 + control_allocation[i] = 'a'; 145 + if (cg_read_key_long(control_group, "memory.stat", "zswapped") < 1) 165 146 goto out; 166 147 167 - /* Verify that no writeback happened because of the memcg allocation */ 168 - if (get_zswap_written_back_pages(&written_back_after)) 148 + /* Allocate 10x memory.max to push wb_group memory into zswap and trigger wb */ 149 + if (cg_run(wb_group, allocate_bytes, (void *)MB(10))) 169 150 goto out; 170 - if (written_back_after == written_back_before) 151 + 152 + /* Verify that only zswapped memory from gwb_group has been written back */ 153 + if (get_cg_wb_count(wb_group) > 0 && get_cg_wb_count(control_group) == 0) 171 154 ret = KSFT_PASS; 172 155 out: 173 - cg_destroy(test_group); 174 - free(test_group); 156 + cg_enter_current(root); 157 + if (control_group) { 158 + cg_destroy(control_group); 159 + free(control_group); 160 + } 161 + cg_destroy(wb_group); 162 + free(wb_group); 163 + if (control_allocation) 164 + free(control_allocation); 175 165 return ret; 176 166 } 177 167