summaryrefslogtreecommitdiff
path: root/include/linux/timer.h
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2003-08-14 10:07:00 -0700
committerLinus Torvalds <torvalds@home.osdl.org>2003-08-14 10:07:00 -0700
commitc49d806049638d278c3d0cdc8d30d770fca183ce (patch)
tree87770f90fc0cdcf227bf4f98448f017292fdfd01 /include/linux/timer.h
parent752274c9ef15215e1c9e7855450203326fdc3644 (diff)
[PATCH] timer race fixes
From: Ingo Molnar <mingo@elte.hu> It unifies the functionality of add_timer() and mod_timer(), and makes any combination of the timer API calls completely SMP-safe. del_timer() is still not using the timer lock. this patch fixes the only timer bug in 2.6 i'm aware of: the del_timer_sync() + add_timer() combination in kernel/itimer.c is buggy. This was correct code in 2.4, because there it was safe to do an add_timer() from the timer handler itself, parallel to a del_timer_sync(). If we want to make this safe in 2.6 too (which i think we want to) then we have to make add_timer() almost equivalent to mod_timer(), locking-wise. And once we are at this point i think it's much cleaner to actually make add_timer() a variant of mod_timer(). (There's no locking cost for add_timer(), only the cost of an extra branch. And we've removed another commonly used function from the icache.)
Diffstat (limited to 'include/linux/timer.h')
-rw-r--r--include/linux/timer.h23
1 files changed, 21 insertions, 2 deletions
diff --git a/include/linux/timer.h b/include/linux/timer.h
index d98c9a948aa7..e8f79ea49c74 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -60,11 +60,30 @@ static inline int timer_pending(const struct timer_list * timer)
return timer->base != NULL;
}
-extern void add_timer(struct timer_list * timer);
extern void add_timer_on(struct timer_list *timer, int cpu);
extern int del_timer(struct timer_list * timer);
+extern int __mod_timer(struct timer_list *timer, unsigned long expires);
extern int mod_timer(struct timer_list *timer, unsigned long expires);
-
+
+/***
+ * add_timer - start a timer
+ * @timer: the timer to be added
+ *
+ * The kernel will do a ->function(->data) callback from the
+ * timer interrupt at the ->expired point in the future. The
+ * current time is 'jiffies'.
+ *
+ * The timer's ->expired, ->function (and if the handler uses it, ->data)
+ * fields must be set prior calling this function.
+ *
+ * Timers with an ->expired field in the past will be executed in the next
+ * timer tick.
+ */
+static inline void add_timer(struct timer_list * timer)
+{
+ __mod_timer(timer, timer->expires);
+}
+
#ifdef CONFIG_SMP
extern int del_timer_sync(struct timer_list * timer);
#else