Skip to content

Commit

Permalink
torture: Address race in module cleanup
Browse files Browse the repository at this point in the history
When performing module cleanups by calling torture_cleanup() the
'torture_type' string in nullified However, callers are not necessarily
done, and might still need to reference the variable. This impacts
both rcutorture and locktorture, causing printing things like:

[   94.226618] (null)-torture: Stopping lock_torture_writer task
[   94.226624] (null)-torture: Stopping lock_torture_stats task

Thus delay this operation until the very end of the cleanup process.
The consequence (which shouldn't matter for this kid of program) is,
of course, that we delay the window between rmmod and modprobing,
for instance in module_torture_begin().

Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
  • Loading branch information
Davidlohr Bueso authored and paulmck committed Sep 16, 2014
1 parent 1e6757a commit d36a7a0
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 6 deletions.
3 changes: 2 additions & 1 deletion include/linux/torture.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ int torture_stutter_init(int s);
/* Initialization and cleanup. */
bool torture_init_begin(char *ttype, bool v, int *runnable);
void torture_init_end(void);
bool torture_cleanup(void);
bool torture_cleanup_begin(void);
void torture_cleanup_end(void);
bool torture_must_stop(void);
bool torture_must_stop_irq(void);
void torture_kthread_stopping(char *title);
Expand Down
3 changes: 2 additions & 1 deletion kernel/locking/locktorture.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ static void lock_torture_cleanup(void)
{
int i;

if (torture_cleanup())
if (torture_cleanup_begin())
return;

if (writer_tasks) {
Expand All @@ -384,6 +384,7 @@ static void lock_torture_cleanup(void)
else
lock_torture_print_module_parms(cur_ops,
"End of test: SUCCESS");
torture_cleanup_end();
}

static int __init lock_torture_init(void)
Expand Down
3 changes: 2 additions & 1 deletion kernel/rcu/rcutorture.c
Original file line number Diff line number Diff line change
Expand Up @@ -1514,7 +1514,7 @@ rcu_torture_cleanup(void)
int i;

rcutorture_record_test_transition();
if (torture_cleanup()) {
if (torture_cleanup_begin()) {
if (cur_ops->cb_barrier != NULL)
cur_ops->cb_barrier();
return;
Expand Down Expand Up @@ -1566,6 +1566,7 @@ rcu_torture_cleanup(void)
"End of test: RCU_HOTPLUG");
else
rcu_torture_print_module_parms(cur_ops, "End of test: SUCCESS");
torture_cleanup_end();
}

#ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD
Expand Down
16 changes: 13 additions & 3 deletions kernel/torture.c
Original file line number Diff line number Diff line change
Expand Up @@ -633,8 +633,13 @@ EXPORT_SYMBOL_GPL(torture_init_end);
*
* This must be called before the caller starts shutting down its own
* kthreads.
*
* Both torture_cleanup_begin() and torture_cleanup_end() must be paired,
* in order to correctly perform the cleanup. They are separated because
* threads can still need to reference the torture_type type, thus nullify
* only after completing all other relevant calls.
*/
bool torture_cleanup(void)
bool torture_cleanup_begin(void)
{
mutex_lock(&fullstop_mutex);
if (ACCESS_ONCE(fullstop) == FULLSTOP_SHUTDOWN) {
Expand All @@ -649,12 +654,17 @@ bool torture_cleanup(void)
torture_shuffle_cleanup();
torture_stutter_cleanup();
torture_onoff_cleanup();
return false;
}
EXPORT_SYMBOL_GPL(torture_cleanup_begin);

void torture_cleanup_end(void)
{
mutex_lock(&fullstop_mutex);
torture_type = NULL;
mutex_unlock(&fullstop_mutex);
return false;
}
EXPORT_SYMBOL_GPL(torture_cleanup);
EXPORT_SYMBOL_GPL(torture_cleanup_end);

/*
* Is it time for the current torture test to stop?
Expand Down

0 comments on commit d36a7a0

Please sign in to comment.