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>
This commit is contained in:
@@ -46,8 +46,6 @@
|
|||||||
#define FULLSTOP_SHUTDOWN 1 /* System shutdown with rcutorture running. */
|
#define FULLSTOP_SHUTDOWN 1 /* System shutdown with rcutorture running. */
|
||||||
#define FULLSTOP_RMMOD 2 /* Normal rmmod of rcutorture. */
|
#define FULLSTOP_RMMOD 2 /* Normal rmmod of rcutorture. */
|
||||||
extern int fullstop;
|
extern int fullstop;
|
||||||
/* Protect fullstop transitions and spawning of kthreads. */
|
|
||||||
extern struct mutex fullstop_mutex;
|
|
||||||
|
|
||||||
#define TORTURE_FLAG "-torture:"
|
#define TORTURE_FLAG "-torture:"
|
||||||
#define TOROUT_STRING(s) \
|
#define TOROUT_STRING(s) \
|
||||||
|
|||||||
@@ -189,23 +189,6 @@ static DECLARE_WAIT_QUEUE_HEAD(barrier_wq);
|
|||||||
/* Forward reference. */
|
/* Forward reference. */
|
||||||
static void rcu_torture_cleanup(void);
|
static void rcu_torture_cleanup(void);
|
||||||
|
|
||||||
/*
|
|
||||||
* Detect and respond to a system shutdown.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
rcutorture_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(/* but going down anyway, so... */
|
|
||||||
"Concurrent 'rmmod rcutorture' and shutdown illegal!\n");
|
|
||||||
mutex_unlock(&fullstop_mutex);
|
|
||||||
return NOTIFY_DONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate an element from the rcu_tortures pool.
|
* Allocate an element from the rcu_tortures pool.
|
||||||
*/
|
*/
|
||||||
@@ -1098,10 +1081,6 @@ rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, const char *tag)
|
|||||||
onoff_interval, onoff_holdoff);
|
onoff_interval, onoff_holdoff);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct notifier_block rcutorture_shutdown_nb = {
|
|
||||||
.notifier_call = rcutorture_shutdown_notify,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void rcutorture_booster_cleanup(int cpu)
|
static void rcutorture_booster_cleanup(int cpu)
|
||||||
{
|
{
|
||||||
struct task_struct *t;
|
struct task_struct *t;
|
||||||
@@ -1428,7 +1407,6 @@ rcu_torture_cleanup(void)
|
|||||||
cur_ops->cb_barrier();
|
cur_ops->cb_barrier();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
unregister_reboot_notifier(&rcutorture_shutdown_nb);
|
|
||||||
|
|
||||||
rcu_torture_barrier_cleanup();
|
rcu_torture_barrier_cleanup();
|
||||||
rcu_torture_stall_cleanup();
|
rcu_torture_stall_cleanup();
|
||||||
@@ -1774,7 +1752,6 @@ rcu_torture_init(void)
|
|||||||
firsterr = i;
|
firsterr = i;
|
||||||
goto unwind;
|
goto unwind;
|
||||||
}
|
}
|
||||||
register_reboot_notifier(&rcutorture_shutdown_nb);
|
|
||||||
i = rcu_torture_stall_init();
|
i = rcu_torture_stall_init();
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
firsterr = i;
|
firsterr = i;
|
||||||
|
|||||||
@@ -54,8 +54,7 @@ static bool verbose;
|
|||||||
|
|
||||||
int fullstop = FULLSTOP_RMMOD;
|
int fullstop = FULLSTOP_RMMOD;
|
||||||
EXPORT_SYMBOL_GPL(fullstop);
|
EXPORT_SYMBOL_GPL(fullstop);
|
||||||
DEFINE_MUTEX(fullstop_mutex);
|
static DEFINE_MUTEX(fullstop_mutex);
|
||||||
EXPORT_SYMBOL_GPL(fullstop_mutex);
|
|
||||||
|
|
||||||
#ifdef CONFIG_HOTPLUG_CPU
|
#ifdef CONFIG_HOTPLUG_CPU
|
||||||
|
|
||||||
@@ -422,14 +421,32 @@ EXPORT_SYMBOL_GPL(torture_shuffle_cleanup);
|
|||||||
void torture_shutdown_absorb(const char *title)
|
void torture_shutdown_absorb(const char *title)
|
||||||
{
|
{
|
||||||
while (ACCESS_ONCE(fullstop) == FULLSTOP_SHUTDOWN) {
|
while (ACCESS_ONCE(fullstop) == FULLSTOP_SHUTDOWN) {
|
||||||
pr_notice(
|
pr_notice("torture thread %s parking due to system shutdown\n",
|
||||||
"torture thread %s parking due to system shutdown\n",
|
title);
|
||||||
title);
|
|
||||||
schedule_timeout_uninterruptible(MAX_SCHEDULE_TIMEOUT);
|
schedule_timeout_uninterruptible(MAX_SCHEDULE_TIMEOUT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(torture_shutdown_absorb);
|
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
|
* Initialize torture module. Please note that this is -not- invoked via
|
||||||
* the usual module_init() mechanism, but rather by an explicit call from
|
* the usual module_init() mechanism, but rather by an explicit call from
|
||||||
@@ -451,6 +468,7 @@ EXPORT_SYMBOL_GPL(torture_init_begin);
|
|||||||
void __init torture_init_end(void)
|
void __init torture_init_end(void)
|
||||||
{
|
{
|
||||||
mutex_unlock(&fullstop_mutex);
|
mutex_unlock(&fullstop_mutex);
|
||||||
|
register_reboot_notifier(&torture_shutdown_nb);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(torture_init_end);
|
EXPORT_SYMBOL_GPL(torture_init_end);
|
||||||
|
|
||||||
@@ -474,6 +492,7 @@ bool torture_cleanup(void)
|
|||||||
}
|
}
|
||||||
fullstop = FULLSTOP_RMMOD;
|
fullstop = FULLSTOP_RMMOD;
|
||||||
mutex_unlock(&fullstop_mutex);
|
mutex_unlock(&fullstop_mutex);
|
||||||
|
unregister_reboot_notifier(&torture_shutdown_nb);
|
||||||
torture_shuffle_cleanup();
|
torture_shuffle_cleanup();
|
||||||
torture_onoff_cleanup();
|
torture_onoff_cleanup();
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user