Commit 6f2b9b9a9d750a9175dc79c74bfed5add840983c

Authored by Johannes Berg
Committed by Ingo Molnar
1 parent 673f820591

timer: implement lockdep deadlock detection

This modifies the timer code in a way to allow lockdep to detect
deadlocks resulting from a lock being taken in the timer function
as well as around the del_timer_sync() call.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>

Showing 2 changed files with 141 additions and 20 deletions Side-by-side Diff

include/linux/timer.h
... ... @@ -5,6 +5,7 @@
5 5 #include <linux/ktime.h>
6 6 #include <linux/stddef.h>
7 7 #include <linux/debugobjects.h>
  8 +#include <linux/stringify.h>
8 9  
9 10 struct tvec_base;
10 11  
11 12  
12 13  
13 14  
14 15  
15 16  
16 17  
17 18  
18 19  
19 20  
20 21  
21 22  
... ... @@ -21,52 +22,126 @@
21 22 char start_comm[16];
22 23 int start_pid;
23 24 #endif
  25 +#ifdef CONFIG_LOCKDEP
  26 + struct lockdep_map lockdep_map;
  27 +#endif
24 28 };
25 29  
26 30 extern struct tvec_base boot_tvec_bases;
27 31  
  32 +#ifdef CONFIG_LOCKDEP
  33 +/*
  34 + * NB: because we have to copy the lockdep_map, setting the lockdep_map key
  35 + * (second argument) here is required, otherwise it could be initialised to
  36 + * the copy of the lockdep_map later! We use the pointer to and the string
  37 + * "<file>:<line>" as the key resp. the name of the lockdep_map.
  38 + */
  39 +#define __TIMER_LOCKDEP_MAP_INITIALIZER(_kn) \
  40 + .lockdep_map = STATIC_LOCKDEP_MAP_INIT(_kn, &_kn),
  41 +#else
  42 +#define __TIMER_LOCKDEP_MAP_INITIALIZER(_kn)
  43 +#endif
  44 +
28 45 #define TIMER_INITIALIZER(_function, _expires, _data) { \
29 46 .entry = { .prev = TIMER_ENTRY_STATIC }, \
30 47 .function = (_function), \
31 48 .expires = (_expires), \
32 49 .data = (_data), \
33 50 .base = &boot_tvec_bases, \
  51 + __TIMER_LOCKDEP_MAP_INITIALIZER( \
  52 + __FILE__ ":" __stringify(__LINE__)) \
34 53 }
35 54  
36 55 #define DEFINE_TIMER(_name, _function, _expires, _data) \
37 56 struct timer_list _name = \
38 57 TIMER_INITIALIZER(_function, _expires, _data)
39 58  
40   -void init_timer(struct timer_list *timer);
41   -void init_timer_deferrable(struct timer_list *timer);
  59 +void init_timer_key(struct timer_list *timer,
  60 + const char *name,
  61 + struct lock_class_key *key);
  62 +void init_timer_deferrable_key(struct timer_list *timer,
  63 + const char *name,
  64 + struct lock_class_key *key);
