Просмотр исходного кода

torture: Check for multiple concurrent torture tests

The torture tests are designed to run in isolation, but do not enforce
this isolation.  This commit therefore checks for concurrent torture
tests, and refuses to start new tests while old tests are running.

Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Reviewed-by: Josh Triplett <josh@joshtriplett.org>
Paul E. McKenney 11 лет назад
Родитель
Сommit
5228084eed
4 измененных файлов с 16 добавлено и 5 удалено
  1. 1 1
      include/linux/torture.h
  2. 2 1
      kernel/locking/locktorture.c
  3. 2 1
      kernel/rcu/rcutorture.c
  4. 11 2
      kernel/torture.c

+ 1 - 1
include/linux/torture.h

@@ -81,7 +81,7 @@ void stutter_wait(const char *title);
 int torture_stutter_init(int s);
 int torture_stutter_init(int s);
 
 
 /* Initialization and cleanup. */
 /* Initialization and cleanup. */
-void torture_init_begin(char *ttype, bool v, int *runnable);
+bool torture_init_begin(char *ttype, bool v, int *runnable);
 void torture_init_end(void);
 void torture_init_end(void);
 bool torture_cleanup(void);
 bool torture_cleanup(void);
 bool torture_must_stop(void);
 bool torture_must_stop(void);

+ 2 - 1
kernel/locking/locktorture.c

@@ -355,7 +355,8 @@ static int __init lock_torture_init(void)
 		&lock_busted_ops, &spin_lock_ops, &spin_lock_irq_ops,
 		&lock_busted_ops, &spin_lock_ops, &spin_lock_irq_ops,
 	};
 	};
 
 
-	torture_init_begin(torture_type, verbose, &locktorture_runnable);
+	if (!torture_init_begin(torture_type, verbose, &locktorture_runnable))
+		return -EBUSY;
 
 
 	/* Process args and tell the world that the torturer is on the job. */
 	/* Process args and tell the world that the torturer is on the job. */
 	for (i = 0; i < ARRAY_SIZE(torture_ops); i++) {
 	for (i = 0; i < ARRAY_SIZE(torture_ops); i++) {

+ 2 - 1
kernel/rcu/rcutorture.c

@@ -1536,7 +1536,8 @@ rcu_torture_init(void)
 		&rcu_ops, &rcu_bh_ops, &rcu_busted_ops, &srcu_ops, &sched_ops,
 		&rcu_ops, &rcu_bh_ops, &rcu_busted_ops, &srcu_ops, &sched_ops,
 	};
 	};
 
 
-	torture_init_begin(torture_type, verbose, &rcutorture_runnable);
+	if (!torture_init_begin(torture_type, verbose, &rcutorture_runnable))
+		return -EBUSY;
 
 
 	/* Process args and tell the world that the torturer is on the job. */
 	/* Process args and tell the world that the torturer is on the job. */
 	for (i = 0; i < ARRAY_SIZE(torture_ops); i++) {
 	for (i = 0; i < ARRAY_SIZE(torture_ops); i++) {

+ 11 - 2
kernel/torture.c

@@ -599,14 +599,20 @@ static void torture_stutter_cleanup(void)
  * The runnable parameter points to a flag that controls whether or not
  * The runnable parameter points to a flag that controls whether or not
  * the test is currently runnable.  If there is no such flag, pass in NULL.
  * the test is currently runnable.  If there is no such flag, pass in NULL.
  */
  */
-void __init torture_init_begin(char *ttype, bool v, int *runnable)
+bool __init torture_init_begin(char *ttype, bool v, int *runnable)
 {
 {
 	mutex_lock(&fullstop_mutex);
 	mutex_lock(&fullstop_mutex);
+	if (torture_type != NULL) {
+		pr_alert("torture_init_begin: refusing %s init: %s running",
+			 ttype, torture_type);
+		mutex_unlock(&fullstop_mutex);
+		return false;
+	}
 	torture_type = ttype;
 	torture_type = ttype;
 	verbose = v;
 	verbose = v;
 	torture_runnable = runnable;
 	torture_runnable = runnable;
 	fullstop = FULLSTOP_DONTSTOP;
 	fullstop = FULLSTOP_DONTSTOP;
-
+	return true;
 }
 }
 EXPORT_SYMBOL_GPL(torture_init_begin);
 EXPORT_SYMBOL_GPL(torture_init_begin);
 
 
@@ -645,6 +651,9 @@ bool torture_cleanup(void)
 	torture_shuffle_cleanup();
 	torture_shuffle_cleanup();
 	torture_stutter_cleanup();
 	torture_stutter_cleanup();
 	torture_onoff_cleanup();
 	torture_onoff_cleanup();
+	mutex_lock(&fullstop_mutex);
+	torture_type = NULL;
+	mutex_unlock(&fullstop_mutex);
 	return false;
 	return false;
 }
 }
 EXPORT_SYMBOL_GPL(torture_cleanup);
 EXPORT_SYMBOL_GPL(torture_cleanup);