1 // SPDX-License-Identifier: GPL-2.0 2 #define _GNU_SOURCE 3 4 #include <linux/limits.h> 5 #include <unistd.h> 6 #include <stdio.h> 7 #include <signal.h> 8 #include <errno.h> 9 #include <fcntl.h> 10 #include <sys/sysinfo.h> 11 #include <string.h> 12 #include <sys/wait.h> 13 #include <sys/mman.h> 14 #include <sys/random.h> 15 16 #include "kselftest.h" 17 #include "cgroup_util.h" 18 19 static int page_size; 20 21 #define PATH_ZSWAP "/sys/module/zswap" 22 #define PATH_ZSWAP_ENABLED "/sys/module/zswap/parameters/enabled" 23 #define PATH_ZSWAP_SHRINKER_ENABLED "/sys/module/zswap/parameters/shrinker_enabled" 24 #define PATH_ZSWAP_STORED_PAGES "/sys/kernel/debug/zswap/stored_pages" 25 26 static int read_int(const char *path, size_t *value) 27 { 28 FILE *file; 29 int ret = 0; 30 31 file = fopen(path, "r"); 32 if (!file) 33 return -1; 34 if (fscanf(file, "%ld", value) != 1) 35 ret = -1; 36 fclose(file); 37 return ret; 38 } 39 40 static int set_min_free_kb(size_t value) 41 { 42 FILE *file; 43 int ret; 44 45 file = fopen("/proc/sys/vm/min_free_kbytes", "w"); 46 if (!file) 47 return -1; 48 ret = fprintf(file, "%ld\n", value); 49 fclose(file); 50 return ret; 51 } 52 53 static int read_min_free_kb(size_t *value) 54 { 55 return read_int("/proc/sys/vm/min_free_kbytes", value); 56 } 57 58 static int get_zswap_stored_pages(size_t *value) 59 { 60 return read_int(PATH_ZSWAP_STORED_PAGES, value); 61 } 62 63 static long get_cg_wb_count(const char *cg) 64 { 65 return cg_read_key_long(cg, "memory.stat", "zswpwb"); 66 } 67 68 static long get_zswpout(const char *cgroup) 69 { 70 return cg_read_key_long(cgroup, "memory.stat", "zswpout "); 71 } 72 73 static int allocate_and_read_bytes(const char *cgroup, void *arg) 74 { 75 size_t size = (size_t)arg; 76 char *mem = (char *)malloc(size); 77 int ret = 0; 78 79 if (!mem) 80 return -1; 81 for (int i = 0; i < size; i += page_size) 82 mem[i] = 'a'; 83 84 /* Go through the allocated memory to (z)swap in and out pages */ 85 for (int i = 0; i < size; i += page_size) { 86 if (mem[i] != 'a') 87 ret = -1; 88 } 89 90 free(mem); 91 return ret; 92 } 93 94 static int allocate_bytes(const char *cgroup, void *arg) 95 { 96 size_t size = (size_t)arg; 97 char *mem = (char *)malloc(size); 98 99 if (!mem) 100 return -1; 101 for (int i = 0; i < size; i += page_size) 102 mem[i] = 'a'; 103 free(mem); 104 return 0; 105 } 106 107 static char *setup_test_group_1M(const char *root, const char *name) 108 { 109 char *group_name = cg_name(root, name); 110 111 if (!group_name) 112 return NULL; 113 if (cg_create(group_name)) 114 goto fail; 115 if (cg_write(group_name, "memory.max", "1M")) { 116 cg_destroy(group_name); 117 goto fail; 118 } 119 return group_name; 120 fail: 121 free(group_name); 122 return NULL; 123 } 124 125 /* 126 * Writeback is asynchronous; poll until at least one writeback has 127 * been recorded for @cg, or until @timeout_ms has elapsed. 128 */ 129 static long wait_for_writeback(const char *cg, int timeout_ms) 130 { 131 long elapsed, count; 132 for (elapsed = 0; elapsed < timeout_ms; elapsed += 100) { 133 count = get_cg_wb_count(cg); 134 135 if (count < 0) 136 return -1; 137 if (count > 0) 138 return count; 139 140 usleep(100000); 141 } 142 143 return 0; 144 } 145 146 /* 147 * Sanity test to check that pages are written into zswap. 148 */ 149 static int test_zswap_usage(const char *root) 150 { 151 long zswpout_before, zswpout_after; 152 int ret = KSFT_FAIL; 153 char *test_group; 154 155 test_group = cg_name(root, "no_shrink_test"); 156 if (!test_group) 157 goto out; 158 if (cg_create(test_group)) 159 goto out; 160 if (cg_write(test_group, "memory.max", "1M")) 161 goto out; 162 163 zswpout_before = get_zswpout(test_group); 164 if (zswpout_before < 0) { 165 ksft_print_msg("Failed to get zswpout\n"); 166 goto out; 167 } 168 169 /* Allocate more than memory.max to push memory into zswap */ 170 if (cg_run(test_group, allocate_bytes, (void *)MB(4))) 171 goto out; 172 173 /* Verify that pages come into zswap */ 174 zswpout_after = get_zswpout(test_group); 175 if (zswpout_after <= zswpout_before) { 176 ksft_print_msg("zswpout does not increase after test program\n"); 177 goto out; 178 } 179 ret = KSFT_PASS; 180 181 out: 182 cg_destroy(test_group); 183 free(test_group); 184 return ret; 185 } 186 187 /* 188 * Check that when memory.zswap.max = 0, no pages can go to the zswap pool for 189 * the cgroup. 190 */ 191 static int test_swapin_nozswap(const char *root) 192 { 193 int ret = KSFT_FAIL; 194 char *test_group, mem_max_buf[32]; 195 long swap_peak, zswpout, min_swap; 196 size_t allocation_size = page_size * 512; 197 198 min_swap = allocation_size / 4; 199 snprintf(mem_max_buf, sizeof(mem_max_buf), "%zu", allocation_size * 3/4); 200 201 test_group = cg_name(root, "no_zswap_test"); 202 if (!test_group) 203 goto out; 204 if (cg_create(test_group)) 205 goto out; 206 if (cg_write(test_group, "memory.max", mem_max_buf)) 207 goto out; 208 if (cg_write(test_group, "memory.zswap.max", "0")) 209 goto out; 210 211 /* Allocate and read more than memory.max to trigger swapin */ 212 if (cg_run(test_group, allocate_and_read_bytes, (void *)allocation_size)) 213 goto out; 214 215 /* Verify that pages are swapped out, but no zswap happened */ 216 swap_peak = cg_read_long(test_group, "memory.swap.peak"); 217 if (swap_peak < 0) { 218 ksft_print_msg("failed to get cgroup's swap_peak\n"); 219 goto out; 220 } 221 222 if (swap_peak < min_swap) { 223 ksft_print_msg("at least %ldKB of memory should be swapped out\n", 224 min_swap / 1024); 225 goto out; 226 } 227 228 zswpout = get_zswpout(test_group); 229 if (zswpout < 0) { 230 ksft_print_msg("failed to get zswpout\n"); 231 goto out; 232 } 233 234 if (zswpout > 0) { 235 ksft_print_msg("zswapout > 0 when memory.zswap.max = 0\n"); 236 goto out; 237 } 238 239 ret = KSFT_PASS; 240 241 out: 242 cg_destroy(test_group); 243 free(test_group); 244 return ret; 245 } 246 247 /* Simple test to verify the (z)swapin code paths */ 248 static int test_zswapin(const char *root) 249 { 250 int ret = KSFT_FAIL; 251 char *test_group; 252 long zswpin; 253 254 test_group = cg_name(root, "zswapin_test"); 255 if (!test_group) 256 goto out; 257 if (cg_create(test_group)) 258 goto out; 259 if (cg_write(test_group, "memory.max", "8M")) 260 goto out; 261 if (cg_write(test_group, "memory.zswap.max", "max")) 262 goto out; 263 264 /* Allocate and read more than memory.max to trigger (z)swap in */ 265 if (cg_run(test_group, allocate_and_read_bytes, (void *)MB(32))) 266 goto out; 267 268 zswpin = cg_read_key_long(test_group, "memory.stat", "zswpin "); 269 if (zswpin < 0) { 270 ksft_print_msg("failed to get zswpin\n"); 271 goto out; 272 } 273 274 if (zswpin < MB(24) / page_size) { 275 ksft_print_msg("at least 24MB should be brought back from zswap\n"); 276 goto out; 277 } 278 279 ret = KSFT_PASS; 280 281 out: 282 cg_destroy(test_group); 283 free(test_group); 284 return ret; 285 } 286 287 /* 288 * Attempt writeback with the following steps: 289 * 1. Allocate memory. 290 * 2. Reclaim memory equal to the amount that was allocated in step 1. 291 This will move it into zswap. 292 * 3. Save current zswap usage. 293 * 4. Move the memory allocated in step 1 back in from zswap. 294 * 5. Set zswap.max to 1/4 of the amount that was recorded in step 3. 295 * 6. Attempt to reclaim memory equal to the amount that was allocated, 296 this will either trigger writeback if it's enabled, or reclamation 297 will fail if writeback is disabled as there isn't enough zswap space. 298 */ 299 static int attempt_writeback(const char *cgroup, void *arg) 300 { 301 size_t memsize = page_size * 1024; 302 char buf[page_size]; 303 long zswap_usage; 304 bool wb_enabled = *(bool *) arg; 305 int ret = -1; 306 char *mem; 307 308 mem = (char *)malloc(memsize); 309 if (!mem) 310 return ret; 311 312 /* 313 * Fill half of each page with increasing data, and keep other 314 * half empty, this will result in data that is still compressible 315 * and ends up in zswap, with material zswap usage. 316 */ 317 for (int i = 0; i < page_size; i++) 318 buf[i] = i < page_size/2 ? (char) i : 0; 319 320 for (int i = 0; i < memsize; i += page_size) 321 memcpy(&mem[i], buf, page_size); 322 323 /* Try and reclaim allocated memory */ 324 if (cg_write_numeric(cgroup, "memory.reclaim", memsize)) { 325 ksft_print_msg("Failed to reclaim all of the requested memory\n"); 326 goto out; 327 } 328 329 zswap_usage = cg_read_long(cgroup, "memory.zswap.current"); 330 331 /* zswpin */ 332 for (int i = 0; i < memsize; i += page_size) { 333 if (memcmp(&mem[i], buf, page_size)) { 334 ksft_print_msg("invalid memory\n"); 335 goto out; 336 } 337 } 338 339 if (cg_write_numeric(cgroup, "memory.zswap.max", zswap_usage/4)) 340 goto out; 341 342 /* 343 * If writeback is enabled, trying to reclaim memory now will trigger a 344 * writeback as zswap.max is 1/4 of what was needed when reclaim ran the first time. 345 * If writeback is disabled, memory reclaim will fail as zswap is limited and 346 * it can't writeback to swap. 347 */ 348 ret = cg_write_numeric(cgroup, "memory.reclaim", memsize); 349 350 /* 351 * When writeback is enabled, memory.reclaim may still fail to reclaim 352 * the requested amount of memory due to a slow swap device. 353 * Ignore -EAGAIN here. The caller determines pass/fail based on the 354 * zswap writeback counter. 355 */ 356 if (wb_enabled && ret == -EAGAIN) 357 ret = 0; 358 else if (!wb_enabled) 359 ret = (ret == -EAGAIN) ? 0 : -1; 360 361 out: 362 free(mem); 363 return ret; 364 } 365 366 static int test_zswap_writeback_one(const char *cgroup, bool wb) 367 { 368 long zswpwb_before, zswpwb_after; 369 370 zswpwb_before = get_cg_wb_count(cgroup); 371 if (zswpwb_before != 0) { 372 ksft_print_msg("zswpwb_before = %ld instead of 0\n", zswpwb_before); 373 return -1; 374 } 375 376 if (cg_run(cgroup, attempt_writeback, (void *) &wb)) 377 return -1; 378 379 /* Verify that zswap writeback occurred only if writeback was enabled */ 380 if (wb) 381 zswpwb_after = wait_for_writeback(cgroup, 5000); 382 else 383 zswpwb_after = get_cg_wb_count(cgroup); 384 if (zswpwb_after < 0) 385 return -1; 386 387 if (wb != !!zswpwb_after) { 388 ksft_print_msg("zswpwb_after is %ld while wb is %s\n", 389 zswpwb_after, wb ? "enabled" : "disabled"); 390 return -1; 391 } 392 393 return 0; 394 } 395 396 /* Test to verify the zswap writeback path */ 397 static int test_zswap_writeback(const char *root, bool wb) 398 { 399 int ret = KSFT_FAIL; 400 char *test_group, *test_group_child = NULL; 401 402 if (cg_read_strcmp(root, "memory.zswap.writeback", "1")) 403 return KSFT_SKIP; 404 405 test_group = cg_name(root, "zswap_writeback_test"); 406 if (!test_group) 407 goto out; 408 if (cg_create(test_group)) 409 goto out; 410 if (cg_write(test_group, "memory.zswap.writeback", wb ? "1" : "0")) 411 goto out; 412 413 if (test_zswap_writeback_one(test_group, wb)) 414 goto out; 415 416 /* Reset memory.zswap.max to max (modified by attempt_writeback), and 417 * set up child cgroup, whose memory.zswap.writeback is hardcoded to 1. 418 * Thus, the parent's setting shall be what's in effect. */ 419 if (cg_write(test_group, "memory.zswap.max", "max")) 420 goto out; 421 if (cg_read_strcmp_wait(test_group, "cgroup.events", "populated 0\n")) 422 goto out; 423 if (cg_write(test_group, "cgroup.subtree_control", "+memory")) 424 goto out; 425 426 test_group_child = cg_name(test_group, "zswap_writeback_test_child"); 427 if (!test_group_child) 428 goto out; 429 if (cg_create(test_group_child)) 430 goto out; 431 if (cg_write(test_group_child, "memory.zswap.writeback", "1")) 432 goto out; 433 434 if (test_zswap_writeback_one(test_group_child, wb)) 435 goto out; 436 437 ret = KSFT_PASS; 438 439 out: 440 if (test_group_child) { 441 cg_destroy(test_group_child); 442 free(test_group_child); 443 } 444 cg_destroy(test_group); 445 free(test_group); 446 return ret; 447 } 448 449 static int test_zswap_writeback_enabled(const char *root) 450 { 451 return test_zswap_writeback(root, true); 452 } 453 454 static int test_zswap_writeback_disabled(const char *root) 455 { 456 return test_zswap_writeback(root, false); 457 } 458 459 static bool zswap_shrinker_enabled(void) 460 { 461 char value[2]; 462 463 if (read_text(PATH_ZSWAP_SHRINKER_ENABLED, value, sizeof(value)) <= 0) 464 return 0; 465 466 return value[0] == 'Y'; 467 } 468 469 /* 470 * When trying to store a memcg page in zswap, if the memcg hits its memory 471 * limit in zswap, writeback should affect only the zswapped pages of that 472 * memcg. 473 */ 474 static int test_no_invasive_cgroup_shrink(const char *root) 475 { 476 int ret = KSFT_FAIL; 477 unsigned int off; 478 long zswpwb_before, zswpwb_after, zswpwb_target; 479 size_t allocation_size = page_size * 1024; 480 unsigned int nr_pages = allocation_size / page_size; 481 char zswap_max_buf[32], mem_max_buf[32]; 482 char *zw_allocation = NULL, *wb_allocation = NULL; 483 char *zw_group = NULL, *wb_group = NULL; 484 485 snprintf(zswap_max_buf, sizeof(zswap_max_buf), "%d", page_size); 486 snprintf(mem_max_buf, sizeof(mem_max_buf), "%zu", allocation_size / 2); 487 488 wb_group = setup_test_group_1M(root, "per_memcg_wb_test1"); 489 if (!wb_group) 490 return KSFT_FAIL; 491 if (cg_write(wb_group, "memory.zswap.max", zswap_max_buf)) 492 goto out; 493 if (cg_write(wb_group, "memory.max", mem_max_buf)) 494 goto out; 495 496 zw_group = setup_test_group_1M(root, "per_memcg_wb_test2"); 497 if (!zw_group) 498 goto out; 499 if (cg_write(zw_group, "memory.max", mem_max_buf)) 500 goto out; 501 502 /* Push some zw_group memory into zswap (simple data, easy to compress) */ 503 if (cg_enter_current(zw_group)) 504 goto out; 505 zw_allocation = malloc(allocation_size); 506 for (int i = 0; i < nr_pages; i++) { 507 off = (unsigned long)i * page_size; 508 memset(&zw_allocation[off], 0, page_size); 509 memset(&zw_allocation[off], 'a', page_size/4); 510 } 511 if (cg_read_key_long(zw_group, "memory.stat", "zswapped") < 1) 512 goto out; 513 514 /* If the shrinker is enabled, try to let the writebacks finish first */ 515 if (zswap_shrinker_enabled()) 516 sleep(5); 517 518 zswpwb_before = get_cg_wb_count(zw_group); 519 if (zswpwb_before < 0) 520 goto out; 521 522 /* Push wb_group memory into zswap with hard-to-compress data to trigger wb */ 523 if (cg_enter_current(wb_group)) 524 goto out; 525 wb_allocation = malloc(allocation_size); 526 if (!wb_allocation) 527 goto out; 528 for (int i = 0; i < nr_pages; i++) { 529 off = (unsigned long)i * page_size; 530 memset(&wb_allocation[off], 0, page_size); 531 getrandom(&wb_allocation[off], page_size/4, 0); 532 } 533 534 /* Verify that only zswapped memory from wb_group has been written back */ 535 zswpwb_target = wait_for_writeback(wb_group, 5000); 536 zswpwb_after = get_cg_wb_count(zw_group); 537 538 if (zswpwb_target > 0 && zswpwb_before == zswpwb_after) 539 ret = KSFT_PASS; 540 541 out: 542 cg_enter_current(root); 543 if (zw_group) { 544 cg_destroy(zw_group); 545 free(zw_group); 546 } 547 if (wb_group) { 548 cg_destroy(wb_group); 549 free(wb_group); 550 } 551 if (zw_allocation) 552 free(zw_allocation); 553 if (wb_allocation) 554 free(wb_allocation); 555 return ret; 556 } 557 558 struct no_kmem_bypass_child_args { 559 size_t target_alloc_bytes; 560 size_t child_allocated; 561 }; 562 563 static int no_kmem_bypass_child(const char *cgroup, void *arg) 564 { 565 struct no_kmem_bypass_child_args *values = arg; 566 void *allocation; 567 568 allocation = malloc(values->target_alloc_bytes); 569 if (!allocation) { 570 values->child_allocated = true; 571 return -1; 572 } 573 for (long i = 0; i < values->target_alloc_bytes; i += page_size) 574 ((char *)allocation)[i] = 'a'; 575 values->child_allocated = true; 576 pause(); 577 free(allocation); 578 return 0; 579 } 580 581 /* 582 * When pages owned by a memcg are pushed to zswap by kswapd, they should be 583 * charged to that cgroup. This wasn't the case before commit 584 * cd08d80ecdac("mm: correctly charge compressed memory to its memcg"). 585 * 586 * The test first allocates memory in a memcg, then raises min_free_kbytes to 587 * a very high value so that the allocation falls below low wm, then makes 588 * another allocation to trigger kswapd that should push the memcg-owned pages 589 * to zswap and verifies that the zswap pages are correctly charged. 590 * 591 * To be run on a VM with at most 4G of memory. 592 */ 593 static int test_no_kmem_bypass(const char *root) 594 { 595 size_t min_free_kb_high, min_free_kb_low, min_free_kb_original; 596 struct no_kmem_bypass_child_args *values; 597 size_t trigger_allocation_size; 598 int wait_child_iteration = 0; 599 long stored_pages_threshold; 600 struct sysinfo sys_info; 601 int ret = KSFT_FAIL; 602 int child_status; 603 char *test_group = NULL; 604 pid_t child_pid; 605 606 /* Read sys info and compute test values accordingly */ 607 if (sysinfo(&sys_info) != 0) 608 return KSFT_FAIL; 609 if (sys_info.totalram > GB(4)) { 610 ksft_print_msg( 611 "requires less than 4GB total ram, sys_info.totalram: %.1fGB\n", 612 (double)sys_info.totalram / GB(1)); 613 return KSFT_SKIP; 614 } 615 if (access(PATH_ZSWAP_STORED_PAGES, R_OK)) { 616 ksft_print_msg("debugfs not mounted at /sys/kernel/debug\n"); 617 return KSFT_SKIP; 618 } 619 values = mmap(0, sizeof(struct no_kmem_bypass_child_args), PROT_READ | 620 PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); 621 if (values == MAP_FAILED) 622 return KSFT_FAIL; 623 if (read_min_free_kb(&min_free_kb_original)) 624 return KSFT_FAIL; 625 min_free_kb_high = sys_info.totalram / 2000; 626 min_free_kb_low = sys_info.totalram / 500000; 627 values->target_alloc_bytes = (sys_info.totalram - min_free_kb_high * 1000) + 628 sys_info.totalram * 5 / 100; 629 stored_pages_threshold = sys_info.totalram / 5 / page_size; 630 trigger_allocation_size = sys_info.totalram / 20; 631 632 /* Set up test memcg */ 633 test_group = cg_name(root, "kmem_bypass_test"); 634 if (!test_group) 635 goto out; 636 637 /* Spawn memcg child and wait for it to allocate */ 638 set_min_free_kb(min_free_kb_low); 639 if (cg_create(test_group)) 640 goto out; 641 values->child_allocated = false; 642 child_pid = cg_run_nowait(test_group, no_kmem_bypass_child, values); 643 if (child_pid < 0) 644 goto out; 645 while (!values->child_allocated && wait_child_iteration++ < 10000) 646 usleep(1000); 647 648 /* Try to wakeup kswapd and let it push child memory to zswap */ 649 set_min_free_kb(min_free_kb_high); 650 for (int i = 0; i < 20; i++) { 651 size_t stored_pages; 652 char *trigger_allocation = malloc(trigger_allocation_size); 653 654 if (!trigger_allocation) 655 break; 656 for (int i = 0; i < trigger_allocation_size; i += page_size) 657 trigger_allocation[i] = 'b'; 658 usleep(100000); 659 free(trigger_allocation); 660 if (get_zswap_stored_pages(&stored_pages)) 661 break; 662 if (stored_pages < 0) 663 break; 664 /* If memory was pushed to zswap, verify it belongs to memcg */ 665 if (stored_pages > stored_pages_threshold) { 666 long zswapped = cg_read_key_long( 667 test_group, "memory.stat", "zswapped "); 668 long long delta = 669 (long long)stored_pages * page_size - zswapped; 670 long long max_delta = 671 (long long)stored_pages * page_size / 4; 672 673 ret = (delta < max_delta) ? KSFT_PASS : KSFT_FAIL; 674 break; 675 } 676 } 677 678 kill(child_pid, SIGTERM); 679 waitpid(child_pid, &child_status, 0); 680 out: 681 set_min_free_kb(min_free_kb_original); 682 cg_destroy(test_group); 683 free(test_group); 684 return ret; 685 } 686 687 struct incomp_child_args { 688 size_t size; 689 int pipefd[2]; 690 int madvise_ret; 691 int madvise_errno; 692 }; 693 694 static int allocate_random_and_wait(const char *cgroup, void *arg) 695 { 696 struct incomp_child_args *values = arg; 697 size_t size = values->size; 698 char *mem; 699 int fd; 700 ssize_t n; 701 702 close(values->pipefd[0]); 703 704 mem = mmap(NULL, size, PROT_READ | PROT_WRITE, 705 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 706 if (mem == MAP_FAILED) 707 return -1; 708 709 /* Fill with random data from /dev/urandom - incompressible */ 710 fd = open("/dev/urandom", O_RDONLY); 711 if (fd < 0) { 712 munmap(mem, size); 713 return -1; 714 } 715 716 for (size_t i = 0; i < size; ) { 717 n = read(fd, mem + i, size - i); 718 if (n <= 0) 719 break; 720 i += n; 721 } 722 close(fd); 723 724 /* Touch all pages to ensure they're faulted in */ 725 for (size_t i = 0; i < size; i += page_size) 726 mem[i] = mem[i]; 727 728 /* Use MADV_PAGEOUT to push pages into zswap */ 729 values->madvise_ret = madvise(mem, size, MADV_PAGEOUT); 730 values->madvise_errno = errno; 731 732 /* Notify parent that allocation and pageout are done */ 733 write(values->pipefd[1], "x", 1); 734 close(values->pipefd[1]); 735 736 /* Keep memory alive for parent to check stats */ 737 pause(); 738 munmap(mem, size); 739 return 0; 740 } 741 742 static long get_zswap_incomp(const char *cgroup) 743 { 744 return cg_read_key_long(cgroup, "memory.stat", "zswap_incomp "); 745 } 746 747 /* 748 * Test that incompressible pages (random data) are tracked by zswap_incomp. 749 * 750 * The child process allocates random data within memory.max, then uses 751 * MADV_PAGEOUT to push pages into zswap. The parent waits on a pipe for 752 * the child to finish, then checks the zswap_incomp stat before the child 753 * exits (zswap_incomp is a gauge that decreases on free). 754 */ 755 static int test_zswap_incompressible(const char *root) 756 { 757 int ret = KSFT_FAIL; 758 struct incomp_child_args *values; 759 char *test_group; 760 long zswap_incomp; 761 pid_t child_pid; 762 int child_status; 763 char buf; 764 765 values = mmap(0, sizeof(struct incomp_child_args), PROT_READ | 766 PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); 767 if (values == MAP_FAILED) 768 return KSFT_FAIL; 769 770 if (pipe(values->pipefd)) { 771 munmap(values, sizeof(struct incomp_child_args)); 772 return KSFT_FAIL; 773 } 774 775 test_group = cg_name(root, "zswap_incompressible_test"); 776 if (!test_group) 777 goto out; 778 if (cg_create(test_group)) 779 goto out; 780 if (cg_write(test_group, "memory.max", "32M")) 781 goto out; 782 783 values->size = MB(4); 784 child_pid = cg_run_nowait(test_group, allocate_random_and_wait, values); 785 if (child_pid < 0) 786 goto out; 787 788 close(values->pipefd[1]); 789 790 /* Wait for child to finish allocating and pageout */ 791 read(values->pipefd[0], &buf, 1); 792 close(values->pipefd[0]); 793 794 zswap_incomp = get_zswap_incomp(test_group); 795 if (zswap_incomp <= 0) { 796 long zswpout = get_zswpout(test_group); 797 long zswapped = cg_read_key_long(test_group, "memory.stat", "zswapped "); 798 long zswap_b = cg_read_key_long(test_group, "memory.stat", "zswap "); 799 800 ksft_print_msg("zswap_incomp not increased: %ld\n", zswap_incomp); 801 ksft_print_msg("debug: zswpout=%ld zswapped=%ld zswap_b=%ld\n", 802 zswpout, zswapped, zswap_b); 803 ksft_print_msg("debug: madvise ret=%d errno=%d\n", 804 values->madvise_ret, values->madvise_errno); 805 goto out_kill; 806 } 807 808 ret = KSFT_PASS; 809 810 out_kill: 811 kill(child_pid, SIGTERM); 812 waitpid(child_pid, &child_status, 0); 813 out: 814 cg_destroy(test_group); 815 free(test_group); 816 munmap(values, sizeof(struct incomp_child_args)); 817 return ret; 818 } 819 820 #define T(x) { x, #x } 821 struct zswap_test { 822 int (*fn)(const char *root); 823 const char *name; 824 } tests[] = { 825 T(test_zswap_usage), 826 T(test_swapin_nozswap), 827 T(test_zswapin), 828 T(test_zswap_writeback_enabled), 829 T(test_zswap_writeback_disabled), 830 T(test_no_kmem_bypass), 831 T(test_no_invasive_cgroup_shrink), 832 T(test_zswap_incompressible), 833 }; 834 #undef T 835 836 static void check_zswap_enabled(void) 837 { 838 char value[2]; 839 840 if (access(PATH_ZSWAP, F_OK)) 841 ksft_exit_skip("zswap isn't configured\n"); 842 843 if (read_text(PATH_ZSWAP_ENABLED, value, sizeof(value)) <= 0) 844 ksft_exit_fail_msg("Failed to read " PATH_ZSWAP_ENABLED "\n"); 845 846 if (value[0] == 'N') 847 ksft_exit_skip("zswap is disabled (hint: echo 1 > " PATH_ZSWAP_ENABLED ")\n"); 848 } 849 850 int main(int argc, char **argv) 851 { 852 char root[PATH_MAX]; 853 int i; 854 855 page_size = sysconf(_SC_PAGE_SIZE); 856 if (page_size <= 0) 857 page_size = BUF_SIZE; 858 859 ksft_print_header(); 860 if (cg_find_unified_root(root, sizeof(root), NULL)) 861 ksft_exit_skip("cgroup v2 isn't mounted\n"); 862 863 check_zswap_enabled(); 864 865 /* 866 * Check that memory controller is available: 867 * memory is listed in cgroup.controllers 868 */ 869 if (cg_read_strstr(root, "cgroup.controllers", "memory")) 870 ksft_exit_skip("memory controller isn't available\n"); 871 872 if (cg_read_strstr(root, "cgroup.subtree_control", "memory")) 873 if (cg_write(root, "cgroup.subtree_control", "+memory")) 874 ksft_exit_skip("Failed to set memory controller\n"); 875 876 ksft_set_plan(ARRAY_SIZE(tests)); 877 for (i = 0; i < ARRAY_SIZE(tests); i++) { 878 switch (tests[i].fn(root)) { 879 case KSFT_PASS: 880 ksft_test_result_pass("%s\n", tests[i].name); 881 break; 882 case KSFT_SKIP: 883 ksft_test_result_skip("%s\n", tests[i].name); 884 break; 885 default: 886 ksft_test_result_fail("%s\n", tests[i].name); 887 break; 888 } 889 } 890 891 ksft_finished(); 892 } 893