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

This patch was generated by Claude given as input the patch making the
same transformation of ref_scale_shutdown().

Signed-off-by: Paul E. McKenney <[email protected]>
---
 kernel/rcu/rcuscale.c                         | 78 +++++--------------
 .../configs/rcuscale/ver_functions.sh         |  2 +-
 2 files changed, 22 insertions(+), 58 deletions(-)

diff --git a/kernel/rcu/rcuscale.c b/kernel/rcu/rcuscale.c
index 4ac2b134a9833..ac0b1c6b7dae2 100644
--- a/kernel/rcu/rcuscale.c
+++ b/kernel/rcu/rcuscale.c
@@ -79,12 +79,6 @@ MODULE_AUTHOR("Paul E. McKenney <[email protected]>");
  * test-end checks, and the pair of calls through pointers.
  */
 
-#ifdef MODULE
-# define RCUSCALE_SHUTDOWN 0
-#else
-# define RCUSCALE_SHUTDOWN 1
-#endif
-
 torture_param(bool, gp_async, false, "Use asynchronous GP wait primitives");
 torture_param(int, gp_async_max, 1000, "Max # outstanding waits per writer");
 torture_param(bool, gp_exp, false, "Use expedited GP wait primitives");
@@ -92,8 +86,8 @@ torture_param(int, holdoff, 10, "Holdoff time before test 
start (s)");
 torture_param(int, minruntime, 0, "Minimum run time (s)");
 torture_param(int, nreaders, -1, "Number of RCU reader threads");
 torture_param(int, nwriters, -1, "Number of RCU updater threads");
-torture_param(bool, shutdown, RCUSCALE_SHUTDOWN,
-             "Shutdown at end of scalability tests.");
+torture_param(int, shutdown_secs, !IS_MODULE(CONFIG_RCU_SCALE_TEST) * 300,
+             "Shutdown at end of scalability tests or at specified timeout 
(s).");
 torture_param(int, verbose, 1, "Enable verbose debugging printk()s");
 torture_param(int, writer_holdoff, 0, "Holdoff (us) between GPs, zero to 
disable");
 torture_param(int, writer_holdoff_jiffies, 0, "Holdoff (jiffies) between GPs, 
zero to disable");
@@ -123,7 +117,6 @@ static int nrealreaders;
 static int nrealwriters;
 static struct task_struct **writer_tasks;
 static struct task_struct **reader_tasks;
-static struct task_struct *shutdown_task;
 
 static u64 **writer_durations;
 static bool *writer_done;
@@ -132,7 +125,6 @@ static int *writer_n_durations;
 static atomic_t n_rcu_scale_reader_started;
 static atomic_t n_rcu_scale_writer_started;
 static atomic_t n_rcu_scale_writer_finished;
-static wait_queue_head_t shutdown_wq;
 static u64 t_rcu_scale_writer_started;
 static u64 t_rcu_scale_writer_finished;
 static unsigned long b_rcu_gp_test_started;
@@ -519,6 +511,8 @@ static void rcu_scale_async_cb(struct rcu_head *rhp)
        rcu_scale_free(wmbp);
 }
 
+static void rcu_scale_cleanup(void);
+
 /*
  * RCU scale writer kthread.  Repeatedly does a grace period.
  */
@@ -622,9 +616,11 @@ rcu_scale_writer(void *arg)
                                        b_rcu_gp_test_finished =
                                                cur_ops->get_gp_seq();
                                }
-                               if (shutdown) {
+                               if (shutdown_secs) {
+                                       writer_tasks[me] = NULL;
                                        smp_mb(); /* Assign before wake. */
-                                       wake_up(&shutdown_wq);
+                                       rcu_scale_cleanup();
+                                       kernel_power_off();
                                }
                        }
                }
@@ -668,8 +664,8 @@ static void
 rcu_scale_print_module_parms(struct rcu_scale_ops *cur_ops, const char *tag)
 {
        pr_alert("%s" SCALE_FLAG
-                "--- %s: gp_async=%d gp_async_max=%d gp_exp=%d holdoff=%d 
minruntime=%d nreaders=%d nwriters=%d writer_holdoff=%d 
writer_holdoff_jiffies=%d verbose=%d shutdown=%d\n",
-                scale_type, tag, gp_async, gp_async_max, gp_exp, holdoff, 
minruntime, nrealreaders, nrealwriters, writer_holdoff, writer_holdoff_jiffies, 
verbose, shutdown);
+                "--- %s: gp_async=%d gp_async_max=%d gp_exp=%d holdoff=%d 
minruntime=%d nreaders=%d nwriters=%d writer_holdoff=%d 
writer_holdoff_jiffies=%d verbose=%d shutdown_secs=%d\n",
+                scale_type, tag, gp_async, gp_async_max, gp_exp, holdoff, 
minruntime, nrealreaders, nrealwriters, writer_holdoff, writer_holdoff_jiffies, 
verbose, shutdown_secs);
 }
 
 /*
@@ -722,6 +718,8 @@ static void kfree_call_rcu(struct rcu_head *rh)
        kfree(obj);
 }
 
+static void kfree_scale_cleanup(void);
+
 static int
 kfree_scale_thread(void *arg)
 {
@@ -791,9 +789,11 @@ kfree_scale_thread(void *arg)
                       rcuscale_seq_diff(b_rcu_gp_test_finished, 
b_rcu_gp_test_started),
                       PAGES_TO_MB(mem_begin - mem_during));
 
-               if (shutdown) {
+               if (shutdown_secs) {
+                       kfree_reader_tasks[me] = NULL;
                        smp_mb(); /* Assign before wake. */
