From: dwalker@mvista.com
To: akpm@osdl.org
Cc: linux-kernel@vger.kernel.org, johnstul@us.ibm.com
Subject: [PATCH 10/10] -mm clocksource: add generic sched_clock()
Date: Thu, 03 Aug 2006 20:24:24 -0700 [thread overview]
Message-ID: <20060804032523.569641000@mvista.com> (raw)
In-Reply-To: 20060804032414.304636000@mvista.com
[-- Attachment #1: add_generic_sched_clock.patch --]
[-- Type: text/plain, Size: 5782 bytes --]
Adds a generic sched_clock, along with a boot time override for the
scheduler clocksource. Hopefully the config option would eventually
be removed.
Signed-Off-By: Daniel Walker <dwalker@mvista.com>
---
arch/i386/Kconfig | 4 +++
arch/i386/kernel/tsc.c | 61 ------------------------------------------------
kernel/sched.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 66 insertions(+), 61 deletions(-)
Index: linux-2.6.17/arch/i386/Kconfig
===================================================================
--- linux-2.6.17.orig/arch/i386/Kconfig
+++ linux-2.6.17/arch/i386/Kconfig
@@ -18,6 +18,10 @@ config GENERIC_TIME
bool
default y
+config GENERIC_SCHED_CLOCK
+ bool
+ default y
+
config LOCKDEP_SUPPORT
bool
default y
Index: linux-2.6.17/arch/i386/kernel/tsc.c
===================================================================
--- linux-2.6.17.orig/arch/i386/kernel/tsc.c
+++ linux-2.6.17/arch/i386/kernel/tsc.c
@@ -69,65 +69,6 @@ void mark_tsc_unstable(void)
}
EXPORT_SYMBOL_GPL(mark_tsc_unstable);
-/* Accellerators for sched_clock()
- * convert from cycles(64bits) => nanoseconds (64bits)
- * basic equation:
- * ns = cycles / (freq / ns_per_sec)
- * ns = cycles * (ns_per_sec / freq)
- * ns = cycles * (10^9 / (cpu_khz * 10^3))
- * ns = cycles * (10^6 / cpu_khz)
- *
- * Then we use scaling math (suggested by george@mvista.com) to get:
- * ns = cycles * (10^6 * SC / cpu_khz) / SC
- * ns = cycles * cyc2ns_scale / SC
- *
- * And since SC is a constant power of two, we can convert the div
- * into a shift.
- *
- * We can use khz divisor instead of mhz to keep a better percision, since
- * cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits.
- * (mathieu.desnoyers@polymtl.ca)
- *
- * -johnstul@us.ibm.com "math is hard, lets go shopping!"
- */
-static unsigned long cyc2ns_scale __read_mostly;
-
-#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
-
-static inline void set_cyc2ns_scale(unsigned long cpu_khz)
-{
- cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz;
-}
-
-static inline unsigned long long cycles_2_ns(unsigned long long cyc)
-{
- return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR;
-}
-
-/*
- * Scheduler clock - returns current time in nanosec units.
- */
-unsigned long long sched_clock(void)
-{
- unsigned long long this_offset;
-
- /*
- * in the NUMA case we dont use the TSC as they are not
- * synchronized across all CPUs.
- */
-#ifndef CONFIG_NUMA
- if (!cpu_khz || check_tsc_unstable())
-#endif
- /* no locking but a rare wrong value is not a big deal */
- return (jiffies_64 - INITIAL_JIFFIES) * (1000000000 / HZ);
-
- /* read the Time Stamp Counter: */
- rdtscll(this_offset);
-
- /* return the value in ns */
- return cycles_2_ns(this_offset);
-}
-
static unsigned long calculate_cpu_khz(void)
{
unsigned long long start, end;
@@ -210,7 +151,6 @@ void tsc_init(void)
(unsigned long)cpu_khz / 1000,
(unsigned long)cpu_khz % 1000);
- set_cyc2ns_scale(cpu_khz);
use_tsc_delay();
}
@@ -285,7 +225,6 @@ time_cpufreq_notifier(struct notifier_bl
ref_freq, freq->new);
if (!(freq->flags & CPUFREQ_CONST_LOOPS)) {
tsc_khz = cpu_khz;
- set_cyc2ns_scale(cpu_khz);
/*
* TSC based sched_clock turns
* to junk w/ cpufreq
Index: linux-2.6.17/kernel/sched.c
===================================================================
--- linux-2.6.17.orig/kernel/sched.c
+++ linux-2.6.17/kernel/sched.c
@@ -16,6 +16,7 @@
* by Davide Libenzi, preemptible kernel bits by Robert Love.
* 2003-09-03 Interactivity tuning by Con Kolivas.
* 2004-04-02 Scheduler domains code by Nick Piggin
+ * 2006-08-03 Generic sched_clock() implementation by Daniel Walker
*/
#include <linux/mm.h>
@@ -53,6 +54,7 @@
#include <linux/acct.h>
#include <linux/kprobes.h>
#include <linux/delayacct.h>
+#include <linux/clocksource.h>
#include <asm/tlb.h>
#include <asm/unistd.h>
@@ -6843,6 +6845,66 @@ int in_sched_functions(unsigned long add
&& addr < (unsigned long)__sched_text_end);
}
+#ifdef CONFIG_GENERIC_SCHED_CLOCK
+static struct clocksource *sched_clocksource = &clocksource_jiffies;
+static char __initdata sched_clock_override[32];
+
+unsigned long long sched_clock(void)
+{
+ return cyc2ns(sched_clocksource, clocksource_read(sched_clocksource));
+}
+
+static int __init boot_override_sched_clocksource(char* str)
+{
+ if (str)
+ strlcpy(sched_clock_override, str,
+ sizeof(sched_clock_override));
+
+ return 1;
+}
+__setup("sched_clocksource=", boot_override_sched_clocksource);
+
+static int
+sched_clock_callback(struct notifier_block *nb, unsigned long op, void *c)
+{
+ /*
+ * If our clock just became unstable switch to the safe,
+ * slow, fast jiffies clock.
+ *
+ * XXX : We could just switch to the next best clock.
+ */
+ if (op == CLOCKSOURCE_NOTIFY_RATING && sched_clocksource == c)
+ sched_clocksource = &clocksource_jiffies;
+ return 0;
+}
+
+static struct notifier_block sched_clock_nb = {
+ .notifier_call = sched_clock_callback,
+};
+
+static int __init sched_clock_init(void)
+{
+ clocksource_notifier_register(&sched_clock_nb);
+
+ if (*sched_clock_override != 0) {
+ sched_clocksource = clocksource_get_clock(sched_clock_override);
+ if (unlikely(sched_clocksource == NULL)) {
+ sched_clocksource = clocksource_get_best_clock();
+ printk(KERN_ERR "Warning: "
+ "Invalid scheduler clock override.\n");
+ return 1;
+ }
+
+ printk(KERN_INFO "Scheduler: %s clocksource has been "
+ "installed.\n", sched_clocksource->name);
+ } else
+ sched_clocksource = clocksource_get_best_clock();
+
+ return 0;
+}
+__initcall(sched_clock_init);
+#endif /* CONFIG_GENERIC_SCHED_CLOCK */
+
void __init sched_init(void)
{
int i, j, k;
--
prev parent reply other threads:[~2006-08-04 3:26 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-08-04 3:24 [PATCH 00/10] -mm generic clocksoure API dwalker
2006-08-04 3:24 ` [PATCH 01/10] -mm clocksource: increase initcall priority dwalker
2006-08-04 18:39 ` john stultz
2006-08-04 3:24 ` [PATCH 02/10] -mm clocksource: small cleanup dwalker
2006-08-04 18:40 ` john stultz
2006-08-04 3:24 ` [PATCH 03/10] -mm clocksource: enable plist dwalker
2006-08-04 3:24 ` [PATCH 04/10] -mm clocksource: add some new API calls dwalker
2006-08-04 19:06 ` john stultz
2006-08-04 19:28 ` Daniel Walker
2006-08-04 21:05 ` Thomas Gleixner
2006-08-04 3:24 ` [PATCH 05/10] -mm clocksource: convert generic timeofday dwalker
2006-08-04 3:24 ` [PATCH 06/10] -mm clocksource: add block notifier dwalker
2006-08-04 3:24 ` [PATCH 07/10] -mm clocksource: remove update_callback dwalker
2006-08-04 19:28 ` john stultz
2006-08-04 3:24 ` [PATCH 08/10] -mm clocksource: cleanup on -mm dwalker
2006-08-04 19:53 ` john stultz
2006-08-04 21:11 ` Daniel Walker
2006-08-04 22:16 ` john stultz
2006-08-04 23:16 ` Daniel Walker
2006-08-04 3:24 ` [PATCH 09/10] -mm clocksource: initialize list value dwalker
2006-08-04 3:24 ` dwalker [this message]
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=20060804032523.569641000@mvista.com \
--to=dwalker@mvista.com \
--cc=akpm@osdl.org \
--cc=johnstul@us.ibm.com \
--cc=linux-kernel@vger.kernel.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