/*
 * Called from run_local_timers in hardirq context every jiffy
 */
void hrtimer_run_queues(void)
{
 struct hrtimer_cpu_base *cpu_base = this_cpu_ptr(&hrtimer_bases);
 ktime_t now;
 if (__hrtimer_hres_active(cpu_base))
  return;
 /*
  * This _is_ ugly: We have to check periodically, whether we
  * can switch to highres and / or nohz mode. The clocksource
  * switch happens with xtime_lock held. Notification from
  * there only sets the check bit in the tick_oneshot code,
  * otherwise we might deadlock vs. xtime_lock.
  */
 if (tick_check_oneshot_change(!hrtimer_is_hres_enabled())) {
  hrtimer_switch_to_hres();
  return;
 }
 raw_spin_lock(&cpu_base->lock);
 now = hrtimer_update_base(cpu_base);
 __hrtimer_run_queues(cpu_base, now);
 raw_spin_unlock(&cpu_base->lock);
}

static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now)
{
 struct hrtimer_clock_base *base = cpu_base->clock_base;
 unsigned int active = cpu_base->active_bases;
 for (; active; base++, active >>= 1) {
  struct timerqueue_node *node;
  ktime_t basenow;
  if (!(active & 0x01))
   continue;
  basenow = ktime_add(now, base->offset);
  while ((node = timerqueue_getnext(&base->active))) {
   struct hrtimer *timer;
   timer = container_of(node, struct hrtimer, node);
   /*
    * The immediate goal for using the softexpires is
    * minimizing wakeups, not running timers at the
    * earliest interrupt after their soft expiration.
    * This allows us to avoid using a Priority Search
    * Tree, which can answer a stabbing querry for
    * overlapping intervals and instead use the simple
    * BST we already have.
    * We don't add extra wakeups by delaying timers that
    * are right-of a not yet expired timer, because that
    * timer will have to trigger a wakeup anyway.
    */
   if (basenow.tv64 < hrtimer_get_softexpires_tv64(timer))
    break;
   __run_hrtimer(cpu_base, base, timer, &basenow);
  }
 }
}


/*
 * The write_seqcount_barrier()s in __run_hrtimer() split the thing into 3
 * distinct sections:
 *
 *  - queued: the timer is queued
 *  - callback: the timer is being ran
 *  - post: the timer is inactive or (re)queued
 *
 * On the read side we ensure we observe timer->state and cpu_base->running
 * from the same section, if anything changed while we looked at it, we retry.
 * This includes timer->base changing because sequence numbers alone are
 * insufficient for that.
 *
 * The sequence numbers are required because otherwise we could still observe
 * a false negative if the read side got smeared over multiple consequtive
 * __run_hrtimer() invocations.
 */
static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base,
     struct hrtimer_clock_base *base,
     struct hrtimer *timer, ktime_t *now)
{
 enum hrtimer_restart (*fn)(struct hrtimer *);
 int restart;
 lockdep_assert_held(&cpu_base->lock);
 debug_deactivate(timer);
 cpu_base->running = timer;
 /*
  * Separate the ->running assignment from the ->state assignment.
  *
  * As with a regular write barrier, this ensures the read side in
  * hrtimer_active() cannot observe cpu_base->running == NULL &&
  * timer->state == INACTIVE.
  */
 raw_write_seqcount_barrier(&cpu_base->seq);
 __remove_hrtimer(timer, base, HRTIMER_STATE_INACTIVE, 0);
 timer_stats_account_hrtimer(timer);
 fn = timer->function;
 /*
  * Clear the 'is relative' flag for the TIME_LOW_RES case. If the
  * timer is restarted with a period then it becomes an absolute
  * timer. If its not restarted it does not matter.
  */
 if (IS_ENABLED(CONFIG_TIME_LOW_RES))
  timer->is_rel = false;
 /*
  * Because we run timers from hardirq context, there is no chance
  * they get migrated to another cpu, therefore its safe to unlock
  * the timer base.
  */
 raw_spin_unlock(&cpu_base->lock);
 trace_hrtimer_expire_entry(timer, now);
 restart = fn(timer);
 trace_hrtimer_expire_exit(timer);
 raw_spin_lock(&cpu_base->lock);
 /*
  * Note: We clear the running state after enqueue_hrtimer and
  * we do not reprogram the event hardware. Happens either in
  * hrtimer_start_range_ns() or in hrtimer_interrupt()
  *
  * Note: Because we dropped the cpu_base->lock above,
  * hrtimer_start_range_ns() can have popped in and enqueued the timer
  * for us already.
  */
 if (restart != HRTIMER_NORESTART &&
     !(timer->state & HRTIMER_STATE_ENQUEUED))
  enqueue_hrtimer(timer, base);
 /*
  * Separate the ->running assignment from the ->state assignment.
  *
  * As with a regular write barrier, this ensures the read side in
  * hrtimer_active() cannot observe cpu_base->running == NULL &&
  * timer->state == INACTIVE.
  */
 raw_write_seqcount_barrier(&cpu_base->seq);
 WARN_ON_ONCE(cpu_base->running != timer);
 cpu_base->running = NULL;
}