-                       wake_up(&shutdown_wq);
+                       kfree_scale_cleanup();
+                       kernel_power_off();
                }
        }
 
@@ -820,22 +820,6 @@ kfree_scale_cleanup(void)
        torture_cleanup_end();
 }
 
-/*
- * shutdown kthread.  Just waits to be awakened, then shuts down system.
- */
-static int
-kfree_scale_shutdown(void *arg)
-{
-       wait_event_idle(shutdown_wq,
-                       atomic_read(&n_kfree_scale_thread_ended) >= 
kfree_nrealthreads);
-
-       smp_mb(); /* Wake before output. */
-
-       kfree_scale_cleanup();
-       kernel_power_off();
-       return -EINVAL;
-}
-
 // Used if doing RCU-kfree'ing via call_rcu().
 static unsigned long jiffies_at_lazy_cb;
 static struct rcu_head lazy_test1_rh;
@@ -895,13 +879,10 @@ kfree_scale_init(void)
 
        kfree_nrealthreads = compute_real(kfree_nthreads);
        /* Start up the kthreads. */
-       if (shutdown) {
-               init_waitqueue_head(&shutdown_wq);
-               firsterr = torture_create_kthread(kfree_scale_shutdown, NULL,
-                                                 shutdown_task);
+       if (shutdown_secs) {
+               firsterr = torture_shutdown_init(shutdown_secs, 
kfree_scale_cleanup);
                if (torture_init_error(firsterr))
                        goto unwind;
-               schedule_timeout_uninterruptible(1);
        }
 
        pr_alert("kfree object size=%zu, kfree_by_call_rcu=%d\n",
@@ -1058,20 +1039,6 @@ rcu_scale_cleanup(void)
        torture_cleanup_end();
 }
 
-/*
- * RCU scalability shutdown kthread.  Just waits to be awakened, then shuts
- * down system.
- */
-static int
-rcu_scale_shutdown(void *arg)
-{
-       wait_event_idle(shutdown_wq, atomic_read(&n_rcu_scale_writer_finished) 
>= nrealwriters);
-       smp_mb(); /* Wake before output. */
-       rcu_scale_cleanup();
-       kernel_power_off();
-       return -EINVAL;
-}
-
 static int __init
 rcu_scale_init(void)
 {
@@ -1121,13 +1088,10 @@ rcu_scale_init(void)
 
        /* Start up the kthreads. */
 
-       if (shutdown) {
-               init_waitqueue_head(&shutdown_wq);
-               firsterr = torture_create_kthread(rcu_scale_shutdown, NULL,
-                                                 shutdown_task);
+       if (shutdown_secs) {
+               firsterr = torture_shutdown_init(shutdown_secs, 
rcu_scale_cleanup);
                if (torture_init_error(firsterr))
                        goto unwind;
-               schedule_timeout_uninterruptible(1);
        }
        reader_tasks = kzalloc_objs(reader_tasks[0], nrealreaders);
        if (reader_tasks == NULL) {
@@ -1201,7 +1165,7 @@ rcu_scale_init(void)
 unwind:
        torture_init_end();
        rcu_scale_cleanup();
-       if (shutdown) {
+       if (shutdown_secs) {
                WARN_ON(!IS_MODULE(CONFIG_RCU_SCALE_TEST));
                kernel_power_off();
        }
diff --git 
a/tools/testing/selftests/rcutorture/configs/rcuscale/ver_functions.sh 
b/tools/testing/selftests/rcutorture/configs/rcuscale/ver_functions.sh
index 28070b43f0171..b78ddc243d891 100644
--- a/tools/testing/selftests/rcutorture/configs/rcuscale/ver_functions.sh
+++ b/tools/testing/selftests/rcutorture/configs/rcuscale/ver_functions.sh
@@ -11,7 +11,7 @@
 #
 # Adds per-version torture-module parameters to kernels supporting them.
 per_version_boot_params () {
-       echo    rcuscale.shutdown=1 \
+       echo    rcuscale.shutdown_secs=$3 \
                rcuscale.verbose=0 \
                $1
 }
-- 
2.40.1


Reply via email to