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

Configure Feed

Select the types of activity you want to include in your feed.

refscale: Ditch ref_scale_shutdown in favor of torture_shutdown_init()

The torture_shutdown_init() function spawns a shutdown kthread in
a manner very similar to that implemented by ref_scale_shutdown().
This commit therefore re-implements ref_scale_shutdown in terms of
torture_shutdown_init().

The initial draft of this patch was generated by version 2.1.16 of the
Claude AI/LLM, but trained and configured for use by my employer, and
prompted to refer to Linux-kernel source code. This initial draft failed
to provide a forward reference to ref_scale_cleanup(), passed zero to
torture_shutdown_init() for an unwelcome insta-shutdown, and failed to
pass the kvm.sh --duration argument in as a refscale module parameter.
On the other hand, it did catch the need to NULL main_task on the
post-test self-shutdown code path, which I might well have forgotten
to do.

This version of the patch fixes those problems, and in fact very little
of the initial draft remains.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Joel Fernandes <joelagnelf@nvidia.com>

authored by

Paul E. McKenney and committed by
Joel Fernandes
b0c8dd50 df6e6ae1

+15 -38
+14 -37
kernel/rcu/refscale.c
··· 92 92 torture_param(int, nruns, 30, "Number of experiments to run."); 93 93 // Reader delay in nanoseconds, 0 for no delay. 94 94 torture_param(int, readdelay, 0, "Read-side delay in nanoseconds."); 95 - 96 - #ifdef MODULE 97 - # define REFSCALE_SHUTDOWN 0 98 - #else 99 - # define REFSCALE_SHUTDOWN 1 100 - #endif 101 - 102 - torture_param(bool, shutdown, REFSCALE_SHUTDOWN, 103 - "Shutdown at end of scalability tests."); 95 + // Maximum shutdown delay in seconds, or zero for no shutdown. 96 + torture_param(int, shutdown_secs, !IS_MODULE(CONFIG_REPRO_TEST) * 300, 97 + "Shutdown at end of scalability tests or at specified timeout (s)."); 104 98 105 99 struct reader_task { 106 100 struct task_struct *task; ··· 103 109 u64 last_duration_ns; 104 110 }; 105 111 106 - static struct task_struct *shutdown_task; 107 - static wait_queue_head_t shutdown_wq; 108 - 109 112 static struct task_struct *main_task; 110 113 static wait_queue_head_t main_wq; 111 - static int shutdown_start; 112 114 113 115 static struct reader_task *reader_tasks; 114 116 ··· 1347 1357 return sum; 1348 1358 } 1349 1359 1360 + static void ref_scale_cleanup(void); 1361 + 1350 1362 // The main_func is the main orchestrator, it performs a bunch of 1351 1363 // experiments. For every experiment, it orders all the readers 1352 1364 // involved to start and waits for them to finish the experiment. It ··· 1435 1443 1436 1444 oom_exit: 1437 1445 // This will shutdown everything including us. 1438 - if (shutdown) { 1439 - shutdown_start = 1; 1440 - wake_up(&shutdown_wq); 1446 + if (shutdown_secs) { 1447 + main_task = NULL; // Avoid self-kill deadlock. 1448 + ref_scale_cleanup(); 1449 + kernel_power_off(); 1441 1450 } 1442 1451 1443 1452 // Wait for torture to stop us ··· 1456 1463 ref_scale_print_module_parms(const struct ref_scale_ops *cur_ops, const char *tag) 1457 1464 { 1458 1465 pr_alert("%s" SCALE_FLAG 1459 - "--- %s: verbose=%d verbose_batched=%d shutdown=%d holdoff=%d lookup_instances=%ld loops=%d nreaders=%d nruns=%d readdelay=%d\n", scale_type, tag, 1460 - verbose, verbose_batched, shutdown, holdoff, lookup_instances, loops, nreaders, nruns, readdelay); 1466 + "--- %s: verbose=%d verbose_batched=%d shutdown_secs=%d holdoff=%d lookup_instances=%ld loops=%d nreaders=%d nruns=%d readdelay=%d\n", scale_type, tag, 1467 + verbose, verbose_batched, shutdown_secs, holdoff, lookup_instances, loops, nreaders, nruns, readdelay); 1461 1468 } 1462 1469 1463 1470 static void ··· 1488 1495 cur_ops->cleanup(); 1489 1496 1490 1497 torture_cleanup_end(); 1491 - } 1492 - 1493 - // Shutdown kthread. Just waits to be awakened, then shuts down system. 1494 - static int 1495 - ref_scale_shutdown(void *arg) 1496 - { 1497 - wait_event_idle(shutdown_wq, shutdown_start); 1498 - 1499 - smp_mb(); // Wake before output. 1500 - ref_scale_cleanup(); 1501 - kernel_power_off(); 1502 - 1503 - return -EINVAL; 1504 1498 } 1505 1499 1506 1500 static int __init ··· 1533 1553 ref_scale_print_module_parms(cur_ops, "Start of test"); 1534 1554 1535 1555 // Shutdown task 1536 - if (shutdown) { 1537 - init_waitqueue_head(&shutdown_wq); 1538 - firsterr = torture_create_kthread(ref_scale_shutdown, NULL, 1539 - shutdown_task); 1556 + if (shutdown_secs) { 1557 + firsterr = torture_shutdown_init(shutdown_secs, ref_scale_cleanup); 1540 1558 if (torture_init_error(firsterr)) 1541 1559 goto unwind; 1542 - schedule_timeout_uninterruptible(1); 1543 1560 } 1544 1561 1545 1562 // Reader tasks (default to ~75% of online CPUs). ··· 1581 1604 unwind: 1582 1605 torture_init_end(); 1583 1606 ref_scale_cleanup(); 1584 - if (shutdown) { 1607 + if (shutdown_secs) { 1585 1608 WARN_ON(!IS_MODULE(CONFIG_RCU_REF_SCALE_TEST)); 1586 1609 kernel_power_off(); 1587 1610 }
+1 -1
tools/testing/selftests/rcutorture/configs/refscale/ver_functions.sh
··· 11 11 # 12 12 # Adds per-version torture-module parameters to kernels supporting them. 13 13 per_version_boot_params () { 14 - echo refscale.shutdown=1 \ 14 + echo refscale.shutdown_secs=$3 \ 15 15 refscale.verbose=0 \ 16 16 $1 17 17 }