sched: fix RCU lockdep splat from task_group()
This addresses the following RCU lockdep splat:
[0.051203] CPU0: AMD QEMU Virtual CPU version 0.12.4 stepping 03
[0.052999] lockdep: fixing up alternatives.
[0.054105]
[0.054106] ===================================================
[0.054999] [ INFO: suspicious rcu_dereference_check() usage. ]
[0.054999] ---------------------------------------------------
[0.054999] kernel/sched.c:616 invoked rcu_dereference_check() without protection!
[0.054999]
[0.054999] other info that might help us debug this:
[0.054999]
[0.054999]
[0.054999] rcu_scheduler_active = 1, debug_locks = 1
[0.054999] 3 locks held by swapper/1:
[0.054999] #0: (cpu_add_remove_lock){+.+.+.}, at: [<
ffffffff814be933>] cpu_up+0x42/0x6a
[0.054999] #1: (cpu_hotplug.lock){+.+.+.}, at: [<
ffffffff810400d8>] cpu_hotplug_begin+0x2a/0x51
[0.054999] #2: (&rq->lock){-.-...}, at: [<
ffffffff814be2f7>] init_idle+0x2f/0x113
[0.054999]
[0.054999] stack backtrace:
[0.054999] Pid: 1, comm: swapper Not tainted 2.6.35 #1
[0.054999] Call Trace:
[0.054999] [<
ffffffff81068054>] lockdep_rcu_dereference+0x9b/0xa3
[0.054999] [<
ffffffff810325c3>] task_group+0x7b/0x8a
[0.054999] [<
ffffffff810325e5>] set_task_rq+0x13/0x40
[0.054999] [<
ffffffff814be39a>] init_idle+0xd2/0x113
[0.054999] [<
ffffffff814be78a>] fork_idle+0xb8/0xc7
[0.054999] [<
ffffffff81068717>] ? mark_held_locks+0x4d/0x6b
[0.054999] [<
ffffffff814bcebd>] do_fork_idle+0x17/0x2b
[0.054999] [<
ffffffff814bc89b>] native_cpu_up+0x1c1/0x724
[0.054999] [<
ffffffff814bcea6>] ? do_fork_idle+0x0/0x2b
[0.054999] [<
ffffffff814be876>] _cpu_up+0xac/0x127
[0.054999] [<
ffffffff814be946>] cpu_up+0x55/0x6a
[0.054999] [<
ffffffff81ab562a>] kernel_init+0xe1/0x1ff
[0.054999] [<
ffffffff81003854>] kernel_thread_helper+0x4/0x10
[0.054999] [<
ffffffff814c353c>] ? restore_args+0x0/0x30
[0.054999] [<
ffffffff81ab5549>] ? kernel_init+0x0/0x1ff
[0.054999] [<
ffffffff81003850>] ? kernel_thread_helper+0x0/0x10
[0.056074] Booting Node 0, Processors #1lockdep: fixing up alternatives.
[0.130045] #2lockdep: fixing up alternatives.
[0.203089] #3 Ok.
[0.275286] Brought up 4 CPUs
[0.276005] Total of 4 processors activated (16017.17 BogoMIPS).
The cgroup_subsys_state structures referenced by idle tasks are never
freed, because the idle tasks should be part of the root cgroup,
which is not removable.
The problem is that while we do in-fact hold rq->lock, the newly spawned
idle thread's cpu is not yet set to the correct cpu so the lockdep check
in task_group():
lockdep_is_held(&task_rq(p)->lock)
will fail.
But this is a chicken and egg problem. Setting the CPU's runqueue requires
that the CPU's runqueue already be set. ;-)
So insert an RCU read-side critical section to avoid the complaint.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>