summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2014-01-30 14:21:11 -0800
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2014-02-23 09:01:08 -0800
commitcc47ae0830264f07442070b36fe0d0a4d4e3c313 (patch)
tree6fb3b6b73a8f47085475d57a966940728a869895
parentb5daa8f3b3b2b0133ad40e13d4f722070119ce36 (diff)
rcutorture: Abstract torture-test cleanup
This commit creates a torture_cleanup() that handles the generic cleanup actions local to kernel/torture.c. Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Reviewed-by: Josh Triplett <josh@joshtriplett.org>
-rw-r--r--include/linux/torture.h4
-rw-r--r--kernel/rcu/rcutorture.c11
-rw-r--r--kernel/torture.c30
3 files changed, 30 insertions, 15 deletions
diff --git a/include/linux/torture.h b/include/linux/torture.h
index 428d2712be0..31d69930e5c 100644
--- a/include/linux/torture.h
+++ b/include/linux/torture.h
@@ -65,7 +65,6 @@ extern struct mutex fullstop_mutex;
/* Definitions for online/offline exerciser. */
int torture_onoff_init(long ooholdoff, long oointerval);
-void torture_onoff_cleanup(void);
char *torture_onoff_stats(char *page);
bool torture_onoff_failures(void);
@@ -80,14 +79,13 @@ unsigned long torture_random(struct torture_random_state *trsp);
/* Task shuffler, which causes CPUs to occasionally go idle. */
void torture_shuffle_task_register(struct task_struct *tp);
int torture_shuffle_init(long shuffint);
-void torture_shuffle_cleanup(void);
/* Shutdown task absorption, for when the tasks cannot safely be killed. */
void torture_shutdown_absorb(const char *title);
/* Initialization and cleanup. */
-
void torture_init_begin(char *ttype, bool v);
void torture_init_end(void);
+bool torture_cleanup(void);
#endif /* __LINUX_TORTURE_H */
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
index 93aca2f9261..68a689fc6ff 100644
--- a/kernel/rcu/rcutorture.c
+++ b/kernel/rcu/rcutorture.c
@@ -1423,21 +1423,13 @@ rcu_torture_cleanup(void)
int i;
rcutorture_record_test_transition();
- mutex_lock(&fullstop_mutex);
- if (fullstop == FULLSTOP_SHUTDOWN) {
- pr_warn(/* but going down anyway, so... */
- "Concurrent 'rmmod rcutorture' and shutdown illegal!\n");
- mutex_unlock(&fullstop_mutex);
- schedule_timeout_uninterruptible(10);
+ if (torture_cleanup()) {
if (cur_ops->cb_barrier != NULL)
cur_ops->cb_barrier();
return;
}
- fullstop = FULLSTOP_RMMOD;
- mutex_unlock(&fullstop_mutex);
unregister_reboot_notifier(&rcutorture_shutdown_nb);
- torture_shuffle_cleanup(); /* Must be first task cleaned up. */
rcu_torture_barrier_cleanup();
rcu_torture_stall_cleanup();
if (stutter_task) {
@@ -1501,7 +1493,6 @@ rcu_torture_cleanup(void)
kthread_stop(shutdown_task);
}
shutdown_task = NULL;
- torture_onoff_cleanup();
/* Wait for all RCU callbacks to fire. */
diff --git a/kernel/torture.c b/kernel/torture.c
index 828d0b1a49b..41ae5cc3c4c 100644
--- a/kernel/torture.c
+++ b/kernel/torture.c
@@ -199,7 +199,7 @@ EXPORT_SYMBOL_GPL(torture_onoff_init);
/*
* Clean up after online/offline testing.
*/
-void torture_onoff_cleanup(void)
+static void torture_onoff_cleanup(void)
{
#ifdef CONFIG_HOTPLUG_CPU
if (onoff_task == NULL)
@@ -403,7 +403,7 @@ EXPORT_SYMBOL_GPL(torture_shuffle_init);
/*
* Stop the shuffling.
*/
-void torture_shuffle_cleanup(void)
+static void torture_shuffle_cleanup(void)
{
torture_shuffle_task_unregister_all();
if (shuffler_task) {
@@ -453,3 +453,29 @@ void __init torture_init_end(void)
mutex_unlock(&fullstop_mutex);
}
EXPORT_SYMBOL_GPL(torture_init_end);
+
+/*
+ * Clean up torture module. Please note that this is -not- invoked via
+ * the usual module_exit() mechanism, but rather by an explicit call from
+ * the client torture module. Returns true if a race with system shutdown
+ * is detected.
+ *
+ * This must be called before the caller starts shutting down its own
+ * kthreads.
+ */
+bool torture_cleanup(void)
+{
+ mutex_lock(&fullstop_mutex);
+ if (fullstop == FULLSTOP_SHUTDOWN) {
+ pr_warn("Concurrent rmmod and shutdown illegal!\n");
+ mutex_unlock(&fullstop_mutex);
+ schedule_timeout_uninterruptible(10);
+ return true;
+ }
+ fullstop = FULLSTOP_RMMOD;
+ mutex_unlock(&fullstop_mutex);
+ torture_shuffle_cleanup();
+ torture_onoff_cleanup();
+ return false;
+}
+EXPORT_SYMBOL_GPL(torture_cleanup);