Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4622b487 authored by Paul E. McKenney's avatar Paul E. McKenney
Browse files

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: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Reviewed-by: default avatarJosh Triplett <josh@joshtriplett.org>
parent 3c626237
Loading
Loading
Loading
Loading
+0 −2
Original line number Original line Diff line number Diff line
@@ -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) \
+0 −23
Original line number Original line Diff line number Diff line
@@ -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;
+24 −5
Original line number Original line Diff line number Diff line
@@ -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;