Re: [PATCH v10 03/20] timers: Move marking timer bases idle into tick_nohz_stop_tick()

Frederic Weisbecker
2024-01-22T21:49:27Z

Le Mon, Jan 22, 2024 at 12:45:03PM +0100, Anna-Maria Behnsen a écrit :
> Frederic Weisbecker <frederic@kernel.org> writes:
>
> > Le Mon, Jan 15, 2024 at 03:37:26PM +0100, Anna-Maria Behnsen a écrit :
> >> @@ -889,12 +884,41 @@ static ktime_t tick_nohz_next_event(struct tick_sched *ts, int cpu)
> >> static void tick_nohz_stop_tick(struct tick_sched *ts, int cpu)
> >> {
> >> struct clock_event_device *dev = __this_cpu_read(tick_cpu_device.evtdev);
> >> + unsigned long basejiff = ts->last_jiffies;
> >> u64 basemono = ts->timer_expires_base;
> >> - u64 expires = ts->timer_expires;
> >> + bool timer_idle;
> >> + u64 expires;
> >>
> >> /* Make sure we won't be trying to stop it twice in a row. */
> >> ts->timer_expires_base = 0;
> >>
> >> + /*
> >> + * Now the tick should be stopped definitely - so the timer base needs
> >> + * to be marked idle as well to not miss a newly queued timer.
> >> + */
> >> + expires = timer_base_try_to_set_idle(basejiff, basemono, &timer_idle);
> >> + if (!timer_idle) {
> >> + /*
> >> + * Do not clear tick_stopped here when it was already set - it
> >
> > Can that really happen? Looking at __get_next_timer_interrupt(), you're making a
> > behavioural change: if base->is_idle was previously set and the next timer is
> > now below/equal a jiffy, base->is_idle is not going to be cleared by
> > __get_next_timer_interrupt().
> >
> > Therefore you shouldn't observe ts->tick_stopped && !timer_idle
> >
> > But I'm assuming that behavioural change wasn't intended?
>
> It was intended to keep tick_stopped and base->is_idle in sync. So when
> tick_stopped is set also base->is_idle needs to be set and dropping it
> before tick_stopped is dropped will break the plan to keep it in sync.

Ok that sounds good.

Thanks!