diff options
author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2015-01-22 21:24:08 -0500 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2015-03-11 16:22:38 -0400 |
commit | 37745d281069682d901f00c0121949a7d224195f (patch) | |
tree | 0c15fd487faa046a257336b4205572b066873ca7 | |
parent | 237a0f2193c6daf9b1edd7fd15d55e680f268952 (diff) |
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>
-rw-r--r-- | Documentation/kernel-parameters.txt | 6 | ||||
-rw-r--r-- | kernel/rcu/tree.c | 10 | ||||
-rw-r--r-- | lib/Kconfig.debug | 24 |
3 files changed, 40 insertions, 0 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index bfcb1a62a7b4..94de410ec341 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -2968,6 +2968,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
2968 | Set maximum number of finished RCU callbacks to | 2968 | Set maximum number of finished RCU callbacks to |
2969 | process in one batch. | 2969 | process in one batch. |
2970 | 2970 | ||
2971 | rcutree.gp_init_delay= [KNL] | ||
2972 | Set the number of jiffies to delay each step of | ||
2973 | RCU grace-period initialization. This only has | ||
2974 | effect when CONFIG_RCU_TORTURE_TEST_SLOW_INIT is | ||
2975 | set. | ||
2976 | |||
2971 | rcutree.rcu_fanout_leaf= [KNL] | 2977 | rcutree.rcu_fanout_leaf= [KNL] |
2972 | Increase the number of CPUs assigned to each | 2978 | Increase the number of CPUs assigned to each |
2973 | leaf rcu_node structure. Useful for very large | 2979 | leaf rcu_node structure. Useful for very large |
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 3b7e4133ca99..b42001fd55fb 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c | |||
@@ -160,6 +160,12 @@ static void invoke_rcu_callbacks(struct rcu_state *rsp, struct rcu_data *rdp); | |||
160 | static int kthread_prio = CONFIG_RCU_KTHREAD_PRIO; | 160 | static int kthread_prio = CONFIG_RCU_KTHREAD_PRIO; |
161 | module_param(kthread_prio, int, 0644); | 161 | module_param(kthread_prio, int, 0644); |
162 | 162 | ||
163 | /* Delay in jiffies for grace-period initialization delays. */ | ||
164 | static int gp_init_delay = IS_ENABLED(CONFIG_RCU_TORTURE_TEST_SLOW_INIT) | ||
165 | ? CONFIG_RCU_TORTURE_TEST_SLOW_INIT_DELAY | ||
166 | : 0; | ||
167 | module_param(gp_init_delay, int, 0644); | ||
168 | |||
163 | /* | 169 | /* |
164 | * Track the rcutorture test sequence number and the update version | 170 | * Track the rcutorture test sequence number and the update version |
165 | * number within a given test. The rcutorture_testseq is incremented | 171 | * number within a given test. The rcutorture_testseq is incremented |
@@ -1769,6 +1775,10 @@ static int rcu_gp_init(struct rcu_state *rsp) | |||
1769 | raw_spin_unlock_irq(&rnp->lock); | 1775 | raw_spin_unlock_irq(&rnp->lock); |
1770 | cond_resched_rcu_qs(); | 1776 | cond_resched_rcu_qs(); |
1771 | ACCESS_ONCE(rsp->gp_activity) = jiffies; | 1777 | ACCESS_ONCE(rsp->gp_activity) = jiffies; |
1778 | if (IS_ENABLED(CONFIG_RCU_TORTURE_TEST_SLOW_INIT) && | ||
1779 | gp_init_delay > 0 && | ||
1780 | !(rsp->gpnum % (rcu_num_nodes * 10))) | ||
1781 | schedule_timeout_uninterruptible(gp_init_delay); | ||
1772 | } | 1782 | } |
1773 | 1783 | ||
1774 | mutex_unlock(&rsp->onoff_mutex); | 1784 | mutex_unlock(&rsp->onoff_mutex); |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index c5cefb3c009c..feee8dab441e 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -1257,6 +1257,30 @@ config RCU_TORTURE_TEST_RUNNABLE | |||
1257 | Say N here if you want the RCU torture tests to start only | 1257 | Say N here if you want the RCU torture tests to start only |
1258 | after being manually enabled via /proc. | 1258 | after being manually enabled via /proc. |
1259 | 1259 | ||
1260 | config RCU_TORTURE_TEST_SLOW_INIT | ||
1261 | bool "Slow down RCU grace-period initialization to expose races" | ||
1262 | depends on RCU_TORTURE_TEST | ||
1263 | help | ||
1264 | This option makes grace-period initialization block for a | ||
1265 | few jiffies between initializing each pair of consecutive | ||
1266 | rcu_node structures. This helps to expose races involving | ||
1267 | grace-period initialization, in other words, it makes your | ||
1268 | kernel less stable. It can also greatly increase grace-period | ||
1269 | latency, especially on systems with large numbers of CPUs. | ||
1270 | This is useful when torture-testing RCU, but in almost no | ||
1271 | other circumstance. | ||
1272 | |||
1273 | Say Y here if you want your system to crash and hang more often. | ||
1274 | Say N if you want a sane system. | ||
1275 | |||
1276 | config RCU_TORTURE_TEST_SLOW_INIT_DELAY | ||
1277 | int "How much to slow down RCU grace-period initialization" | ||
1278 | range 0 5 | ||
1279 | default 0 | ||
1280 | help | ||
1281 | This option specifies the number of jiffies to wait between | ||
1282 | each rcu_node structure initialization. | ||
1283 | |||
1260 | config RCU_CPU_STALL_TIMEOUT | 1284 | config RCU_CPU_STALL_TIMEOUT |
1261 | int "RCU CPU stall timeout in seconds" | 1285 | int "RCU CPU stall timeout in seconds" |
1262 | depends on RCU_STALL_COMMON | 1286 | depends on RCU_STALL_COMMON |