]> rtime.felk.cvut.cz Git - linux-imx.git/commit
clocksource: Reselect clocksource when watchdog validated high-res capability
authorThomas Gleixner <tglx@linutronix.de>
Thu, 4 Jul 2013 20:46:45 +0000 (22:46 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Fri, 5 Jul 2013 09:09:28 +0000 (11:09 +0200)
commit332962f2c88868ed3cdab466870baaa34dd58612
treed670139ba37bca7b8f5a5179f401c8694636285c
parent2b0f89317e99735bbf32eaede81f707f98ab1b5e
clocksource: Reselect clocksource when watchdog validated high-res capability

Up to commit 5d33b883a (clocksource: Always verify highres capability)
we had no sanity check when selecting a clocksource, which prevented
that a non highres capable clocksource is used when the system already
switched to highres/nohz mode.

The new sanity check works as Alex and Tim found out. It prevents the
TSC from being used. This happens because on x86 the boot process
looks like this:

 tsc_start_freqency_validation(TSC);
 clocksource_register(HPET);
 clocksource_done_booting();
clocksource_select()
Selects HPET which is valid for high-res

 switch_to_highres();

 clocksource_register(TSC);
  TSC is not selected, because it is not yet
flagged as VALID_HIGH_RES

 clocksource_watchdog()
Validates TSC for highres, but that does not make TSC
the current clocksource.

Before the sanity check was added, we installed TSC unvalidated which
worked most of the time. If the TSC was really detected as unstable,
then the unstable logic removed it and installed HPET again.

The sanity check is correct and needed. So the watchdog needs to kick
a reselection of the clocksource, when it qualifies TSC as a valid
high res clocksource.

To solve this, we mark the clocksource which got the flag
CLOCK_SOURCE_VALID_FOR_HRES set by the watchdog with an new flag
CLOCK_SOURCE_RESELECT and trigger the watchdog thread. The watchdog
thread evaluates the flag and invokes clocksource_select() when set.

To avoid that the clocksource_done_booting() code, which is about to
install the first real clocksource anyway, needs to go through
clocksource_select and tick_oneshot_notify() pointlessly, split out
the clocksource_watchdog_kthread() list walk code and invoke the
select/notify only when called from clocksource_watchdog_kthread().

So clocksource_done_booting() can utilize the same splitout code
without the select/notify invocation and the clocksource_mutex
unlock/relock dance.

Reported-and-tested-by: Alex Shi <alex.shi@intel.com>
Cc: Hans Peter Anvin <hpa@linux.intel.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: Andi Kleen <andi.kleen@intel.com>
Tested-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Davidlohr Bueso <davidlohr.bueso@hp.com>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/alpine.DEB.2.02.1307042239150.11637@ionos.tec.linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
include/linux/clocksource.h
kernel/time/clocksource.c