From: Thomas Gleixner <tglx@linutronix.de>
To: LKML <linux-kernel@vger.kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>,
John Stultz <john.stultz@linaro.org>,
Eric Dumazet <edumazet@google.com>,
Anna-Maria Gleixner <anna-maria@linutronix.de>,
"Rafael J. Wysocki" <rafael.j.wysocki@intel.com>,
linux-pm@vger.kernel.org, Arjan van de Ven <arjan@infradead.org>,
"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>,
Frederic Weisbecker <fweisbec@gmail.com>,
Rik van Riel <riel@redhat.com>,
Richard Cochran <rcochran@linutronix.de>
Subject: [patch V2 05/10] timer: Retrieve next expiry of pinned/non-pinned timers seperately
Date: Tue, 18 Apr 2017 13:11:07 +0200 [thread overview]
Message-ID: <20170418111400.778021491@linutronix.de> (raw)
In-Reply-To: 20170418111102.490432548@linutronix.de
[-- Attachment #1: timer_Provide_both_pinned_and_movable_expiration_times.patch --]
[-- Type: text/plain, Size: 4686 bytes --]
To prepare for the conversion of the NOHZ timer placement to a pull at
expiry time model it's required to have seperate expiry times for the
pinned and the non-pinned (movable) timers.
No functional change
Signed-off-by: Richard Cochran <rcochran@linutronix.de>
Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/time/tick-internal.h | 3 ++-
kernel/time/tick-sched.c | 10 ++++++----
kernel/time/timer.c | 41 +++++++++++++++++++++++++++++++++++------
3 files changed, 43 insertions(+), 11 deletions(-)
--- a/kernel/time/tick-internal.h
+++ b/kernel/time/tick-internal.h
@@ -163,5 +163,6 @@ static inline void timers_update_migrati
DECLARE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases);
-extern u64 get_next_timer_interrupt(unsigned long basej, u64 basem);
+extern u64 get_next_timer_interrupt(unsigned long basej, u64 basem,
+ u64 *global_evt);
void timer_clear_idle(void);
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -666,7 +666,7 @@ static ktime_t tick_nohz_stop_sched_tick
ktime_t now, int cpu)
{
struct clock_event_device *dev = __this_cpu_read(tick_cpu_device.evtdev);
- u64 basemono, next_tick, next_tmr, next_rcu, delta, expires;
+ u64 basemono, next_tick, next_local, next_global, next_rcu, delta, expires;
unsigned long seq, basejiff;
ktime_t tick;
@@ -689,10 +689,12 @@ static ktime_t tick_nohz_stop_sched_tick
* disabled this also looks at the next expiring
* hrtimer.
*/
- next_tmr = get_next_timer_interrupt(basejiff, basemono);
- ts->next_timer = next_tmr;
+ next_local = get_next_timer_interrupt(basejiff, basemono,
+ &next_global);
+ next_local = min(next_local, next_global);
+ ts->next_timer = next_local;
/* Take the next rcu event into account */
- next_tick = next_rcu < next_tmr ? next_rcu : next_tmr;
+ next_tick = next_rcu < next_local ? next_rcu : next_local;
}
/*
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -1472,23 +1472,27 @@ static u64 cmp_next_hrtimer_event(u64 ba
* get_next_timer_interrupt - return the time (clock mono) of the next timer
* @basej: base time jiffies
* @basem: base time clock monotonic
+ * @global_evt: Pointer to store the expiry time of the next global timer
*
* Returns the tick aligned clock monotonic time of the next pending
* timer or KTIME_MAX if no timer is pending.
*/
-u64 get_next_timer_interrupt(unsigned long basej, u64 basem)
+u64 get_next_timer_interrupt(unsigned long basej, u64 basem, u64 *global_evt)
{
unsigned long nextevt, nextevt_local, nextevt_global;
bool local_empty, global_empty, local_first, is_idle;
struct timer_base *base_local, *base_global;
- u64 expires = KTIME_MAX;
+ u64 local_evt = KTIME_MAX;
+
+ /* Preset global event */
+ *global_evt = KTIME_MAX;
/*
* Pretend that there is no timer pending if the cpu is offline.
* Possible pending timers will be migrated later to an active cpu.
*/
if (cpu_is_offline(smp_processor_id()))
- return expires;
+ return local_evt;
base_local = this_cpu_ptr(&timer_bases[BASE_LOCAL]);
base_global = this_cpu_ptr(&timer_bases[BASE_GLOBAL]);
@@ -1532,14 +1536,39 @@ u64 get_next_timer_interrupt(unsigned lo
spin_unlock(&base_local->lock);
spin_unlock(&base_global->lock);
- if (!local_empty || !global_empty) {
+ /*
+ * If the bases are not marked idle, i.e one of the events is at
+ * max. one tick away, use the next event for calculating next
+ * local expiry value. The next global event is left as KTIME_MAX,
+ * so this CPU will not queue itself in the global expiry
+ * mechanism.
+ */
+ if (!is_idle) {
/* If we missed a tick already, force 0 delta */
if (time_before_eq(nextevt, basej))
nextevt = basej;
- expires = basem + (nextevt - basej) * TICK_NSEC;
+ local_evt = basem + (nextevt - basej) * TICK_NSEC;
+ return cmp_next_hrtimer_event(basem, local_evt);
}
- return cmp_next_hrtimer_event(basem, expires);
+ /*
+ * If the bases are marked idle, i.e. the next event on both the
+ * local and the global queue are farther away than a tick,
+ * evaluate both bases. No need to check whether one of the bases
+ * has an already expired timer as this is caught by the !is_idle
+ * condition above.
+ */
+ if (!local_empty)
+ local_evt = basem + (nextevt_local - basej) * TICK_NSEC;
+
+ /*
+ * If the local queue expires first, there is no requirement for
+ * queuing the CPU in the global expiry mechanism.
+ */
+ if (!local_first && !global_empty)
+ *global_evt = basem + (nextevt_global - basej) * TICK_NSEC;
+
+ return cmp_next_hrtimer_event(basem, local_evt);
}
/**
next prev parent reply other threads:[~2017-04-18 16:43 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-04-18 11:11 [patch V2 00/10] timer: Move from a push remote at enqueue to a pull at expiry model Thomas Gleixner
2017-04-18 11:11 ` [patch V2 01/10] timer: Invoke timer_start_debug() where it makes sense Thomas Gleixner
2017-04-18 11:11 ` [patch V2 02/10] timerqueue: Document return values of timerqueue_add/del() Thomas Gleixner
2017-04-18 11:11 ` [patch V2 03/10] timers: Rework idle logic Thomas Gleixner
2017-04-19 6:50 ` Peter Zijlstra
2017-04-21 14:43 ` Frederic Weisbecker
2017-04-18 11:11 ` [patch V2 04/10] timer: Keep the pinned timers separate from the others Thomas Gleixner
2017-04-18 11:11 ` Thomas Gleixner [this message]
2017-04-19 7:05 ` [patch V2 05/10] timer: Retrieve next expiry of pinned/non-pinned timers seperately Peter Zijlstra
2017-04-19 9:56 ` Thomas Gleixner
2017-04-18 11:11 ` [patch V2 06/10] timer: Restructure internal locking Thomas Gleixner
2017-04-19 7:07 ` Peter Zijlstra
2017-04-18 11:11 ` [patch V2 07/10] tick/sched: Split out jiffies update helper function Thomas Gleixner
2017-04-18 11:11 ` [patch V2 08/10] timer: Implement the hierarchical pull model Thomas Gleixner
2017-04-19 7:20 ` Peter Zijlstra
2017-04-19 7:24 ` Peter Zijlstra
2017-04-19 7:34 ` Peter Zijlstra
2017-04-19 7:38 ` Peter Zijlstra
2017-04-19 8:11 ` Peter Zijlstra
2017-04-19 8:31 ` Thomas Gleixner
2017-04-19 8:36 ` Peter Zijlstra
2017-04-19 9:03 ` Thomas Gleixner
2017-04-19 8:52 ` Peter Zijlstra
2017-04-19 9:09 ` Peter Zijlstra
2017-04-19 9:43 ` Thomas Gleixner
2017-04-19 9:52 ` Peter Zijlstra
2017-04-19 9:44 ` Peter Zijlstra
2017-04-19 9:53 ` Peter Zijlstra
2017-04-19 9:20 ` Peter Zijlstra
2017-04-19 10:22 ` Peter Zijlstra
2017-04-18 11:11 ` [patch V2 09/10] timer_migration: Add tracepoints Thomas Gleixner
2017-04-18 11:11 ` [patch V2 10/10] timer: Always queue timers on the local CPU Thomas Gleixner
2017-04-21 19:28 ` [patch V2 00/10] timer: Move from a push remote at enqueue to a pull at expiry model Paul E. McKenney
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170418111400.778021491@linutronix.de \
--to=tglx@linutronix.de \
--cc=anna-maria@linutronix.de \
--cc=arjan@infradead.org \
--cc=edumazet@google.com \
--cc=fweisbec@gmail.com \
--cc=john.stultz@linaro.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=paulmck@linux.vnet.ibm.com \
--cc=peterz@infradead.org \
--cc=rafael.j.wysocki@intel.com \
--cc=rcochran@linutronix.de \
--cc=riel@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).