aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/hrtimer.h2
-rw-r--r--kernel/hrtimer.c57
-rw-r--r--kernel/time/timekeeping.c128
-rw-r--r--kernel/timer.c24
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 */
56ktime_t ktime_get(void)
57{
58 struct timespec now;
59
60 ktime_get_ts(&now);
61
62 return timespec_to_ktime(now);
63}
64EXPORT_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 */
71ktime_t ktime_get_real(void)
72{
73 struct timespec now;
74
75 getnstimeofday(&now);
76
77 return timespec_to_ktime(now);
78}
79
80EXPORT_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 */
117void 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}
132EXPORT_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
126EXPORT_SYMBOL(getnstimeofday); 126EXPORT_SYMBOL(getnstimeofday);
127 127
128ktime_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}
157EXPORT_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 */
167void 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}
195EXPORT_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 */
225static inline void clocksource_forward_now(void) { } 294static inline void clocksource_forward_now(void) { }
226static inline void change_clocksource(void) { } 295static 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 */
302ktime_t ktime_get(void)
303{
304 struct timespec now;
305
306 ktime_get_ts(&now);
307
308 return timespec_to_ktime(now);
309}
310EXPORT_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 */
320void 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}
335EXPORT_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 */
343ktime_t ktime_get_real(void)
344{
345 struct timespec now;
346
347 getnstimeofday(&now);
348
349 return timespec_to_ktime(now);
350}
351EXPORT_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
668out_unlock: 675out_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 }
855out: 871out:
@@ -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}