diff options
author | Zhang, Yanmin <yanmin_zhang@linux.intel.com> | 2030-08-14 03:56:40 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-08-14 04:58:48 -0400 |
commit | 09f2724a786f76475ef2985cf84f5359c553aade (patch) | |
tree | 0c2bf6c6651b14c9ae12150af9ad06b2d9ee8a60 | |
parent | 30a2f3c60a84092c8084dfe788b710f8d0768cd4 (diff) |
sched: fix the race between walk_tg_tree and sched_create_group
With 2.6.27-rc3, I hit a kernel panic when running volanoMark on my
new x86_64 machine. I also hit it with other 2.6.27-rc kernels.
See below log.
Basically, function walk_tg_tree and sched_create_group have a race
between accessing and initiating tg->children. Below patch fixes it
by moving tg->children initiation to the front of linking tg->siblings
to parent->children.
{----------------panic log------------}
BUG: unable to handle kernel NULL pointer dereference at 0000000000000000
IP: [<ffffffff802292ab>] walk_tg_tree+0x45/0x7f
PGD 1be1c4067 PUD 1bdd8d067 PMD 0
Oops: 0000 [1] SMP
CPU 11
Modules linked in: igb
Pid: 22979, comm: java Not tainted 2.6.27-rc3 #1
RIP: 0010:[<ffffffff802292ab>] [<ffffffff802292ab>] walk_tg_tree+0x45/0x7f
RSP: 0018:ffff8801bfbbbd18 EFLAGS: 00010083
RAX: 0000000000000000 RBX: ffff8800be0dce40 RCX: ffffffffffffffc0
RDX: ffff880102c43740 RSI: 0000000000000000 RDI: ffff8800be0dce40
RBP: ffff8801bfbbbd48 R08: ffff8800ba437bc8 R09: 0000000000001f40
R10: ffff8801be812100 R11: ffffffff805fdf44 R12: ffff880102c43740
R13: 0000000000000000 R14: ffffffff8022cf0f R15: ffffffff8022749f
FS: 00000000568ac950(0063) GS:ffff8801bfa26d00(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 0000000000000000 CR3: 00000001bd848000 CR4: 00000000000006e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process java (pid: 22979, threadinfo ffff8801b145a000, task ffff8801bf18e450)
Stack: 0000000000000001 ffff8800ba5c8d60 0000000000000001 0000000000000001
ffff8800bad1ccb8 0000000000000000 ffff8801bfbbbd98 ffffffff8022ed37
0000000000000001 0000000000000286 ffff8801bd5ee180 ffff8800ba437bc8
Call Trace:
<IRQ> [<ffffffff8022ed37>] try_to_wake_up+0x71/0x24c
[<ffffffff80247177>] autoremove_wake_function+0x9/0x2e
[<ffffffff80228039>] ? __wake_up_common+0x46/0x76
[<ffffffff802296d5>] __wake_up+0x38/0x4f
[<ffffffff806169cc>] tcp_v4_rcv+0x380/0x62e
Signed-off-by: Zhang Yanmin <yanmin_zhang@linux.intel.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | kernel/sched.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index d601fb0406ca..8bf8a5528bc7 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -8462,8 +8462,8 @@ struct task_group *sched_create_group(struct task_group *parent) | |||
8462 | WARN_ON(!parent); /* root should already exist */ | 8462 | WARN_ON(!parent); /* root should already exist */ |
8463 | 8463 | ||
8464 | tg->parent = parent; | 8464 | tg->parent = parent; |
8465 | list_add_rcu(&tg->siblings, &parent->children); | ||
8466 | INIT_LIST_HEAD(&tg->children); | 8465 | INIT_LIST_HEAD(&tg->children); |
8466 | list_add_rcu(&tg->siblings, &parent->children); | ||
8467 | spin_unlock_irqrestore(&task_group_lock, flags); | 8467 | spin_unlock_irqrestore(&task_group_lock, flags); |
8468 | 8468 | ||
8469 | return tg; | 8469 | return tg; |