]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
rcutorture: Abstract torture-test cleanup
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Thu, 30 Jan 2014 22:21:11 +0000 (14:21 -0800)
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Sun, 23 Feb 2014 17:01:08 +0000 (09:01 -0800)
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>
include/linux/torture.h
kernel/rcu/rcutorture.c
kernel/torture.c

index 428d2712be04eb5c394babc486f09f40c2090207..31d69930e5cf84c9f2537df9ac20654c83526692 100644 (file)
@@ -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 */
index 93aca2f9261e9f349645a29cbae27cbb482b08a3..68a689fc6ffa85b6f832616c1714e4b914552a07 100644 (file)
@@ -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.  */
 
index 828d0b1a49b83736fa7081c5ce89c5d8e26456ef..41ae5cc3c4c352146d5f589fc5c6789d831fab93 100644 (file)
@@ -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);