diff options
-rw-r--r-- | include/linux/hrtimer.h | 2 | ||||
-rw-r--r-- | kernel/hrtimer.c | 57 | ||||
-rw-r--r-- | kernel/time/timekeeping.c | 128 | ||||
-rw-r--r-- | kernel/timer.c | 24 |
4 files changed, 149 insertions, 62 deletions
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 4759917adc71..ff037f0b1b4e 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h | |||
@@ -91,7 +91,6 @@ enum hrtimer_restart { | |||
91 | * @function: timer expiry callback function | 91 | * @function: timer expiry callback function |
92 | * @base: pointer to the timer base (per cpu and per clock) | 92 | * @base: pointer to the timer base (per cpu and per clock) |
93 | * @state: state information (See bit values above) | 93 | * @state: state information (See bit values above) |
94 | * @cb_entry: list head to enqueue an expired timer into the callback list | ||
95 | * @start_site: timer statistics field to store the site where the timer | 94 | * @start_site: timer statistics field to store the site where the timer |
96 | * was started | 95 | * was started |
97 | * @start_comm: timer statistics field to store the name of the process which | 96 | * @start_comm: timer statistics field to store the name of the process which |
@@ -108,7 +107,6 @@ struct hrtimer { | |||
108 | enum hrtimer_restart (*function)(struct hrtimer *); | 107 | enum hrtimer_restart (*function)(struct hrtimer *); |
109 | struct hrtimer_clock_base *base; | 108 | struct hrtimer_clock_base *base; |
110 | unsigned long state; | 109 | unsigned long state; |
111 | struct list_head cb_entry; | ||
112 | #ifdef CONFIG_TIMER_STATS | 110 | #ifdef CONFIG_TIMER_STATS |
113 | int start_pid; | 111 | int start_pid; |
114 | void *start_site; | 112 | void *start_site; |
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 49da79ab8486..e2f91ecc01a8 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
@@ -48,37 +48,6 @@ | |||
48 | 48 | ||
49 | #include <asm/uaccess.h> | 49 | #include <asm/uaccess.h> |
50 | 50 | ||
51 | /** | ||
52 | * ktime_get - get the monotonic time in ktime_t format | ||
53 | * | ||
54 | * returns the time in ktime_t format | ||
55 | */ | ||
56 | ktime_t ktime_get(void) | ||
57 | { | ||
58 | struct timespec now; | ||
59 | |||
60 | ktime_get_ts(&now); | ||
61 | |||
62 | return timespec_to_ktime(now); | ||
63 | } | ||
64 | EXPORT_SYMBOL_GPL(ktime_get); | ||
65 | |||
66 | /** | ||
67 | * ktime_get_real - get the real (wall-) time in ktime_t format | ||
68 | * | ||
69 | * returns the time in ktime_t format | ||
70 | */ | ||
71 | ktime_t ktime_get_real(void) | ||
72 | { | ||
73 | struct timespec now; | ||
74 | |||
75 | getnstimeofday(&now); | ||
76 | |||
77 | return timespec_to_ktime(now); | ||
78 | } | ||
79 | |||
80 | EXPORT_SYMBOL_GPL(ktime_get_real); | ||
81 | |||
82 | /* | 51 | /* |
83 | * The timer bases: | 52 | * The timer bases: |
84 | * | 53 | * |
@@ -106,31 +75,6 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) = | |||
106 | } | 75 | } |
107 | }; | 76 | }; |
108 | 77 | ||
109 | /** | ||
110 | * ktime_get_ts - get the monotonic clock in timespec format | ||
111 | * @ts: pointer to timespec variable | ||
112 | * | ||
113 | * The function calculates the monotonic clock from the realtime | ||
114 | * clock and the wall_to_monotonic offset and stores the result | ||
115 | * in normalized timespec format in the variable pointed to by @ts. | ||
116 | */ | ||
117 | void ktime_get_ts(struct timespec *ts) | ||
118 | { | ||
119 | struct timespec tomono; | ||
120 | unsigned long seq; | ||
121 | |||
122 | do { | ||
123 | seq = read_seqbegin(&xtime_lock); | ||
124 | getnstimeofday(ts); | ||
125 | tomono = wall_to_monotonic; | ||
126 | |||
127 | } while (read_seqretry(&xtime_lock, seq)); | ||
128 | |||
129 | set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec, | ||
130 | ts->tv_nsec + tomono.tv_nsec); | ||
131 | } | ||
132 | EXPORT_SYMBOL_GPL(ktime_get_ts); | ||
133 | |||
134 | /* | 78 | /* |
135 | * Get the coarse grained time at the softirq based on xtime and | 79 | * Get the coarse grained time at the softirq based on xtime and |
136 | * wall_to_monotonic. | 80 | * wall_to_monotonic. |
@@ -1154,7 +1098,6 @@ static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id, | |||
1154 | clock_id = CLOCK_MONOTONIC; | 1098 | clock_id = CLOCK_MONOTONIC; |
1155 | 1099 | ||
1156 | timer->base = &cpu_base->clock_base[clock_id]; | 1100 | timer->base = &cpu_base->clock_base[clock_id]; |
1157 | INIT_LIST_HEAD(&timer->cb_entry); | ||
1158 | hrtimer_init_timer_hres(timer); | 1101 | hrtimer_init_timer_hres(timer); |
1159 | 1102 | ||
1160 | #ifdef CONFIG_TIMER_STATS | 1103 | #ifdef CONFIG_TIMER_STATS |
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index e8c77d9c633a..02c0b2c9c674 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -125,6 +125,75 @@ void getnstimeofday(struct timespec *ts) | |||
125 | 125 | ||
126 | EXPORT_SYMBOL(getnstimeofday); | 126 | EXPORT_SYMBOL(getnstimeofday); |
127 | 127 | ||
128 | ktime_t ktime_get(void) | ||
129 | { | ||
130 | cycle_t cycle_now, cycle_delta; | ||
131 | unsigned int seq; | ||
132 | s64 secs, nsecs; | ||
133 | |||
134 | WARN_ON(timekeeping_suspended); | ||
135 | |||
136 | do { | ||
137 | seq = read_seqbegin(&xtime_lock); | ||
138 | secs = xtime.tv_sec + wall_to_monotonic.tv_sec; | ||
139 | nsecs = xtime.tv_nsec + wall_to_monotonic.tv_nsec; | ||
140 | |||
141 | /* read clocksource: */ | ||
142 | cycle_now = clocksource_read(clock); | ||
143 | |||
144 | /* calculate the delta since the last update_wall_time: */ | ||
145 | cycle_delta = (cycle_now - clock->cycle_last) & clock->mask; | ||
146 | |||
147 | /* convert to nanoseconds: */ | ||
148 | nsecs += cyc2ns(clock, cycle_delta); | ||
149 | |||
150 | } while (read_seqretry(&xtime_lock, seq)); | ||
151 | /* | ||
152 | * Use ktime_set/ktime_add_ns to create a proper ktime on | ||
153 | * 32-bit architectures without CONFIG_KTIME_SCALAR. | ||
154 | */ | ||
155 | return ktime_add_ns(ktime_set(secs, 0), nsecs); | ||
156 | } | ||
157 | EXPORT_SYMBOL_GPL(ktime_get); | ||
158 | |||
159 | /** | ||
160 | * ktime_get_ts - get the monotonic clock in timespec format | ||
161 | * @ts: pointer to timespec variable | ||
162 | * | ||
163 | * The function calculates the monotonic clock from the realtime | ||
164 | * clock and the wall_to_monotonic offset and stores the result | ||
165 | * in normalized timespec format in the variable pointed to by @ts. | ||
166 | */ | ||
167 | void ktime_get_ts(struct timespec *ts) | ||
168 | { | ||
169 | cycle_t cycle_now, cycle_delta; | ||
170 | struct timespec tomono; | ||
171 | unsigned int seq; | ||
172 | s64 nsecs; | ||
173 | |||
174 | WARN_ON(timekeeping_suspended); | ||
175 | |||
176 | do { | ||
177 | seq = read_seqbegin(&xtime_lock); | ||
178 | *ts = xtime; | ||
179 | tomono = wall_to_monotonic; | ||
180 | |||
181 | /* read clocksource: */ | ||
182 | cycle_now = clocksource_read(clock); | ||
183 | |||
184 | /* calculate the delta since the last update_wall_time: */ | ||
185 | cycle_delta = (cycle_now - clock->cycle_last) & clock->mask; | ||
186 | |||
187 | /* convert to nanoseconds: */ | ||
188 | nsecs = cyc2ns(clock, cycle_delta); | ||
189 | |||
190 | } while (read_seqretry(&xtime_lock, seq)); | ||
191 | |||
192 | set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec, | ||
193 | ts->tv_nsec + tomono.tv_nsec + nsecs); | ||
194 | } | ||
195 | EXPORT_SYMBOL_GPL(ktime_get_ts); | ||
196 | |||
128 | /** | 197 | /** |
129 | * do_gettimeofday - Returns the time of day in a timeval | 198 | * do_gettimeofday - Returns the time of day in a timeval |
130 | * @tv: pointer to the timeval to be set | 199 | * @tv: pointer to the timeval to be set |
@@ -221,10 +290,65 @@ static void change_clocksource(void) | |||
221 | clock->name); | 290 | clock->name); |
222 | */ | 291 | */ |
223 | } | 292 | } |
224 | #else | 293 | #else /* GENERIC_TIME */ |
225 | static inline void clocksource_forward_now(void) { } | 294 | static inline void clocksource_forward_now(void) { } |
226 | static inline void change_clocksource(void) { } | 295 | static inline void change_clocksource(void) { } |
227 | #endif | 296 | |
297 | /** | ||
298 | * ktime_get - get the monotonic time in ktime_t format | ||
299 | * | ||
300 | * returns the time in ktime_t format | ||
301 | */ | ||
302 | ktime_t ktime_get(void) | ||
303 | { | ||
304 | struct timespec now; | ||
305 | |||
306 | ktime_get_ts(&now); | ||
307 | |||
308 | return timespec_to_ktime(now); | ||
309 | } | ||
310 | EXPORT_SYMBOL_GPL(ktime_get); | ||
311 | |||
312 | /** | ||
313 | * ktime_get_ts - get the monotonic clock in timespec format | ||
314 | * @ts: pointer to timespec variable | ||
315 | * | ||
316 | * The function calculates the monotonic clock from the realtime | ||
317 | * clock and the wall_to_monotonic offset and stores the result | ||
318 | * in normalized timespec format in the variable pointed to by @ts. | ||
319 | */ | ||
320 | void ktime_get_ts(struct timespec *ts) | ||
321 | { | ||
322 | struct timespec tomono; | ||
323 | unsigned long seq; | ||
324 | |||
325 | do { | ||
326 | seq = read_seqbegin(&xtime_lock); | ||
327 | getnstimeofday(ts); | ||
328 | tomono = wall_to_monotonic; | ||
329 | |||
330 | } while (read_seqretry(&xtime_lock, seq)); | ||
331 | |||
332 | set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec, | ||
333 | ts->tv_nsec + tomono.tv_nsec); | ||
334 | } | ||
335 | EXPORT_SYMBOL_GPL(ktime_get_ts); | ||
336 | #endif /* !GENERIC_TIME */ | ||
337 | |||
338 | /** | ||
339 | * ktime_get_real - get the real (wall-) time in ktime_t format | ||
340 | * | ||
341 | * returns the time in ktime_t format | ||
342 | */ | ||
343 | ktime_t ktime_get_real(void) | ||
344 | { | ||
345 | struct timespec now; | ||
346 | |||
347 | getnstimeofday(&now); | ||
348 | |||
349 | return timespec_to_ktime(now); | ||
350 | } | ||
351 | EXPORT_SYMBOL_GPL(ktime_get_real); | ||
228 | 352 | ||
229 | /** | 353 | /** |
230 | * getrawmonotonic - Returns the raw monotonic time in a timespec | 354 | * getrawmonotonic - Returns the raw monotonic time in a timespec |
diff --git a/kernel/timer.c b/kernel/timer.c index a7f07d5a6241..33fc9d175f40 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -72,6 +72,7 @@ struct tvec_base { | |||
72 | spinlock_t lock; | 72 | spinlock_t lock; |
73 | struct timer_list *running_timer; | 73 | struct timer_list *running_timer; |
74 | unsigned long timer_jiffies; | 74 | unsigned long timer_jiffies; |
75 | unsigned long next_timer; | ||
75 | struct tvec_root tv1; | 76 | struct tvec_root tv1; |
76 | struct tvec tv2; | 77 | struct tvec tv2; |
77 | struct tvec tv3; | 78 | struct tvec tv3; |
@@ -622,6 +623,9 @@ __mod_timer(struct timer_list *timer, unsigned long expires, | |||
622 | 623 | ||
623 | if (timer_pending(timer)) { | 624 | if (timer_pending(timer)) { |
624 | detach_timer(timer, 0); | 625 | detach_timer(timer, 0); |
626 | if (timer->expires == base->next_timer && | ||
627 | !tbase_get_deferrable(timer->base)) | ||
628 | base->next_timer = base->timer_jiffies; | ||
625 | ret = 1; | 629 | ret = 1; |
626 | } else { | 630 | } else { |
627 | if (pending_only) | 631 | if (pending_only) |
@@ -663,6 +667,9 @@ __mod_timer(struct timer_list *timer, unsigned long expires, | |||
663 | } | 667 | } |
664 | 668 | ||
665 | timer->expires = expires; | 669 | timer->expires = expires; |
670 | if (time_before(timer->expires, base->next_timer) && | ||
671 | !tbase_get_deferrable(timer->base)) | ||
672 | base->next_timer = timer->expires; | ||
666 | internal_add_timer(base, timer); | 673 | internal_add_timer(base, timer); |
667 | 674 | ||
668 | out_unlock: | 675 | out_unlock: |
@@ -781,6 +788,9 @@ void add_timer_on(struct timer_list *timer, int cpu) | |||
781 | spin_lock_irqsave(&base->lock, flags); | 788 | spin_lock_irqsave(&base->lock, flags); |
782 | timer_set_base(timer, base); | 789 | timer_set_base(timer, base); |
783 | debug_timer_activate(timer); | 790 | debug_timer_activate(timer); |
791 | if (time_before(timer->expires, base->next_timer) && | ||
792 | !tbase_get_deferrable(timer->base)) | ||
793 | base->next_timer = timer->expires; | ||
784 | internal_add_timer(base, timer); | 794 | internal_add_timer(base, timer); |
785 | /* | 795 | /* |
786 | * Check whether the other CPU is idle and needs to be | 796 | * Check whether the other CPU is idle and needs to be |
@@ -817,6 +827,9 @@ int del_timer(struct timer_list *timer) | |||
817 | base = lock_timer_base(timer, &flags); | 827 | base = lock_timer_base(timer, &flags); |
818 | if (timer_pending(timer)) { | 828 | if (timer_pending(timer)) { |
819 | detach_timer(timer, 1); | 829 | detach_timer(timer, 1); |
830 | if (timer->expires == base->next_timer && | ||
831 | !tbase_get_deferrable(timer->base)) | ||
832 | base->next_timer = base->timer_jiffies; | ||
820 | ret = 1; | 833 | ret = 1; |
821 | } | 834 | } |
822 | spin_unlock_irqrestore(&base->lock, flags); | 835 | spin_unlock_irqrestore(&base->lock, flags); |
@@ -850,6 +863,9 @@ int try_to_del_timer_sync(struct timer_list *timer) | |||
850 | ret = 0; | 863 | ret = 0; |
851 | if (timer_pending(timer)) { | 864 | if (timer_pending(timer)) { |
852 | detach_timer(timer, 1); | 865 | detach_timer(timer, 1); |
866 | if (timer->expires == base->next_timer && | ||
867 | !tbase_get_deferrable(timer->base)) | ||
868 | base->next_timer = base->timer_jiffies; | ||
853 | ret = 1; | 869 | ret = 1; |
854 | } | 870 | } |
855 | out: | 871 | out: |
@@ -1134,7 +1150,9 @@ unsigned long get_next_timer_interrupt(unsigned long now) | |||
1134 | unsigned long expires; | 1150 | unsigned long expires; |
1135 | 1151 | ||
1136 | spin_lock(&base->lock); | 1152 | spin_lock(&base->lock); |
1137 | expires = __next_timer_interrupt(base); | 1153 | if (time_before_eq(base->next_timer, base->timer_jiffies)) |
1154 | base->next_timer = __next_timer_interrupt(base); | ||
1155 | expires = base->next_timer; | ||
1138 | spin_unlock(&base->lock); | 1156 | spin_unlock(&base->lock); |
1139 | 1157 | ||
1140 | if (time_before_eq(expires, now)) | 1158 | if (time_before_eq(expires, now)) |
@@ -1523,6 +1541,7 @@ static int __cpuinit init_timers_cpu(int cpu) | |||
1523 | INIT_LIST_HEAD(base->tv1.vec + j); | 1541 | INIT_LIST_HEAD(base->tv1.vec + j); |
1524 | 1542 | ||
1525 | base->timer_jiffies = jiffies; | 1543 | base->timer_jiffies = jiffies; |
1544 | base->next_timer = base->timer_jiffies; | ||
1526 | return 0; | 1545 | return 0; |
1527 | } | 1546 | } |
1528 | 1547 | ||
@@ -1535,6 +1554,9 @@ static void migrate_timer_list(struct tvec_base *new_base, struct list_head *hea | |||
1535 | timer = list_first_entry(head, struct timer_list, entry); | 1554 | timer = list_first_entry(head, struct timer_list, entry); |
1536 | detach_timer(timer, 0); | 1555 | detach_timer(timer, 0); |
1537 | timer_set_base(timer, new_base); | 1556 | timer_set_base(timer, new_base); |
1557 | if (time_before(timer->expires, new_base->next_timer) && | ||
1558 | !tbase_get_deferrable(timer->base)) | ||
1559 | new_base->next_timer = timer->expires; | ||
1538 | internal_add_timer(new_base, timer); | 1560 | internal_add_timer(new_base, timer); |
1539 | } | 1561 | } |
1540 | } | 1562 | } |