diff options
author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2012-04-23 18:52:53 -0400 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2012-07-02 15:33:20 -0400 |
commit | f885b7f2b2de70be266d2cecc476f773a1e2ca5d (patch) | |
tree | c4f4d03ca1469f22701b848274034a74c5ae2b04 /kernel/rcutree.h | |
parent | cba6d0d64ee53772b285d0c0c288deefbeaf7775 (diff) |
rcu: Control RCU_FANOUT_LEAF from boot-time parameter
Although making RCU_FANOUT_LEAF a kernel configuration parameter rather
than a fixed constant makes it easier for people to decrease cache-miss
overhead for large systems, it is of little help for people who must
run a single pre-built kernel binary.
This commit therefore allows the value of RCU_FANOUT_LEAF to be
increased (but not decreased!) via a boot-time parameter named
rcutree.rcu_fanout_leaf.
Reported-by: Mike Galbraith <efault@gmx.de>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'kernel/rcutree.h')
-rw-r--r-- | kernel/rcutree.h | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/kernel/rcutree.h b/kernel/rcutree.h index 19b61ac1079f..780a0195d35a 100644 --- a/kernel/rcutree.h +++ b/kernel/rcutree.h | |||
@@ -42,28 +42,28 @@ | |||
42 | #define RCU_FANOUT_4 (RCU_FANOUT_3 * CONFIG_RCU_FANOUT) | 42 | #define RCU_FANOUT_4 (RCU_FANOUT_3 * CONFIG_RCU_FANOUT) |
43 | 43 | ||
44 | #if NR_CPUS <= RCU_FANOUT_1 | 44 | #if NR_CPUS <= RCU_FANOUT_1 |
45 | # define NUM_RCU_LVLS 1 | 45 | # define RCU_NUM_LVLS 1 |
46 | # define NUM_RCU_LVL_0 1 | 46 | # define NUM_RCU_LVL_0 1 |
47 | # define NUM_RCU_LVL_1 (NR_CPUS) | 47 | # define NUM_RCU_LVL_1 (NR_CPUS) |
48 | # define NUM_RCU_LVL_2 0 | 48 | # define NUM_RCU_LVL_2 0 |
49 | # define NUM_RCU_LVL_3 0 | 49 | # define NUM_RCU_LVL_3 0 |
50 | # define NUM_RCU_LVL_4 0 | 50 | # define NUM_RCU_LVL_4 0 |
51 | #elif NR_CPUS <= RCU_FANOUT_2 | 51 | #elif NR_CPUS <= RCU_FANOUT_2 |
52 | # define NUM_RCU_LVLS 2 | 52 | # define RCU_NUM_LVLS 2 |
53 | # define NUM_RCU_LVL_0 1 | 53 | # define NUM_RCU_LVL_0 1 |
54 | # define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_1) | 54 | # define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_1) |
55 | # define NUM_RCU_LVL_2 (NR_CPUS) | 55 | # define NUM_RCU_LVL_2 (NR_CPUS) |
56 | # define NUM_RCU_LVL_3 0 | 56 | # define NUM_RCU_LVL_3 0 |
57 | # define NUM_RCU_LVL_4 0 | 57 | # define NUM_RCU_LVL_4 0 |
58 | #elif NR_CPUS <= RCU_FANOUT_3 | 58 | #elif NR_CPUS <= RCU_FANOUT_3 |
59 | # define NUM_RCU_LVLS 3 | 59 | # define RCU_NUM_LVLS 3 |
60 | # define NUM_RCU_LVL_0 1 | 60 | # define NUM_RCU_LVL_0 1 |
61 | # define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_2) | 61 | # define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_2) |
62 | # define NUM_RCU_LVL_2 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_1) | 62 | # define NUM_RCU_LVL_2 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_1) |
63 | # define NUM_RCU_LVL_3 (NR_CPUS) | 63 | # define NUM_RCU_LVL_3 (NR_CPUS) |
64 | # define NUM_RCU_LVL_4 0 | 64 | # define NUM_RCU_LVL_4 0 |
65 | #elif NR_CPUS <= RCU_FANOUT_4 | 65 | #elif NR_CPUS <= RCU_FANOUT_4 |
66 | # define NUM_RCU_LVLS 4 | 66 | # define RCU_NUM_LVLS 4 |
67 | # define NUM_RCU_LVL_0 1 | 67 | # define NUM_RCU_LVL_0 1 |
68 | # define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_3) | 68 | # define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_3) |
69 | # define NUM_RCU_LVL_2 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_2) | 69 | # define NUM_RCU_LVL_2 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_2) |
@@ -76,6 +76,9 @@ | |||
76 | #define RCU_SUM (NUM_RCU_LVL_0 + NUM_RCU_LVL_1 + NUM_RCU_LVL_2 + NUM_RCU_LVL_3 + NUM_RCU_LVL_4) | 76 | #define RCU_SUM (NUM_RCU_LVL_0 + NUM_RCU_LVL_1 + NUM_RCU_LVL_2 + NUM_RCU_LVL_3 + NUM_RCU_LVL_4) |
77 | #define NUM_RCU_NODES (RCU_SUM - NR_CPUS) | 77 | #define NUM_RCU_NODES (RCU_SUM - NR_CPUS) |
78 | 78 | ||
79 | extern int rcu_num_lvls; | ||
80 | extern int rcu_num_nodes; | ||
81 | |||
79 | /* | 82 | /* |
80 | * Dynticks per-CPU state. | 83 | * Dynticks per-CPU state. |
81 | */ | 84 | */ |
@@ -206,7 +209,7 @@ struct rcu_node { | |||
206 | */ | 209 | */ |
207 | #define rcu_for_each_node_breadth_first(rsp, rnp) \ | 210 | #define rcu_for_each_node_breadth_first(rsp, rnp) \ |
208 | for ((rnp) = &(rsp)->node[0]; \ | 211 | for ((rnp) = &(rsp)->node[0]; \ |
209 | (rnp) < &(rsp)->node[NUM_RCU_NODES]; (rnp)++) | 212 | (rnp) < &(rsp)->node[rcu_num_nodes]; (rnp)++) |
210 | 213 | ||
211 | /* | 214 | /* |
212 | * Do a breadth-first scan of the non-leaf rcu_node structures for the | 215 | * Do a breadth-first scan of the non-leaf rcu_node structures for the |
@@ -215,7 +218,7 @@ struct rcu_node { | |||
215 | */ | 218 | */ |
216 | #define rcu_for_each_nonleaf_node_breadth_first(rsp, rnp) \ | 219 | #define rcu_for_each_nonleaf_node_breadth_first(rsp, rnp) \ |
217 | for ((rnp) = &(rsp)->node[0]; \ | 220 | for ((rnp) = &(rsp)->node[0]; \ |
218 | (rnp) < (rsp)->level[NUM_RCU_LVLS - 1]; (rnp)++) | 221 | (rnp) < (rsp)->level[rcu_num_lvls - 1]; (rnp)++) |
219 | 222 | ||
220 | /* | 223 | /* |
221 | * Scan the leaves of the rcu_node hierarchy for the specified rcu_state | 224 | * Scan the leaves of the rcu_node hierarchy for the specified rcu_state |
@@ -224,8 +227,8 @@ struct rcu_node { | |||
224 | * It is still a leaf node, even if it is also the root node. | 227 | * It is still a leaf node, even if it is also the root node. |
225 | */ | 228 | */ |
226 | #define rcu_for_each_leaf_node(rsp, rnp) \ | 229 | #define rcu_for_each_leaf_node(rsp, rnp) \ |
227 | for ((rnp) = (rsp)->level[NUM_RCU_LVLS - 1]; \ | 230 | for ((rnp) = (rsp)->level[rcu_num_lvls - 1]; \ |
228 | (rnp) < &(rsp)->node[NUM_RCU_NODES]; (rnp)++) | 231 | (rnp) < &(rsp)->node[rcu_num_nodes]; (rnp)++) |
229 | 232 | ||
230 | /* Index values for nxttail array in struct rcu_data. */ | 233 | /* Index values for nxttail array in struct rcu_data. */ |
231 | #define RCU_DONE_TAIL 0 /* Also RCU_WAIT head. */ | 234 | #define RCU_DONE_TAIL 0 /* Also RCU_WAIT head. */ |
@@ -357,9 +360,9 @@ do { \ | |||
357 | */ | 360 | */ |
358 | struct rcu_state { | 361 | struct rcu_state { |
359 | struct rcu_node node[NUM_RCU_NODES]; /* Hierarchy. */ | 362 | struct rcu_node node[NUM_RCU_NODES]; /* Hierarchy. */ |
360 | struct rcu_node *level[NUM_RCU_LVLS]; /* Hierarchy levels. */ | 363 | struct rcu_node *level[RCU_NUM_LVLS]; /* Hierarchy levels. */ |
361 | u32 levelcnt[MAX_RCU_LVLS + 1]; /* # nodes in each level. */ | 364 | u32 levelcnt[MAX_RCU_LVLS + 1]; /* # nodes in each level. */ |
362 | u8 levelspread[NUM_RCU_LVLS]; /* kids/node in each level. */ | 365 | u8 levelspread[RCU_NUM_LVLS]; /* kids/node in each level. */ |
363 | struct rcu_data __percpu *rda; /* pointer of percu rcu_data. */ | 366 | struct rcu_data __percpu *rda; /* pointer of percu rcu_data. */ |
364 | 367 | ||
365 | /* The following fields are guarded by the root rcu_node's lock. */ | 368 | /* The following fields are guarded by the root rcu_node's lock. */ |