From: John Stultz <john.stultz@linaro.org>
To: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Cc: John Stultz <john.stultz@linaro.org>,
Dave Jones <davej@codemonkey.org.uk>,
Linus Torvalds <torvalds@linux-foundation.org>,
Thomas Gleixner <tglx@linutronix.de>,
Richard Cochran <richardcochran@gmail.com>,
Prarit Bhargava <prarit@redhat.com>,
Stephen Boyd <sboyd@codeaurora.org>,
Ingo Molnar <mingo@kernel.org>,
Peter Zijlstra <peterz@infradead.org>,
"David S. Miller" <davem@davemloft.net>,
Martin Schwidefsky <schwidefsky@de.ibm.com>
Subject: [PATCH 08/10] clocksource: Mostly kill clocksource_register()
Date: Fri, 9 Jan 2015 16:34:26 -0800 [thread overview]
Message-ID: <1420850068-27828-9-git-send-email-john.stultz@linaro.org> (raw)
In-Reply-To: <1420850068-27828-1-git-send-email-john.stultz@linaro.org>
A long running project has been to cleanup remaining uses
of clocksource_register(), replacing it with the simpler
clocksource_register_khz/hz().
However, there are a few cases where we need to self-define
our mult/shift values, so switch the function to a more
obviously internal __clocksource_register(), and consolidate
much of the internal logic so we don't have duplication.
Cc: Dave Jones <davej@codemonkey.org.uk>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Stephen Boyd <sboyd@codeaurora.org>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
arch/s390/kernel/time.c | 2 +-
arch/sparc/kernel/time_32.c | 2 +-
include/linux/clocksource.h | 10 +++++-
kernel/time/clocksource.c | 83 +++++++++++++++++++--------------------------
kernel/time/jiffies.c | 4 +--
5 files changed, 47 insertions(+), 54 deletions(-)
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 20660dd..6c273cd 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -283,7 +283,7 @@ void __init time_init(void)
if (register_external_irq(EXT_IRQ_TIMING_ALERT, timing_alert_interrupt))
panic("Couldn't request external interrupt 0x1406");
- if (clocksource_register(&clocksource_tod) != 0)
+ if (__clocksource_register(&clocksource_tod) != 0)
panic("Could not register TOD clock source");
/* Enable TOD clock interrupts on the boot cpu. */
diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c
index 2f80d23..a31c0c8 100644
--- a/arch/sparc/kernel/time_32.c
+++ b/arch/sparc/kernel/time_32.c
@@ -191,7 +191,7 @@ static __init int setup_timer_cs(void)
timer_cs.mult = clocksource_hz2mult(sparc_config.clock_rate,
timer_cs.shift);
- return clocksource_register(&timer_cs);
+ return __clocksource_register(&timer_cs);
}
#ifdef CONFIG_SMP
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index 9b54cb9..ba25e70 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -280,7 +280,6 @@ static inline s64 clocksource_cyc2ns(cycle_t cycles, u32 mult, u32 shift)
}
-extern int clocksource_register(struct clocksource*);
extern int clocksource_unregister(struct clocksource*);
extern void clocksource_touch_watchdog(void);
extern struct clocksource* clocksource_get_next(void);
@@ -305,6 +304,15 @@ __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq);
extern void
__clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq);
+/*
+ * Dont' call this unless you're a default clocksource
+ * (AKA: jiffies) and absolutely have to.
+ */
+static inline int __clocksource_register(struct clocksource *cs)
+{
+ return __clocksource_register_scale(cs, 1, 0);
+}
+
static inline int clocksource_register_hz(struct clocksource *cs, u32 hz)
{
return __clocksource_register_scale(cs, 1, hz);
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index c2f8639..9a0b951 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -721,38 +721,52 @@ static void clocksource_enqueue(struct clocksource *cs)
void __clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq)
{
u64 sec;
+
/*
- * Calc the maximum number of seconds which we can run before
- * wrapping around. For clocksources which have a mask > 32bit
- * we need to limit the max sleep time to have a good
- * conversion precision. 10 minutes is still a reasonable
- * amount. That results in a shift value of 24 for a
- * clocksource with mask >= 40bit and f >= 4GHz. That maps to
- * ~ 0.06ppm granularity for NTP.
+ * Default clocksources are *special* and self-define their mult/shift.
+ * But, you're not special, so you should specify a freq value.
*/
- sec = cs->mask;
- do_div(sec, freq);
- do_div(sec, scale);
- if (!sec)
- sec = 1;
- else if (sec > 600 && cs->mask > UINT_MAX)
- sec = 600;
-
- clocks_calc_mult_shift(&cs->mult, &cs->shift, freq,
- NSEC_PER_SEC / scale, sec * scale);
-
+ if (freq) {
+ /*
+ * Calc the maximum number of seconds which we can run before
+ * wrapping around. For clocksources which have a mask > 32bit
+ * we need to limit the max sleep time to have a good
+ * conversion precision. 10 minutes is still a reasonable
+ * amount. That results in a shift value of 24 for a
+ * clocksource with mask >= 40bit and f >= 4GHz. That maps to
+ * ~ 0.06ppm granularity for NTP.
+ */
+ sec = cs->mask;
+ do_div(sec, freq);
+ do_div(sec, scale);
+ if (!sec)
+ sec = 1;
+ else if (sec > 600 && cs->mask > UINT_MAX)
+ sec = 600;
+
+ clocks_calc_mult_shift(&cs->mult, &cs->shift, freq,
+ NSEC_PER_SEC / scale, sec * scale);
+ }
/*
* Ensure clocksources that have large mults don't overflow
* when adjusted.
*/
cs->maxadj = clocksource_max_adjustment(cs);
- while ((cs->mult + cs->maxadj < cs->mult)
- || (cs->mult - cs->maxadj > cs->mult)) {
+ while (freq && ((cs->mult + cs->maxadj < cs->mult)
+ || (cs->mult - cs->maxadj > cs->mult))) {
cs->mult >>= 1;
cs->shift--;
cs->maxadj = clocksource_max_adjustment(cs);
}
+ /*
+ * Only warn for *special* clocksources that self-define
+ * their mult/shift values and don't specify a freq.
+ */
+ WARN_ONCE(cs->mult + cs->maxadj < cs->mult,
+ "Clocksource %s might overflow on 11%% adjustment\n",
+ cs->name);
+
cs->max_idle_ns = clocks_calc_max_nsecs(cs->mult, cs->shift,
cs->maxadj, cs->mask,
&cs->max_cycles);
@@ -786,35 +800,6 @@ int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq)
}
EXPORT_SYMBOL_GPL(__clocksource_register_scale);
-
-/**
- * clocksource_register - Used to install new clocksources
- * @cs: clocksource to be registered
- *
- * Returns -EBUSY if registration fails, zero otherwise.
- */
-int clocksource_register(struct clocksource *cs)
-{
- /* calculate max adjustment for given mult/shift */
- cs->maxadj = clocksource_max_adjustment(cs);
- WARN_ONCE(cs->mult + cs->maxadj < cs->mult,
- "Clocksource %s might overflow on 11%% adjustment\n",
- cs->name);
-
- /* calculate max idle time permitted for this clocksource */
- cs->max_idle_ns = clocks_calc_max_nsecs(cs->mult, cs->shift,
- cs->maxadj, cs->mask,
- &cs->max_cycles);
-
- mutex_lock(&clocksource_mutex);
- clocksource_enqueue(cs);
- clocksource_enqueue_watchdog(cs);
- clocksource_select();
- mutex_unlock(&clocksource_mutex);
- return 0;
-}
-EXPORT_SYMBOL(clocksource_register);
-
static void __clocksource_change_rating(struct clocksource *cs, int rating)
{
list_del(&cs->list);
diff --git a/kernel/time/jiffies.c b/kernel/time/jiffies.c
index 7e41390..c4bb518 100644
--- a/kernel/time/jiffies.c
+++ b/kernel/time/jiffies.c
@@ -95,7 +95,7 @@ EXPORT_SYMBOL(jiffies);
static int __init init_jiffies_clocksource(void)
{
- return clocksource_register(&clocksource_jiffies);
+ return __clocksource_register(&clocksource_jiffies);
}
core_initcall(init_jiffies_clocksource);
@@ -131,6 +131,6 @@ int register_refined_jiffies(long cycles_per_second)
refined_jiffies.mult = ((u32)nsec_per_tick) << JIFFIES_SHIFT;
- clocksource_register(&refined_jiffies);
+ __clocksource_register(&refined_jiffies);
return 0;
}
--
1.9.1
next prev parent reply other threads:[~2015-01-10 0:34 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-01-10 0:34 [PATCH 00/10][RFC] Increased clocksource validation and cleanups John Stultz
2015-01-10 0:34 ` [PATCH 01/10] clocksource: Simplify clocks_calc_max_nsecs logic John Stultz
2015-01-10 0:34 ` [PATCH 02/10] clocksource: Simplify logic around clocksource wrapping saftey margins John Stultz
2015-01-10 2:03 ` Stephen Boyd
2015-01-10 0:34 ` [PATCH 03/10] clocksource: Remove clocksource_max_deferment() John Stultz
2015-01-11 11:47 ` Richard Cochran
2015-01-12 18:36 ` John Stultz
2015-01-12 20:16 ` Richard Cochran
2015-01-10 0:34 ` [PATCH 04/10] clocksource: Add max_cycles to clocksource structure John Stultz
2015-01-10 2:06 ` Stephen Boyd
2015-01-10 0:34 ` [PATCH 05/10] time: Add debugging checks to warn if we see delays John Stultz
2015-01-10 0:34 ` [PATCH 06/10] time: Cap clocksource reads to the clocksource max_cycles value John Stultz
2015-01-11 12:41 ` Richard Cochran
2015-01-12 18:54 ` John Stultz
2015-01-12 19:02 ` Linus Torvalds
2015-01-12 20:37 ` Richard Cochran
2015-01-12 20:30 ` Richard Cochran
2015-01-12 20:49 ` Richard Cochran
2015-01-13 11:11 ` Peter Zijlstra
2015-01-13 21:33 ` John Stultz
2015-01-13 22:51 ` Linus Torvalds
2015-01-14 9:35 ` Peter Zijlstra
2015-01-22 20:55 ` John Stultz
2015-01-10 0:34 ` [PATCH 07/10] time: Try to catch clocksource delta underflows John Stultz
2015-01-10 0:34 ` John Stultz [this message]
2015-01-10 0:34 ` [PATCH 09/10] sparc: Convert to using clocksource_register_hz() John Stultz
2015-01-10 0:34 ` [PATCH 10/10] clocksource: Add some debug info about clocksources being registered John Stultz
2015-01-10 2:02 ` Stephen Boyd
2015-01-22 0:51 ` John Stultz
2015-01-22 12:27 ` Prarit Bhargava
2015-01-11 11:41 ` [PATCH 00/10][RFC] Increased clocksource validation and cleanups Richard Cochran
2015-01-12 18:22 ` John Stultz
2015-01-12 20:45 ` Richard Cochran
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=1420850068-27828-9-git-send-email-john.stultz@linaro.org \
--to=john.stultz@linaro.org \
--cc=davej@codemonkey.org.uk \
--cc=davem@davemloft.net \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=peterz@infradead.org \
--cc=prarit@redhat.com \
--cc=richardcochran@gmail.com \
--cc=sboyd@codeaurora.org \
--cc=schwidefsky@de.ibm.com \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.org \
/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).