aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rcu/tree.h
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2015-10-07 19:05:21 -0400
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2015-10-07 19:05:21 -0400
commitd2856b046d2ce2bfb664727cb8671ad0e371bd6c (patch)
treecb9056e8fb6a3038db6629781dfefbac8387d0c2 /kernel/rcu/tree.h
parent7f5f873c6a0772970d5fee1f364231207051ecd8 (diff)
parent338b0f760e84676130c6e4d8268cb8c923b38c8c (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.h48
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 */
285union 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 */
574static void rcu_print_detail_task_stall(struct rcu_state *rsp); 581static void rcu_print_detail_task_stall(struct rcu_state *rsp);
575static int rcu_print_task_stall(struct rcu_node *rnp); 582static int rcu_print_task_stall(struct rcu_node *rnp);
583static int rcu_print_task_exp_stall(struct rcu_node *rnp);
576static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp); 584static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp);
577static void rcu_preempt_check_callbacks(void); 585static void rcu_preempt_check_callbacks(void);
578void call_rcu(struct rcu_head *head, rcu_callback_t func); 586void call_rcu(struct rcu_head *head, rcu_callback_t func);