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.h57
1 files changed, 53 insertions, 4 deletions
diff --git a/include/linux/timer.h b/include/linux/timer.h
index a2d1eb6cb3f0..6abd9138beda 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -10,17 +10,23 @@
10struct tvec_base; 10struct tvec_base;
11 11
12struct timer_list { 12struct timer_list {
13 /*
14 * All fields that change during normal runtime grouped to the
15 * same cacheline
16 */
13 struct list_head entry; 17 struct list_head entry;
14 unsigned long expires; 18 unsigned long expires;
19 struct tvec_base *base;
15 20
16 void (*function)(unsigned long); 21 void (*function)(unsigned long);
17 unsigned long data; 22 unsigned long data;
18 23
19 struct tvec_base *base; 24 int slack;
25
20#ifdef CONFIG_TIMER_STATS 26#ifdef CONFIG_TIMER_STATS
27 int start_pid;
21 void *start_site; 28 void *start_site;
22 char start_comm[16]; 29 char start_comm[16];
23 int start_pid;
24#endif 30#endif
25#ifdef CONFIG_LOCKDEP 31#ifdef CONFIG_LOCKDEP
26 struct lockdep_map lockdep_map; 32 struct lockdep_map lockdep_map;
@@ -42,12 +48,38 @@ extern struct tvec_base boot_tvec_bases;
42#define __TIMER_LOCKDEP_MAP_INITIALIZER(_kn) 48#define __TIMER_LOCKDEP_MAP_INITIALIZER(_kn)
43#endif 49#endif
44 50
51/*
52 * Note that all tvec_bases are 2 byte aligned and lower bit of
53 * base in timer_list is guaranteed to be zero. Use the LSB to
54 * indicate whether the timer is deferrable.
55 *
56 * 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,
58 * the timer will be serviced when the CPU eventually wakes up with a
59 * subsequent non-deferrable timer.
60 */
61#define TBASE_DEFERRABLE_FLAG (0x1)
62
45#define TIMER_INITIALIZER(_function, _expires, _data) { \ 63#define TIMER_INITIALIZER(_function, _expires, _data) { \
46 .entry = { .prev = TIMER_ENTRY_STATIC }, \ 64 .entry = { .prev = TIMER_ENTRY_STATIC }, \
47 .function = (_function), \ 65 .function = (_function), \
48 .expires = (_expires), \ 66 .expires = (_expires), \
49 .data = (_data), \ 67 .data = (_data), \
50 .base = &boot_tvec_bases, \ 68 .base = &boot_tvec_bases, \
69 .slack = -1, \
70 __TIMER_LOCKDEP_MAP_INITIALIZER( \
71 __FILE__ ":" __stringify(__LINE__)) \
72 }
73
74#define TBASE_MAKE_DEFERRED(ptr) ((struct tvec_base *) \
75 ((unsigned char *)(ptr) + TBASE_DEFERRABLE_FLAG))
76
77#define TIMER_DEFERRED_INITIALIZER(_function, _expires, _data) {\
78 .entry = { .prev = TIMER_ENTRY_STATIC }, \
79 .function = (_function), \
80 .expires = (_expires), \
81 .data = (_data), \
82 .base = TBASE_MAKE_DEFERRED(&boot_tvec_bases), \
51 __TIMER_LOCKDEP_MAP_INITIALIZER( \ 83 __TIMER_LOCKDEP_MAP_INITIALIZER( \
52 __FILE__ ":" __stringify(__LINE__)) \ 84 __FILE__ ":" __stringify(__LINE__)) \
53 } 85 }
@@ -94,6 +126,13 @@ void init_timer_deferrable_key(struct timer_list *timer,
94 setup_timer_on_stack_key((timer), #timer, &__key, \ 126 setup_timer_on_stack_key((timer), #timer, &__key, \
95 (fn), (data)); \ 127 (fn), (data)); \
96 } while (0) 128 } while (0)
129#define setup_deferrable_timer_on_stack(timer, fn, data) \
130 do { \
131 static struct lock_class_key __key; \
132 setup_deferrable_timer_on_stack_key((timer), #timer, \
133 &__key, (fn), \
134 (data)); \
135 } while (0)
97#else 136#else
98#define init_timer(timer)\ 137#define init_timer(timer)\
99 init_timer_key((timer), NULL, NULL) 138 init_timer_key((timer), NULL, NULL)
@@ -105,6 +144,8 @@ void init_timer_deferrable_key(struct timer_list *timer,
105 setup_timer_key((timer), NULL, NULL, (fn), (data)) 144 setup_timer_key((timer), NULL, NULL, (fn), (data))
106#define setup_timer_on_stack(timer, fn, data)\ 145#define setup_timer_on_stack(timer, fn, data)\
107 setup_timer_on_stack_key((timer), NULL, NULL, (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))
108#endif 149#endif
109 150
110#ifdef CONFIG_DEBUG_OBJECTS_TIMERS 151#ifdef CONFIG_DEBUG_OBJECTS_TIMERS
@@ -144,6 +185,12 @@ static inline void setup_timer_on_stack_key(struct timer_list *timer,
144 init_timer_on_stack_key(timer, name, key); 185 init_timer_on_stack_key(timer, name, key);
145} 186}
146 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
147/** 194/**
148 * timer_pending - is a timer pending? 195 * timer_pending - is a timer pending?
149 * @timer: the timer in question 196 * @timer: the timer in question
@@ -165,6 +212,8 @@ extern int mod_timer(struct timer_list *timer, unsigned long expires);
165extern int mod_timer_pending(struct timer_list *timer, unsigned long expires); 212extern int mod_timer_pending(struct timer_list *timer, unsigned long expires);
166extern int mod_timer_pinned(struct timer_list *timer, unsigned long expires); 213extern int mod_timer_pinned(struct timer_list *timer, unsigned long expires);
167 214
215extern void set_timer_slack(struct timer_list *time, int slack_hz);
216
168#define TIMER_NOT_PINNED 0 217#define TIMER_NOT_PINNED 0
169#define TIMER_PINNED 1 218#define TIMER_PINNED 1
170/* 219/*
@@ -225,11 +274,11 @@ static inline void timer_stats_timer_clear_start_info(struct timer_list *timer)
225 274
226extern void add_timer(struct timer_list *timer); 275extern void add_timer(struct timer_list *timer);
227 276
277extern int try_to_del_timer_sync(struct timer_list *timer);
278
228#ifdef CONFIG_SMP 279#ifdef CONFIG_SMP
229 extern int try_to_del_timer_sync(struct timer_list *timer);
230 extern int del_timer_sync(struct timer_list *timer); 280 extern int del_timer_sync(struct timer_list *timer);
231#else 281#else
232# define try_to_del_timer_sync(t) del_timer(t)
233# define del_timer_sync(t) del_timer(t) 282# define del_timer_sync(t) del_timer(t)
234#endif 283#endif
235 284