aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rcutorture.c
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2012-08-25 18:27:40 -0400
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2012-09-23 10:42:23 -0400
commit60f53782c51f27c695840ce90c6c432284319eef (patch)
treedaf20b20a35f09ecfa214127cf3c676f12c4edd1 /kernel/rcutorture.c
parent2caa1e4432be7260dca60c3de6949b77eb007515 (diff)
rcu: Prevent initialization race in rcutorture kthreads
When you do something like "t = kthread_run(...)", it is possible that the kthread will start running before the assignment to "t" happens. If the child kthread expects to find a pointer to its task_struct in "t", it will then be fatally disappointed. This commit therefore switches such cases to kthread_create() followed by wake_up_process(), guaranteeing that the assignment happens before the child kthread starts running. Reported-by: Fengguang Wu <fengguang.wu@intel.com> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'kernel/rcutorture.c')
-rw-r--r--kernel/rcutorture.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index 61be03ba598d..aaa7b9f3532a 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -2029,14 +2029,15 @@ rcu_torture_init(void)
2029 /* Start up the kthreads. */ 2029 /* Start up the kthreads. */
2030 2030
2031 VERBOSE_PRINTK_STRING("Creating rcu_torture_writer task"); 2031 VERBOSE_PRINTK_STRING("Creating rcu_torture_writer task");
2032 writer_task = kthread_run(rcu_torture_writer, NULL, 2032 writer_task = kthread_create(rcu_torture_writer, NULL,
2033 "rcu_torture_writer"); 2033 "rcu_torture_writer");
2034 if (IS_ERR(writer_task)) { 2034 if (IS_ERR(writer_task)) {
2035 firsterr = PTR_ERR(writer_task); 2035 firsterr = PTR_ERR(writer_task);
2036 VERBOSE_PRINTK_ERRSTRING("Failed to create writer"); 2036 VERBOSE_PRINTK_ERRSTRING("Failed to create writer");
2037 writer_task = NULL; 2037 writer_task = NULL;
2038 goto unwind; 2038 goto unwind;
2039 } 2039 }
2040 wake_up_process(writer_task);
2040 fakewriter_tasks = kzalloc(nfakewriters * sizeof(fakewriter_tasks[0]), 2041 fakewriter_tasks = kzalloc(nfakewriters * sizeof(fakewriter_tasks[0]),
2041 GFP_KERNEL); 2042 GFP_KERNEL);
2042 if (fakewriter_tasks == NULL) { 2043 if (fakewriter_tasks == NULL) {
@@ -2151,14 +2152,15 @@ rcu_torture_init(void)
2151 } 2152 }
2152 if (shutdown_secs > 0) { 2153 if (shutdown_secs > 0) {
2153 shutdown_time = jiffies + shutdown_secs * HZ; 2154 shutdown_time = jiffies + shutdown_secs * HZ;
2154 shutdown_task = kthread_run(rcu_torture_shutdown, NULL, 2155 shutdown_task = kthread_create(rcu_torture_shutdown, NULL,
2155 "rcu_torture_shutdown"); 2156 "rcu_torture_shutdown");
2156 if (IS_ERR(shutdown_task)) { 2157 if (IS_ERR(shutdown_task)) {
2157 firsterr = PTR_ERR(shutdown_task); 2158 firsterr = PTR_ERR(shutdown_task);
2158 VERBOSE_PRINTK_ERRSTRING("Failed to create shutdown"); 2159 VERBOSE_PRINTK_ERRSTRING("Failed to create shutdown");
2159 shutdown_task = NULL; 2160 shutdown_task = NULL;
2160 goto unwind; 2161 goto unwind;
2161 } 2162 }
2163 wake_up_process(shutdown_task);
2162 } 2164 }
2163 i = rcu_torture_onoff_init(); 2165 i = rcu_torture_onoff_init();
2164 if (i != 0) { 2166 if (i != 0) {