diff options
Diffstat (limited to 'kernel/rcutree.h')
-rw-r--r-- | kernel/rcutree.h | 104 |
1 files changed, 84 insertions, 20 deletions
diff --git a/kernel/rcutree.h b/kernel/rcutree.h index e8f057e44e3e..257664815d5d 100644 --- a/kernel/rcutree.h +++ b/kernel/rcutree.h | |||
@@ -91,6 +91,14 @@ struct rcu_dynticks { | |||
91 | /* remains even for nmi from irq handler. */ | 91 | /* remains even for nmi from irq handler. */ |
92 | }; | 92 | }; |
93 | 93 | ||
94 | /* RCU's kthread states for tracing. */ | ||
95 | #define RCU_KTHREAD_STOPPED 0 | ||
96 | #define RCU_KTHREAD_RUNNING 1 | ||
97 | #define RCU_KTHREAD_WAITING 2 | ||
98 | #define RCU_KTHREAD_OFFCPU 3 | ||
99 | #define RCU_KTHREAD_YIELDING 4 | ||
100 | #define RCU_KTHREAD_MAX 4 | ||
101 | |||
94 | /* | 102 | /* |
95 | * Definition for node within the RCU grace-period-detection hierarchy. | 103 | * Definition for node within the RCU grace-period-detection hierarchy. |
96 | */ | 104 | */ |
@@ -109,10 +117,11 @@ struct rcu_node { | |||
109 | /* an rcu_data structure, otherwise, each */ | 117 | /* an rcu_data structure, otherwise, each */ |
110 | /* bit corresponds to a child rcu_node */ | 118 | /* bit corresponds to a child rcu_node */ |
111 | /* structure. */ | 119 | /* structure. */ |
112 | unsigned long expmask; /* Groups that have ->blocked_tasks[] */ | 120 | unsigned long expmask; /* Groups that have ->blkd_tasks */ |
113 | /* elements that need to drain to allow the */ | 121 | /* elements that need to drain to allow the */ |
114 | /* current expedited grace period to */ | 122 | /* current expedited grace period to */ |
115 | /* complete (only for TREE_PREEMPT_RCU). */ | 123 | /* complete (only for TREE_PREEMPT_RCU). */ |
124 | unsigned long wakemask; /* CPUs whose kthread needs to be awakened. */ | ||
116 | unsigned long qsmaskinit; | 125 | unsigned long qsmaskinit; |
117 | /* Per-GP initial value for qsmask & expmask. */ | 126 | /* Per-GP initial value for qsmask & expmask. */ |
118 | unsigned long grpmask; /* Mask to apply to parent qsmask. */ | 127 | unsigned long grpmask; /* Mask to apply to parent qsmask. */ |
@@ -122,11 +131,68 @@ struct rcu_node { | |||
122 | u8 grpnum; /* CPU/group number for next level up. */ | 131 | u8 grpnum; /* CPU/group number for next level up. */ |
123 | u8 level; /* root is at level 0. */ | 132 | u8 level; /* root is at level 0. */ |
124 | struct rcu_node *parent; | 133 | struct rcu_node *parent; |
125 | struct list_head blocked_tasks[4]; | 134 | struct list_head blkd_tasks; |
126 | /* Tasks blocked in RCU read-side critsect. */ | 135 | /* Tasks blocked in RCU read-side critical */ |
127 | /* Grace period number (->gpnum) x blocked */ | 136 | /* section. Tasks are placed at the head */ |
128 | /* by tasks on the (x & 0x1) element of the */ | 137 | /* of this list and age towards the tail. */ |
129 | /* blocked_tasks[] array. */ | 138 | struct list_head *gp_tasks; |
139 | /* Pointer to the first task blocking the */ | ||
140 | /* current grace period, or NULL if there */ | ||
141 | /* is no such task. */ | ||
142 | struct list_head *exp_tasks; | ||
143 | /* Pointer to the first task blocking the */ | ||
144 | /* current expedited grace period, or NULL */ | ||
145 | /* if there is no such task. If there */ | ||
146 | /* is no current expedited grace period, */ | ||
147 | /* then there can cannot be any such task. */ | ||
148 | #ifdef CONFIG_RCU_BOOST | ||
149 | struct list_head *boost_tasks; | ||
150 | /* Pointer to first task that needs to be */ | ||
151 | /* priority boosted, or NULL if no priority */ | ||
152 | /* boosting is needed for this rcu_node */ | ||
153 | /* structure. If there are no tasks */ | ||
154 | /* queued on this rcu_node structure that */ | ||
155 | /* are blocking the current grace period, */ | ||
156 | /* there can be no such task. */ | ||
157 | unsigned long boost_time; | ||
158 | /* When to start boosting (jiffies). */ | ||
159 | struct task_struct *boost_kthread_task; | ||
160 | /* kthread that takes care of priority */ | ||
161 | /* boosting for this rcu_node structure. */ | ||
162 | wait_queue_head_t boost_wq; | ||
163 | /* Wait queue on which to park the boost */ | ||
164 | /* kthread. */ | ||
165 | unsigned int boost_kthread_status; | ||
166 | /* State of boost_kthread_task for tracing. */ | ||
167 | unsigned long n_tasks_boosted; | ||
168 | /* Total number of tasks boosted. */ | ||
169 | unsigned long n_exp_boosts; | ||
170 | /* Number of tasks boosted for expedited GP. */ | ||
171 | unsigned long n_normal_boosts; | ||
172 | /* Number of tasks boosted for normal GP. */ | ||
173 | unsigned long n_balk_blkd_tasks; | ||
174 | /* Refused to boost: no blocked tasks. */ | ||
175 | unsigned long n_balk_exp_gp_tasks; | ||
176 | /* Refused to boost: nothing blocking GP. */ | ||
177 | unsigned long n_balk_boost_tasks; | ||
178 | /* Refused to boost: already boosting. */ | ||
179 | unsigned long n_balk_notblocked; | ||
180 | /* Refused to boost: RCU RS CS still running. */ | ||
181 | unsigned long n_balk_notyet; | ||
182 | /* Refused to boost: not yet time. */ | ||
183 | unsigned long n_balk_nos; | ||
184 | /* Refused to boost: not sure why, though. */ | ||
185 | /* This can happen due to race conditions. */ | ||
186 | #endif /* #ifdef CONFIG_RCU_BOOST */ | ||
187 | struct task_struct *node_kthread_task; | ||
188 | /* kthread that takes care of this rcu_node */ | ||
189 | /* structure, for example, awakening the */ | ||
190 | /* per-CPU kthreads as needed. */ | ||
191 | wait_queue_head_t node_wq; | ||
192 | /* Wait queue on which to park the per-node */ | ||
193 | /* kthread. */ | ||
194 | unsigned int node_kthread_status; | ||
195 | /* State of node_kthread_task for tracing. */ | ||
130 | } ____cacheline_internodealigned_in_smp; | 196 | } ____cacheline_internodealigned_in_smp; |
131 | 197 | ||
132 | /* | 198 | /* |
@@ -175,7 +241,7 @@ struct rcu_data { | |||
175 | bool passed_quiesc; /* User-mode/idle loop etc. */ | 241 | bool passed_quiesc; /* User-mode/idle loop etc. */ |
176 | bool qs_pending; /* Core waits for quiesc state. */ | 242 | bool qs_pending; /* Core waits for quiesc state. */ |
177 | bool beenonline; /* CPU online at least once. */ | 243 | bool beenonline; /* CPU online at least once. */ |
178 | bool preemptable; /* Preemptable RCU? */ | 244 | bool preemptible; /* Preemptible RCU? */ |
179 | struct rcu_node *mynode; /* This CPU's leaf of hierarchy */ | 245 | struct rcu_node *mynode; /* This CPU's leaf of hierarchy */ |
180 | unsigned long grpmask; /* Mask to apply to leaf qsmask. */ | 246 | unsigned long grpmask; /* Mask to apply to leaf qsmask. */ |
181 | 247 | ||
@@ -254,7 +320,6 @@ struct rcu_data { | |||
254 | #endif /* #else #ifdef CONFIG_NO_HZ */ | 320 | #endif /* #else #ifdef CONFIG_NO_HZ */ |
255 | 321 | ||
256 | #define RCU_JIFFIES_TILL_FORCE_QS 3 /* for rsp->jiffies_force_qs */ | 322 | #define RCU_JIFFIES_TILL_FORCE_QS 3 /* for rsp->jiffies_force_qs */ |
257 | #ifdef CONFIG_RCU_CPU_STALL_DETECTOR | ||
258 | 323 | ||
259 | #ifdef CONFIG_PROVE_RCU | 324 | #ifdef CONFIG_PROVE_RCU |
260 | #define RCU_STALL_DELAY_DELTA (5 * HZ) | 325 | #define RCU_STALL_DELAY_DELTA (5 * HZ) |
@@ -272,13 +337,6 @@ struct rcu_data { | |||
272 | /* scheduling clock irq */ | 337 | /* scheduling clock irq */ |
273 | /* before ratting on them. */ | 338 | /* before ratting on them. */ |
274 | 339 | ||
275 | #ifdef CONFIG_RCU_CPU_STALL_DETECTOR_RUNNABLE | ||
276 | #define RCU_CPU_STALL_SUPPRESS_INIT 0 | ||
277 | #else | ||
278 | #define RCU_CPU_STALL_SUPPRESS_INIT 1 | ||
279 | #endif | ||
280 | |||
281 | #endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */ | ||
282 | 340 | ||
283 | /* | 341 | /* |
284 | * RCU global state, including node hierarchy. This hierarchy is | 342 | * RCU global state, including node hierarchy. This hierarchy is |
@@ -325,12 +383,12 @@ struct rcu_state { | |||
325 | /* due to lock unavailable. */ | 383 | /* due to lock unavailable. */ |
326 | unsigned long n_force_qs_ngp; /* Number of calls leaving */ | 384 | unsigned long n_force_qs_ngp; /* Number of calls leaving */ |
327 | /* due to no GP active. */ | 385 | /* due to no GP active. */ |
328 | #ifdef CONFIG_RCU_CPU_STALL_DETECTOR | ||
329 | unsigned long gp_start; /* Time at which GP started, */ | 386 | unsigned long gp_start; /* Time at which GP started, */ |
330 | /* but in jiffies. */ | 387 | /* but in jiffies. */ |
331 | unsigned long jiffies_stall; /* Time at which to check */ | 388 | unsigned long jiffies_stall; /* Time at which to check */ |
332 | /* for CPU stalls. */ | 389 | /* for CPU stalls. */ |
333 | #endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */ | 390 | unsigned long gp_max; /* Maximum GP duration in */ |
391 | /* jiffies. */ | ||
334 | char *name; /* Name of structure. */ | 392 | char *name; /* Name of structure. */ |
335 | }; | 393 | }; |
336 | 394 | ||
@@ -361,16 +419,14 @@ DECLARE_PER_CPU(struct rcu_data, rcu_preempt_data); | |||
361 | static void rcu_bootup_announce(void); | 419 | static void rcu_bootup_announce(void); |
362 | long rcu_batches_completed(void); | 420 | long rcu_batches_completed(void); |
363 | static void rcu_preempt_note_context_switch(int cpu); | 421 | static void rcu_preempt_note_context_switch(int cpu); |
364 | static int rcu_preempted_readers(struct rcu_node *rnp); | 422 | static int rcu_preempt_blocked_readers_cgp(struct rcu_node *rnp); |
365 | #ifdef CONFIG_HOTPLUG_CPU | 423 | #ifdef CONFIG_HOTPLUG_CPU |
366 | static void rcu_report_unblock_qs_rnp(struct rcu_node *rnp, | 424 | static void rcu_report_unblock_qs_rnp(struct rcu_node *rnp, |
367 | unsigned long flags); | 425 | unsigned long flags); |
368 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ | 426 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ |
369 | #ifdef CONFIG_RCU_CPU_STALL_DETECTOR | ||
370 | static void rcu_print_detail_task_stall(struct rcu_state *rsp); | 427 | static void rcu_print_detail_task_stall(struct rcu_state *rsp); |
371 | static void rcu_print_task_stall(struct rcu_node *rnp); | 428 | static void rcu_print_task_stall(struct rcu_node *rnp); |
372 | static void rcu_preempt_stall_reset(void); | 429 | static void rcu_preempt_stall_reset(void); |
373 | #endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */ | ||
374 | static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp); | 430 | static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp); |
375 | #ifdef CONFIG_HOTPLUG_CPU | 431 | #ifdef CONFIG_HOTPLUG_CPU |
376 | static int rcu_preempt_offline_tasks(struct rcu_state *rsp, | 432 | static int rcu_preempt_offline_tasks(struct rcu_state *rsp, |
@@ -390,5 +446,13 @@ static void __cpuinit rcu_preempt_init_percpu_data(int cpu); | |||
390 | static void rcu_preempt_send_cbs_to_online(void); | 446 | static void rcu_preempt_send_cbs_to_online(void); |
391 | static void __init __rcu_init_preempt(void); | 447 | static void __init __rcu_init_preempt(void); |
392 | static void rcu_needs_cpu_flush(void); | 448 | static void rcu_needs_cpu_flush(void); |
449 | static void __init rcu_init_boost_waitqueue(struct rcu_node *rnp); | ||
450 | static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags); | ||
451 | static void rcu_boost_kthread_setaffinity(struct rcu_node *rnp, | ||
452 | cpumask_var_t cm); | ||
453 | static void rcu_preempt_boost_start_gp(struct rcu_node *rnp); | ||
454 | static int __cpuinit rcu_spawn_one_boost_kthread(struct rcu_state *rsp, | ||
455 | struct rcu_node *rnp, | ||
456 | int rnp_index); | ||
393 | 457 | ||
394 | #endif /* #ifndef RCU_TREE_NONCORE */ | 458 | #endif /* #ifndef RCU_TREE_NONCORE */ |