aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rcutree.h
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2009-10-07 00:48:17 -0400
committerIngo Molnar <mingo@elte.hu>2009-10-07 02:11:20 -0400
commite74f4c4564455c91a3b4075bb1721993c2a95dda (patch)
tree213f9df0974c6e1e729de207b2c6dd942a39ba8c /kernel/rcutree.h
parentd0ec774cb2599c858be9d923bb873cf6697520d8 (diff)
rcu: Make hot-unplugged CPU relinquish its own RCU callbacks
The current interaction between RCU and CPU hotplug requires that RCU block in CPU notifiers waiting for callbacks to drain. This can be greatly simplified by having each CPU relinquish its own callbacks, and for both _rcu_barrier() and CPU_DEAD notifiers to adopt all callbacks that were previously relinquished. This change also eliminates the possibility of certain types of hangs due to the previous practice of waiting for callbacks to be invoked from within CPU notifiers. If you don't every wait, you cannot hang. Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Cc: laijs@cn.fujitsu.com Cc: dipankar@in.ibm.com Cc: akpm@linux-foundation.org Cc: mathieu.desnoyers@polymtl.ca Cc: josh@joshtriplett.org Cc: dvhltc@us.ibm.com Cc: niv@us.ibm.com Cc: peterz@infradead.org Cc: rostedt@goodmis.org Cc: Valdis.Kletnieks@vt.edu Cc: dhowells@redhat.com LKML-Reference: <1254890898456-git-send-email-> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/rcutree.h')
-rw-r--r--kernel/rcutree.h11
1 files changed, 10 insertions, 1 deletions
diff --git a/kernel/rcutree.h b/kernel/rcutree.h
index 676eecd371d9..b40ac5706040 100644
--- a/kernel/rcutree.h
+++ b/kernel/rcutree.h
@@ -244,7 +244,15 @@ struct rcu_state {
244 /* End of fields guarded by root rcu_node's lock. */ 244 /* End of fields guarded by root rcu_node's lock. */
245 245
246 spinlock_t onofflock; /* exclude on/offline and */ 246 spinlock_t onofflock; /* exclude on/offline and */
247 /* starting new GP. */ 247 /* starting new GP. Also */
248 /* protects the following */
249 /* orphan_cbs fields. */
250 struct rcu_head *orphan_cbs_list; /* list of rcu_head structs */
251 /* orphaned by all CPUs in */
252 /* a given leaf rcu_node */
253 /* going offline. */
254 struct rcu_head **orphan_cbs_tail; /* And tail pointer. */
255 long orphan_qlen; /* Number of orphaned cbs. */
248 spinlock_t fqslock; /* Only one task forcing */ 256 spinlock_t fqslock; /* Only one task forcing */
249 /* quiescent states. */ 257 /* quiescent states. */
250 unsigned long jiffies_force_qs; /* Time at which to invoke */ 258 unsigned long jiffies_force_qs; /* Time at which to invoke */
@@ -305,6 +313,7 @@ void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu));
305static int rcu_preempt_pending(int cpu); 313static int rcu_preempt_pending(int cpu);
306static int rcu_preempt_needs_cpu(int cpu); 314static int rcu_preempt_needs_cpu(int cpu);
307static void __cpuinit rcu_preempt_init_percpu_data(int cpu); 315static void __cpuinit rcu_preempt_init_percpu_data(int cpu);
316static void rcu_preempt_send_cbs_to_orphanage(void);
308static void __init __rcu_init_preempt(void); 317static void __init __rcu_init_preempt(void);
309 318
310#endif /* #else #ifdef RCU_TREE_NONCORE */ 319#endif /* #else #ifdef RCU_TREE_NONCORE */