Commit 60f53782 authored by Paul E. McKenney's avatar Paul E. McKenney

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: default avatarFengguang Wu <fengguang.wu@intel.com>
Signed-off-by: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>
parent 2caa1e44
...@@ -2029,14 +2029,15 @@ rcu_torture_init(void) ...@@ -2029,14 +2029,15 @@ rcu_torture_init(void)
/* Start up the kthreads. */ /* Start up the kthreads. */
VERBOSE_PRINTK_STRING("Creating rcu_torture_writer task"); VERBOSE_PRINTK_STRING("Creating rcu_torture_writer task");
writer_task = kthread_run(rcu_torture_writer, NULL, writer_task = kthread_create(rcu_torture_writer, NULL,
"rcu_torture_writer"); "rcu_torture_writer");
if (IS_ERR(writer_task)) { if (IS_ERR(writer_task)) {
firsterr = PTR_ERR(writer_task); firsterr = PTR_ERR(writer_task);
VERBOSE_PRINTK_ERRSTRING("Failed to create writer"); VERBOSE_PRINTK_ERRSTRING("Failed to create writer");
writer_task = NULL; writer_task = NULL;
goto unwind; goto unwind;
} }
wake_up_process(writer_task);
fakewriter_tasks = kzalloc(nfakewriters * sizeof(fakewriter_tasks[0]), fakewriter_tasks = kzalloc(nfakewriters * sizeof(fakewriter_tasks[0]),
GFP_KERNEL); GFP_KERNEL);
if (fakewriter_tasks == NULL) { if (fakewriter_tasks == NULL) {
...@@ -2151,14 +2152,15 @@ rcu_torture_init(void) ...@@ -2151,14 +2152,15 @@ rcu_torture_init(void)
} }
if (shutdown_secs > 0) { if (shutdown_secs > 0) {
shutdown_time = jiffies + shutdown_secs * HZ; shutdown_time = jiffies + shutdown_secs * HZ;
shutdown_task = kthread_run(rcu_torture_shutdown, NULL, shutdown_task = kthread_create(rcu_torture_shutdown, NULL,
"rcu_torture_shutdown"); "rcu_torture_shutdown");
if (IS_ERR(shutdown_task)) { if (IS_ERR(shutdown_task)) {
firsterr = PTR_ERR(shutdown_task); firsterr = PTR_ERR(shutdown_task);
VERBOSE_PRINTK_ERRSTRING("Failed to create shutdown"); VERBOSE_PRINTK_ERRSTRING("Failed to create shutdown");
shutdown_task = NULL; shutdown_task = NULL;
goto unwind; goto unwind;
} }
wake_up_process(shutdown_task);
} }
i = rcu_torture_onoff_init(); i = rcu_torture_onoff_init();
if (i != 0) { if (i != 0) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment