--- x/kernel/time/hrtimer.c +++ y/kernel/time/hrtimer.c @@ -1647,6 +1647,8 @@ static void __run_hrtimer(struct hrtimer enum hrtimer_restart (*fn)(struct hrtimer *); bool expires_in_hardirq; int restart; + unsigned long jts; + ktime_t kts, kte; lockdep_assert_held(&cpu_base->lock); @@ -1678,16 +1680,24 @@ static void __run_hrtimer(struct hrtimer * protected against migration to a different CPU even if the lock * is dropped. */ + jts = jiffies + 20; + kts = hrtimer_update_base(cpu_base); + kts = ktime_add_ns(kts, jiffies_to_nsecs(20)); + raw_spin_unlock_irqrestore(&cpu_base->lock, flags); trace_hrtimer_expire_entry(timer, now); expires_in_hardirq = lockdep_hrtimer_enter(timer); restart = fn(timer); + WARN_ONCE(jiffies > jts, "jts hrtimer %pS runs more than 20 ticks\n", fn); + lockdep_hrtimer_exit(expires_in_hardirq); trace_hrtimer_expire_exit(timer); raw_spin_lock_irq(&cpu_base->lock); + kte = hrtimer_update_base(cpu_base); + WARN_ONCE(ktime_after(kte, kts), "kts hrtimer %pS runs more than 20 ticks\n", fn); /* * Note: We clear the running state after enqueue_hrtimer and * we do not reprogram the event hardware. Happens either in