• Thomas Gleixner's avatar
    clocksource: Reselect clocksource when watchdog validated high-res capability · 332962f2
    Thomas Gleixner authored
    Up to commit 5d33b883 (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: default avatarAlex 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: default avatarPeter 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.deSigned-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    332962f2
clocksource.c 29.1 KB