diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-08 22:28:09 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-08 22:28:09 -0500 |
commit | fbf07eac7bf21c262143194181bd97c5d18b8ceb (patch) | |
tree | c9228b7d272f1e39472da28032605ecd1860e688 | |
parent | 60d8ce2cd6c283132928c11f3fd57ff4187287e0 (diff) | |
parent | 8629ea2eaba8ca0de2e38ce1b4a825e16255976e (diff) |
Merge branch 'timers-for-linus-urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'timers-for-linus-urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
hrtimer: Fix /proc/timer_list regression
itimers: Fix racy writes to cpu_itimer fields
timekeeping: Fix clock_gettime vsyscall time warp
-rw-r--r-- | arch/ia64/kernel/time.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/time.c | 5 | ||||
-rw-r--r-- | arch/s390/kernel/time.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/vsyscall_64.c | 5 | ||||
-rw-r--r-- | include/linux/clocksource.h | 6 | ||||
-rw-r--r-- | include/linux/hrtimer.h | 4 | ||||
-rw-r--r-- | kernel/itimer.c | 7 | ||||
-rw-r--r-- | kernel/time/timekeeping.c | 6 |
8 files changed, 23 insertions, 17 deletions
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 4990495d7531..a35c661e5e89 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c | |||
@@ -473,7 +473,7 @@ void update_vsyscall_tz(void) | |||
473 | { | 473 | { |
474 | } | 474 | } |
475 | 475 | ||
476 | void update_vsyscall(struct timespec *wall, struct clocksource *c) | 476 | void update_vsyscall(struct timespec *wall, struct clocksource *c, u32 mult) |
477 | { | 477 | { |
478 | unsigned long flags; | 478 | unsigned long flags; |
479 | 479 | ||
@@ -481,7 +481,7 @@ void update_vsyscall(struct timespec *wall, struct clocksource *c) | |||
481 | 481 | ||
482 | /* copy fsyscall clock data */ | 482 | /* copy fsyscall clock data */ |
483 | fsyscall_gtod_data.clk_mask = c->mask; | 483 | fsyscall_gtod_data.clk_mask = c->mask; |
484 | fsyscall_gtod_data.clk_mult = c->mult; | 484 | fsyscall_gtod_data.clk_mult = mult; |
485 | fsyscall_gtod_data.clk_shift = c->shift; | 485 | fsyscall_gtod_data.clk_shift = c->shift; |
486 | fsyscall_gtod_data.clk_fsys_mmio = c->fsys_mmio; | 486 | fsyscall_gtod_data.clk_fsys_mmio = c->fsys_mmio; |
487 | fsyscall_gtod_data.clk_cycle_last = c->cycle_last; | 487 | fsyscall_gtod_data.clk_cycle_last = c->cycle_last; |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index d18a7f04edec..674800b242d6 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -834,7 +834,8 @@ static cycle_t timebase_read(struct clocksource *cs) | |||
834 | return (cycle_t)get_tb(); | 834 | return (cycle_t)get_tb(); |
835 | } | 835 | } |
836 | 836 | ||
837 | void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) | 837 | void update_vsyscall(struct timespec *wall_time, struct clocksource *clock, |
838 | u32 mult) | ||
838 | { | 839 | { |
839 | u64 t2x, stamp_xsec; | 840 | u64 t2x, stamp_xsec; |
840 | 841 | ||
@@ -847,7 +848,7 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) | |||
847 | 848 | ||
848 | /* XXX this assumes clock->shift == 22 */ | 849 | /* XXX this assumes clock->shift == 22 */ |
849 | /* 4611686018 ~= 2^(20+64-22) / 1e9 */ | 850 | /* 4611686018 ~= 2^(20+64-22) / 1e9 */ |
850 | t2x = (u64) clock->mult * 4611686018ULL; | 851 | t2x = (u64) mult * 4611686018ULL; |
851 | stamp_xsec = (u64) xtime.tv_nsec * XSEC_PER_SEC; | 852 | stamp_xsec = (u64) xtime.tv_nsec * XSEC_PER_SEC; |
852 | do_div(stamp_xsec, 1000000000); | 853 | do_div(stamp_xsec, 1000000000); |
853 | stamp_xsec += (u64) xtime.tv_sec * XSEC_PER_SEC; | 854 | stamp_xsec += (u64) xtime.tv_sec * XSEC_PER_SEC; |
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 34162a0b2caa..68e1ecf5ebab 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c | |||
@@ -214,7 +214,8 @@ struct clocksource * __init clocksource_default_clock(void) | |||
214 | return &clocksource_tod; | 214 | return &clocksource_tod; |
215 | } | 215 | } |
216 | 216 | ||
217 | void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) | 217 | void update_vsyscall(struct timespec *wall_time, struct clocksource *clock, |
218 | u32 mult) | ||
218 | { | 219 | { |
219 | if (clock != &clocksource_tod) | 220 | if (clock != &clocksource_tod) |
220 | return; | 221 | return; |
diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c index e02d92d12bcd..9055e5872ff0 100644 --- a/arch/x86/kernel/vsyscall_64.c +++ b/arch/x86/kernel/vsyscall_64.c | |||
@@ -73,7 +73,8 @@ void update_vsyscall_tz(void) | |||
73 | write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags); | 73 | write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags); |
74 | } | 74 | } |
75 | 75 | ||
76 | void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) | 76 | void update_vsyscall(struct timespec *wall_time, struct clocksource *clock, |
77 | u32 mult) | ||
77 | { | 78 | { |
78 | unsigned long flags; | 79 | unsigned long flags; |
79 | 80 | ||
@@ -82,7 +83,7 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) | |||
82 | vsyscall_gtod_data.clock.vread = clock->vread; | 83 | vsyscall_gtod_data.clock.vread = clock->vread; |
83 | vsyscall_gtod_data.clock.cycle_last = clock->cycle_last; | 84 | vsyscall_gtod_data.clock.cycle_last = clock->cycle_last; |
84 | vsyscall_gtod_data.clock.mask = clock->mask; | 85 | vsyscall_gtod_data.clock.mask = clock->mask; |
85 | vsyscall_gtod_data.clock.mult = clock->mult; | 86 | vsyscall_gtod_data.clock.mult = mult; |
86 | vsyscall_gtod_data.clock.shift = clock->shift; | 87 | vsyscall_gtod_data.clock.shift = clock->shift; |
87 | vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec; | 88 | vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec; |
88 | vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec; | 89 | vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec; |
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index 279c5478e8a6..8a4a130cc196 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h | |||
@@ -292,10 +292,12 @@ clocksource_calc_mult_shift(struct clocksource *cs, u32 freq, u32 minsec) | |||
292 | } | 292 | } |
293 | 293 | ||
294 | #ifdef CONFIG_GENERIC_TIME_VSYSCALL | 294 | #ifdef CONFIG_GENERIC_TIME_VSYSCALL |
295 | extern void update_vsyscall(struct timespec *ts, struct clocksource *c); | 295 | extern void |
296 | update_vsyscall(struct timespec *ts, struct clocksource *c, u32 mult); | ||
296 | extern void update_vsyscall_tz(void); | 297 | extern void update_vsyscall_tz(void); |
297 | #else | 298 | #else |
298 | static inline void update_vsyscall(struct timespec *ts, struct clocksource *c) | 299 | static inline void |
300 | update_vsyscall(struct timespec *ts, struct clocksource *c, u32 mult) | ||
299 | { | 301 | { |
300 | } | 302 | } |
301 | 303 | ||
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index ff037f0b1b4e..9bace4b9f4fe 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h | |||
@@ -446,7 +446,7 @@ extern void timer_stats_update_stats(void *timer, pid_t pid, void *startf, | |||
446 | 446 | ||
447 | static inline void timer_stats_account_hrtimer(struct hrtimer *timer) | 447 | static inline void timer_stats_account_hrtimer(struct hrtimer *timer) |
448 | { | 448 | { |
449 | if (likely(!timer->start_site)) | 449 | if (likely(!timer_stats_active)) |
450 | return; | 450 | return; |
451 | timer_stats_update_stats(timer, timer->start_pid, timer->start_site, | 451 | timer_stats_update_stats(timer, timer->start_pid, timer->start_site, |
452 | timer->function, timer->start_comm, 0); | 452 | timer->function, timer->start_comm, 0); |
@@ -457,8 +457,6 @@ extern void __timer_stats_hrtimer_set_start_info(struct hrtimer *timer, | |||
457 | 457 | ||
458 | static inline void timer_stats_hrtimer_set_start_info(struct hrtimer *timer) | 458 | static inline void timer_stats_hrtimer_set_start_info(struct hrtimer *timer) |
459 | { | 459 | { |
460 | if (likely(!timer_stats_active)) | ||
461 | return; | ||
462 | __timer_stats_hrtimer_set_start_info(timer, __builtin_return_address(0)); | 460 | __timer_stats_hrtimer_set_start_info(timer, __builtin_return_address(0)); |
463 | } | 461 | } |
464 | 462 | ||
diff --git a/kernel/itimer.c b/kernel/itimer.c index b03451ede528..d802883153da 100644 --- a/kernel/itimer.c +++ b/kernel/itimer.c | |||
@@ -146,6 +146,7 @@ static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id, | |||
146 | { | 146 | { |
147 | cputime_t cval, nval, cinterval, ninterval; | 147 | cputime_t cval, nval, cinterval, ninterval; |
148 | s64 ns_ninterval, ns_nval; | 148 | s64 ns_ninterval, ns_nval; |
149 | u32 error, incr_error; | ||
149 | struct cpu_itimer *it = &tsk->signal->it[clock_id]; | 150 | struct cpu_itimer *it = &tsk->signal->it[clock_id]; |
150 | 151 | ||
151 | nval = timeval_to_cputime(&value->it_value); | 152 | nval = timeval_to_cputime(&value->it_value); |
@@ -153,8 +154,8 @@ static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id, | |||
153 | ninterval = timeval_to_cputime(&value->it_interval); | 154 | ninterval = timeval_to_cputime(&value->it_interval); |
154 | ns_ninterval = timeval_to_ns(&value->it_interval); | 155 | ns_ninterval = timeval_to_ns(&value->it_interval); |
155 | 156 | ||
156 | it->incr_error = cputime_sub_ns(ninterval, ns_ninterval); | 157 | error = cputime_sub_ns(nval, ns_nval); |
157 | it->error = cputime_sub_ns(nval, ns_nval); | 158 | incr_error = cputime_sub_ns(ninterval, ns_ninterval); |
158 | 159 | ||
159 | spin_lock_irq(&tsk->sighand->siglock); | 160 | spin_lock_irq(&tsk->sighand->siglock); |
160 | 161 | ||
@@ -168,6 +169,8 @@ static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id, | |||
168 | } | 169 | } |
169 | it->expires = nval; | 170 | it->expires = nval; |
170 | it->incr = ninterval; | 171 | it->incr = ninterval; |
172 | it->error = error; | ||
173 | it->incr_error = incr_error; | ||
171 | trace_itimer_state(clock_id == CPUCLOCK_VIRT ? | 174 | trace_itimer_state(clock_id == CPUCLOCK_VIRT ? |
172 | ITIMER_VIRTUAL : ITIMER_PROF, value, nval); | 175 | ITIMER_VIRTUAL : ITIMER_PROF, value, nval); |
173 | 176 | ||
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index d1aebd73b191..af4135f05825 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -170,7 +170,7 @@ void timekeeping_leap_insert(int leapsecond) | |||
170 | { | 170 | { |
171 | xtime.tv_sec += leapsecond; | 171 | xtime.tv_sec += leapsecond; |
172 | wall_to_monotonic.tv_sec -= leapsecond; | 172 | wall_to_monotonic.tv_sec -= leapsecond; |
173 | update_vsyscall(&xtime, timekeeper.clock); | 173 | update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult); |
174 | } | 174 | } |
175 | 175 | ||
176 | #ifdef CONFIG_GENERIC_TIME | 176 | #ifdef CONFIG_GENERIC_TIME |
@@ -328,7 +328,7 @@ int do_settimeofday(struct timespec *tv) | |||
328 | timekeeper.ntp_error = 0; | 328 | timekeeper.ntp_error = 0; |
329 | ntp_clear(); | 329 | ntp_clear(); |
330 | 330 | ||
331 | update_vsyscall(&xtime, timekeeper.clock); | 331 | update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult); |
332 | 332 | ||
333 | write_sequnlock_irqrestore(&xtime_lock, flags); | 333 | write_sequnlock_irqrestore(&xtime_lock, flags); |
334 | 334 | ||
@@ -840,7 +840,7 @@ void update_wall_time(void) | |||
840 | timekeeper.ntp_error_shift; | 840 | timekeeper.ntp_error_shift; |
841 | 841 | ||
842 | /* check to see if there is a new clocksource to use */ | 842 | /* check to see if there is a new clocksource to use */ |
843 | update_vsyscall(&xtime, timekeeper.clock); | 843 | update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult); |
844 | } | 844 | } |
845 | 845 | ||
846 | /** | 846 | /** |