[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <tip-c272ca58c3ec5631f4ab507489d9477f74efe645@git.kernel.org>
Date: Mon, 15 Jan 2018 19:44:17 -0800
From: tip-bot for Anna-Maria Gleixner <tipbot@...or.com>
To: linux-tip-commits@...r.kernel.org
Cc: hch@....de, tglx@...utronix.de, anna-maria@...utronix.de,
peterz@...radead.org, torvalds@...ux-foundation.org,
mingo@...nel.org, john.stultz@...aro.org,
linux-kernel@...r.kernel.org, hpa@...or.com
Subject: [tip:timers/core] hrtimer: Switch 'for' loop to _ffs() evaluation
Commit-ID: c272ca58c3ec5631f4ab507489d9477f74efe645
Gitweb: https://git.kernel.org/tip/c272ca58c3ec5631f4ab507489d9477f74efe645
Author: Anna-Maria Gleixner <anna-maria@...utronix.de>
AuthorDate: Thu, 21 Dec 2017 11:41:39 +0100
Committer: Ingo Molnar <mingo@...nel.org>
CommitDate: Tue, 16 Jan 2018 02:35:46 +0100
hrtimer: Switch 'for' loop to _ffs() evaluation
Looping over all clock bases to find active bits is suboptimal if not all
bases are active.
Avoid this by converting it to a __ffs() evaluation. The functionallity is
outsourced into its own function and is called via a macro as suggested by
Peter Zijlstra.
Suggested-by: Peter Zijlstra <peterz@...radead.org>
Signed-off-by: Anna-Maria Gleixner <anna-maria@...utronix.de>
Cc: Christoph Hellwig <hch@....de>
Cc: John Stultz <john.stultz@...aro.org>
Cc: Linus Torvalds <torvalds@...ux-foundation.org>
Cc: Thomas Gleixner <tglx@...utronix.de>
Cc: keescook@...omium.org
Link: http://lkml.kernel.org/r/20171221104205.7269-11-anna-maria@linutronix.de
Signed-off-by: Ingo Molnar <mingo@...nel.org>
---
kernel/time/hrtimer.c | 31 +++++++++++++++++++++----------
1 file changed, 21 insertions(+), 10 deletions(-)
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index f4f4658..cfcf8de 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -448,6 +448,23 @@ static inline void debug_deactivate(struct hrtimer *timer)
trace_hrtimer_cancel(timer);
}
+static struct hrtimer_clock_base *
+__next_base(struct hrtimer_cpu_base *cpu_base, unsigned int *active)
+{
+ unsigned int idx;
+
+ if (!*active)
+ return NULL;
+
+ idx = __ffs(*active);
+ *active &= ~(1U << idx);
+
+ return &cpu_base->clock_base[idx];
+}
+
+#define for_each_active_base(base, cpu_base, 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)
@@ -459,18 +476,15 @@ static inline void hrtimer_update_next_timer(struct hrtimer_cpu_base *cpu_base,
static ktime_t __hrtimer_get_next_event(struct hrtimer_cpu_base *cpu_base)
{
- struct hrtimer_clock_base *base = cpu_base->clock_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);
- for (; active; base++, active >>= 1) {
+ for_each_active_base(base, cpu_base, active) {
struct timerqueue_node *next;
struct hrtimer *timer;
- if (!(active & 0x01))
- continue;
-
next = timerqueue_getnext(&base->active);
timer = container_of(next, struct hrtimer, node);
expires = ktime_sub(hrtimer_get_expires(timer), base->offset);
@@ -1241,16 +1255,13 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base,
static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now)
{
- struct hrtimer_clock_base *base = cpu_base->clock_base;
+ struct hrtimer_clock_base *base;
unsigned int active = cpu_base->active_bases;
- for (; active; base++, active >>= 1) {
+ for_each_active_base(base, cpu_base, active) {
struct timerqueue_node *node;
ktime_t basenow;
- if (!(active & 0x01))
- continue;
-
basenow = ktime_add(now, base->offset);
while ((node = timerqueue_getnext(&base->active))) {
Powered by blists - more mailing lists