42 65  
  66 +#ifdef CONFIG_LOCKDEP
  67 +#define init_timer(timer) \
  68 + do { \
  69 + static struct lock_class_key __key; \
  70 + init_timer_key((timer), #timer, &__key); \
  71 + } while (0)
  72 +
  73 +#define init_timer_deferrable(timer) \
  74 + do { \
  75 + static struct lock_class_key __key; \
  76 + init_timer_deferrable_key((timer), #timer, &__key); \
  77 + } while (0)
  78 +
  79 +#define init_timer_on_stack(timer) \
  80 + do { \
  81 + static struct lock_class_key __key; \
  82 + init_timer_on_stack_key((timer), #timer, &__key); \
  83 + } while (0)
  84 +
  85 +#define setup_timer(timer, fn, data) \
  86 + do { \
  87 + static struct lock_class_key __key; \
  88 + setup_timer_key((timer), #timer, &__key, (fn), (data));\
  89 + } while (0)
  90 +
  91 +#define setup_timer_on_stack(timer, fn, data) \
  92 + do { \
  93 + static struct lock_class_key __key; \
  94 + setup_timer_on_stack_key((timer), #timer, &__key, \
  95 + (fn), (data)); \
  96 + } while (0)
  97 +#else
  98 +#define init_timer(timer)\
  99 + init_timer_key((timer), NULL, NULL)
  100 +#define init_timer_deferrable(timer)\
  101 + init_timer_deferrable_key((timer), NULL, NULL)
  102 +#define init_timer_on_stack(timer)\
  103 + init_timer_on_stack_key((timer), NULL, NULL)
  104 +#define setup_timer(timer, fn, data)\
  105 + setup_timer_key((timer), NULL, NULL, (fn), (data))
  106 +#define setup_timer_on_stack(timer, fn, data)\
  107 + setup_timer_on_stack_key((timer), NULL, NULL, (fn), (data))
  108 +#endif
  109 +
43 110 #ifdef CONFIG_DEBUG_OBJECTS_TIMERS
44   -extern void init_timer_on_stack(struct timer_list *timer);
  111 +extern void init_timer_on_stack_key(struct timer_list *timer,
  112 + const char *name,
  113 + struct lock_class_key *key);
45 114 extern void destroy_timer_on_stack(struct timer_list *timer);
46 115 #else
47 116 static inline void destroy_timer_on_stack(struct timer_list *timer) { }
48   -static inline void init_timer_on_stack(struct timer_list *timer)
  117 +static inline void init_timer_on_stack_key(struct timer_list *timer,
  118 + const char *name,
  119 + struct lock_class_key *key)
49 120 {
50   - init_timer(timer);
  121 + init_timer_key(timer, name, key);
51 122 }
52 123 #endif
53 124  
54   -static inline void setup_timer(struct timer_list * timer,
  125 +static inline void setup_timer_key(struct timer_list * timer,
  126 + const char *name,
  127 + struct lock_class_key *key,
55 128 void (*function)(unsigned long),
56 129 unsigned long data)
57 130 {
58 131 timer->function = function;
59 132 timer->data = data;
60   - init_timer(timer);
  133 + init_timer_key(timer, name, key);
61 134 }
62 135  
63   -static inline void setup_timer_on_stack(struct timer_list *timer,
  136 +static inline void setup_timer_on_stack_key(struct timer_list *timer,
  137 + const char *name,
  138 + struct lock_class_key *key,
64 139 void (*function)(unsigned long),
65 140 unsigned long data)
66 141 {
67 142 timer->function = function;
68 143 timer->data = data;
69   - init_timer_on_stack(timer);
  144 + init_timer_on_stack_key(timer, name, key);
70 145 }
71 146  
72 147 /**
... ... @@ -491,14 +491,18 @@
491 491 debug_object_free(timer, &timer_debug_descr);
492 492 }
493 493  
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);
495 497  
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)
497 501 {
498 502 debug_object_init_on_stack(timer, &timer_debug_descr);
499   - __init_timer(timer);
  503 + __init_timer(timer, name, key);
500 504 }
501   -EXPORT_SYMBOL_GPL(init_timer_on_stack);
  505 +EXPORT_SYMBOL_GPL(init_timer_on_stack_key);
502 506  
503 507 void destroy_timer_on_stack(struct timer_list *timer)
504 508 {
... ... @@ -512,7 +516,9 @@
512 516 static inline void debug_timer_deactivate(struct timer_list *timer) { }
513 517 #endif
514 518  
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)
516 522 {
517 523 timer->entry.next = NULL;
518 524 timer->base = __raw_get_cpu_var(tvec_bases);
... ... @@ -521,6 +527,7 @@
521 527 timer->start_pid = -1;
522 528 memset(timer->start_comm, 0, TASK_COMM_LEN);
523 529 #endif
  530 + lockdep_init_map(&timer->lockdep_map, name, key, 0);
524 531 }
525 532  
526 533 /**
527 534  
528 535  
529 536  
530 537  
531 538  
... ... @@ -530,19 +537,23 @@
530 537 * init_timer() must be done to a timer prior calling *any* of the
531 538 * other timer functions.
532 539 */
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)
534 543 {
535 544 debug_timer_init(timer);
536   - __init_timer(timer);
  545 + __init_timer(timer, name, key);
537 546 }
538   -EXPORT_SYMBOL(init_timer);
  547 +EXPORT_SYMBOL(init_timer_key);
539 548  
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)
541 552 {
542   - init_timer(timer);
  553 + init_timer_key(timer, name, key);
543 554 timer_set_deferrable(timer);
544 555 }
545   -EXPORT_SYMBOL(init_timer_deferrable);
  556 +EXPORT_SYMBOL(init_timer_deferrable_key);
546 557  
547 558 static inline void detach_timer(struct timer_list *timer,
548 559 int clear_pending)
... ... @@ -789,6 +800,15 @@
789 800 */
790 801 int del_timer_sync(struct timer_list *timer)
791 802 {
  803 +#ifdef CONFIG_LOCKDEP
  804 + unsigned long flags;
  805 +
  806 + local_irq_save(flags);
  807 + lock_map_acquire(&timer->lockdep_map);
  808 + lock_map_release(&timer->lockdep_map);
  809 + local_irq_restore(flags);
  810 +#endif
  811 +
792 812 for (;;) {
793 813 int ret = try_to_del_timer_sync(timer);
794 814 if (ret >= 0)
795 815  
796 816  
... ... @@ -861,10 +881,36 @@
861 881  
862 882 set_running_timer(base, timer);
863 883 detach_timer(timer, 1);
  884 +
864 885 spin_unlock_irq(&base->lock);
865 886 {
866 887 int preempt_count = preempt_count();
  888 +
  889 +#ifdef CONFIG_LOCKDEP
  890 + /*
  891 + * It is permissible to free the timer from
  892 + * inside the function that is called from
  893 + * it, this we need to take into account for
  894 + * lockdep too. To avoid bogus "held lock
  895 + * freed" warnings as well as problems when
  896 + * looking into timer->lockdep_map, make a
  897 + * copy and use that here.
  898 + */
  899 + struct lockdep_map lockdep_map =
  900 + timer->lockdep_map;
  901 +#endif
  902 + /*
  903 + * Couple the lock chain with the lock chain at
  904 + * del_timer_sync() by acquiring the lock_map
  905 + * around the fn() call here and in
  906 + * del_timer_sync().
  907 + */
  908 + lock_map_acquire(&lockdep_map);
  909 +
867 910 fn(data);
  911 +
  912 + lock_map_release(&lockdep_map);
  913 +
868 914 if (preempt_count != preempt_count()) {
869 915 printk(KERN_ERR "huh, entered %p "
870 916 "with preempt_count %08x, exited"