summaryrefslogtreecommitdiff
path: root/kernel/torture.c
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2014-01-30 15:37:19 -0800
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2014-02-23 09:01:11 -0800
commit4622b487ecf0094401ac10e504606e5cbdea5a6e (patch)
treed3548e9eca81a35029cf889ed4713743f08be4c8 /kernel/torture.c
parent3c626237eb359cf125051f2fe8b419ddae0f5291 (diff)
rcutorture: Abstract torture_shutdown_notify()
Because handling the race between rmmod and system shutdown is not specific to RCU, this commit abstracts torture_shutdown_notify(), placing this code into kernel/torture.c. This change also allows fullstop_mutex to be private to kernel/torture.c. Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Reviewed-by: Josh Triplett <josh@joshtriplett.org>
Diffstat (limited to 'kernel/torture.c')
-rw-r--r--kernel/torture.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/kernel/torture.c b/kernel/torture.c
index 41ae5cc3c4c3..b02fa2785bbb 100644
--- a/kernel/torture.c
+++ b/kernel/torture.c
@@ -54,8 +54,7 @@ static bool verbose;
int fullstop = FULLSTOP_RMMOD;
EXPORT_SYMBOL_GPL(fullstop);
-DEFINE_MUTEX(fullstop_mutex);
-EXPORT_SYMBOL_GPL(fullstop_mutex);
+static DEFINE_MUTEX(fullstop_mutex);
#ifdef CONFIG_HOTPLUG_CPU
@@ -422,15 +421,33 @@ EXPORT_SYMBOL_GPL(torture_shuffle_cleanup);
void torture_shutdown_absorb(const char *title)
{
while (ACCESS_ONCE(fullstop) == FULLSTOP_SHUTDOWN) {
- pr_notice(
- "torture thread %s parking due to system shutdown\n",
- title);
+ pr_notice("torture thread %s parking due to system shutdown\n",
+ title);
schedule_timeout_uninterruptible(MAX_SCHEDULE_TIMEOUT);
}
}
EXPORT_SYMBOL_GPL(torture_shutdown_absorb);
/*
+ * Detect and respond to a system shutdown.
+ */
+static int torture_shutdown_notify(struct notifier_block *unused1,
+ unsigned long unused2, void *unused3)
+{
+ mutex_lock(&fullstop_mutex);
+ if (fullstop == FULLSTOP_DONTSTOP)
+ fullstop = FULLSTOP_SHUTDOWN;
+ else
+ pr_warn("Concurrent rmmod and shutdown illegal!\n");
+ mutex_unlock(&fullstop_mutex);
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block torture_shutdown_nb = {
+ .notifier_call = torture_shutdown_notify,
+};
+
+/*
* Initialize torture module. Please note that this is -not- invoked via
* the usual module_init() mechanism, but rather by an explicit call from
* the client torture module. This call must be paired with a later
@@ -451,6 +468,7 @@ EXPORT_SYMBOL_GPL(torture_init_begin);
void __init torture_init_end(void)
{
mutex_unlock(&fullstop_mutex);
+ register_reboot_notifier(&torture_shutdown_nb);
}
EXPORT_SYMBOL_GPL(torture_init_end);
@@ -474,6 +492,7 @@ bool torture_cleanup(void)
}
fullstop = FULLSTOP_RMMOD;
mutex_unlock(&fullstop_mutex);
+ unregister_reboot_notifier(&torture_shutdown_nb);
torture_shuffle_cleanup();
torture_onoff_cleanup();
return false;