Re: timers: Move clearing of base::timer_running under base::lock

From: Sebastian Andrzej Siewior
Date: Tue Dec 08 2020 - 03:51:50 EST


On 2020-12-07 08:06:48 [-0800], Paul E. McKenney wrote:
> > Yes, but it triggers frequently. Like `rcuc' is somehow is aligned with
> > the timeout.
>
> Given that a lot of RCU processing is event-driven based on timers,
> and given that the scheduling-clock interrupts are synchronized for
> energy-efficiency reasons on many configs, maybe this alignment is
> expected behavior?

No, it is the fact that rcu_preempt has a higher priority than
ksoftirqd. So immediately after the wakeup (of rcu_preempt) there is a
context switch and expire_timers() has this:

| raw_spin_unlock_irq(&base->lock);
| call_timer_fn(timer, fn, baseclk);
| raw_spin_lock_irq(&base->lock);
| base->running_timer = NULL;
| timer_sync_wait_running(base);

So ->running_timer isn't reset and try_to_del_timer_sync() (that
del_timer_sync() from schedule_timeout()) returns -1 and then the corner
case is handled where `expiry_lock' is acquired. So everything goes as
expected.

> Thanx, Paul

Sebastian