On Tue, 31 Mar 2015, Viresh Kumar wrote:
@@ -1213,6 +1249,25 @@ static inline void __run_timers(struct tvec_base *base) call_timer_fn(timer, fn, data); spin_lock_irq(&base->lock); }
/*
* Handler running on this base, re-queued itself on
* another base ?
*/
if (unlikely(timer->base != base)) {
unsigned long flags;
struct tvec_base *tbase;
spin_unlock(&base->lock);
tbase = lock_timer_base(timer, &flags);
timer_clear_running(timer);
spin_unlock(&tbase->lock);
spin_lock(&base->lock);
} else {
timer_clear_running(timer);
}
And just for the record:
Dereferencing timer _AFTER_ the callback function is a big NONO. The callback function is allowed to free the timer. See the comment in call_timer_fn()
Oh well,
tglx