• Paul E. McKenney's avatar
    clocksource: Reduce clocksource-skew threshold · 2e27e793
    Paul E. McKenney authored
    Currently, WATCHDOG_THRESHOLD is set to detect a 62.5-millisecond skew in
    a 500-millisecond WATCHDOG_INTERVAL.  This requires that clocks be skewed
    by more than 12.5% in order to be marked unstable.  Except that a clock
    that is skewed by that much is probably destroying unsuspecting software
    right and left.  And given that there are now checks for false-positive
    skews due to delays between reading the two clocks, it should be possible
    to greatly decrease WATCHDOG_THRESHOLD, at least for fine-grained clocks
    such as TSC.
    
    Therefore, add a new uncertainty_margin field to the clocksource structure
    that contains the maximum uncertainty in nanoseconds for the corresponding
    clock.  This field may be initialized manually, as it is for
    clocksource_tsc_early and clocksource_jiffies, which is copied to
    refined_jiffies.  If the field is not initialized manually, it will be
    computed at clock-registry time as the period of the clock in question
    based on the scale and freq parameters to __clocksource_update_freq_scale()
    function.  If either of those two parameters are zero, the
    tens-of-milliseconds WATCHDOG_THRESHOLD is used as a cowardly alternative
    to dividing by zero.  No matter how the uncertainty_margin field is
    calculated, it is bounded below by twice WATCHDOG_MAX_SKEW, that is, by 100
    microseconds.
    
    Note that manually initialized uncertainty_margin fields are not adjusted,
    but there is a WARN_ON_ONCE() that triggers if any such field is less than
    twice WATCHDOG_MAX_SKEW.  This WARN_ON_ONCE() is intended to discourage
    production use of the one-nanosecond uncertainty_margin values that are
    used to test the clock-skew code itself.
    
    The actual clock-skew check uses the sum of the uncertainty_margin fields
    of the two clocksource structures being compared.  Integer overflow is
    avoided because the largest computed value of the uncertainty_margin
    fields is one billion (10^9), and double that value fits into an
    unsigned int.  However, if someone manually specifies (say) UINT_MAX,
    they will get what they deserve.
    
    Note that the refined_jiffies uncertainty_margin field is initialized to
    TICK_NSEC, which means that skew checks involving this clocksource will
    be sufficently forgiving.  In a similar vein, the clocksource_tsc_early
    uncertainty_margin field is initialized to 32*NSEC_PER_MSEC, which
    replicates the current behavior and allows custom setting if needed
    in order to address the rare skews detected for this clocksource in
    current mainline.
    Suggested-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Acked-by: default avatarFeng Tang <feng.tang@intel.com>
    Link: https://lore.kernel.org/r/20210527190124.440372-4-paulmck@kernel.org
    2e27e793
clocksource.c 39.9 KB