diff options
| author | Alexander Gordeev <agordeev@redhat.com> | 2015-06-03 02:18:23 -0400 |
|---|---|---|
| committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2015-07-15 17:45:12 -0400 |
| commit | 75cf15a4c0dd57f5d230bd30c2d41bd8e06ae5a9 (patch) | |
| tree | 24f503cd5513b51bb1c629ce2d9229c40fc040f2 /kernel/rcu/tree.c | |
| parent | 319362c90f7af92d03714759bea5d2ba7c88e388 (diff) | |
rcu: Panic if RCU tree can not accommodate all CPUs
Currently a condition when RCU tree is unable to accommodate
the configured number of CPUs is not permitted and causes
a fall back to compile-time values. However, the code has no
means to exceed the RCU tree capacity neither at compile-time
nor in run-time. Therefore, if the condition is met in run-
time then it indicates a serios problem elsewhere and should
be handled with a panic.
Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'kernel/rcu/tree.c')
| -rw-r--r-- | kernel/rcu/tree.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 1c58cbd03922..fe8d92987dfa 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c | |||
| @@ -4107,6 +4107,19 @@ static void __init rcu_init_geometry(void) | |||
| 4107 | rcu_fanout_leaf, nr_cpu_ids); | 4107 | rcu_fanout_leaf, nr_cpu_ids); |
| 4108 | 4108 | ||
| 4109 | /* | 4109 | /* |
| 4110 | * The boot-time rcu_fanout_leaf parameter is only permitted | ||
| 4111 | * to increase the leaf-level fanout, not decrease it. Of course, | ||
| 4112 | * the leaf-level fanout cannot exceed the number of bits in | ||
| 4113 | * the rcu_node masks. Complain and fall back to the compile- | ||
| 4114 | * time values if these limits are exceeded. | ||
| 4115 | */ | ||
| 4116 | if (rcu_fanout_leaf < RCU_FANOUT_LEAF || | ||
| 4117 | rcu_fanout_leaf > sizeof(unsigned long) * 8) { | ||
| 4118 | WARN_ON(1); | ||
| 4119 | return; | ||
| 4120 | } | ||
| 4121 | |||
| 4122 | /* | ||
| 4110 | * Compute number of nodes that can be handled an rcu_node tree | 4123 | * Compute number of nodes that can be handled an rcu_node tree |
| 4111 | * with the given number of levels. Setting rcu_capacity[0] makes | 4124 | * with the given number of levels. Setting rcu_capacity[0] makes |
| 4112 | * some of the arithmetic easier. | 4125 | * some of the arithmetic easier. |
| @@ -4117,19 +4130,11 @@ static void __init rcu_init_geometry(void) | |||
| 4117 | rcu_capacity[i] = rcu_capacity[i - 1] * RCU_FANOUT; | 4130 | rcu_capacity[i] = rcu_capacity[i - 1] * RCU_FANOUT; |
| 4118 | 4131 | ||
| 4119 | /* | 4132 | /* |
| 4120 | * The boot-time rcu_fanout_leaf parameter is only permitted | 4133 | * The tree must be able to accommodate the configured number of CPUs. |
| 4121 | * to increase the leaf-level fanout, not decrease it. Of course, | 4134 | * If this limit is exceeded than we have a serious problem elsewhere. |
| 4122 | * the leaf-level fanout cannot exceed the number of bits in | ||
| 4123 | * the rcu_node masks. Finally, the tree must be able to accommodate | ||
| 4124 | * the configured number of CPUs. Complain and fall back to the | ||
| 4125 | * compile-time values if these limits are exceeded. | ||
| 4126 | */ | 4135 | */ |
| 4127 | if (rcu_fanout_leaf < RCU_FANOUT_LEAF || | 4136 | if (n > rcu_capacity[MAX_RCU_LVLS]) |
| 4128 | rcu_fanout_leaf > sizeof(unsigned long) * 8 || | 4137 | panic("rcu_init_geometry: rcu_capacity[] is too small"); |
| 4129 | n > rcu_capacity[MAX_RCU_LVLS]) { | ||
| 4130 | WARN_ON(1); | ||
| 4131 | return; | ||
| 4132 | } | ||
| 4133 | 4138 | ||
| 4134 | /* Calculate the number of rcu_nodes at each level of the tree. */ | 4139 | /* Calculate the number of rcu_nodes at each level of the tree. */ |
| 4135 | for (i = 1; i <= MAX_RCU_LVLS; i++) | 4140 | for (i = 1; i <= MAX_RCU_LVLS; i++) |
