On Tue, Jul 08, 2014 at 04:10:47PM +0530, Viresh Kumar wrote:
hrtimer_start*() family never fails to enqueue a hrtimer to a clock-base. In case the hrtimer was in past and getting added on this_cpu's clock-base, we raise a softirq and exit.
At several places in the kernel, we try to make sure if hrtimer was added properly or not by calling hrtimer_active(), like:
hrtimer_start(timer, expires, mode); if (hrtimer_active(timer)) { /* Added successfully */ } else { /* Was added in the past */ }
As hrtimer_start*() never fails, hrtimer_active() is guaranteed to return 'true'. So, there is no point calling hrtimer_active().
Also this is done in while loop at several places, which isn't required if hrtimer_start*() never fails. Drop those loops as well.
This patch only updates tick-sched.c file currently, others will be fixed if above explanation holds true.
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org
Makes sense, assuming I'm not missing something obvious.
But you might want to add a WARN_ON_ONCE(!hrtimer_active(hrtimer)) on the end of these hrtimer_start common parts. In the end of __hrtimer_start_range_ns() maybe.
Thanks.
This was also raised here and didn't attract many: https://www.lkml.org/lkml/2014/7/3/559
Pushed here: git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/linux.git tick/remove-stale-hrtimer_active
kernel/time/tick-sched.c | 45 ++++++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 27 deletions(-)
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 6558b7a..66ca5ab 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -658,9 +658,7 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts, if (ts->nohz_mode == NOHZ_MODE_HIGHRES) { hrtimer_start(&ts->sched_timer, expires, HRTIMER_MODE_ABS_PINNED);
/* Check, if the timer was already in the past */
if (hrtimer_active(&ts->sched_timer))
goto out;
} else if (!tick_program_event(expires, 0)) goto out; /*goto out;
@@ -844,24 +842,25 @@ static void tick_nohz_restart(struct tick_sched *ts, ktime_t now) hrtimer_cancel(&ts->sched_timer); hrtimer_set_expires(&ts->sched_timer, ts->last_tick);
- while (1) {
/* Forward the time to expire in the future */
hrtimer_forward(&ts->sched_timer, now, tick_period);
- /* Forward the time to expire in the future */
- hrtimer_forward(&ts->sched_timer, now, tick_period);
if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
hrtimer_start_expires(&ts->sched_timer,
HRTIMER_MODE_ABS_PINNED);
/* Check, if the timer was already in the past */
if (hrtimer_active(&ts->sched_timer))
break;
} else {
if (!tick_program_event(
hrtimer_get_expires(&ts->sched_timer), 0))
break;
}
- if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
hrtimer_start_expires(&ts->sched_timer,
HRTIMER_MODE_ABS_PINNED);
return;
- }
- while (1) {
if (!tick_program_event(hrtimer_get_expires(&ts->sched_timer),
0))
/* Reread time and update jiffies */ now = ktime_get(); tick_do_update_jiffies64(now);break;
/* Forward the time to expire in the future */
}hrtimer_forward(&ts->sched_timer, now, tick_period);
} @@ -1104,7 +1103,6 @@ early_param("skew_tick", skew_tick); void tick_setup_sched_timer(void) { struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
- ktime_t now = ktime_get();
/* * Emulate tick processing via per-CPU hrtimers: @@ -1123,15 +1121,8 @@ void tick_setup_sched_timer(void) hrtimer_add_expires_ns(&ts->sched_timer, offset); }
- for (;;) {
hrtimer_forward(&ts->sched_timer, now, tick_period);
hrtimer_start_expires(&ts->sched_timer,
HRTIMER_MODE_ABS_PINNED);
/* Check, if the timer was already in the past */
if (hrtimer_active(&ts->sched_timer))
break;
now = ktime_get();
- }
- hrtimer_forward(&ts->sched_timer, ktime_get(), tick_period);
- hrtimer_start_expires(&ts->sched_timer, HRTIMER_MODE_ABS_PINNED);
#ifdef CONFIG_NO_HZ_COMMON if (tick_nohz_enabled) { -- 2.0.0.rc2