aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/timer.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-15 21:28:30 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-15 21:28:30 -0400
commit0586bed3e8563c2eb89bc7256e30ce633ae06cfb (patch)
tree7a59610f45f7222f25b3212c53fa28636bb4427c /kernel/timer.c
parentb80cd62b7d4406bbe8c573fe4381dcc71a2850fd (diff)
parentdbebbfbb1605f0179e7c0d900d941cc9c45de569 (diff)
Merge branch 'core-locking-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'core-locking-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: rtmutex: tester: Remove the remaining BKL leftovers lockdep/timers: Explain in detail the locking problems del_timer_sync() may cause rtmutex: Simplify PI algorithm and make highest prio task get lock rwsem: Remove redundant asmregparm annotation rwsem: Move duplicate function prototypes to linux/rwsem.h rwsem: Unify the duplicate rwsem_is_locked() inlines rwsem: Move duplicate init macros and functions to linux/rwsem.h rwsem: Move duplicate struct rwsem declaration to linux/rwsem.h x86: Cleanup rwsem_count_t typedef rwsem: Cleanup includes locking: Remove deprecated lock initializers cred: Replace deprecated spinlock initialization kthread: Replace deprecated spinlock initialization xtensa: Replace deprecated spinlock initialization um: Replace deprecated spinlock initialization sparc: Replace deprecated spinlock initialization mips: Replace deprecated spinlock initialization cris: Replace deprecated spinlock initialization alpha: Replace deprecated spinlock initialization rtmutex-tester: Remove BKL tests
Diffstat (limited to 'kernel/timer.c')
-rw-r--r--kernel/timer.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/kernel/timer.c b/kernel/timer.c
index 33a67925d900..3503c17ac1d3 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -970,6 +970,25 @@ EXPORT_SYMBOL(try_to_del_timer_sync);
970 * add_timer_on(). Upon exit the timer is not queued and the handler is 970 * add_timer_on(). Upon exit the timer is not queued and the handler is
971 * not running on any CPU. 971 * not running on any CPU.
972 * 972 *
973 * Note: You must not hold locks that are held in interrupt context
974 * while calling this function. Even if the lock has nothing to do
975 * with the timer in question. Here's why:
976 *
977 * CPU0 CPU1
978 * ---- ----
979 * <SOFTIRQ>
980 * call_timer_fn();
981 * base->running_timer = mytimer;
982 * spin_lock_irq(somelock);
983 * <IRQ>
984 * spin_lock(somelock);
985 * del_timer_sync(mytimer);
986 * while (base->running_timer == mytimer);
987 *
988 * Now del_timer_sync() will never return and never release somelock.
989 * The interrupt on the other CPU is waiting to grab somelock but
990 * it has interrupted the softirq that CPU0 is waiting to finish.
991 *
973 * The function returns whether it has deactivated a pending timer or not. 992 * The function returns whether it has deactivated a pending timer or not.
974 */ 993 */
975int del_timer_sync(struct timer_list *timer) 994int del_timer_sync(struct timer_list *timer)
@@ -977,6 +996,10 @@ int del_timer_sync(struct timer_list *timer)
977#ifdef CONFIG_LOCKDEP 996#ifdef CONFIG_LOCKDEP
978 unsigned long flags; 997 unsigned long flags;
979 998
999 /*
1000 * If lockdep gives a backtrace here, please reference
1001 * the synchronization rules above.
1002 */
980 local_irq_save(flags); 1003 local_irq_save(flags);
981 lock_map_acquire(&timer->lockdep_map); 1004 lock_map_acquire(&timer->lockdep_map);
982 lock_map_release(&timer->lockdep_map); 1005 lock_map_release(&timer->lockdep_map);