Commit fbf07eac authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'timers-for-linus-urgent' of...

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
parents 60d8ce2c 8629ea2e
...@@ -473,7 +473,7 @@ void update_vsyscall_tz(void) ...@@ -473,7 +473,7 @@ void update_vsyscall_tz(void)
{ {
} }
void update_vsyscall(struct timespec *wall, struct clocksource *c) void update_vsyscall(struct timespec *wall, struct clocksource *c, u32 mult)
{ {
unsigned long flags; unsigned long flags;
...@@ -481,7 +481,7 @@ void update_vsyscall(struct timespec *wall, struct clocksource *c) ...@@ -481,7 +481,7 @@ void update_vsyscall(struct timespec *wall, struct clocksource *c)
/* copy fsyscall clock data */ /* copy fsyscall clock data */
fsyscall_gtod_data.clk_mask = c->mask; fsyscall_gtod_data.clk_mask = c->mask;
fsyscall_gtod_data.clk_mult = c->mult; fsyscall_gtod_data.clk_mult = mult;
fsyscall_gtod_data.clk_shift = c->shift; fsyscall_gtod_data.clk_shift = c->shift;
fsyscall_gtod_data.clk_fsys_mmio = c->fsys_mmio; fsyscall_gtod_data.clk_fsys_mmio = c->fsys_mmio;
fsyscall_gtod_data.clk_cycle_last = c->cycle_last; fsyscall_gtod_data.clk_cycle_last = c->cycle_last;
......
...@@ -834,7 +834,8 @@ static cycle_t timebase_read(struct clocksource *cs) ...@@ -834,7 +834,8 @@ static cycle_t timebase_read(struct clocksource *cs)
return (cycle_t)get_tb(); return (cycle_t)get_tb();
} }
void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
u32 mult)
{ {
u64 t2x, stamp_xsec; u64 t2x, stamp_xsec;
...@@ -847,7 +848,7 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) ...@@ -847,7 +848,7 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
/* XXX this assumes clock->shift == 22 */ /* XXX this assumes clock->shift == 22 */
/* 4611686018 ~= 2^(20+64-22) / 1e9 */ /* 4611686018 ~= 2^(20+64-22) / 1e9 */
t2x = (u64) clock->mult * 4611686018ULL; t2x = (u64) mult * 4611686018ULL;
stamp_xsec = (u64) xtime.tv_nsec * XSEC_PER_SEC; stamp_xsec = (u64) xtime.tv_nsec * XSEC_PER_SEC;
do_div(stamp_xsec, 1000000000); do_div(stamp_xsec, 1000000000);
stamp_xsec += (u64) xtime.tv_sec * XSEC_PER_SEC; stamp_xsec += (u64) xtime.tv_sec * XSEC_PER_SEC;
......
...@@ -214,7 +214,8 @@ struct clocksource * __init clocksource_default_clock(void) ...@@ -214,7 +214,8 @@ struct clocksource * __init clocksource_default_clock(void)
return &clocksource_tod; return &clocksource_tod;
} }
void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
u32 mult)
{ {
if (clock != &clocksource_tod) if (clock != &clocksource_tod)
return; return;
......
...@@ -73,7 +73,8 @@ void update_vsyscall_tz(void) ...@@ -73,7 +73,8 @@ void update_vsyscall_tz(void)
write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags); write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags);
} }
void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
u32 mult)
{ {
unsigned long flags; unsigned long flags;
...@@ -82,7 +83,7 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) ...@@ -82,7 +83,7 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
vsyscall_gtod_data.clock.vread = clock->vread; vsyscall_gtod_data.clock.vread = clock->vread;
vsyscall_gtod_data.clock.cycle_last = clock->cycle_last; vsyscall_gtod_data.clock.cycle_last = clock->cycle_last;
vsyscall_gtod_data.clock.mask = clock->mask; vsyscall_gtod_data.clock.mask = clock->mask;
vsyscall_gtod_data.clock.mult = clock->mult; vsyscall_gtod_data.clock.mult = mult;
vsyscall_gtod_data.clock.shift = clock->shift; vsyscall_gtod_data.clock.shift = clock->shift;
vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec; vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec;
vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec; vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec;
......
...@@ -292,10 +292,12 @@ clocksource_calc_mult_shift(struct clocksource *cs, u32 freq, u32 minsec) ...@@ -292,10 +292,12 @@ clocksource_calc_mult_shift(struct clocksource *cs, u32 freq, u32 minsec)
} }
#ifdef CONFIG_GENERIC_TIME_VSYSCALL #ifdef CONFIG_GENERIC_TIME_VSYSCALL
extern void update_vsyscall(struct timespec *ts, struct clocksource *c); extern void
update_vsyscall(struct timespec *ts, struct clocksource *c, u32 mult);
extern void update_vsyscall_tz(void); extern void update_vsyscall_tz(void);
#else #else
static inline void update_vsyscall(struct timespec *ts, struct clocksource *c) static inline void
update_vsyscall(struct timespec *ts, struct clocksource *c, u32 mult)
{ {
} }
......
...@@ -446,7 +446,7 @@ extern void timer_stats_update_stats(void *timer, pid_t pid, void *startf, ...@@ -446,7 +446,7 @@ extern void timer_stats_update_stats(void *timer, pid_t pid, void *startf,
static inline void timer_stats_account_hrtimer(struct hrtimer *timer) static inline void timer_stats_account_hrtimer(struct hrtimer *timer)
{ {
if (likely(!timer->start_site)) if (likely(!timer_stats_active))
return; return;
timer_stats_update_stats(timer, timer->start_pid, timer->start_site, timer_stats_update_stats(timer, timer->start_pid, timer->start_site,
timer->function, timer->start_comm, 0); timer->function, timer->start_comm, 0);
...@@ -457,8 +457,6 @@ extern void __timer_stats_hrtimer_set_start_info(struct hrtimer *timer, ...@@ -457,8 +457,6 @@ extern void __timer_stats_hrtimer_set_start_info(struct hrtimer *timer,
static inline void timer_stats_hrtimer_set_start_info(struct hrtimer *timer) static inline void timer_stats_hrtimer_set_start_info(struct hrtimer *timer)
{ {
if (likely(!timer_stats_active))
return;
__timer_stats_hrtimer_set_start_info(timer, __builtin_return_address(0)); __timer_stats_hrtimer_set_start_info(timer, __builtin_return_address(0));
} }
......
...@@ -146,6 +146,7 @@ static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id, ...@@ -146,6 +146,7 @@ static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id,
{ {
cputime_t cval, nval, cinterval, ninterval; cputime_t cval, nval, cinterval, ninterval;
s64 ns_ninterval, ns_nval; s64 ns_ninterval, ns_nval;
u32 error, incr_error;
struct cpu_itimer *it = &tsk->signal->it[clock_id]; struct cpu_itimer *it = &tsk->signal->it[clock_id];
nval = timeval_to_cputime(&value->it_value); 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,8 +154,8 @@ static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id,
ninterval = timeval_to_cputime(&value->it_interval); ninterval = timeval_to_cputime(&value->it_interval);
ns_ninterval = timeval_to_ns(&value->it_interval); ns_ninterval = timeval_to_ns(&value->it_interval);
it->incr_error = cputime_sub_ns(ninterval, ns_ninterval); error = cputime_sub_ns(nval, ns_nval);
it->error = cputime_sub_ns(nval, ns_nval); incr_error = cputime_sub_ns(ninterval, ns_ninterval);
spin_lock_irq(&tsk->sighand->siglock); spin_lock_irq(&tsk->sighand->siglock);
...@@ -168,6 +169,8 @@ static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id, ...@@ -168,6 +169,8 @@ static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id,
} }
it->expires = nval; it->expires = nval;
it->incr = ninterval; it->incr = ninterval;
it->error = error;
it->incr_error = incr_error;
trace_itimer_state(clock_id == CPUCLOCK_VIRT ? trace_itimer_state(clock_id == CPUCLOCK_VIRT ?
ITIMER_VIRTUAL : ITIMER_PROF, value, nval); ITIMER_VIRTUAL : ITIMER_PROF, value, nval);
......
...@@ -170,7 +170,7 @@ void timekeeping_leap_insert(int leapsecond) ...@@ -170,7 +170,7 @@ void timekeeping_leap_insert(int leapsecond)
{ {
xtime.tv_sec += leapsecond; xtime.tv_sec += leapsecond;
wall_to_monotonic.tv_sec -= leapsecond; wall_to_monotonic.tv_sec -= leapsecond;
update_vsyscall(&xtime, timekeeper.clock); update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult);
} }
#ifdef CONFIG_GENERIC_TIME #ifdef CONFIG_GENERIC_TIME
...@@ -328,7 +328,7 @@ int do_settimeofday(struct timespec *tv) ...@@ -328,7 +328,7 @@ int do_settimeofday(struct timespec *tv)
timekeeper.ntp_error = 0; timekeeper.ntp_error = 0;
ntp_clear(); ntp_clear();
update_vsyscall(&xtime, timekeeper.clock); update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult);
write_sequnlock_irqrestore(&xtime_lock, flags); write_sequnlock_irqrestore(&xtime_lock, flags);
...@@ -840,7 +840,7 @@ void update_wall_time(void) ...@@ -840,7 +840,7 @@ void update_wall_time(void)
timekeeper.ntp_error_shift; timekeeper.ntp_error_shift;
/* check to see if there is a new clocksource to use */ /* check to see if there is a new clocksource to use */
update_vsyscall(&xtime, timekeeper.clock); update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult);
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment