linux/kernel
Heiko Carstens e81ce1f7ec [PATCH] timer/hrtimer: take per cpu locks in sane order
Doing something like this on a two cpu system

  # echo 0 > /sys/devices/system/cpu/cpu0/online
  # echo 1 > /sys/devices/system/cpu/cpu0/online
  # echo 0 > /sys/devices/system/cpu/cpu1/online

will give me this:

  =======================================================
  [ INFO: possible circular locking dependency detected ]
  2.6.21-rc2-g562aa1d4-dirty #7
  -------------------------------------------------------
  bash/1282 is trying to acquire lock:
   (&cpu_base->lock_key){.+..}, at: [<000000000005f17e>] hrtimer_cpu_notify+0xc6/0x240

  but task is already holding lock:
   (&cpu_base->lock_key#2){.+..}, at: [<000000000005f174>] hrtimer_cpu_notify+0xbc/0x240

  which lock already depends on the new lock.

This happens because we have the following code in kernel/hrtimer.c:

  migrate_hrtimers(int cpu)
  [...]
  old_base = &per_cpu(hrtimer_bases, cpu);
  new_base = &get_cpu_var(hrtimer_bases);
  [...]
  spin_lock(&new_base->lock);
  spin_lock(&old_base->lock);

Which means the spinlocks are taken in an order which depends on which cpu
gets shut down from which other cpu. Therefore lockdep complains that there
might be an ABBA deadlock. Since migrate_hrtimers() gets only called on
cpu hotplug it's safe to assume that it isn't executed concurrently on a

The same problem exists in kernel/timer.c: migrate_timers().

As pointed out by Christian Borntraeger one possible solution to avoid
the locking order complaints would be to make sure that the locks are
always taken in the same order. E.g. by taking the lock of the cpu with
the lower number first.

To achieve this we introduce two new spinlock functions double_spin_lock
and double_spin_unlock which lock or unlock two locks in a given order.

Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Roman Zippel <zippel@linux-m68k.org>
Cc: John Stultz <johnstul@us.ibm.com>
Cc: Christian Borntraeger <cborntra@de.ibm.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-03-05 07:57:53 -08:00
..
irq [PATCH] genirq: Mask irqs when migrating them. 2007-02-26 10:34:08 -08:00
power power management: no valid states w/o pm_ops 2007-02-23 14:52:09 -08:00
time [PATCH] clocksource init adjustments (fix bug #7426) 2007-03-05 07:57:53 -08:00
.gitignore
acct.c
audit.c [PATCH] audit config lockdown 2007-02-17 21:30:12 -05:00
audit.h
auditfilter.c [PATCH] minor update to rule add/delete messages (ver 2) 2007-02-17 21:30:09 -05:00
auditsc.c [PATCH] AUDIT_FD_PAIR 2007-02-17 21:30:15 -05:00
capability.c [PATCH] pid: replace do/while_each_task_pid with do/while_each_pid_task 2007-02-12 09:48:32 -08:00
compat.c [PATCH] Common compat_sys_sysinfo 2007-02-11 10:51:32 -08:00
configs.c
cpu.c [PATCH] swsusp: Change code ordering in disk.c 2007-02-11 10:51:19 -08:00
cpuset.c [PATCH] mark struct inode_operations const 2 2007-02-12 09:48:46 -08:00
delayacct.c
dma.c
exec_domain.c
exit.c [PATCH] pid: replace is_orphaned_pgrp with is_current_pgrp_orphaned 2007-02-12 09:48:32 -08:00
extable.c
fork.c [PATCH] hrtimers: namespace and enum cleanup 2007-02-16 08:13:58 -08:00
futex_compat.c
futex.c [PATCH] hrtimers: namespace and enum cleanup 2007-02-16 08:13:58 -08:00
hrtimer.c [PATCH] timer/hrtimer: take per cpu locks in sane order 2007-03-05 07:57:53 -08:00
itimer.c [PATCH] hrtimers: prevent possible itimer DoS 2007-02-16 08:13:59 -08:00
kallsyms.c
Kconfig.hz
Kconfig.preempt
kexec.c
kfifo.c [PATCH] Numerous fixes to kernel-doc info in source files. 2007-02-11 10:51:32 -08:00
kmod.c Revert "Driver core: let request_module() send a /sys/modules/kmod/-uevent" 2007-02-23 14:54:57 -08:00
kprobes.c [PATCH] kprobes: list all active probes in the system 2007-02-20 17:10:14 -08:00
ksysfs.c
kthread.c [PATCH] Numerous fixes to kernel-doc info in source files. 2007-02-11 10:51:32 -08:00
latency.c
lockdep_internals.h
lockdep_proc.c [PATCH] remove many unneeded #includes of sched.h 2007-02-14 08:09:54 -08:00
lockdep.c [PATCH] fix section mismatch warning in lockdep 2007-03-01 14:53:37 -08:00
Makefile [PATCH] sysctl: move utsname sysctls to their own file 2007-02-14 08:09:58 -08:00
module.c Revert "Driver core: let request_module() send a /sys/modules/kmod/-uevent" 2007-02-23 14:54:57 -08:00
mutex-debug.c [PATCH] remove many unneeded #includes of sched.h 2007-02-14 08:09:54 -08:00
mutex-debug.h
mutex.c
mutex.h
nsproxy.c Revert "[PATCH] namespaces: fix exit race by splitting exit" 2007-01-30 13:35:18 -08:00
panic.c [PATCH] Add TAINT_USER and ability to set taint flags from userspace 2007-02-11 10:51:29 -08:00
params.c Revert "Driver core: let request_module() send a /sys/modules/kmod/-uevent" 2007-02-23 14:54:57 -08:00
pid.c [PATCH] namespaces: fix task exit disaster 2007-01-30 13:40:36 -08:00
posix-cpu-timers.c [PATCH] posix timers: RCU optimization for clock_gettime() 2007-02-16 08:14:00 -08:00
posix-timers.c [PATCH] hrtimers: add high resolution timer support 2007-02-16 08:13:59 -08:00
printk.c kernel/printk.c: comment fix 2007-02-17 20:10:16 +01:00
profile.c [PATCH] proc: remove useless (and buggy) ->nlink settings 2007-02-11 10:51:32 -08:00
ptrace.c
rcupdate.c
rcutorture.c [PATCH] rcu: rcutorture suspend fix 2006-12-30 10:55:55 -08:00
relay.c [PATCH] kernel-doc fixes for 2.6.20-git15 (non-drivers) 2007-03-01 14:53:37 -08:00
resource.c [PATCH] remove many unneeded #includes of sched.h 2007-02-14 08:09:54 -08:00
rtmutex_common.h
rtmutex-debug.c
rtmutex-debug.h
rtmutex-tester.c
rtmutex.c [PATCH] hrtimers: namespace and enum cleanup 2007-02-16 08:13:58 -08:00
rtmutex.h
rwsem.c
sched.c [PATCH] sched: remove SMT nice 2007-03-05 07:57:51 -08:00
seccomp.c
signal.c Merge master.kernel.org:/pub/scm/linux/kernel/git/kyle/parisc-2.6 2007-02-26 12:48:06 -08:00
softirq.c [PATCH] tick-management: dyntick / highres functionality 2007-02-16 08:13:59 -08:00
softlockup.c
spinlock.c
srcu.c
stacktrace.c
stop_machine.c
sys_ni.c
sys.c [PATCH] pid: replace do/while_each_task_pid with do/while_each_pid_task 2007-02-12 09:48:32 -08:00
sysctl.c [PATCH] fix the SYSCTL=n compilation 2007-03-01 14:53:37 -08:00
taskstats.c
time.c [PATCH] Fix multiple conversion bugs in msecs_to_jiffies 2007-02-16 08:13:56 -08:00
timer.c [PATCH] timer/hrtimer: take per cpu locks in sane order 2007-03-05 07:57:53 -08:00
tsacct.c [PATCH] time: x86_64: split x86_64/kernel/time.c up 2007-02-16 08:14:00 -08:00
uid16.c
user.c
utsname_sysctl.c [PATCH] sysctl: remove insert_at_head from register_sysctl 2007-02-14 08:09:59 -08:00
utsname.c
wait.c
workqueue.c [PATCH] Add debugging feature /proc/timer_stat 2007-02-16 08:13:59 -08:00