rcu: Provide diagnostic option to slow down grace-period initialization
Grace-period initialization normally proceeds quite quickly, so that it is very difficult to reproduce races against grace-period initialization. This commit therefore allows grace-period initialization to be artificially slowed down, increasing race-reproduction probability. A pair of new Kconfig parameters are provided, CONFIG_RCU_TORTURE_TEST_SLOW_INIT to enable the slowdowns, and CONFIG_RCU_TORTURE_TEST_SLOW_INIT_DELAY to specify the number of jiffies of slowdown to apply. A boot-time parameter named rcutree.gp_init_delay allows boot-time delay to be specified. By default, no delay will be applied even if CONFIG_RCU_TORTURE_TEST_SLOW_INIT is set. Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
This commit is contained in:
@@ -2968,6 +2968,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||||||
Set maximum number of finished RCU callbacks to
|
Set maximum number of finished RCU callbacks to
|
||||||
process in one batch.
|
process in one batch.
|
||||||
|
|
||||||
|
rcutree.gp_init_delay= [KNL]
|
||||||
|
Set the number of jiffies to delay each step of
|
||||||
|
RCU grace-period initialization. This only has
|
||||||
|
effect when CONFIG_RCU_TORTURE_TEST_SLOW_INIT is
|
||||||
|
set.
|
||||||
|
|
||||||
rcutree.rcu_fanout_leaf= [KNL]
|
rcutree.rcu_fanout_leaf= [KNL]
|
||||||
Increase the number of CPUs assigned to each
|
Increase the number of CPUs assigned to each
|
||||||
leaf rcu_node structure. Useful for very large
|
leaf rcu_node structure. Useful for very large
|
||||||
|
|||||||
@@ -160,6 +160,12 @@ static void invoke_rcu_callbacks(struct rcu_state *rsp, struct rcu_data *rdp);
|
|||||||
static int kthread_prio = CONFIG_RCU_KTHREAD_PRIO;
|
static int kthread_prio = CONFIG_RCU_KTHREAD_PRIO;
|
||||||
module_param(kthread_prio, int, 0644);
|
module_param(kthread_prio, int, 0644);
|
||||||
|
|
||||||
|
/* Delay in jiffies for grace-period initialization delays. */
|
||||||
|
static int gp_init_delay = IS_ENABLED(CONFIG_RCU_TORTURE_TEST_SLOW_INIT)
|
||||||
|
? CONFIG_RCU_TORTURE_TEST_SLOW_INIT_DELAY
|
||||||
|
: 0;
|
||||||
|
module_param(gp_init_delay, int, 0644);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Track the rcutorture test sequence number and the update version
|
* Track the rcutorture test sequence number and the update version
|
||||||
* number within a given test. The rcutorture_testseq is incremented
|
* number within a given test. The rcutorture_testseq is incremented
|
||||||
@@ -1769,6 +1775,10 @@ static int rcu_gp_init(struct rcu_state *rsp)
|
|||||||
raw_spin_unlock_irq(&rnp->lock);
|
raw_spin_unlock_irq(&rnp->lock);
|
||||||
cond_resched_rcu_qs();
|
cond_resched_rcu_qs();
|
||||||
ACCESS_ONCE(rsp->gp_activity) = jiffies;
|
ACCESS_ONCE(rsp->gp_activity) = jiffies;
|
||||||
|
if (IS_ENABLED(CONFIG_RCU_TORTURE_TEST_SLOW_INIT) &&
|
||||||
|
gp_init_delay > 0 &&
|
||||||
|
!(rsp->gpnum % (rcu_num_nodes * 10)))
|
||||||
|
schedule_timeout_uninterruptible(gp_init_delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&rsp->onoff_mutex);
|
mutex_unlock(&rsp->onoff_mutex);
|
||||||
|
|||||||
@@ -1257,6 +1257,30 @@ config RCU_TORTURE_TEST_RUNNABLE
|
|||||||
Say N here if you want the RCU torture tests to start only
|
Say N here if you want the RCU torture tests to start only
|
||||||
after being manually enabled via /proc.
|
after being manually enabled via /proc.
|
||||||
|
|
||||||
|
config RCU_TORTURE_TEST_SLOW_INIT
|
||||||
|
bool "Slow down RCU grace-period initialization to expose races"
|
||||||
|
depends on RCU_TORTURE_TEST
|
||||||
|
help
|
||||||
|
This option makes grace-period initialization block for a
|
||||||
|
few jiffies between initializing each pair of consecutive
|
||||||
|
rcu_node structures. This helps to expose races involving
|
||||||
|
grace-period initialization, in other words, it makes your
|
||||||
|
kernel less stable. It can also greatly increase grace-period
|
||||||
|
latency, especially on systems with large numbers of CPUs.
|
||||||
|
This is useful when torture-testing RCU, but in almost no
|
||||||
|
other circumstance.
|
||||||
|
|
||||||
|
Say Y here if you want your system to crash and hang more often.
|
||||||
|
Say N if you want a sane system.
|
||||||
|
|
||||||
|
config RCU_TORTURE_TEST_SLOW_INIT_DELAY
|
||||||
|
int "How much to slow down RCU grace-period initialization"
|
||||||
|
range 0 5
|
||||||
|
default 0
|
||||||
|
help
|
||||||
|
This option specifies the number of jiffies to wait between
|
||||||
|
each rcu_node structure initialization.
|
||||||
|
|
||||||
config RCU_CPU_STALL_TIMEOUT
|
config RCU_CPU_STALL_TIMEOUT
|
||||||
int "RCU CPU stall timeout in seconds"
|
int "RCU CPU stall timeout in seconds"
|
||||||
depends on RCU_STALL_COMMON
|
depends on RCU_STALL_COMMON
|
||||||
|
|||||||
Reference in New Issue
Block a user