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

cgroup: Add test_cpucg_nested_weight_underprovisioned() testcase

The cgroup cpu controller test suite currently contains a testcase called
test_cpucg_nested_weight_underprovisioned() which verifies the expected
behavior of cpu.weight when applied to nested cgroups. That first testcase
validated the expected behavior when the processes in the leaf cgroups
overcommitted the system. This patch adds a complementary
test_cpucg_nested_weight_underprovisioned() testcase which validates
behavior when those leaf cgroups undercommit the system.

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
89ca0efa b76ee4f5

+57 -16
+57 -16
tools/testing/selftests/cgroup/test_cpu.c
··· 403 403 underprovision_validate); 404 404 } 405 405 406 - /* 407 - * First, this test creates the following hierarchy: 408 - * A 409 - * A/B cpu.weight = 1000 410 - * A/C cpu.weight = 1000 411 - * A/C/D cpu.weight = 5000 412 - * A/C/E cpu.weight = 5000 413 - * 414 - * A separate process is then created for each leaf, which spawn nproc threads 415 - * that burn a CPU for a few seconds. 416 - * 417 - * Once all of those processes have exited, we verify that each of the leaf 418 - * cgroups have roughly the same usage from cpu.stat. 419 - */ 420 406 static int 421 - test_cpucg_nested_weight_overprovisioned(const char *root) 407 + run_cpucg_nested_weight_test(const char *root, bool overprovisioned) 422 408 { 423 409 int ret = KSFT_FAIL, i; 424 410 char *parent = NULL, *child = NULL; 425 411 struct cpu_hogger leaf[3] = {NULL}; 426 412 long nested_leaf_usage, child_usage; 427 413 int nprocs = get_nprocs(); 414 + 415 + if (!overprovisioned) { 416 + if (nprocs < 4) 417 + /* 418 + * Only run the test if there are enough cores to avoid overprovisioning 419 + * the system. 420 + */ 421 + return KSFT_SKIP; 422 + nprocs /= 4; 423 + } 428 424 429 425 parent = cg_name(root, "cpucg_test"); 430 426 child = cg_name(parent, "cpucg_child"); ··· 497 501 } 498 502 499 503 nested_leaf_usage = leaf[1].usage + leaf[2].usage; 500 - if (!values_close(leaf[0].usage, nested_leaf_usage, 15)) 504 + if (overprovisioned) { 505 + if (!values_close(leaf[0].usage, nested_leaf_usage, 15)) 506 + goto cleanup; 507 + } else if (!values_close(leaf[0].usage * 2, nested_leaf_usage, 15)) 501 508 goto cleanup; 509 + 502 510 503 511 child_usage = cg_read_key_long(child, "cpu.stat", "usage_usec"); 504 512 if (child_usage <= 0) ··· 524 524 return ret; 525 525 } 526 526 527 + /* 528 + * First, this test creates the following hierarchy: 529 + * A 530 + * A/B cpu.weight = 1000 531 + * A/C cpu.weight = 1000 532 + * A/C/D cpu.weight = 5000 533 + * A/C/E cpu.weight = 5000 534 + * 535 + * A separate process is then created for each leaf, which spawn nproc threads 536 + * that burn a CPU for a few seconds. 537 + * 538 + * Once all of those processes have exited, we verify that each of the leaf 539 + * cgroups have roughly the same usage from cpu.stat. 540 + */ 541 + static int 542 + test_cpucg_nested_weight_overprovisioned(const char *root) 543 + { 544 + return run_cpucg_nested_weight_test(root, true); 545 + } 546 + 547 + /* 548 + * First, this test creates the following hierarchy: 549 + * A 550 + * A/B cpu.weight = 1000 551 + * A/C cpu.weight = 1000 552 + * A/C/D cpu.weight = 5000 553 + * A/C/E cpu.weight = 5000 554 + * 555 + * A separate process is then created for each leaf, which nproc / 4 threads 556 + * that burns a CPU for a few seconds. 557 + * 558 + * Once all of those processes have exited, we verify that each of the leaf 559 + * cgroups have roughly the same usage from cpu.stat. 560 + */ 561 + static int 562 + test_cpucg_nested_weight_underprovisioned(const char *root) 563 + { 564 + return run_cpucg_nested_weight_test(root, false); 565 + } 566 + 527 567 #define T(x) { x, #x } 528 568 struct cpucg_test { 529 569 int (*fn)(const char *root); ··· 574 534 T(test_cpucg_weight_overprovisioned), 575 535 T(test_cpucg_weight_underprovisioned), 576 536 T(test_cpucg_nested_weight_overprovisioned), 537 + T(test_cpucg_nested_weight_underprovisioned), 577 538 }; 578 539 #undef T 579 540