kernel-ark/kernel
Paul Jackson abb5a5cc6b [PATCH] Cpuset: fix ABBA deadlock with cpu hotplug lock
Fix ABBA deadlock between lock_cpu_hotplug() and the cpuset
callback_mutex lock.

It only happens on cpu_exclusive cpusets, due to the dynamic
sched domain code trying to take the cpu hotplug lock inside
the cpuset callback_mutex lock.

This bug has apparently been here for several months, but didn't
get hit until the right customer load on a large system.

This fix appears right from inspection, but it will take a few
more days running it on that customers workload to be confident
we nailed it.  We don't have any other reproducible test case.

The cpu_hotplug_lock() tends to cover large runs of code.
The other places that hold both that lock and the cpuset callback
mutex lock always nest the cpuset lock inside the hotplug lock.
This place tries to do the reverse, risking an ABBA deadlock.

This is in the cpuset_rmdir() code, where we:
  * take the callback_mutex lock
  * mark the cpuset CS_REMOVED
  * call update_cpu_domains for cpu_exclusive cpusets
  * in that call, take the cpu_hotplug lock if the
    cpuset is marked for removal.

Thanks to Jack Steiner for identifying this deadlock.

The fix is to tear down the dynamic sched domain before we grab
the cpuset callback_mutex lock.  This way, the two locks are
serialized, with the hotplug lock taken and released before
trying for the cpuset lock.

I suspect that this bug was introduced when I changed the
cpuset locking from one lock to two.  The dynamic sched domain
dependency on cpu_exclusive cpusets and its hotplug hooks were
added to this code earlier, when cpusets had only a single lock.
It may well have been fine then.

Signed-off-by: Paul Jackson <pj@sgi.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-07-23 13:03:05 -07:00
..
irq
power [PATCH] remove kernel/power/pm.c:pm_unregister_all() 2006-07-12 16:09:08 -07:00
time
.gitignore
acct.c [PATCH] Fix sighand->siglock usage in kernel/acct.c 2006-07-14 21:53:54 -07:00
audit.c
audit.h
auditfilter.c
auditsc.c
capability.c
compat.c
configs.c
cpu.c cpu hotplug: simplify and hopefully fix locking 2006-07-23 12:12:16 -07:00
cpuset.c [PATCH] Cpuset: fix ABBA deadlock with cpu hotplug lock 2006-07-23 13:03:05 -07:00
delayacct.c [PATCH] per-task-delay-accounting: /proc export of aggregated block I/O delays 2006-07-14 21:53:57 -07:00
dma.c
exec_domain.c
exit.c [PATCH] per-task delay accounting taskstats interface: control exit data through cpumasks 2006-07-14 21:53:57 -07:00
extable.c
fork.c [PATCH] delay accounting taskstats interface send tgid once 2006-07-14 21:53:57 -07:00
futex_compat.c
futex.c
hrtimer.c
itimer.c
kallsyms.c [PATCH] null-terminate over-long /proc/kallsyms symbols 2006-07-14 21:53:52 -07:00
Kconfig.hz
Kconfig.preempt
kexec.c
kfifo.c
kmod.c
kprobes.c
ksysfs.c
kthread.c [PATCH] remove kernel/kthread.c:kthread_stop_sem() 2006-07-14 21:53:52 -07:00
lockdep_internals.h
lockdep_proc.c
lockdep.c
Makefile [PATCH] per-task-delay-accounting: taskstats interface 2006-07-14 21:53:56 -07:00
module.c [PATCH] null-terminate over-long /proc/kallsyms symbols 2006-07-14 21:53:52 -07:00
mutex-debug.c
mutex-debug.h
mutex.c
mutex.h
panic.c [PATCH] lockdep: disable lock debugging when kernel state becomes untrusted 2006-07-10 13:24:27 -07:00
params.c
pid.c
posix-cpu-timers.c
posix-timers.c
printk.c
profile.c
ptrace.c
rcupdate.c
rcutorture.c
relay.c
resource.c [PATCH] The scheduled unexport of insert_resource 2006-07-12 16:09:08 -07:00
rtmutex_common.h
rtmutex-debug.c
rtmutex-debug.h
rtmutex-tester.c [PATCH] Add try_to_freeze() to rt-test kthreads 2006-07-14 21:53:53 -07:00
rtmutex.c
rtmutex.h
rwsem.c
sched.c [PATCH] per-task-delay-accounting: cpu delay collection via schedstats 2006-07-14 21:53:56 -07:00
seccomp.c
signal.c
softirq.c [PATCH] unexport open_softirq 2006-07-14 21:53:53 -07:00
softlockup.c
spinlock.c
stacktrace.c
stop_machine.c
sys_ni.c
sys.c [PATCH] Fix prctl privilege escalation and suid_dumpable (CVE-2006-2451) 2006-07-12 12:50:25 -07:00
sysctl.c
taskstats.c [PATCH] Remove down_write() from taskstats code invoked on the exit() path 2006-07-14 21:53:57 -07:00
time.c
timer.c [PATCH] improve timekeeping resume robustness 2006-07-14 21:53:54 -07:00
uid16.c
unwind.c
user.c
wait.c [PATCH] uninline init_waitqueue_head() 2006-07-10 13:24:25 -07:00
workqueue.c