diff options
-rw-r--r-- | include/linux/timer.h | 16 | ||||
-rw-r--r-- | kernel/timer.c | 35 |
2 files changed, 36 insertions, 15 deletions
diff --git a/include/linux/timer.h b/include/linux/timer.h index 3f95c1fa615e..8c5a197e1587 100644 --- a/include/linux/timer.h +++ b/include/linux/timer.h | |||
@@ -49,18 +49,26 @@ 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 TIMER_DEFERRABLE 0x1LU | 68 | #define TIMER_DEFERRABLE 0x1LU |
69 | #define TIMER_IRQSAFE 0x2LU | ||
62 | 70 | ||
63 | #define TIMER_FLAG_MASK 0x1LU | 71 | #define TIMER_FLAG_MASK 0x3LU |
64 | 72 | ||
65 | #define __TIMER_INITIALIZER(_function, _expires, _data, _flags) { \ | 73 | #define __TIMER_INITIALIZER(_function, _expires, _data, _flags) { \ |
66 | .entry = { .prev = TIMER_ENTRY_STATIC }, \ | 74 | .entry = { .prev = TIMER_ENTRY_STATIC }, \ |
diff --git a/kernel/timer.c b/kernel/timer.c index 8d185a1677cc..706fe4c53e82 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -95,6 +95,11 @@ static inline unsigned int tbase_get_deferrable(struct tvec_base *base) | |||
95 | return ((unsigned int)(unsigned long)base & TIMER_DEFERRABLE); | 95 | return ((unsigned int)(unsigned long)base & TIMER_DEFERRABLE); |
96 | } | 96 | } |
97 | 97 | ||
98 | static inline unsigned int tbase_get_irqsafe(struct tvec_base *base) | ||
99 | { | ||
100 | return ((unsigned int)(unsigned long)base & TIMER_IRQSAFE); | ||
101 | } | ||
102 | |||
98 | static inline struct tvec_base *tbase_get_base(struct tvec_base *base) | 103 | static inline struct tvec_base *tbase_get_base(struct tvec_base *base) |
99 | { | 104 | { |
100 | return ((struct tvec_base *)((unsigned long)base & ~TIMER_FLAG_MASK)); | 105 | return ((struct tvec_base *)((unsigned long)base & ~TIMER_FLAG_MASK)); |
@@ -1002,14 +1007,14 @@ EXPORT_SYMBOL(try_to_del_timer_sync); | |||
1002 | * | 1007 | * |
1003 | * Synchronization rules: Callers must prevent restarting of the timer, | 1008 | * Synchronization rules: Callers must prevent restarting of the timer, |
1004 | * otherwise this function is meaningless. It must not be called from | 1009 | * otherwise this function is meaningless. It must not be called from |
1005 | * interrupt contexts. The caller must not hold locks which would prevent | 1010 | * interrupt contexts unless the timer is an irqsafe one. The caller must |
1006 | * completion of the timer's handler. The timer's handler must not call | 1011 | * not hold locks which would prevent completion of the timer's |
1007 | * add_timer_on(). Upon exit the timer is not queued and the handler is | 1012 | * handler. The timer's handler must not call add_timer_on(). Upon exit the |
1008 | * not running on any CPU. | 1013 | * timer is not queued and the handler is not running on any CPU. |
1009 | * | 1014 | * |
1010 | * Note: You must not hold locks that are held in interrupt context | 1015 | * Note: For !irqsafe timers, you must not hold locks that are held in |
1011 | * while calling this function. Even if the lock has nothing to do | 1016 | * interrupt context while calling this function. Even if the lock has |
1012 | * with the timer in question. Here's why: | 1017 | * nothing to do with the timer in question. Here's why: |
1013 | * | 1018 | * |
1014 | * CPU0 CPU1 | 1019 | * CPU0 CPU1 |
1015 | * ---- ---- | 1020 | * ---- ---- |
@@ -1046,7 +1051,7 @@ int del_timer_sync(struct timer_list *timer) | |||
1046 | * don't use it in hardirq context, because it | 1051 | * don't use it in hardirq context, because it |
1047 | * could lead to deadlock. | 1052 | * could lead to deadlock. |
1048 | */ | 1053 | */ |
1049 | WARN_ON(in_irq()); | 1054 | WARN_ON(in_irq() && !tbase_get_irqsafe(timer->base)); |
1050 | for (;;) { | 1055 | for (;;) { |
1051 | int ret = try_to_del_timer_sync(timer); | 1056 | int ret = try_to_del_timer_sync(timer); |
1052 | if (ret >= 0) | 1057 | if (ret >= 0) |
@@ -1153,19 +1158,27 @@ static inline void __run_timers(struct tvec_base *base) | |||
1153 | while (!list_empty(head)) { | 1158 | while (!list_empty(head)) { |
1154 | void (*fn)(unsigned long); | 1159 | void (*fn)(unsigned long); |
1155 | unsigned long data; | 1160 | unsigned long data; |
1161 | bool irqsafe; | ||
1156 | 1162 | ||
1157 | timer = list_first_entry(head, struct timer_list,entry); | 1163 | timer = list_first_entry(head, struct timer_list,entry); |
1158 | fn = timer->function; | 1164 | fn = timer->function; |
1159 | data = timer->data; | 1165 | data = timer->data; |
1166 | irqsafe = tbase_get_irqsafe(timer->base); | ||
1160 | 1167 | ||
1161 | timer_stats_account_timer(timer); | 1168 | timer_stats_account_timer(timer); |
1162 | 1169 | ||
1163 | base->running_timer = timer; | 1170 | base->running_timer = timer; |
1164 | detach_expired_timer(timer, base); | 1171 | detach_expired_timer(timer, base); |
1165 | 1172 | ||
1166 | spin_unlock_irq(&base->lock); | 1173 | if (irqsafe) { |
1167 | call_timer_fn(timer, fn, data); | 1174 | spin_unlock(&base->lock); |
1168 | spin_lock_irq(&base->lock); | 1175 | call_timer_fn(timer, fn, data); |
1176 | spin_lock(&base->lock); | ||
1177 | } else { | ||
1178 | spin_unlock_irq(&base->lock); | ||
1179 | call_timer_fn(timer, fn, data); | ||
1180 | spin_lock_irq(&base->lock); | ||
1181 | } | ||
1169 | } | 1182 | } |
1170 | } | 1183 | } |
1171 | base->running_timer = NULL; | 1184 | base->running_timer = NULL; |