diff options
author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2015-10-07 19:05:21 -0400 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2015-10-07 19:05:21 -0400 |
commit | d2856b046d2ce2bfb664727cb8671ad0e371bd6c (patch) | |
tree | cb9056e8fb6a3038db6629781dfefbac8387d0c2 /kernel/rcu/tree.h | |
parent | 7f5f873c6a0772970d5fee1f364231207051ecd8 (diff) | |
parent | 338b0f760e84676130c6e4d8268cb8c923b38c8c (diff) |
Merge branches 'fixes.2015.10.06a' and 'exp.2015.10.07a' into HEAD
exp.2015.10.07a: Reduce OS jitter of RCU-sched expedited grace periods.
fixes.2015.10.06a: Miscellaneous fixes.
Diffstat (limited to 'kernel/rcu/tree.h')
-rw-r--r-- | kernel/rcu/tree.h | 48 |
1 files changed, 28 insertions, 20 deletions
diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h index 674ebbc3e406..9fb4e238d4dc 100644 --- a/kernel/rcu/tree.h +++ b/kernel/rcu/tree.h | |||
@@ -70,8 +70,6 @@ | |||
70 | # define RCU_NODE_NAME_INIT { "rcu_node_0" } | 70 | # define RCU_NODE_NAME_INIT { "rcu_node_0" } |
71 | # define RCU_FQS_NAME_INIT { "rcu_node_fqs_0" } | 71 | # define RCU_FQS_NAME_INIT { "rcu_node_fqs_0" } |
72 | # define RCU_EXP_NAME_INIT { "rcu_node_exp_0" } | 72 | # define RCU_EXP_NAME_INIT { "rcu_node_exp_0" } |
73 | # define RCU_EXP_SCHED_NAME_INIT \ | ||
74 | { "rcu_node_exp_sched_0" } | ||
75 | #elif NR_CPUS <= RCU_FANOUT_2 | 73 | #elif NR_CPUS <= RCU_FANOUT_2 |
76 | # define RCU_NUM_LVLS 2 | 74 | # define RCU_NUM_LVLS 2 |
77 | # define NUM_RCU_LVL_0 1 | 75 | # define NUM_RCU_LVL_0 1 |
@@ -81,8 +79,6 @@ | |||
81 | # define RCU_NODE_NAME_INIT { "rcu_node_0", "rcu_node_1" } | 79 | # define RCU_NODE_NAME_INIT { "rcu_node_0", "rcu_node_1" } |
82 | # define RCU_FQS_NAME_INIT { "rcu_node_fqs_0", "rcu_node_fqs_1" } | 80 | # define RCU_FQS_NAME_INIT { "rcu_node_fqs_0", "rcu_node_fqs_1" } |
83 | # define RCU_EXP_NAME_INIT { "rcu_node_exp_0", "rcu_node_exp_1" } | 81 | # define RCU_EXP_NAME_INIT { "rcu_node_exp_0", "rcu_node_exp_1" } |
84 | # define RCU_EXP_SCHED_NAME_INIT \ | ||
85 | { "rcu_node_exp_sched_0", "rcu_node_exp_sched_1" } | ||
86 | #elif NR_CPUS <= RCU_FANOUT_3 | 82 | #elif NR_CPUS <= RCU_FANOUT_3 |
87 | # define RCU_NUM_LVLS 3 | 83 | # define RCU_NUM_LVLS 3 |
88 | # define NUM_RCU_LVL_0 1 | 84 | # define NUM_RCU_LVL_0 1 |
@@ -93,8 +89,6 @@ | |||
93 | # define RCU_NODE_NAME_INIT { "rcu_node_0", "rcu_node_1", "rcu_node_2" } | 89 | # define RCU_NODE_NAME_INIT { "rcu_node_0", "rcu_node_1", "rcu_node_2" } |
94 | # define RCU_FQS_NAME_INIT { "rcu_node_fqs_0", "rcu_node_fqs_1", "rcu_node_fqs_2" } | 90 | # define RCU_FQS_NAME_INIT { "rcu_node_fqs_0", "rcu_node_fqs_1", "rcu_node_fqs_2" } |
95 | # define RCU_EXP_NAME_INIT { "rcu_node_exp_0", "rcu_node_exp_1", "rcu_node_exp_2" } | 91 | # define RCU_EXP_NAME_INIT { "rcu_node_exp_0", "rcu_node_exp_1", "rcu_node_exp_2" } |
96 | # define RCU_EXP_SCHED_NAME_INIT \ | ||
97 | { "rcu_node_exp_sched_0", "rcu_node_exp_sched_1", "rcu_node_exp_sched_2" } | ||
98 | #elif NR_CPUS <= RCU_FANOUT_4 | 92 | #elif NR_CPUS <= RCU_FANOUT_4 |
99 | # define RCU_NUM_LVLS 4 | 93 | # define RCU_NUM_LVLS 4 |
100 | # define NUM_RCU_LVL_0 1 | 94 | # define NUM_RCU_LVL_0 1 |
@@ -106,8 +100,6 @@ | |||
106 | # define RCU_NODE_NAME_INIT { "rcu_node_0", "rcu_node_1", "rcu_node_2", "rcu_node_3" } | 100 | # define RCU_NODE_NAME_INIT { "rcu_node_0", "rcu_node_1", "rcu_node_2", "rcu_node_3" } |
107 | # define RCU_FQS_NAME_INIT { "rcu_node_fqs_0", "rcu_node_fqs_1", "rcu_node_fqs_2", "rcu_node_fqs_3" } | 101 | # define RCU_FQS_NAME_INIT { "rcu_node_fqs_0", "rcu_node_fqs_1", "rcu_node_fqs_2", "rcu_node_fqs_3" } |
108 | # define RCU_EXP_NAME_INIT { "rcu_node_exp_0", "rcu_node_exp_1", "rcu_node_exp_2", "rcu_node_exp_3" } | 102 | # define RCU_EXP_NAME_INIT { "rcu_node_exp_0", "rcu_node_exp_1", "rcu_node_exp_2", "rcu_node_exp_3" } |
109 | # define RCU_EXP_SCHED_NAME_INIT \ | ||
110 | { "rcu_node_exp_sched_0", "rcu_node_exp_sched_1", "rcu_node_exp_sched_2", "rcu_node_exp_sched_3" } | ||
111 | #else | 103 | #else |
112 | # error "CONFIG_RCU_FANOUT insufficient for NR_CPUS" | 104 | # error "CONFIG_RCU_FANOUT insufficient for NR_CPUS" |
113 | #endif /* #if (NR_CPUS) <= RCU_FANOUT_1 */ | 105 | #endif /* #if (NR_CPUS) <= RCU_FANOUT_1 */ |
@@ -171,16 +163,21 @@ struct rcu_node { | |||
171 | /* an rcu_data structure, otherwise, each */ | 163 | /* an rcu_data structure, otherwise, each */ |
172 | /* bit corresponds to a child rcu_node */ | 164 | /* bit corresponds to a child rcu_node */ |
173 | /* structure. */ | 165 | /* structure. */ |
174 | unsigned long expmask; /* Groups that have ->blkd_tasks */ | ||
175 | /* elements that need to drain to allow the */ | ||
176 | /* current expedited grace period to */ | ||
177 | /* complete (only for PREEMPT_RCU). */ | ||
178 | unsigned long qsmaskinit; | 166 | unsigned long qsmaskinit; |
179 | /* Per-GP initial value for qsmask & expmask. */ | 167 | /* Per-GP initial value for qsmask. */ |
180 | /* Initialized from ->qsmaskinitnext at the */ | 168 | /* Initialized from ->qsmaskinitnext at the */ |
181 | /* beginning of each grace period. */ | 169 | /* beginning of each grace period. */ |
182 | unsigned long qsmaskinitnext; | 170 | unsigned long qsmaskinitnext; |
183 | /* Online CPUs for next grace period. */ | 171 | /* Online CPUs for next grace period. */ |
172 | unsigned long expmask; /* CPUs or groups that need to check in */ | ||
173 | /* to allow the current expedited GP */ | ||
174 | /* to complete. */ | ||
175 | unsigned long expmaskinit; | ||
176 | /* Per-GP initial values for expmask. */ | ||
177 | /* Initialized from ->expmaskinitnext at the */ | ||
178 | /* beginning of each expedited GP. */ | ||
179 | unsigned long expmaskinitnext; | ||
180 | /* Online CPUs for next expedited GP. */ | ||
184 | unsigned long grpmask; /* Mask to apply to parent qsmask. */ | 181 | unsigned long grpmask; /* Mask to apply to parent qsmask. */ |
185 | /* Only one bit will be set in this mask. */ | 182 | /* Only one bit will be set in this mask. */ |
186 | int grplo; /* lowest-numbered CPU or group here. */ | 183 | int grplo; /* lowest-numbered CPU or group here. */ |
@@ -281,6 +278,18 @@ struct rcu_node { | |||
281 | for ((rnp) = (rsp)->level[rcu_num_lvls - 1]; \ | 278 | for ((rnp) = (rsp)->level[rcu_num_lvls - 1]; \ |
282 | (rnp) < &(rsp)->node[rcu_num_nodes]; (rnp)++) | 279 | (rnp) < &(rsp)->node[rcu_num_nodes]; (rnp)++) |
283 | 280 | ||
281 | /* | ||
282 | * Union to allow "aggregate OR" operation on the need for a quiescent | ||
283 | * state by the normal and expedited grace periods. | ||
284 | */ | ||
285 | union rcu_noqs { | ||
286 | struct { | ||
287 | u8 norm; | ||
288 | u8 exp; | ||
289 | } b; /* Bits. */ | ||
290 | u16 s; /* Set of bits, aggregate OR here. */ | ||
291 | }; | ||
292 | |||
284 | /* Index values for nxttail array in struct rcu_data. */ | 293 | /* Index values for nxttail array in struct rcu_data. */ |
285 | #define RCU_DONE_TAIL 0 /* Also RCU_WAIT head. */ | 294 | #define RCU_DONE_TAIL 0 /* Also RCU_WAIT head. */ |
286 | #define RCU_WAIT_TAIL 1 /* Also RCU_NEXT_READY head. */ | 295 | #define RCU_WAIT_TAIL 1 /* Also RCU_NEXT_READY head. */ |
@@ -297,8 +306,8 @@ struct rcu_data { | |||
297 | /* is aware of having started. */ | 306 | /* is aware of having started. */ |
298 | unsigned long rcu_qs_ctr_snap;/* Snapshot of rcu_qs_ctr to check */ | 307 | unsigned long rcu_qs_ctr_snap;/* Snapshot of rcu_qs_ctr to check */ |
299 | /* for rcu_all_qs() invocations. */ | 308 | /* for rcu_all_qs() invocations. */ |
300 | bool passed_quiesce; /* User-mode/idle loop etc. */ | 309 | union rcu_noqs cpu_no_qs; /* No QSes yet for this CPU. */ |
301 | bool qs_pending; /* Core waits for quiesc state. */ | 310 | bool core_needs_qs; /* Core waits for quiesc state. */ |
302 | bool beenonline; /* CPU online at least once. */ | 311 | bool beenonline; /* CPU online at least once. */ |
303 | bool gpwrap; /* Possible gpnum/completed wrap. */ | 312 | bool gpwrap; /* Possible gpnum/completed wrap. */ |
304 | struct rcu_node *mynode; /* This CPU's leaf of hierarchy */ | 313 | struct rcu_node *mynode; /* This CPU's leaf of hierarchy */ |
@@ -307,9 +316,6 @@ struct rcu_data { | |||
307 | /* ticks this CPU has handled */ | 316 | /* ticks this CPU has handled */ |
308 | /* during and after the last grace */ | 317 | /* during and after the last grace */ |
309 | /* period it is aware of. */ | 318 | /* period it is aware of. */ |
310 | struct cpu_stop_work exp_stop_work; | ||
311 | /* Expedited grace-period control */ | ||
312 | /* for CPU stopping. */ | ||
313 | 319 | ||
314 | /* 2) batch handling */ | 320 | /* 2) batch handling */ |
315 | /* | 321 | /* |
@@ -363,7 +369,7 @@ struct rcu_data { | |||
363 | 369 | ||
364 | /* 5) __rcu_pending() statistics. */ | 370 | /* 5) __rcu_pending() statistics. */ |
365 | unsigned long n_rcu_pending; /* rcu_pending() calls since boot. */ | 371 | unsigned long n_rcu_pending; /* rcu_pending() calls since boot. */ |
366 | unsigned long n_rp_qs_pending; | 372 | unsigned long n_rp_core_needs_qs; |
367 | unsigned long n_rp_report_qs; | 373 | unsigned long n_rp_report_qs; |
368 | unsigned long n_rp_cb_ready; | 374 | unsigned long n_rp_cb_ready; |
369 | unsigned long n_rp_cpu_needs_gp; | 375 | unsigned long n_rp_cpu_needs_gp; |
@@ -378,7 +384,6 @@ struct rcu_data { | |||
378 | struct rcu_head oom_head; | 384 | struct rcu_head oom_head; |
379 | #endif /* #ifdef CONFIG_RCU_FAST_NO_HZ */ | 385 | #endif /* #ifdef CONFIG_RCU_FAST_NO_HZ */ |
380 | struct mutex exp_funnel_mutex; | 386 | struct mutex exp_funnel_mutex; |
381 | bool exp_done; /* Expedited QS for this CPU? */ | ||
382 | 387 | ||
383 | /* 7) Callback offloading. */ | 388 | /* 7) Callback offloading. */ |
384 | #ifdef CONFIG_RCU_NOCB_CPU | 389 | #ifdef CONFIG_RCU_NOCB_CPU |
@@ -458,6 +463,7 @@ struct rcu_state { | |||
458 | u8 flavor_mask; /* bit in flavor mask. */ | 463 | u8 flavor_mask; /* bit in flavor mask. */ |
459 | struct rcu_data __percpu *rda; /* pointer of percu rcu_data. */ | 464 | struct rcu_data __percpu *rda; /* pointer of percu rcu_data. */ |
460 | call_rcu_func_t call; /* call_rcu() flavor. */ | 465 | call_rcu_func_t call; /* call_rcu() flavor. */ |
466 | int ncpus; /* # CPUs seen so far. */ | ||
461 | 467 | ||
462 | /* The following fields are guarded by the root rcu_node's lock. */ | 468 | /* The following fields are guarded by the root rcu_node's lock. */ |
463 | 469 | ||
@@ -499,6 +505,7 @@ struct rcu_state { | |||
499 | atomic_long_t expedited_normal; /* # fallbacks to normal. */ | 505 | atomic_long_t expedited_normal; /* # fallbacks to normal. */ |
500 | atomic_t expedited_need_qs; /* # CPUs left to check in. */ | 506 | atomic_t expedited_need_qs; /* # CPUs left to check in. */ |
501 | wait_queue_head_t expedited_wq; /* Wait for check-ins. */ | 507 | wait_queue_head_t expedited_wq; /* Wait for check-ins. */ |
508 | int ncpus_snap; /* # CPUs seen last time. */ | ||
502 | 509 | ||
503 | unsigned long jiffies_force_qs; /* Time at which to invoke */ | 510 | unsigned long jiffies_force_qs; /* Time at which to invoke */ |
504 | /* force_quiescent_state(). */ | 511 | /* force_quiescent_state(). */ |
@@ -573,6 +580,7 @@ static bool rcu_preempt_has_tasks(struct rcu_node *rnp); | |||
573 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ | 580 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ |
574 | static void rcu_print_detail_task_stall(struct rcu_state *rsp); | 581 | static void rcu_print_detail_task_stall(struct rcu_state *rsp); |
575 | static int rcu_print_task_stall(struct rcu_node *rnp); | 582 | static int rcu_print_task_stall(struct rcu_node *rnp); |
583 | static int rcu_print_task_exp_stall(struct rcu_node *rnp); | ||
576 | static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp); | 584 | static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp); |
577 | static void rcu_preempt_check_callbacks(void); | 585 | static void rcu_preempt_check_callbacks(void); |
578 | void call_rcu(struct rcu_head *head, rcu_callback_t func); | 586 | void call_rcu(struct rcu_head *head, rcu_callback_t func); |