public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Martin Schwidefsky <schwidefsky@de.ibm.com>
To: linux-kernel@vger.kernel.org
Cc: Ingo Molnar <mingo@elte.hu>, Thomas Gleixner <tglx@linutronix.de>,
	john stultz <johnstul@us.ibm.com>,
	Martin Schwidefsky <schwidefsky@de.ibm.com>
Subject: [RFC][patch 5/5] update clocksource with stop_machine
Date: Tue, 21 Jul 2009 21:17:50 +0200	[thread overview]
Message-ID: <20090721192101.545285889@de.ibm.com> (raw)
In-Reply-To: 20090721191745.788551122@de.ibm.com

[-- Attachment #1: clocksource-stop_machine.diff --]
[-- Type: text/plain, Size: 6875 bytes --]

From: Martin Schwidefsky <schwidefsky@de.ibm.com>

update_wall_time calls change_clocksource HZ times per second to check
if a new clock source is available. In close to 100% of all calls there
is no new clock. Replace the tick based check by an update done with
stop_machine.

Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: john stultz <johnstul@us.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---
 include/linux/clocksource.h |    2 -
 kernel/time/clocksource.c   |   82 ++++++++++++++++----------------------------
 kernel/time/timekeeping.c   |    2 -
 3 files changed, 31 insertions(+), 55 deletions(-)

Index: linux-2.6/include/linux/clocksource.h
===================================================================
--- linux-2.6.orig/include/linux/clocksource.h
+++ linux-2.6/include/linux/clocksource.h
@@ -340,10 +340,8 @@ extern void clocksource_resume(void);
 
 #ifdef CONFIG_GENERIC_TIME
 extern void clocksource_forward_now(void);
-extern void change_clocksource(void);
 #else
 static inline void clocksource_forward_now(void) { }
-static inline void change_clocksource(void) { }
 #endif
 
 #ifdef CONFIG_GENERIC_TIME_VSYSCALL
Index: linux-2.6/kernel/time/clocksource.c
===================================================================
--- linux-2.6.orig/kernel/time/clocksource.c
+++ linux-2.6/kernel/time/clocksource.c
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/sched.h> /* for spin_unlock_irq() using preempt_count() m68k */
 #include <linux/tick.h>
+#include <linux/stop_machine.h>
 
 void timecounter_init(struct timecounter *tc,
 		      const struct cyclecounter *cc,
@@ -107,46 +108,26 @@ u64 timecounter_cyc2time(struct timecoun
 }
 EXPORT_SYMBOL(timecounter_cyc2time);
 
-/* XXX - Would like a better way for initializing curr_clocksource */
+/* XXX - Would like a better way for initializing clock */
 extern struct clocksource clocksource_jiffies;
 
 /* Currently selected clock source. */
 struct clocksource *clock;
 
 /*[Clocksource internal variables]---------
- * curr_clocksource:
- *	currently selected clocksource. Initialized to clocksource_jiffies.
- * next_clocksource:
- *	pending next selected clocksource.
  * clocksource_list:
  *	linked list with the registered clocksources
  * clocksource_lock:
- *	protects manipulations to curr_clocksource and next_clocksource
- *	and the clocksource_list
+ *	protects manipulations to the clocksource_list
  * override_name:
  *	Name of the user-specified clocksource.
  */
-static struct clocksource *curr_clocksource = &clocksource_jiffies;
-static struct clocksource *next_clocksource;
 static struct clocksource *clocksource_override;
 static LIST_HEAD(clocksource_list);
 static DEFINE_SPINLOCK(clocksource_lock);
 static char override_name[32];
 static int finished_booting;
 
-/* clocksource_done_booting - Called near the end of core bootup
- *
- * Hack to avoid lots of clocksource churn at boot time.
- * We use fs_initcall because we want this to start before
- * device_initcall but after subsys_initcall.
- */
-static int __init clocksource_done_booting(void)
-{
-	finished_booting = 1;
-	return 0;
-}
-fs_initcall(clocksource_done_booting);
-
 #ifdef CONFIG_CLOCKSOURCE_WATCHDOG
 static LIST_HEAD(watchdog_list);
 static struct clocksource *watchdog;
@@ -323,24 +304,6 @@ void clocksource_touch_watchdog(void)
 	clocksource_resume_watchdog();
 }
 
-/**
- * clocksource_get_next - Returns the selected clocksource
- *
- */
-struct clocksource *clocksource_get_next(void)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&clocksource_lock, flags);
-	if (next_clocksource && finished_booting) {
-		curr_clocksource = next_clocksource;
-		next_clocksource = NULL;
-	}
-	spin_unlock_irqrestore(&clocksource_lock, flags);
-
-	return curr_clocksource;
-}
-
 /*
  * Enqueue the clocksource sorted by rating
  */
@@ -552,23 +515,22 @@ static struct clocksource *select_clocks
 }
 
 /**
- * change_clocksource - Swaps clocksources if a new one is available
+ * clocksource_swap - Swaps clocksources if a new one is available
  *
  * Accumulates current time interval and initializes new clocksource
  */
