From: Roman Zippel Pass current time to hrtimer_forward(). This allows to use the softirq time in the timer base when the forward function is called from the timer callback. Other places pass current time with a call to timer->base->get_time(). Signed-off-by: Roman Zippel Signed-off-by: Thomas Gleixner Signed-off-by: Andrew Morton --- include/linux/hrtimer.h | 3 ++- kernel/hrtimer.c | 7 +++---- kernel/itimer.c | 3 ++- kernel/posix-timers.c | 14 ++++++++++---- 4 files changed, 17 insertions(+), 10 deletions(-) diff -puN include/linux/hrtimer.h~pass-current-time-to-hrtimer_forward include/linux/hrtimer.h --- devel/include/linux/hrtimer.h~pass-current-time-to-hrtimer_forward 2006-03-12 03:37:12.000000000 -0800 +++ devel-akpm/include/linux/hrtimer.h 2006-03-12 03:37:12.000000000 -0800 @@ -130,7 +130,8 @@ static inline int hrtimer_active(const s } /* Forward a hrtimer so it expires after now: */ -extern unsigned long hrtimer_forward(struct hrtimer *timer, ktime_t interval); +extern unsigned long +hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval); /* Precise sleep: */ extern long hrtimer_nanosleep(struct timespec *rqtp, diff -puN kernel/hrtimer.c~pass-current-time-to-hrtimer_forward kernel/hrtimer.c --- devel/kernel/hrtimer.c~pass-current-time-to-hrtimer_forward 2006-03-12 03:37:12.000000000 -0800 +++ devel-akpm/kernel/hrtimer.c 2006-03-12 03:37:12.000000000 -0800 @@ -301,18 +301,17 @@ void unlock_hrtimer_base(const struct hr * hrtimer_forward - forward the timer expiry * * @timer: hrtimer to forward + * @now: forward past this time * @interval: the interval to forward * * Forward the timer expiry so it will expire in the future. * Returns the number of overruns. */ unsigned long -hrtimer_forward(struct hrtimer *timer, ktime_t interval) +hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval) { unsigned long orun = 1; - ktime_t delta, now; - - now = timer->base->get_time(); + ktime_t delta; delta = ktime_sub(now, timer->expires); diff -puN kernel/itimer.c~pass-current-time-to-hrtimer_forward kernel/itimer.c --- devel/kernel/itimer.c~pass-current-time-to-hrtimer_forward 2006-03-12 03:37:12.000000000 -0800 +++ devel-akpm/kernel/itimer.c 2006-03-12 03:37:12.000000000 -0800 @@ -136,7 +136,8 @@ int it_real_fn(void *data) if (tsk->signal->it_real_incr.tv64 != 0) { hrtimer_forward(&tsk->signal->real_timer, - tsk->signal->it_real_incr); + tsk->signal->real_timer.base->softirq_time, + tsk->signal->it_real_incr); return HRTIMER_RESTART; } diff -puN kernel/posix-timers.c~pass-current-time-to-hrtimer_forward kernel/posix-timers.c --- devel/kernel/posix-timers.c~pass-current-time-to-hrtimer_forward 2006-03-12 03:37:12.000000000 -0800 +++ devel-akpm/kernel/posix-timers.c 2006-03-12 03:37:12.000000000 -0800 @@ -251,15 +251,18 @@ __initcall(init_posix_timers); static void schedule_next_timer(struct k_itimer *timr) { + struct hrtimer *timer = &timr->it.real.timer; + if (timr->it.real.interval.tv64 == 0) return; - timr->it_overrun += hrtimer_forward(&timr->it.real.timer, + timr->it_overrun += hrtimer_forward(timer, timer->base->get_time(), timr->it.real.interval); + timr->it_overrun_last = timr->it_overrun; timr->it_overrun = -1; ++timr->it_requeue_pending; - hrtimer_restart(&timr->it.real.timer); + hrtimer_restart(timer); } /* @@ -334,6 +337,7 @@ EXPORT_SYMBOL_GPL(posix_timer_event); static int posix_timer_fn(void *data) { struct k_itimer *timr = data; + struct hrtimer *timer = &timr->it.real.timer; unsigned long flags; int si_private = 0; int ret = HRTIMER_NORESTART; @@ -351,7 +355,8 @@ static int posix_timer_fn(void *data) */ if (timr->it.real.interval.tv64 != 0) { timr->it_overrun += - hrtimer_forward(&timr->it.real.timer, + hrtimer_forward(timer, + timer->base->softirq_time, timr->it.real.interval); ret = HRTIMER_RESTART; } @@ -622,7 +627,8 @@ common_timer_get(struct k_itimer *timr, if (timr->it_requeue_pending & REQUEUE_PENDING || (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE) { timr->it_overrun += - hrtimer_forward(timer, timr->it.real.interval); + hrtimer_forward(timer, timer->base->get_time(), + timr->it.real.interval); remaining = hrtimer_get_remaining(timer); } calci: _