aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/timer.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/timer.h')
-rw-r--r--include/linux/timer.h165
1 files changed, 65 insertions, 100 deletions
diff --git a/include/linux/timer.h b/include/linux/timer.h
index 6abd9138beda..8c5a197e1587 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -49,147 +49,112 @@ extern struct tvec_base boot_tvec_bases;
49#endif 49#endif
50 50
51/* 51/*
52 * Note that all tvec_bases are 2 byte aligned and lower bit of 52 * Note that all tvec_bases are at least 4 byte aligned and lower two bits
53 * base in timer_list is guaranteed to be zero. Use the LSB to 53 * of base in timer_list is guaranteed to be zero. Use them for flags.
54 * indicate whether the timer is deferrable.
55 * 54 *
56 * A deferrable timer will work normally when the system is busy, but 55 * A deferrable timer will work normally when the system is busy, but
57 * will not cause a CPU to come out of idle just to service it; instead, 56 * will not cause a CPU to come out of idle just to service it; instead,
58 * the timer will be serviced when the CPU eventually wakes up with a 57 * the timer will be serviced when the CPU eventually wakes up with a
59 * subsequent non-deferrable timer. 58 * subsequent non-deferrable timer.
59 *
60 * An irqsafe timer is executed with IRQ disabled and it's safe to wait for
61 * the completion of the running instance from IRQ handlers, for example,
62 * by calling del_timer_sync().
63 *
64 * Note: The irq disabled callback execution is a special case for
65 * workqueue locking issues. It's not meant for executing random crap
66 * with interrupts disabled. Abuse is monitored!
60 */ 67 */
61#define TBASE_DEFERRABLE_FLAG (0x1) 68#define TIMER_DEFERRABLE 0x1LU
69#define TIMER_IRQSAFE 0x2LU
62 70
63#define TIMER_INITIALIZER(_function, _expires, _data) { \ 71#define TIMER_FLAG_MASK 0x3LU
72
73#define __TIMER_INITIALIZER(_function, _expires, _data, _flags) { \
64 .entry = { .prev = TIMER_ENTRY_STATIC }, \ 74 .entry = { .prev = TIMER_ENTRY_STATIC }, \
65 .function = (_function), \ 75 .function = (_function), \
66 .expires = (_expires), \ 76 .expires = (_expires), \
67 .data = (_data), \ 77 .data = (_data), \
68 .base = &boot_tvec_bases, \ 78 .base = (void *)((unsigned long)&boot_tvec_bases + (_flags)), \
69 .slack = -1, \ 79 .slack = -1, \
70 __TIMER_LOCKDEP_MAP_INITIALIZER( \ 80 __TIMER_LOCKDEP_MAP_INITIALIZER( \
71 __FILE__ ":" __stringify(__LINE__)) \ 81 __FILE__ ":" __stringify(__LINE__)) \
72 } 82 }
73 83
74#define TBASE_MAKE_DEFERRED(ptr) ((struct tvec_base *) \ 84#define TIMER_INITIALIZER(_function, _expires, _data) \
75 ((unsigned char *)(ptr) + TBASE_DEFERRABLE_FLAG)) 85 __TIMER_INITIALIZER((_function), (_expires), (_data), 0)
76 86
77#define TIMER_DEFERRED_INITIALIZER(_function, _expires, _data) {\ 87#define TIMER_DEFERRED_INITIALIZER(_function, _expires, _data) \
78 .entry = { .prev = TIMER_ENTRY_STATIC }, \ 88 __TIMER_INITIALIZER((_function), (_expires), (_data), TIMER_DEFERRABLE)
79 .function = (_function), \
80 .expires = (_expires), \
81 .data = (_data), \
82 .base = TBASE_MAKE_DEFERRED(&boot_tvec_bases), \
83 __TIMER_LOCKDEP_MAP_INITIALIZER( \
84 __FILE__ ":" __stringify(__LINE__)) \
85 }
86 89
87#define DEFINE_TIMER(_name, _function, _expires, _data) \ 90#define DEFINE_TIMER(_name, _function, _expires, _data) \
88 struct timer_list _name = \ 91 struct timer_list _name = \
89 TIMER_INITIALIZER(_function, _expires, _data) 92 TIMER_INITIALIZER(_function, _expires, _data)
90 93
91void init_timer_key(struct timer_list *timer, 94void init_timer_key(struct timer_list *timer, unsigned int flags,
92 const char *name, 95 const char *name, struct lock_class_key *key);
93 struct lock_class_key *key); 96
94void init_timer_deferrable_key(struct timer_list *timer, 97#ifdef CONFIG_DEBUG_OBJECTS_TIMERS
95 const char *name, 98extern void init_timer_on_stack_key(struct timer_list *timer,
96 struct lock_class_key *key); 99 unsigned int flags, const char *name,
100 struct lock_class_key *key);
101extern void destroy_timer_on_stack(struct timer_list *timer);
102#else
103static inline void destroy_timer_on_stack(struct timer_list *timer) { }
104static inline void init_timer_on_stack_key(struct timer_list *timer,
105 unsigned int flags, const char *name,
106 struct lock_class_key *key)
107{
108 init_timer_key(timer, flags, name, key);
109}
110#endif
97 111
98#ifdef CONFIG_LOCKDEP 112#ifdef CONFIG_LOCKDEP
99#define init_timer(timer) \ 113#define __init_timer(_timer, _flags) \
100 do { \ 114 do { \
101 static struct lock_class_key __key; \ 115 static struct lock_class_key __key; \
102 init_timer_key((timer), #timer, &__key); \ 116 init_timer_key((_timer), (_flags), #_timer, &__key); \
103 } while (0) 117 } while (0)
104 118
105#define init_timer_deferrable(timer) \ 119#define __init_timer_on_stack(_timer, _flags) \
106 do { \ 120 do { \
107 static struct lock_class_key __key; \ 121 static struct lock_class_key __key; \
108 init_timer_deferrable_key((timer), #timer, &__key); \ 122 init_timer_on_stack_key((_timer), (_flags), #_timer, &__key); \
109 } while (0) 123 } while (0)
124#else
125#define __init_timer(_timer, _flags) \
126 init_timer_key((_timer), (_flags), NULL, NULL)
127#define __init_timer_on_stack(_timer, _flags) \
128 init_timer_on_stack_key((_timer), (_flags), NULL, NULL)
129#endif
110 130
131#define init_timer(timer) \
132 __init_timer((timer), 0)
133#define init_timer_deferrable(timer) \
134 __init_timer((timer), TIMER_DEFERRABLE)
111#define init_timer_on_stack(timer) \ 135#define init_timer_on_stack(timer) \
136 __init_timer_on_stack((timer), 0)
137
138#define __setup_timer(_timer, _fn, _data, _flags) \
112 do { \ 139 do { \
113 static struct lock_class_key __key; \ 140 __init_timer((_timer), (_flags)); \
114 init_timer_on_stack_key((timer), #timer, &__key); \ 141 (_timer)->function = (_fn); \
142 (_timer)->data = (_data); \
115 } while (0) 143 } while (0)
116 144
117#define setup_timer(timer, fn, data) \ 145#define __setup_timer_on_stack(_timer, _fn, _data, _flags) \
118 do { \ 146 do { \
119 static struct lock_class_key __key; \ 147 __init_timer_on_stack((_timer), (_flags)); \
120 setup_timer_key((timer), #timer, &__key, (fn), (data));\ 148 (_timer)->function = (_fn); \
149 (_timer)->data = (_data); \
121 } while (0) 150 } while (0)
122 151
152#define setup_timer(timer, fn, data) \
153 __setup_timer((timer), (fn), (data), 0)
123#define setup_timer_on_stack(timer, fn, data) \ 154#define setup_timer_on_stack(timer, fn, data) \
124 do { \ 155 __setup_timer_on_stack((timer), (fn), (data), 0)
125 static struct lock_class_key __key; \
126 setup_timer_on_stack_key((timer), #timer, &__key, \
127 (fn), (data)); \
128 } while (0)
129#define setup_deferrable_timer_on_stack(timer, fn, data) \ 156#define setup_deferrable_timer_on_stack(timer, fn, data) \
130 do { \ 157 __setup_timer_on_stack((timer), (fn), (data), TIMER_DEFERRABLE)
131 static struct lock_class_key __key; \
132 setup_deferrable_timer_on_stack_key((timer), #timer, \
133 &__key, (fn), \
134 (data)); \
135 } while (0)
136#else
137#define init_timer(timer)\
138 init_timer_key((timer), NULL, NULL)
139#define init_timer_deferrable(timer)\
140 init_timer_deferrable_key((timer), NULL, NULL)
141#define init_timer_on_stack(timer)\
142 init_timer_on_stack_key((timer), NULL, NULL)
143#define setup_timer(timer, fn, data)\
144 setup_timer_key((timer), NULL, NULL, (fn), (data))
145#define setup_timer_on_stack(timer, fn, data)\
146 setup_timer_on_stack_key((timer), NULL, NULL, (fn), (data))
147#define setup_deferrable_timer_on_stack(timer, fn, data)\
148 setup_deferrable_timer_on_stack_key((timer), NULL, NULL, (fn), (data))
149#endif
150
151#ifdef CONFIG_DEBUG_OBJECTS_TIMERS
152extern void init_timer_on_stack_key(struct timer_list *timer,
153 const char *name,
154 struct lock_class_key *key);
155extern void destroy_timer_on_stack(struct timer_list *timer);
156#else
157static inline void destroy_timer_on_stack(struct timer_list *timer) { }
158static inline void init_timer_on_stack_key(struct timer_list *timer,
159 const char *name,
160 struct lock_class_key *key)
161{
162 init_timer_key(timer, name, key);
163}
164#endif
165
166static inline void setup_timer_key(struct timer_list * timer,
167 const char *name,
168 struct lock_class_key *key,
169 void (*function)(unsigned long),
170 unsigned long data)
171{
172 timer->function = function;
173 timer->data = data;
174 init_timer_key(timer, name, key);
175}
176
177static inline void setup_timer_on_stack_key(struct timer_list *timer,
178 const char *name,
179 struct lock_class_key *key,
180 void (*function)(unsigned long),
181 unsigned long data)
182{
183 timer->function = function;
184 timer->data = data;
185 init_timer_on_stack_key(timer, name, key);
186}
187
188extern void setup_deferrable_timer_on_stack_key(struct timer_list *timer,
189 const char *name,
190 struct lock_class_key *key,
191 void (*function)(unsigned long),
192 unsigned long data);
193 158
194/** 159/**
195 * timer_pending - is a timer pending? 160 * timer_pending - is a timer pending?