100 lines
3.8 KiB
Diff
100 lines
3.8 KiB
Diff
From: Anna-Maria Gleixner <anna-maria@linutronix.de>
|
|
Date: Sun, 22 Oct 2017 23:39:54 +0200
|
|
Subject: [PATCH 16/36] hrtimer: Make hrtimer_cpu_base.next_timer handling
|
|
unconditional
|
|
Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/4.14/older/patches-4.14.1-rt3.tar.xz
|
|
|
|
hrtimer_cpu_base.next_timer stores the pointer to the next expiring timer
|
|
in a cpu base.
|
|
|
|
This pointer cannot be dereferenced and is solely used to check whether a
|
|
hrtimer which is removed is the hrtimer which is the first to expire in the
|
|
CPU base. If this is the case, then the timer hardware needs to be
|
|
reprogrammed to avoid an extra interrupt for nothing.
|
|
|
|
Again, this is conditional functionality, but there is no compelling reason
|
|
to make this conditional. As a preparation, hrtimer_cpu_base.next_timer
|
|
needs to be available unconditonal. Aside of that the upcoming support for
|
|
softirq based hrtimers requires access to this pointer unconditionally.
|
|
|
|
Make the update of hrtimer_cpu_base.next_timer unconditional and remove the
|
|
ifdef cruft. The impact on CONFIG_HIGH_RES_TIMERS=n && CONFIG_NOHZ=n is
|
|
marginal as it's just a store on an already dirtied cacheline.
|
|
|
|
No functional change.
|
|
|
|
Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>
|
|
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
|
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
|
---
|
|
include/linux/hrtimer.h | 4 ++--
|
|
kernel/time/hrtimer.c | 12 ++----------
|
|
2 files changed, 4 insertions(+), 12 deletions(-)
|
|
|
|
--- a/include/linux/hrtimer.h
|
|
+++ b/include/linux/hrtimer.h
|
|
@@ -164,13 +164,13 @@ enum hrtimer_base_type {
|
|
* @hres_active: State of high resolution mode
|
|
* @in_hrtirq: hrtimer_interrupt() is currently executing
|
|
* @hang_detected: The last hrtimer interrupt detected a hang
|
|
- * @next_timer: Pointer to the first expiring timer
|
|
* @nr_events: Total number of hrtimer interrupt events
|
|
* @nr_retries: Total number of hrtimer interrupt retries
|
|
* @nr_hangs: Total number of hrtimer interrupt hangs
|
|
* @max_hang_time: Maximum time spent in hrtimer_interrupt
|
|
* @expires_next: absolute time of the next event, is required for remote
|
|
* hrtimer enqueue
|
|
+ * @next_timer: Pointer to the first expiring timer
|
|
* @clock_base: array of clock bases for this cpu
|
|
*
|
|
* Note: next_timer is just an optimization for __remove_hrtimer().
|
|
@@ -186,13 +186,13 @@ struct hrtimer_cpu_base {
|
|
#ifdef CONFIG_HIGH_RES_TIMERS
|
|
unsigned int in_hrtirq : 1,
|
|
hang_detected : 1;
|
|
- struct hrtimer *next_timer;
|
|
unsigned int nr_events;
|
|
unsigned short nr_retries;
|
|
unsigned short nr_hangs;
|
|
unsigned int max_hang_time;
|
|
#endif
|
|
ktime_t expires_next;
|
|
+ struct hrtimer *next_timer;
|
|
struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES];
|
|
} ____cacheline_aligned;
|
|
|
|
--- a/kernel/time/hrtimer.c
|
|
+++ b/kernel/time/hrtimer.c
|
|
@@ -459,21 +459,13 @@ static struct hrtimer_clock_base *
|
|
while ((base = __next_base((cpu_base), &(active))))
|
|
|
|
#if defined(CONFIG_NO_HZ_COMMON) || defined(CONFIG_HIGH_RES_TIMERS)
|
|
-static inline void hrtimer_update_next_timer(struct hrtimer_cpu_base *cpu_base,
|
|
- struct hrtimer *timer)
|
|
-{
|
|
-#ifdef CONFIG_HIGH_RES_TIMERS
|
|
- cpu_base->next_timer = timer;
|
|
-#endif
|
|
-}
|
|
-
|
|
static ktime_t __hrtimer_get_next_event(struct hrtimer_cpu_base *cpu_base)
|
|
{
|
|
struct hrtimer_clock_base *base;
|
|
unsigned int active = cpu_base->active_bases;
|
|
ktime_t expires, expires_next = KTIME_MAX;
|
|
|
|
- hrtimer_update_next_timer(cpu_base, NULL);
|
|
+ cpu_base->next_timer = NULL;
|
|
for_each_active_base(base, cpu_base, active) {
|
|
struct timerqueue_node *next;
|
|
struct hrtimer *timer;
|
|
@@ -483,7 +475,7 @@ static ktime_t __hrtimer_get_next_event(
|
|
expires = ktime_sub(hrtimer_get_expires(timer), base->offset);
|
|
if (expires < expires_next) {
|
|
expires_next = expires;
|
|
- hrtimer_update_next_timer(cpu_base, timer);
|
|
+ cpu_base->next_timer = timer;
|
|
}
|
|
}
|
|
/*
|