Skip to content

Commit

Permalink
hrtimer: Consolidate reprogramming code
Browse files Browse the repository at this point in the history
This code is mostly duplicated. The redudant store in the force reprogram
case does no harm and the in hrtimer interrupt condition cannot be true for
the force reprogram invocations.

Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20210713135158.054424875@linutronix.de
  • Loading branch information
Peter Zijlstra authored and Thomas Gleixner committed Aug 10, 2021
1 parent 627ef5a commit b14bca9
Showing 1 changed file with 29 additions and 43 deletions.
72 changes: 29 additions & 43 deletions kernel/time/hrtimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -652,21 +652,24 @@ static inline int hrtimer_hres_active(void)
return __hrtimer_hres_active(this_cpu_ptr(&hrtimer_bases));
}

/*
* Reprogram the event source with checking both queues for the
* next event
* Called with interrupts disabled and base->lock held
*/
static void
hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal)
__hrtimer_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal,
struct hrtimer *next_timer, ktime_t expires_next)
{
ktime_t expires_next;
/*
* If the hrtimer interrupt is running, then it will reevaluate the
* clock bases and reprogram the clock event device.
*/
if (cpu_base->in_hrtirq)
return;

expires_next = hrtimer_update_next_event(cpu_base);
if (expires_next > cpu_base->expires_next)
return;

if (skip_equal && expires_next == cpu_base->expires_next)
return;

cpu_base->next_timer = next_timer;
cpu_base->expires_next = expires_next;

/*
Expand All @@ -689,7 +692,23 @@ hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal)
if (!__hrtimer_hres_active(cpu_base) || cpu_base->hang_detected)
return;

tick_program_event(cpu_base->expires_next, 1);
tick_program_event(expires_next, 1);
}

/*
* Reprogram the event source with checking both queues for the
* next event
* Called with interrupts disabled and base->lock held
*/
static void
hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal)
{
ktime_t expires_next;

expires_next = hrtimer_update_next_event(cpu_base);

__hrtimer_reprogram(cpu_base, skip_equal, cpu_base->next_timer,
expires_next);
}

/* High resolution timer related functions */
Expand Down Expand Up @@ -835,40 +854,7 @@ static void hrtimer_reprogram(struct hrtimer *timer, bool reprogram)
if (base->cpu_base != cpu_base)
return;

/*
* If the hrtimer interrupt is running, then it will
* reevaluate the clock bases and reprogram the clock event
* device. The callbacks are always executed in hard interrupt
* context so we don't need an extra check for a running
* callback.
*/
if (cpu_base->in_hrtirq)
return;

if (expires >= cpu_base->expires_next)
return;

/* Update the pointer to the next expiring timer */
cpu_base->next_timer = timer;
cpu_base->expires_next = expires;

/*
* If hres is not active, hardware does not have to be
* programmed yet.
*
* If a hang was detected in the last timer interrupt then we
* do not schedule a timer which is earlier than the expiry
* which we enforced in the hang detection. We want the system
* to make progress.
*/
if (!__hrtimer_hres_active(cpu_base) || cpu_base->hang_detected)
return;

/*
* Program the timer hardware. We enforce the expiry for
* events which are already in the past.
*/
tick_program_event(expires, 1);
__hrtimer_reprogram(cpu_base, true, timer, expires);
}

/*
Expand Down

0 comments on commit b14bca9

Please sign in to comment.