diff options
author | Nathan Lynch <nathanl@austin.ibm.com> | 2004-07-28 08:56:54 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-07-28 08:56:54 -0700 |
commit | 805540843e4f600f0a1bd0bf989719f77cb9b7f6 (patch) | |
tree | 3d93390057699adf0aa6c0198b04e2247fc529e4 /kernel | |
parent | bc2b7e977da422e84c02cca04ff8ea0f958287e2 (diff) | |
download | history-805540843e4f600f0a1bd0bf989719f77cb9b7f6.tar.gz |
[PATCH] fixes for rcu_offline_cpu, rcu_move_batch
rcu_offline_cpu and rcu_move_batch have been broken since the list_head's
in struct rcu_head and struct rcu_data were replaced with singly-linked
lists:
CC kernel/rcupdate.o
kernel/rcupdate.c: In function `rcu_move_batch':
kernel/rcupdate.c:222: warning: passing arg 2 of `list_add_tail' from
incompatible pointer type
kernel/rcupdate.c: In function `rcu_offline_cpu':
kernel/rcupdate.c:239: warning: passing arg 1 of `rcu_move_batch' from
incompatible pointer type
kernel/rcupdate.c:240: warning: passing arg 1 of `rcu_move_batch' from
incompatible pointer type
kernel/rcupdate.c:236: warning: label `unlock' defined but not used
Kernel crashes when you try to offline a cpu, not surprisingly.
It also looks like rcu_move_batch isn't preempt-safe so I touched that up,
and got rid of an unused label in rcu_offline_cpu.
Signed-off-by: Nathan Lynch <nathanl@austin.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/rcupdate.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index f35f944abe3d3a..b331fe3f64e990 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -210,16 +210,18 @@ static void rcu_check_quiescent_state(void) * locking requirements, the list it's pulling from has to belong to a cpu * which is dead and hence not processing interrupts. */ -static void rcu_move_batch(struct list_head *list) +static void rcu_move_batch(struct rcu_head *list) { - struct list_head *entry; - int cpu = smp_processor_id(); + int cpu; local_irq_disable(); - while (!list_empty(list)) { - entry = list->next; - list_del(entry); - list_add_tail(entry, &RCU_nxtlist(cpu)); + + cpu = smp_processor_id(); + + while (list != NULL) { + *RCU_nxttail(cpu) = list; + RCU_nxttail(cpu) = &list->next; + list = list->next; } local_irq_enable(); } @@ -233,11 +235,10 @@ static void rcu_offline_cpu(int cpu) spin_lock_bh(&rcu_state.mutex); if (rcu_ctrlblk.cur != rcu_ctrlblk.completed) cpu_quiet(cpu); -unlock: spin_unlock_bh(&rcu_state.mutex); - rcu_move_batch(&RCU_curlist(cpu)); - rcu_move_batch(&RCU_nxtlist(cpu)); + rcu_move_batch(RCU_curlist(cpu)); + rcu_move_batch(RCU_nxtlist(cpu)); tasklet_kill_immediate(&RCU_tasklet(cpu), cpu); } |