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

cgroup: Add test_cpucg_max_nested() testcase

The cgroup cpu controller selftests have a test_cpucg_max() testcase
that validates the behavior of the cpu.max knob. Let's also add a
testcase that verifies that the behavior works correctly when set on a
nested cgroup.

Signed-off-by: David Vernet <void@manifault.com>
Signed-off-by: Tejun Heo <tj@kernel.org>

authored by

David Vernet and committed by
Tejun Heo
a7990657 889ab811

+63
+63
tools/testing/selftests/cgroup/test_cpu.c
··· 617 617 return ret; 618 618 } 619 619 620 + /* 621 + * This test verifies that a process inside of a nested cgroup whose parent 622 + * group has a cpu.max value set, is properly throttled. 623 + */ 624 + static int test_cpucg_max_nested(const char *root) 625 + { 626 + int ret = KSFT_FAIL; 627 + long usage_usec, user_usec; 628 + long usage_seconds = 1; 629 + long expected_usage_usec = usage_seconds * USEC_PER_SEC; 630 + char *parent, *child; 631 + 632 + parent = cg_name(root, "cpucg_parent"); 633 + child = cg_name(parent, "cpucg_child"); 634 + if (!parent || !child) 635 + goto cleanup; 636 + 637 + if (cg_create(parent)) 638 + goto cleanup; 639 + 640 + if (cg_write(parent, "cgroup.subtree_control", "+cpu")) 641 + goto cleanup; 642 + 643 + if (cg_create(child)) 644 + goto cleanup; 645 + 646 + if (cg_write(parent, "cpu.max", "1000")) 647 + goto cleanup; 648 + 649 + struct cpu_hog_func_param param = { 650 + .nprocs = 1, 651 + .ts = { 652 + .tv_sec = usage_seconds, 653 + .tv_nsec = 0, 654 + }, 655 + .clock_type = CPU_HOG_CLOCK_WALL, 656 + }; 657 + if (cg_run(child, hog_cpus_timed, (void *)&param)) 658 + goto cleanup; 659 + 660 + usage_usec = cg_read_key_long(child, "cpu.stat", "usage_usec"); 661 + user_usec = cg_read_key_long(child, "cpu.stat", "user_usec"); 662 + if (user_usec <= 0) 663 + goto cleanup; 664 + 665 + if (user_usec >= expected_usage_usec) 666 + goto cleanup; 667 + 668 + if (values_close(usage_usec, expected_usage_usec, 95)) 669 + goto cleanup; 670 + 671 + ret = KSFT_PASS; 672 + 673 + cleanup: 674 + cg_destroy(child); 675 + free(child); 676 + cg_destroy(parent); 677 + free(parent); 678 + 679 + return ret; 680 + } 681 + 620 682 #define T(x) { x, #x } 621 683 struct cpucg_test { 622 684 int (*fn)(const char *root); ··· 691 629 T(test_cpucg_nested_weight_overprovisioned), 692 630 T(test_cpucg_nested_weight_underprovisioned), 693 631 T(test_cpucg_max), 632 + T(test_cpucg_max_nested), 694 633 }; 695 634 #undef T 696 635