Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+40
+6
Documentation/kernel-parameters.txt
··· 2968 2968 Set maximum number of finished RCU callbacks to 2969 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 2977 rcutree.rcu_fanout_leaf= [KNL] 2972 2978 Increase the number of CPUs assigned to each 2973 2979 leaf rcu_node structure. Useful for very large
+10
kernel/rcu/tree.c
··· 160 160 static int kthread_prio = CONFIG_RCU_KTHREAD_PRIO; 161 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 170 * Track the rcutorture test sequence number and the update version 165 171 * number within a given test. The rcutorture_testseq is incremented ··· 1775 1769 raw_spin_unlock_irq(&rnp->lock); 1776 1770 cond_resched_rcu_qs(); 1777 1771 ACCESS_ONCE(rsp->gp_activity) = jiffies; 1772 + if (IS_ENABLED(CONFIG_RCU_TORTURE_TEST_SLOW_INIT) && 1773 + gp_init_delay > 0 && 1774 + !(rsp->gpnum % (rcu_num_nodes * 10))) 1775 + schedule_timeout_uninterruptible(gp_init_delay); 1778 1776 } 1779 1777 1780 1778 mutex_unlock(&rsp->onoff_mutex);
+24
lib/Kconfig.debug
··· 1257 1257 Say N here if you want the RCU torture tests to start only 1258 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 1284 config RCU_CPU_STALL_TIMEOUT 1261 1285 int "RCU CPU stall timeout in seconds" 1262 1286 depends on RCU_STALL_COMMON