Merge branch 'timers-for-linus-urgent' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 9 Dec 2009 03:28:09 +0000 (19:28 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 9 Dec 2009 03:28:09 +0000 (19:28 -0800)
* '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

arch/ia64/kernel/time.c
arch/powerpc/kernel/time.c
arch/s390/kernel/time.c
arch/x86/kernel/vsyscall_64.c
include/linux/clocksource.h
include/linux/hrtimer.h
kernel/itimer.c
kernel/time/timekeeping.c

index 4990495d753189933bebf64f18d1f52303b6e6cd..a35c661e5e89a544b097f731af1e65486c3077c2 100644 (file)
@@ -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;
 
@@ -481,7 +481,7 @@ void update_vsyscall(struct timespec *wall, struct clocksource *c)
 
         /* copy fsyscall clock data */
         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_fsys_mmio = c->fsys_mmio;
         fsyscall_gtod_data.clk_cycle_last = c->cycle_last;
index d18a7f04edec5af925c97dbc46059ea4ce1f9776..674800b242d6167262178006c7f50afbe65c26ca 100644 (file)
@@ -834,7 +834,8 @@ static cycle_t timebase_read(struct clocksource *cs)
        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;
 
@@ -847,7 +848,7 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
 
        /* XXX this assumes clock->shift == 22 */
        /* 4611686018 ~= 2^(20+64-22) / 1e9 */
-       t2x = (u64) clock->mult * 4611686018ULL;
+       t2x = (u64) mult * 4611686018ULL;
        stamp_xsec = (u64) xtime.tv_nsec * XSEC_PER_SEC;
        do_div(stamp_xsec, 1000000000);
        stamp_xsec += (u64) xtime.tv_sec * XSEC_PER_SEC;
index 34162a0b2caa6483f397306cc3e21a457b83b051..68e1ecf5ebabf657a6c7e053577752dc69d6046b 100644 (file)
@@ -214,7 +214,8 @@ struct clocksource * __init clocksource_default_clock(void)
        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)
                return;
index e02d92d12bcd326f907f6751d3cb4024243913f6..9055e5872ff0a5afa668d1d7fa9517eeb6f618c8 100644 (file)
@@ -73,7 +73,8 @@ void update_vsyscall_tz(void)
        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;
 
@@ -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.cycle_last = clock->cycle_last;
        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.wall_time_sec = wall_time->tv_sec;
        vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec;
index 279c5478e8a6aaf7c4a6944166dcc22eb708d5ed..8a4a130cc19698ab8a03c6c6344e3b24f42932f8 100644 (file)
@@ -292,10 +292,12 @@ clocksource_calc_mult_shift(struct clocksource *cs, u32 freq, u32 minsec)
 }
 
 #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);
 #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)
 {
 }
 
index ff037f0b1b4e07a1ce5d9e5ca06efc8be147a00c..9bace4b9f4fe954717b0bf45c840c3fd794734f8 100644 (file)
@@ -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)
 {
-       if (likely(!timer->start_site))
+       if (likely(!timer_stats_active))
                return;
        timer_stats_update_stats(timer, timer->start_pid, timer->start_site,
                                 timer->function, timer->start_comm, 0);
@@ -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)
 {
-       if (likely(!timer_stats_active))
-               return;
        __timer_stats_hrtimer_set_start_info(timer, __builtin_return_address(0));
 }
 
index b03451ede5285822aa92f8be19f3247c80a93a92..d802883153da62210eea20e13f5f91170f67ebbf 100644 (file)
@@ -146,6 +146,7 @@ static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id,
 {
        cputime_t cval, nval, cinterval, ninterval;
        s64 ns_ninterval, ns_nval;
+       u32 error, incr_error;
        struct cpu_itimer *it = &tsk->signal->it[clock_id];
 
        nval = timeval_to_cputime(&value->it_value);
@@ -153,8 +154,8 @@ static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id,
        ninterval = timeval_to_cputime(&value->it_interval);
        ns_ninterval = timeval_to_ns(&value->it_interval);
 
-       it->incr_error = cputime_sub_ns(ninterval, ns_ninterval);
-       it->error = cputime_sub_ns(nval, ns_nval);
+       error = cputime_sub_ns(nval, ns_nval);
+       incr_error = cputime_sub_ns(ninterval, ns_ninterval);
 
        spin_lock_irq(&tsk->sighand->siglock);
 
@@ -168,6 +169,8 @@ static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id,
        }
        it->expires = nval;
        it->incr = ninterval;
+       it->error = error;
+       it->incr_error = incr_error;
        trace_itimer_state(clock_id == CPUCLOCK_VIRT ?
                           ITIMER_VIRTUAL : ITIMER_PROF, value, nval);
 
index d1aebd73b19146795a4589f6c38ffcf6268c0335..af4135f058254b0607fc2594f2c52ae6355e76b1 100644 (file)
@@ -170,7 +170,7 @@ void timekeeping_leap_insert(int leapsecond)
 {
        xtime.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
@@ -328,7 +328,7 @@ int do_settimeofday(struct timespec *tv)
        timekeeper.ntp_error = 0;
        ntp_clear();
 
-       update_vsyscall(&xtime, timekeeper.clock);
+       update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult);
 
        write_sequnlock_irqrestore(&xtime_lock, flags);
 
@@ -840,7 +840,7 @@ void update_wall_time(void)
                                timekeeper.ntp_error_shift;
 
        /* check to see if there is a new clocksource to use */
-       update_vsyscall(&xtime, timekeeper.clock);
+       update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult);
 }
 
 /**