-void change_clocksource(void)
+static int clocksource_swap(void *dummy)
 {
 	struct clocksource *new, *old;
 
-	new = clocksource_get_next();
-
-	if (clock == new)
-		return;
+	new = select_clocksource();
+	if (!new || clock == new)
+		return 0;
 
 	clocksource_forward_now();
 
 	if (new->enable && !new->enable(new))
-		return;
+		return 0;
 
 	/* save mult_orig after successful enable */
 	new->mult_orig = new->mult;
@@ -592,6 +554,7 @@ void change_clocksource(void)
 	printk(KERN_INFO "Time: %s clocksource has been installed.\n",
 	       clock->name);
 	 */
+	return 0;
 }
 
 /**
@@ -602,11 +565,13 @@ static void clocksource_update(void)
 	struct clocksource *new;
 	unsigned long flags;
 
+	if (!finished_booting)
+		return;
 	spin_lock_irqsave(&clocksource_lock, flags);
 	new = select_clocksource();
-	if (new)
-		next_clocksource = new;
 	spin_unlock_irqrestore(&clocksource_lock, flags);
+	if (new && new != clock)
+		stop_machine(clocksource_swap, NULL, NULL);
 }
 #else /* CONFIG_GENERIC_TIME */
 static inline void clocksource_update(void) { }
@@ -657,7 +622,7 @@ void clocksource_unregister(struct clock
  */
 void __init clocksource_init(void)
 {
-	clock = clocksource_get_next();
+	clock = &clocksource_jiffies;
 	if (clock->enable)
 		clock->enable(clock);
 	/* save mult_orig on enable */
@@ -666,6 +631,21 @@ void __init clocksource_init(void)
 	clock->cycle_last = clock->read(clock);
 }
 
+/**
+ * clocksource_done_booting - Called near the end of core bootup
+ *
+ * Hack to avoid lots of clocksource churn at boot time.
+ * We use fs_initcall because we want this to start before
+ * device_initcall but after subsys_initcall.
+ */
+static int __init clocksource_done_booting(void)
+{
+	finished_booting = 1;
+	clocksource_update();
+	return 0;
+}
+fs_initcall(clocksource_done_booting);
+
 #ifdef CONFIG_SYSFS
 /**
  * sysfs_show_current_clocksources - sysfs interface for current clocksource
@@ -681,7 +661,7 @@ sysfs_show_current_clocksources(struct s
 	ssize_t count = 0;
 
 	spin_lock_irq(&clocksource_lock);
-	count = snprintf(buf, PAGE_SIZE, "%s\n", curr_clocksource->name);
+	count = snprintf(buf, PAGE_SIZE, "%s\n", clock->name);
 	spin_unlock_irq(&clocksource_lock);
 
 	return count;
Index: linux-2.6/kernel/time/timekeeping.c
===================================================================
--- linux-2.6.orig/kernel/time/timekeeping.c
+++ linux-2.6/kernel/time/timekeeping.c
@@ -491,8 +491,6 @@ void update_wall_time(void)
 
 	update_xtime_cache(cyc2ns(clock, offset));
 
-	/* check to see if there is a new clocksource to use */
-	change_clocksource();
 	update_vsyscall(&xtime, clock);
 }
 

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


      parent reply	other threads:[~2009-07-21 19:21 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-07-21 19:17 [RFC][patch 0/5] clocksource cleanup / improvement Martin Schwidefsky
2009-07-21 19:17 ` [RFC][patch 1/5] move clock source related code to clocksource.c Martin Schwidefsky
2009-07-21 19:50   ` Daniel Walker
2009-07-21 21:55     ` Martin Schwidefsky
2009-07-21 22:00     ` john stultz
2009-07-22  7:25       ` Martin Schwidefsky
2009-07-22 17:45         ` john stultz
2009-07-23  0:28           ` john stultz
2009-07-23  7:53             ` Martin Schwidefsky
2009-07-23 10:52             ` Martin Schwidefsky
2009-07-25  0:08               ` john stultz
2009-07-27 11:55                 ` Martin Schwidefsky
2009-07-23  7:23           ` Martin Schwidefsky
2009-07-21 19:17 ` [RFC][patch 2/5] cleanup clocksource selection Martin Schwidefsky
2009-07-21 22:07   ` john stultz
2009-07-21 19:17 ` [RFC][patch 3/5] remove clocksource inline functions Martin Schwidefsky
2009-07-21 19:48   ` Daniel Walker
2009-07-21 22:03   ` john stultz
2009-07-22  7:33     ` Martin Schwidefsky
2009-07-21 19:17 ` [RFC][patch 4/5] clocksource_read/clocksource_read_raw " Martin Schwidefsky
2009-07-21 22:01   ` john stultz
2009-07-22  7:29     ` Martin Schwidefsky
2009-07-21 19:17 ` Martin Schwidefsky [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=20090721192101.545285889@de.ibm.com \
    --to=schwidefsky@de.ibm.com \
    --cc=johnstul@us.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=tglx@linutronix.de \
    /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