rcutorture: Abstract torture_shutdown()
Because auto-shutdown of torture testing is not specific to RCU, this commit moves the auto-shutdown function 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:
parent
57a2fe90fc
commit
e991dbc077
@ -72,8 +72,10 @@ unsigned long torture_random(struct torture_random_state *trsp);
|
|||||||
void torture_shuffle_task_register(struct task_struct *tp);
|
void torture_shuffle_task_register(struct task_struct *tp);
|
||||||
int torture_shuffle_init(long shuffint);
|
int torture_shuffle_init(long shuffint);
|
||||||
|
|
||||||
/* Shutdown task absorption, for when the tasks cannot safely be killed. */
|
/* Test auto-shutdown handling. */
|
||||||
void torture_shutdown_absorb(const char *title);
|
void torture_shutdown_absorb(const char *title);
|
||||||
|
int torture_shutdown_init(int ssecs, void (*cleanup)(void));
|
||||||
|
void torture_shutdown_cleanup(void);
|
||||||
|
|
||||||
/* Task stuttering, which forces load/no-load transitions. */
|
/* Task stuttering, which forces load/no-load transitions. */
|
||||||
void stutter_wait(const char *title);
|
void stutter_wait(const char *title);
|
||||||
|
@ -105,7 +105,6 @@ static struct task_struct **reader_tasks;
|
|||||||
static struct task_struct *stats_task;
|
static struct task_struct *stats_task;
|
||||||
static struct task_struct *fqs_task;
|
static struct task_struct *fqs_task;
|
||||||
static struct task_struct *boost_tasks[NR_CPUS];
|
static struct task_struct *boost_tasks[NR_CPUS];
|
||||||
static struct task_struct *shutdown_task;
|
|
||||||
static struct task_struct *stall_task;
|
static struct task_struct *stall_task;
|
||||||
static struct task_struct **barrier_cbs_tasks;
|
static struct task_struct **barrier_cbs_tasks;
|
||||||
static struct task_struct *barrier_task;
|
static struct task_struct *barrier_task;
|
||||||
@ -173,7 +172,6 @@ static u64 notrace rcu_trace_clock_local(void)
|
|||||||
}
|
}
|
||||||
#endif /* #else #ifdef CONFIG_RCU_TRACE */
|
#endif /* #else #ifdef CONFIG_RCU_TRACE */
|
||||||
|
|
||||||
static unsigned long shutdown_time; /* jiffies to system shutdown. */
|
|
||||||
static unsigned long boost_starttime; /* jiffies of next boost test start. */
|
static unsigned long boost_starttime; /* jiffies of next boost test start. */
|
||||||
DEFINE_MUTEX(boost_mutex); /* protect setting boost_starttime */
|
DEFINE_MUTEX(boost_mutex); /* protect setting boost_starttime */
|
||||||
/* and boost task create/destroy. */
|
/* and boost task create/destroy. */
|
||||||
@ -183,9 +181,6 @@ static atomic_t barrier_cbs_invoked; /* Barrier callbacks invoked. */
|
|||||||
static wait_queue_head_t *barrier_cbs_wq; /* Coordinate barrier testing. */
|
static wait_queue_head_t *barrier_cbs_wq; /* Coordinate barrier testing. */
|
||||||
static DECLARE_WAIT_QUEUE_HEAD(barrier_wq);
|
static DECLARE_WAIT_QUEUE_HEAD(barrier_wq);
|
||||||
|
|
||||||
/* Forward reference. */
|
|
||||||
static void rcu_torture_cleanup(void);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate an element from the rcu_tortures pool.
|
* Allocate an element from the rcu_tortures pool.
|
||||||
*/
|
*/
|
||||||
@ -1086,42 +1081,6 @@ static int rcutorture_booster_init(int cpu)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Cause the rcutorture test to shutdown the system after the test has
|
|
||||||
* run for the time specified by the shutdown_secs module parameter.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
rcu_torture_shutdown(void *arg)
|
|
||||||
{
|
|
||||||
long delta;
|
|
||||||
unsigned long jiffies_snap;
|
|
||||||
|
|
||||||
VERBOSE_TOROUT_STRING("rcu_torture_shutdown task started");
|
|
||||||
jiffies_snap = ACCESS_ONCE(jiffies);
|
|
||||||
while (ULONG_CMP_LT(jiffies_snap, shutdown_time) &&
|
|
||||||
!kthread_should_stop()) {
|
|
||||||
delta = shutdown_time - jiffies_snap;
|
|
||||||
if (verbose)
|
|
||||||
pr_alert("%s" TORTURE_FLAG
|
|
||||||
"rcu_torture_shutdown task: %lu jiffies remaining\n",
|
|
||||||
torture_type, delta);
|
|
||||||
schedule_timeout_interruptible(delta);
|
|
||||||
jiffies_snap = ACCESS_ONCE(jiffies);
|
|
||||||
}
|
|
||||||
if (kthread_should_stop()) {
|
|
||||||
VERBOSE_TOROUT_STRING("rcu_torture_shutdown task stopping");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* OK, shut down the system. */
|
|
||||||
|
|
||||||
VERBOSE_TOROUT_STRING("rcu_torture_shutdown task shutting down system");
|
|
||||||
shutdown_task = NULL; /* Avoid self-kill deadlock. */
|
|
||||||
rcu_torture_cleanup(); /* Get the success/failure message. */
|
|
||||||
kernel_power_off(); /* Shut down the system. */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CPU-stall kthread. It waits as specified by stall_cpu_holdoff, then
|
* CPU-stall kthread. It waits as specified by stall_cpu_holdoff, then
|
||||||
* induces a CPU stall for the time specified by stall_cpu.
|
* induces a CPU stall for the time specified by stall_cpu.
|
||||||
@ -1421,11 +1380,7 @@ rcu_torture_cleanup(void)
|
|||||||
for_each_possible_cpu(i)
|
for_each_possible_cpu(i)
|
||||||
rcutorture_booster_cleanup(i);
|
rcutorture_booster_cleanup(i);
|
||||||
}
|
}
|
||||||
if (shutdown_task != NULL) {
|
torture_shutdown_cleanup();
|
||||||
VERBOSE_TOROUT_STRING("Stopping rcu_torture_shutdown task");
|
|
||||||
kthread_stop(shutdown_task);
|
|
||||||
}
|
|
||||||
shutdown_task = NULL;
|
|
||||||
|
|
||||||
/* Wait for all RCU callbacks to fire. */
|
/* Wait for all RCU callbacks to fire. */
|
||||||
|
|
||||||
@ -1681,18 +1636,10 @@ rcu_torture_init(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (shutdown_secs > 0) {
|
i = torture_shutdown_init(shutdown_secs, rcu_torture_cleanup);
|
||||||
shutdown_time = jiffies + shutdown_secs * HZ;
|
if (i != 0) {
|
||||||
shutdown_task = kthread_create(rcu_torture_shutdown, NULL,
|
firsterr = i;
|
||||||
"rcu_torture_shutdown");
|
goto unwind;
|
||||||
if (IS_ERR(shutdown_task)) {
|
|
||||||
firsterr = PTR_ERR(shutdown_task);
|
|
||||||
VERBOSE_TOROUT_ERRSTRING("Failed to create shutdown");
|
|
||||||
shutdown_task = NULL;
|
|
||||||
goto unwind;
|
|
||||||
}
|
|
||||||
torture_shuffle_task_register(shutdown_task);
|
|
||||||
wake_up_process(shutdown_task);
|
|
||||||
}
|
}
|
||||||
i = torture_onoff_init(onoff_holdoff * HZ, onoff_interval * HZ);
|
i = torture_onoff_init(onoff_holdoff * HZ, onoff_interval * HZ);
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
|
@ -418,6 +418,15 @@ static void torture_shuffle_cleanup(void)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(torture_shuffle_cleanup);
|
EXPORT_SYMBOL_GPL(torture_shuffle_cleanup);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Variables for auto-shutdown. This allows "lights out" torture runs
|
||||||
|
* to be fully scripted.
|
||||||
|
*/
|
||||||
|
static int shutdown_secs; /* desired test duration in seconds. */
|
||||||
|
static struct task_struct *shutdown_task;
|
||||||
|
static unsigned long shutdown_time; /* jiffies to system shutdown. */
|
||||||
|
static void (*torture_shutdown_hook)(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Absorb kthreads into a kernel function that won't return, so that
|
* Absorb kthreads into a kernel function that won't return, so that
|
||||||
* they won't ever access module text or data again.
|
* they won't ever access module text or data again.
|
||||||
@ -432,6 +441,81 @@ void torture_shutdown_absorb(const char *title)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(torture_shutdown_absorb);
|
EXPORT_SYMBOL_GPL(torture_shutdown_absorb);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cause the torture test to shutdown the system after the test has
|
||||||
|
* run for the time specified by the shutdown_secs parameter.
|
||||||
|
*/
|
||||||
|
static int torture_shutdown(void *arg)
|
||||||
|
{
|
||||||
|
long delta;
|
||||||
|
unsigned long jiffies_snap;
|
||||||
|
|
||||||
|
VERBOSE_TOROUT_STRING("torture_shutdown task started");
|
||||||
|
jiffies_snap = jiffies;
|
||||||
|
while (ULONG_CMP_LT(jiffies_snap, shutdown_time) &&
|
||||||
|
!torture_must_stop()) {
|
||||||
|
delta = shutdown_time - jiffies_snap;
|
||||||
|
if (verbose)
|
||||||
|
pr_alert("%s" TORTURE_FLAG
|
||||||
|
"torture_shutdown task: %lu jiffies remaining\n",
|
||||||
|
torture_type, delta);
|
||||||
|
schedule_timeout_interruptible(delta);
|
||||||
|
jiffies_snap = jiffies;
|
||||||
|
}
|
||||||
|
if (torture_must_stop()) {
|
||||||
|
VERBOSE_TOROUT_STRING("torture_shutdown task stopping");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OK, shut down the system. */
|
||||||
|
|
||||||
|
VERBOSE_TOROUT_STRING("torture_shutdown task shutting down system");
|
||||||
|
shutdown_task = NULL; /* Avoid self-kill deadlock. */
|
||||||
|
torture_shutdown_hook();/* Shut down the enclosing torture test. */
|
||||||
|
kernel_power_off(); /* Shut down the system. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start up the shutdown task.
|
||||||
|
*/
|
||||||
|
int torture_shutdown_init(int ssecs, void (*cleanup)(void))
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
shutdown_secs = ssecs;
|
||||||
|
torture_shutdown_hook = cleanup;
|
||||||
|
if (shutdown_secs > 0) {
|
||||||
|
shutdown_time = jiffies + shutdown_secs * HZ;
|
||||||
|
shutdown_task = kthread_create(torture_shutdown, NULL,
|
||||||
|
"torture_shutdown");
|
||||||
|
if (IS_ERR(shutdown_task)) {
|
||||||
|
ret = PTR_ERR(shutdown_task);
|
||||||
|
VERBOSE_TOROUT_ERRSTRING("Failed to create shutdown");
|
||||||
|
shutdown_task = NULL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
torture_shuffle_task_register(shutdown_task);
|
||||||
|
wake_up_process(shutdown_task);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(torture_shutdown_init);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shut down the shutdown task. Say what??? Heh! This can happen if
|
||||||
|
* the torture module gets an rmmod before the shutdown time arrives. ;-)
|
||||||
|
*/
|
||||||
|
void torture_shutdown_cleanup(void)
|
||||||
|
{
|
||||||
|
if (shutdown_task != NULL) {
|
||||||
|
VERBOSE_TOROUT_STRING("Stopping torture_shutdown task");
|
||||||
|
kthread_stop(shutdown_task);
|
||||||
|
}
|
||||||
|
shutdown_task = NULL;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(torture_shutdown_cleanup);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Detect and respond to a system shutdown.
|
* Detect and respond to a system shutdown.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user