diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 5 | ||||
-rw-r--r-- | kernel/rcu/tree.c | 27 |
2 files changed, 32 insertions, 0 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index f5582dcdf80d..a1cb88d9864e 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -2992,6 +2992,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
2992 | Set maximum number of finished RCU callbacks to | 2992 | Set maximum number of finished RCU callbacks to |
2993 | process in one batch. | 2993 | process in one batch. |
2994 | 2994 | ||
2995 | rcutree.dump_tree= [KNL] | ||
2996 | Dump the structure of the rcu_node combining tree | ||
2997 | out at early boot. This is used for diagnostic | ||
2998 | purposes, to verify correct tree setup. | ||
2999 | |||
2995 | rcutree.gp_cleanup_delay= [KNL] | 3000 | rcutree.gp_cleanup_delay= [KNL] |
2996 | Set the number of jiffies to delay each step of | 3001 | Set the number of jiffies to delay each step of |
2997 | RCU grace-period cleanup. This only has effect | 3002 | RCU grace-period cleanup. This only has effect |
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index b49c474e1fff..1bc14c670641 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c | |||
@@ -113,6 +113,9 @@ RCU_STATE_INITIALIZER(rcu_bh, 'b', call_rcu_bh); | |||
113 | static struct rcu_state *rcu_state_p; | 113 | static struct rcu_state *rcu_state_p; |
114 | LIST_HEAD(rcu_struct_flavors); | 114 | LIST_HEAD(rcu_struct_flavors); |
115 | 115 | ||
116 | /* Dump rcu_node combining tree at boot to verify correct setup. */ | ||
117 | static bool dump_tree; | ||
118 | module_param(dump_tree, bool, 0444); | ||
116 | /* Control rcu_node-tree auto-balancing at boot time. */ | 119 | /* Control rcu_node-tree auto-balancing at boot time. */ |
117 | static bool rcu_fanout_exact; | 120 | static bool rcu_fanout_exact; |
118 | module_param(rcu_fanout_exact, bool, 0444); | 121 | module_param(rcu_fanout_exact, bool, 0444); |
@@ -4144,6 +4147,28 @@ static void __init rcu_init_geometry(void) | |||
4144 | rcu_num_nodes -= n; | 4147 | rcu_num_nodes -= n; |
4145 | } | 4148 | } |
4146 | 4149 | ||
4150 | /* | ||
4151 | * Dump out the structure of the rcu_node combining tree associated | ||
4152 | * with the rcu_state structure referenced by rsp. | ||
4153 | */ | ||
4154 | static void __init rcu_dump_rcu_node_tree(struct rcu_state *rsp) | ||
4155 | { | ||
4156 | int level = 0; | ||
4157 | struct rcu_node *rnp; | ||
4158 | |||
4159 | pr_info("rcu_node tree layout dump\n"); | ||
4160 | pr_info(" "); | ||
4161 | rcu_for_each_node_breadth_first(rsp, rnp) { | ||
4162 | if (rnp->level != level) { | ||
4163 | pr_cont("\n"); | ||
4164 | pr_info(" "); | ||
4165 | level = rnp->level; | ||
4166 | } | ||
4167 | pr_cont("%d:%d ^%d ", rnp->grplo, rnp->grphi, rnp->grpnum); | ||
4168 | } | ||
4169 | pr_cont("\n"); | ||
4170 | } | ||
4171 | |||
4147 | void __init rcu_init(void) | 4172 | void __init rcu_init(void) |
4148 | { | 4173 | { |
4149 | int cpu; | 4174 | int cpu; |
@@ -4154,6 +4179,8 @@ void __init rcu_init(void) | |||
4154 | rcu_init_geometry(); | 4179 | rcu_init_geometry(); |
4155 | rcu_init_one(&rcu_bh_state, &rcu_bh_data); | 4180 | rcu_init_one(&rcu_bh_state, &rcu_bh_data); |
4156 | rcu_init_one(&rcu_sched_state, &rcu_sched_data); | 4181 | rcu_init_one(&rcu_sched_state, &rcu_sched_data); |
4182 | if (dump_tree) | ||
4183 | rcu_dump_rcu_node_tree(&rcu_sched_state); | ||
4157 | __rcu_init_preempt(); | 4184 | __rcu_init_preempt(); |
4158 | open_softirq(RCU_SOFTIRQ, rcu_process_callbacks); | 4185 | open_softirq(RCU_SOFTIRQ, rcu_process_callbacks); |
4159 | 4186 | ||