History

Merge branch 'locking-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'locking-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (33 commits) lockdep: fix deadlock in lockdep_trace_alloc lockdep: annotate reclaim context (__GFP_NOFS), fix SLOB lockdep: annotate reclaim context (__GFP_NOFS), fix lockdep: build fix for !PROVE_LOCKING lockstat: warn about disabled lock debugging lockdep: use stringify.h lockdep: simplify check_prev_add_irq() lockdep: get_user_chars() redo lockdep: simplify get_user_chars() lockdep: add comments to mark_lock_irq() lockdep: remove macro usage from mark_held_locks() lockdep: fully reduce mark_lock_irq() lockdep: merge the !_READ mark_lock_irq() helpers lockdep: merge the _READ mark_lock_irq() helpers lockdep: simplify mark_lock_irq() helpers #3 lockdep: further simplify mark_lock_irq() helpers lockdep: simplify the mark_lock_irq() helpers lockdep: split up mark_lock_irq() lockdep: generate usage strings lockdep: generate the state bit definitions ...

Linus Torvalds committed 17 years ago

Commit c4e1aa62 parents cf2f7d7 2f8501821 files · +730 −379Browse files

Showing the changes to kernel/timer.c (1 of 21 files). Show all

Unified · Split

kernel/timer.c+57−11
@@ -491,14 +491,18 @@ static inline void debug_timer_free(struct timer_list *timer) · 490 unmodified lines
491491 debug_object_free(timer, &timer_debug_descr);
492492 }
493493
494−static void __init_timer(struct timer_list *timer);
494+static void __init_timer(struct timer_list *timer,
495+ const char *name,
496+ struct lock_class_key *key);
495497
496−void init_timer_on_stack(struct timer_list *timer)
498+void init_timer_on_stack_key(struct timer_list *timer,
499+ const char *name,
500+ struct lock_class_key *key)
497501 {
498502 debug_object_init_on_stack(timer, &timer_debug_descr);
499− __init_timer(timer);
503+ __init_timer(timer, name, key);
500504 }
501−EXPORT_SYMBOL_GPL(init_timer_on_stack);
505+EXPORT_SYMBOL_GPL(init_timer_on_stack_key);
502506
503507 void destroy_timer_on_stack(struct timer_list *timer)
504508 {
@@ -512,7 +516,9 @@ static inline void debug_timer_activate(struct timer_list *timer) { } · 7 unmodified lines
512516 static inline void debug_timer_deactivate(struct timer_list *timer) { }
513517 #endif
514518
515−static void __init_timer(struct timer_list *timer)
519+static void __init_timer(struct timer_list *timer,
520+ const char *name,
521+ struct lock_class_key *key)
516522 {
517523 timer->entry.next = NULL;
518524 timer->base = __raw_get_cpu_var(tvec_bases);
@@ -521,6 +527,7 @@ static void __init_timer(struct timer_list *timer) · 2 unmodified lines
521527 timer->start_pid = -1;
522528 memset(timer->start_comm, 0, TASK_COMM_LEN);
523529 #endif
530+ lockdep_init_map(&timer->lockdep_map, name, key, 0);
524531 }
525532
526533 /**
@@ -530,19 +537,23 @@ static void __init_timer(struct timer_list *timer) · 3 unmodified lines
530537 * init_timer() must be done to a timer prior calling *any* of the
531538 * other timer functions.
532539 */
533−void init_timer(struct timer_list *timer)
540+void init_timer_key(struct timer_list *timer,
541+ const char *name,
542+ struct lock_class_key *key)
534543 {
535544 debug_timer_init(timer);
536− __init_timer(timer);
545+ __init_timer(timer, name, key);
537546 }
538−EXPORT_SYMBOL(init_timer);
547+EXPORT_SYMBOL(init_timer_key);
539548
540−void init_timer_deferrable(struct timer_list *timer)
549+void init_timer_deferrable_key(struct timer_list *timer,
550+ const char *name,
551+ struct lock_class_key *key)
541552 {
542− init_timer(timer);
553+ init_timer_key(timer, name, key);
543554 timer_set_deferrable(timer);
544555 }
545−EXPORT_SYMBOL(init_timer_deferrable);
556+EXPORT_SYMBOL(init_timer_deferrable_key);
546557
547558 static inline void detach_timer(struct timer_list *timer,
548559 int clear_pending)
@@ -826,6 +837,15 @@ EXPORT_SYMBOL(try_to_del_timer_sync); · 277 unmodified lines
826837 */
827838 int del_timer_sync(struct timer_list *timer)
828839 {
840+#ifdef CONFIG_LOCKDEP
841+ unsigned long flags;
842+
843+ local_irq_save(flags);
844+ lock_map_acquire(&timer->lockdep_map);
845+ lock_map_release(&timer->lockdep_map);
846+ local_irq_restore(flags);
847+#endif
848+
829849 for (;;) {
830850 int ret = try_to_del_timer_sync(timer);
831851 if (ret >= 0)
@@ -897,10 +917,36 @@ static inline void __run_timers(struct tvec_base *base) · 65 unmodified lines
897917
898918 set_running_timer(base, timer);
899919 detach_timer(timer, 1);
920+
900921 spin_unlock_irq(&base->lock);
901922 {
902923 int preempt_count = preempt_count();
924+
925+#ifdef CONFIG_LOCKDEP
926+ /*
927+ * It is permissible to free the timer from
928+ * inside the function that is called from
929+ * it, this we need to take into account for
930+ * lockdep too. To avoid bogus "held lock
931+ * freed" warnings as well as problems when
932+ * looking into timer->lockdep_map, make a
933+ * copy and use that here.
934+ */
935+ struct lockdep_map lockdep_map =
936+ timer->lockdep_map;
937+#endif
938+ /*
939+ * Couple the lock chain with the lock chain at
940+ * del_timer_sync() by acquiring the lock_map
941+ * around the fn() call here and in
942+ * del_timer_sync().
943+ */
944+ lock_map_acquire(&lockdep_map);
945+
903946 fn(data);
947+
948+ lock_map_release(&lockdep_map);
949+
904950 if (preempt_count != preempt_count()) {
905951 printk(KERN_ERR "huh, entered %p "
906952 "with preempt_count %08x, exited"