]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
hrtimer: Make hrtimer_cpu_base.next_timer handling unconditional
authorAnna-Maria Gleixner <anna-maria@linutronix.de>
Thu, 21 Dec 2017 10:41:45 +0000 (11:41 +0100)
committerIngo Molnar <mingo@kernel.org>
Tue, 16 Jan 2018 01:35:47 +0000 (02:35 +0100)
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 unconditonally.

Aside of that the upcoming support for softirq based hrtimers requires access
to this pointer unconditionally as well, so our motivation is not entirely
simplicity based.

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>
Cc: Christoph Hellwig <hch@lst.de>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: keescook@chromium.org
Link: http://lkml.kernel.org/r/20171221104205.7269-17-anna-maria@linutronix.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
include/linux/hrtimer.h
kernel/time/hrtimer.c

index bb7270e8bc3734d285b538bd73a6e4bc5b128253..2d3e1d678a4d7144cb4b7ec00c8f7161bd3c8b16 100644 (file)
@@ -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;
 
index a9ab67f3e5d5a4704b24b1f0e7aa5676eedd014d..26abaa7b041930573b7bafe02baf012265aff2d5 100644 (file)
@@ -459,21 +459,13 @@ __next_base(struct hrtimer_cpu_base *cpu_base, unsigned int *active)
        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(struct hrtimer_cpu_base *cpu_base)
                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;
                }
        }
        /*