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.

rcuscale: Ditch rcu_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 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 <paulmck@kernel.org>
Signed-off-by: Joel Fernandes <joelagnelf@nvidia.com>

authored by

Paul E. McKenney and committed by
Joel Fernandes
359cf5c9 b0c8dd50

+22 -58
+21 -57
kernel/rcu/rcuscale.c
··· 79 79 * test-end checks, and the pair of calls through pointers. 80 80 */ 81 81 82 - #ifdef MODULE 83 - # define RCUSCALE_SHUTDOWN 0 84 - #else 85 - # define RCUSCALE_SHUTDOWN 1 86 - #endif 87 - 88 82 torture_param(bool, gp_async, false, "Use asynchronous GP wait primitives"); 89 83 torture_param(int, gp_async_max, 1000, "Max # outstanding waits per writer"); 90 84 torture_param(bool, gp_exp, false, "Use expedited GP wait primitives"); ··· 86 92 torture_param(int, minruntime, 0, "Minimum run time (s)"); 87 93 torture_param(int, nreaders, -1, "Number of RCU reader threads"); 88 94 torture_param(int, nwriters, -1, "Number of RCU updater threads"); 89 - torture_param(bool, shutdown, RCUSCALE_SHUTDOWN, 90 - "Shutdown at end of scalability tests."); 95 + torture_param(int, shutdown_secs, !IS_MODULE(CONFIG_RCU_SCALE_TEST) * 300, 96 + "Shutdown at end of scalability tests or at specified timeout (s)."); 91 97 torture_param(int, verbose, 1, "Enable verbose debugging printk()s"); 92 98 torture_param(int, writer_holdoff, 0, "Holdoff (us) between GPs, zero to disable"); 93 99 torture_param(int, writer_holdoff_jiffies, 0, "Holdoff (jiffies) between GPs, zero to disable"); ··· 117 123 static int nrealwriters; 118 124 static struct task_struct **writer_tasks; 119 125 static struct task_struct **reader_tasks; 120 - static struct task_struct *shutdown_task; 121 126 122 127 static u64 **writer_durations; 123 128 static bool *writer_done; ··· 125 132 static atomic_t n_rcu_scale_reader_started; 126 133 static atomic_t n_rcu_scale_writer_started; 127 134 static atomic_t n_rcu_scale_writer_finished; 128 - static wait_queue_head_t shutdown_wq; 129 135 static u64 t_rcu_scale_writer_started; 130 136 static u64 t_rcu_scale_writer_finished; 131 137 static unsigned long b_rcu_gp_test_started; ··· 511 519 rcu_scale_free(wmbp); 512 520 } 513 521 522 + static void rcu_scale_cleanup(void); 523 + 514 524 /* 515 525 * RCU scale writer kthread. Repeatedly does a grace period. 516 526 */ ··· 616 622 b_rcu_gp_test_finished = 617 623 cur_ops->get_gp_seq(); 618 624 } 619 - if (shutdown) { 625 + if (shutdown_secs) { 626 + writer_tasks[me] = NULL; 620 627 smp_mb(); /* Assign before wake. */ 621 - wake_up(&shutdown_wq); 628 + rcu_scale_cleanup(); 629 + kernel_power_off(); 622 630 } 623 631 } 624 632 } ··· 664 668 rcu_scale_print_module_parms(struct rcu_scale_ops *cur_ops, const char *tag) 665 669 { 666 670 pr_alert("%s" SCALE_FLAG 667 - "--- %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", 668 - scale_type, tag, gp_async, gp_async_max, gp_exp, holdoff, minruntime, nrealreaders, nrealwriters, writer_holdoff, writer_holdoff_jiffies, verbose, shutdown); 671 + "--- %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", 672 + scale_type, tag, gp_async, gp_async_max, gp_exp, holdoff, minruntime, nrealreaders, nrealwriters, writer_holdoff, writer_holdoff_jiffies, verbose, shutdown_secs); 669 673 } 670 674 671 675 /* ··· 717 721 718 722 kfree(obj); 719 723 } 724 + 725 + static void kfree_scale_cleanup(void); 720 726 721 727 static int 722 728 kfree_scale_thread(void *arg) ··· 789 791 rcuscale_seq_diff(b_rcu_gp_test_finished, b_rcu_gp_test_started), 790 792 PAGES_TO_MB(mem_begin - mem_during)); 791 793 792 - if (shutdown) { 794 + if (shutdown_secs) { 795 + kfree_reader_tasks[me] = NULL; 793 796 smp_mb(); /* Assign before wake. */ 794 - wake_up(&shutdown_wq); 797 + kfree_scale_cleanup(); 798 + kernel_power_off(); 795 799 } 796 800 } 797 801 ··· 818 818 } 819 819 820 820 torture_cleanup_end(); 821 - } 822 - 823 - /* 824 - * shutdown kthread. Just waits to be awakened, then shuts down system. 825 - */ 826 - static int 827 - kfree_scale_shutdown(void *arg) 828 - { 829 - wait_event_idle(shutdown_wq, 830 - atomic_read(&n_kfree_scale_thread_ended) >= kfree_nrealthreads); 831 - 832 - smp_mb(); /* Wake before output. */ 833 - 834 - kfree_scale_cleanup(); 835 - kernel_power_off(); 836 - return -EINVAL; 837 821 } 838 822 839 823 // Used if doing RCU-kfree'ing via call_rcu(). ··· 879 895 880 896 kfree_nrealthreads = compute_real(kfree_nthreads); 881 897 /* Start up the kthreads. */ 882 - if (shutdown) { 883 - init_waitqueue_head(&shutdown_wq); 884 - firsterr = torture_create_kthread(kfree_scale_shutdown, NULL, 885 - shutdown_task); 898 + if (shutdown_secs) { 899 + firsterr = torture_shutdown_init(shutdown_secs, kfree_scale_cleanup); 886 900 if (torture_init_error(firsterr)) 887 901 goto unwind; 888 - schedule_timeout_uninterruptible(1); 889 902 } 890 903 891 904 pr_alert("kfree object size=%zu, kfree_by_call_rcu=%d\n", ··· 1039 1058 torture_cleanup_end(); 1040 1059 } 1041 1060 1042 - /* 1043 - * RCU scalability shutdown kthread. Just waits to be awakened, then shuts 1044 - * down system. 1045 - */ 1046 - static int 1047 - rcu_scale_shutdown(void *arg) 1048 - { 1049 - wait_event_idle(shutdown_wq, atomic_read(&n_rcu_scale_writer_finished) >= nrealwriters); 1050 - smp_mb(); /* Wake before output. */ 1051 - rcu_scale_cleanup(); 1052 - kernel_power_off(); 1053 - return -EINVAL; 1054 - } 1055 - 1056 1061 static int __init 1057 1062 rcu_scale_init(void) 1058 1063 { ··· 1088 1121 1089 1122 /* Start up the kthreads. */ 1090 1123 1091 - if (shutdown) { 1092 - init_waitqueue_head(&shutdown_wq); 1093 - firsterr = torture_create_kthread(rcu_scale_shutdown, NULL, 1094 - shutdown_task); 1124 + if (shutdown_secs) { 1125 + firsterr = torture_shutdown_init(shutdown_secs, rcu_scale_cleanup); 1095 1126 if (torture_init_error(firsterr)) 1096 1127 goto unwind; 1097 - schedule_timeout_uninterruptible(1); 1098 1128 } 1099 1129 reader_tasks = kzalloc_objs(reader_tasks[0], nrealreaders); 1100 1130 if (reader_tasks == NULL) { ··· 1165 1201 unwind: 1166 1202 torture_init_end(); 1167 1203 rcu_scale_cleanup(); 1168 - if (shutdown) { 1204 + if (shutdown_secs) { 1169 1205 WARN_ON(!IS_MODULE(CONFIG_RCU_SCALE_TEST)); 1170 1206 kernel_power_off(); 1171 1207 }
+1 -1
tools/testing/selftests/rcutorture/configs/rcuscale/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 rcuscale.shutdown=1 \ 14 + echo rcuscale.shutdown_secs=$3 \ 15 15 rcuscale.verbose=0 \ 16 16 $1 17 17 }