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

lib/test_vmalloc.c: add a new 'nr_threads' parameter

By using this parameter we can specify how many workers are created to
perform vmalloc tests. By default it is one CPU. The maximum value is
set to 1024.

As a result of this change a 'single_cpu_test' one becomes obsolete,
therefore it is no longer needed.

[urezki@gmail.com: extend max value of nr_threads parameter]
Link: https://lkml.kernel.org/r/20210406124536.19658-1-urezki@gmail.com

Link: https://lkml.kernel.org/r/20210402202237.20334-2-urezki@gmail.com
Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
Cc: Hillf Danton <hdanton@sina.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Oleksiy Avramchenko <oleksiy.avramchenko@sonymobile.com>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Uladzislau Rezki (Sony) and committed by
Linus Torvalds
80f47599 a8033158

+40 -48
+40 -48
lib/test_vmalloc.c
··· 23 23 module_param(name, type, 0444); \ 24 24 MODULE_PARM_DESC(name, msg) \ 25 25 26 - __param(bool, single_cpu_test, false, 27 - "Use single first online CPU to run tests"); 26 + __param(int, nr_threads, 0, 27 + "Number of workers to perform tests(min: 1 max: USHRT_MAX)"); 28 28 29 29 __param(bool, sequential_test_order, false, 30 30 "Use sequential stress tests order"); ··· 49 49 "\t\tid: 512, name: kvfree_rcu_2_arg_vmalloc_test\n" 50 50 /* Add a new test case description here. */ 51 51 ); 52 - 53 - /* 54 - * Depends on single_cpu_test parameter. If it is true, then 55 - * use first online CPU to trigger a test on, otherwise go with 56 - * all online CPUs. 57 - */ 58 - static cpumask_t cpus_run_test_mask = CPU_MASK_NONE; 59 52 60 53 /* 61 54 * Read write semaphore for synchronization of setup ··· 379 386 u64 time; 380 387 }; 381 388 382 - /* Split it to get rid of: WARNING: line over 80 characters */ 383 - static struct test_case_data 384 - per_cpu_test_data[NR_CPUS][ARRAY_SIZE(test_case_array)]; 385 - 386 389 static struct test_driver { 387 390 struct task_struct *task; 391 + struct test_case_data data[ARRAY_SIZE(test_case_array)]; 392 + 388 393 unsigned long start; 389 394 unsigned long stop; 390 - int cpu; 391 - } per_cpu_test_driver[NR_CPUS]; 395 + } *tdriver; 392 396 393 397 static void shuffle_array(int *arr, int n) 394 398 { ··· 413 423 ktime_t kt; 414 424 u64 delta; 415 425 416 - if (set_cpus_allowed_ptr(current, cpumask_of(t->cpu)) < 0) 417 - pr_err("Failed to set affinity to %d CPU\n", t->cpu); 418 - 419 426 for (i = 0; i < ARRAY_SIZE(test_case_array); i++) 420 427 random_array[i] = i; 421 428 ··· 437 450 kt = ktime_get(); 438 451 for (j = 0; j < test_repeat_count; j++) { 439 452 if (!test_case_array[index].test_func()) 440 - per_cpu_test_data[t->cpu][index].test_passed++; 453 + t->data[index].test_passed++; 441 454 else 442 - per_cpu_test_data[t->cpu][index].test_failed++; 455 + t->data[index].test_failed++; 443 456 } 444 457 445 458 /* ··· 448 461 delta = (u64) ktime_us_delta(ktime_get(), kt); 449 462 do_div(delta, (u32) test_repeat_count); 450 463 451 - per_cpu_test_data[t->cpu][index].time = delta; 464 + t->data[index].time = delta; 452 465 } 453 466 t->stop = get_cycles(); 454 467 ··· 464 477 return 0; 465 478 } 466 479 467 - static void 480 + static int 468 481 init_test_configurtion(void) 469 482 { 470 483 /* 471 - * Reset all data of all CPUs. 484 + * A maximum number of workers is defined as hard-coded 485 + * value and set to USHRT_MAX. We add such gap just in 486 + * case and for potential heavy stressing. 472 487 */ 473 - memset(per_cpu_test_data, 0, sizeof(per_cpu_test_data)); 488 + nr_threads = clamp(nr_threads, 1, (int) USHRT_MAX); 474 489 475 - if (single_cpu_test) 476 - cpumask_set_cpu(cpumask_first(cpu_online_mask), 477 - &cpus_run_test_mask); 478 - else 479 - cpumask_and(&cpus_run_test_mask, cpu_online_mask, 480 - cpu_online_mask); 490 + /* Allocate the space for test instances. */ 491 + tdriver = kvcalloc(nr_threads, sizeof(*tdriver), GFP_KERNEL); 492 + if (tdriver == NULL) 493 + return -1; 481 494 482 495 if (test_repeat_count <= 0) 483 496 test_repeat_count = 1; 484 497 485 498 if (test_loop_count <= 0) 486 499 test_loop_count = 1; 500 + 501 + return 0; 487 502 } 488 503 489 504 static void do_concurrent_test(void) 490 505 { 491 - int cpu, ret; 506 + int i, ret; 492 507 493 508 /* 494 509 * Set some basic configurations plus sanity check. 495 510 */ 496 - init_test_configurtion(); 511 + ret = init_test_configurtion(); 512 + if (ret < 0) 513 + return; 497 514 498 515 /* 499 516 * Put on hold all workers. 500 517 */ 501 518 down_write(&prepare_for_test_rwsem); 502 519 503 - for_each_cpu(cpu, &cpus_run_test_mask) { 504 - struct test_driver *t = &per_cpu_test_driver[cpu]; 520 + for (i = 0; i < nr_threads; i++) { 521 + struct test_driver *t = &tdriver[i]; 505 522 506 - t->cpu = cpu; 507 - t->task = kthread_run(test_func, t, "vmalloc_test/%d", cpu); 523 + t->task = kthread_run(test_func, t, "vmalloc_test/%d", i); 508 524 509 525 if (!IS_ERR(t->task)) 510 526 /* Success. */ 511 527 atomic_inc(&test_n_undone); 512 528 else 513 - pr_err("Failed to start kthread for %d CPU\n", cpu); 529 + pr_err("Failed to start %d kthread\n", i); 514 530 } 515 531 516 532 /* ··· 531 541 ret = wait_for_completion_timeout(&test_all_done_comp, HZ); 532 542 } while (!ret); 533 543 534 - for_each_cpu(cpu, &cpus_run_test_mask) { 535 - struct test_driver *t = &per_cpu_test_driver[cpu]; 536 - int i; 544 + for (i = 0; i < nr_threads; i++) { 545 + struct test_driver *t = &tdriver[i]; 546 + int j; 537 547 538 548 if (!IS_ERR(t->task)) 539 549 kthread_stop(t->task); 540 550 541 - for (i = 0; i < ARRAY_SIZE(test_case_array); i++) { 542 - if (!((run_test_mask & (1 << i)) >> i)) 551 + for (j = 0; j < ARRAY_SIZE(test_case_array); j++) { 552 + if (!((run_test_mask & (1 << j)) >> j)) 543 553 continue; 544 554 545 555 pr_info( 546 556 "Summary: %s passed: %d failed: %d repeat: %d loops: %d avg: %llu usec\n", 547 - test_case_array[i].test_name, 548 - per_cpu_test_data[cpu][i].test_passed, 549 - per_cpu_test_data[cpu][i].test_failed, 557 + test_case_array[j].test_name, 558 + t->data[j].test_passed, 559 + t->data[j].test_failed, 550 560 test_repeat_count, test_loop_count, 551 - per_cpu_test_data[cpu][i].time); 561 + t->data[j].time); 552 562 } 553 563 554 - pr_info("All test took CPU%d=%lu cycles\n", 555 - cpu, t->stop - t->start); 564 + pr_info("All test took worker%d=%lu cycles\n", 565 + i, t->stop - t->start); 556 566 } 567 + 568 + kvfree(tdriver); 557 569 } 558 570 559 571 static int vmalloc_test_init(void)