Commit 80554084 authored by Nathan Lynch's avatar Nathan Lynch Committed by Linus Torvalds

[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: default avatarNathan Lynch <nathanl@austin.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent bc2b7e97
...@@ -210,16 +210,18 @@ static void rcu_check_quiescent_state(void) ...@@ -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 * locking requirements, the list it's pulling from has to belong to a cpu
* which is dead and hence not processing interrupts. * 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;
int cpu = smp_processor_id();
local_irq_disable(); local_irq_disable();
while (!list_empty(list)) {
entry = list->next; cpu = smp_processor_id();
list_del(entry);
list_add_tail(entry, &RCU_nxtlist(cpu)); while (list != NULL) {
*RCU_nxttail(cpu) = list;
RCU_nxttail(cpu) = &list->next;
list = list->next;
} }
local_irq_enable(); local_irq_enable();
} }
...@@ -233,11 +235,10 @@ static void rcu_offline_cpu(int cpu) ...@@ -233,11 +235,10 @@ static void rcu_offline_cpu(int cpu)
spin_lock_bh(&rcu_state.mutex); spin_lock_bh(&rcu_state.mutex);
if (rcu_ctrlblk.cur != rcu_ctrlblk.completed) if (rcu_ctrlblk.cur != rcu_ctrlblk.completed)
cpu_quiet(cpu); cpu_quiet(cpu);
unlock:
spin_unlock_bh(&rcu_state.mutex); spin_unlock_bh(&rcu_state.mutex);
rcu_move_batch(&RCU_curlist(cpu)); rcu_move_batch(RCU_curlist(cpu));
rcu_move_batch(&RCU_nxtlist(cpu)); rcu_move_batch(RCU_nxtlist(cpu));
tasklet_kill_immediate(&RCU_tasklet(cpu), cpu); tasklet_kill_immediate(&RCU_tasklet(cpu), cpu);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment