aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--init/Kconfig27
-rw-r--r--kernel/rcutree.c2
-rw-r--r--kernel/rcutree.h10
3 files changed, 31 insertions, 8 deletions
diff --git a/init/Kconfig b/init/Kconfig
index 85c6870ed476..6d18ef8071b5 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -458,6 +458,33 @@ config RCU_FANOUT
458 Select a specific number if testing RCU itself. 458 Select a specific number if testing RCU itself.
459 Take the default if unsure. 459 Take the default if unsure.
460 460
461config RCU_FANOUT_LEAF
462 int "Tree-based hierarchical RCU leaf-level fanout value"
463 range 2 RCU_FANOUT if 64BIT
464 range 2 RCU_FANOUT if !64BIT
465 depends on TREE_RCU || TREE_PREEMPT_RCU
466 default 16
467 help
468 This option controls the leaf-level fanout of hierarchical
469 implementations of RCU, and allows trading off cache misses
470 against lock contention. Systems that synchronize their
471 scheduling-clock interrupts for energy-efficiency reasons will
472 want the default because the smaller leaf-level fanout keeps
473 lock contention levels acceptably low. Very large systems
474 (hundreds or thousands of CPUs) will instead want to set this
475 value to the maximum value possible in order to reduce the
476 number of cache misses incurred during RCU's grace-period
477 initialization. These systems tend to run CPU-bound, and thus
478 are not helped by synchronized interrupts, and thus tend to
479 skew them, which reduces lock contention enough that large
480 leaf-level fanouts work well.
481
482 Select a specific number if testing RCU itself.
483
484 Select the maximum permissible value for large systems.
485
486 Take the default if unsure.
487
461config RCU_FANOUT_EXACT 488config RCU_FANOUT_EXACT
462 bool "Disable tree-based hierarchical RCU auto-balancing" 489 bool "Disable tree-based hierarchical RCU auto-balancing"
463 depends on TREE_RCU || TREE_PREEMPT_RCU 490 depends on TREE_RCU || TREE_PREEMPT_RCU
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index 1050d6d3922c..780acf8e15e9 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -2418,7 +2418,7 @@ static void __init rcu_init_levelspread(struct rcu_state *rsp)
2418 2418
2419 for (i = NUM_RCU_LVLS - 1; i > 0; i--) 2419 for (i = NUM_RCU_LVLS - 1; i > 0; i--)
2420 rsp->levelspread[i] = CONFIG_RCU_FANOUT; 2420 rsp->levelspread[i] = CONFIG_RCU_FANOUT;
2421 rsp->levelspread[0] = RCU_FANOUT_LEAF; 2421 rsp->levelspread[0] = CONFIG_RCU_FANOUT_LEAF;
2422} 2422}
2423#else /* #ifdef CONFIG_RCU_FANOUT_EXACT */ 2423#else /* #ifdef CONFIG_RCU_FANOUT_EXACT */
2424static void __init rcu_init_levelspread(struct rcu_state *rsp) 2424static void __init rcu_init_levelspread(struct rcu_state *rsp)
diff --git a/kernel/rcutree.h b/kernel/rcutree.h
index cdd1be0a4072..a905c200405c 100644
--- a/kernel/rcutree.h
+++ b/kernel/rcutree.h
@@ -29,18 +29,14 @@
29#include <linux/seqlock.h> 29#include <linux/seqlock.h>
30 30
31/* 31/*
32 * Define shape of hierarchy based on NR_CPUS and CONFIG_RCU_FANOUT. 32 * Define shape of hierarchy based on NR_CPUS, CONFIG_RCU_FANOUT, and
33 * CONFIG_RCU_FANOUT_LEAF.
33 * In theory, it should be possible to add more levels straightforwardly. 34 * In theory, it should be possible to add more levels straightforwardly.
34 * In practice, this did work well going from three levels to four. 35 * In practice, this did work well going from three levels to four.
35 * Of course, your mileage may vary. 36 * Of course, your mileage may vary.
36 */ 37 */
37#define MAX_RCU_LVLS 4 38#define MAX_RCU_LVLS 4
38#if CONFIG_RCU_FANOUT > 16 39#define RCU_FANOUT_1 (CONFIG_RCU_FANOUT_LEAF)
39#define RCU_FANOUT_LEAF 16
40#else /* #if CONFIG_RCU_FANOUT > 16 */
41#define RCU_FANOUT_LEAF (CONFIG_RCU_FANOUT)
42#endif /* #else #if CONFIG_RCU_FANOUT > 16 */
43#define RCU_FANOUT_1 (RCU_FANOUT_LEAF)
44#define RCU_FANOUT_2 (RCU_FANOUT_1 * CONFIG_RCU_FANOUT) 40#define RCU_FANOUT_2 (RCU_FANOUT_1 * CONFIG_RCU_FANOUT)
45#define RCU_FANOUT_3 (RCU_FANOUT_2 * CONFIG_RCU_FANOUT) 41#define RCU_FANOUT_3 (RCU_FANOUT_2 * CONFIG_RCU_FANOUT)
46#define RCU_FANOUT_4 (RCU_FANOUT_3 * CONFIG_RCU_FANOUT) 42#define RCU_FANOUT_4 (RCU_FANOUT_3 * CONFIG_RCU_FANOUT)