2018-11-01 02:21:09 +08:00
|
|
|
// SPDX-License-Identifier: GPL-2.0+
|
2018-11-01 02:21:12 +08:00
|
|
|
/*
|
|
|
|
* This file contains the jiffies based clocksource.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2004, 2005 IBM, John Stultz (johnstul@us.ibm.com)
|
|
|
|
*/
|
2006-06-26 15:25:05 +08:00
|
|
|
#include <linux/clocksource.h>
|
|
|
|
#include <linux/jiffies.h>
|
2011-01-27 22:59:00 +08:00
|
|
|
#include <linux/module.h>
|
2006-06-26 15:25:05 +08:00
|
|
|
#include <linux/init.h>
|
|
|
|
|
2015-03-25 20:06:04 +08:00
|
|
|
#include "timekeeping.h"
|
2021-08-13 00:31:28 +08:00
|
|
|
#include "tick-internal.h"
|
2011-01-27 23:00:32 +08:00
|
|
|
|
2006-06-26 15:25:05 +08:00
|
|
|
|
2016-12-22 03:32:01 +08:00
|
|
|
static u64 jiffies_read(struct clocksource *cs)
|
2006-06-26 15:25:05 +08:00
|
|
|
{
|
2016-12-22 03:32:01 +08:00
|
|
|
return (u64) jiffies;
|
2006-06-26 15:25:05 +08:00
|
|
|
}
|
|
|
|
|
2017-01-31 11:09:16 +08:00
|
|
|
/*
|
|
|
|
* The Jiffies based clocksource is the lowest common
|
|
|
|
* denominator clock source which should function on
|
|
|
|
* all systems. It has the same coarse resolution as
|
|
|
|
* the timer interrupt frequency HZ and it suffers
|
|
|
|
* inaccuracies caused by missed or lost timer
|
|
|
|
* interrupts and the inability for the timer
|
2021-03-23 05:39:03 +08:00
|
|
|
* interrupt hardware to accurately tick at the
|
2017-01-31 11:09:16 +08:00
|
|
|
* requested HZ value. It is also not recommended
|
|
|
|
* for "tick-less" systems.
|
|
|
|
*/
|
2012-10-18 17:34:41 +08:00
|
|
|
static struct clocksource clocksource_jiffies = {
|
clocksource: Reduce clocksource-skew threshold
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: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Feng Tang <feng.tang@intel.com>
Link: https://lore.kernel.org/r/20210527190124.440372-4-paulmck@kernel.org
2021-05-28 03:01:22 +08:00
|
|
|
.name = "jiffies",
|
|
|
|
.rating = 1, /* lowest valid rating*/
|
|
|
|
.uncertainty_margin = 32 * NSEC_PER_MSEC,
|
|
|
|
.read = jiffies_read,
|
|
|
|
.mask = CLOCKSOURCE_MASK(32),
|
|
|
|
.mult = TICK_NSEC << JIFFIES_SHIFT, /* details above */
|
|
|
|
.shift = JIFFIES_SHIFT,
|
|
|
|
.max_cycles = 10,
|
2006-06-26 15:25:05 +08:00
|
|
|
};
|
|
|
|
|
2020-03-21 19:25:58 +08:00
|
|
|
__cacheline_aligned_in_smp DEFINE_RAW_SPINLOCK(jiffies_lock);
|
2020-10-22 03:07:49 +08:00
|
|
|
__cacheline_aligned_in_smp seqcount_raw_spinlock_t jiffies_seq =
|
|
|
|
SEQCNT_RAW_SPINLOCK_ZERO(jiffies_seq, &jiffies_lock);
|
2012-02-29 08:50:11 +08:00
|
|
|
|
2011-01-27 22:59:00 +08:00
|
|
|
#if (BITS_PER_LONG < 64)
|
|
|
|
u64 get_jiffies_64(void)
|
|
|
|
{
|
2019-03-19 03:55:56 +08:00
|
|
|
unsigned int seq;
|
2011-01-27 22:59:00 +08:00
|
|
|
u64 ret;
|
|
|
|
|
|
|
|
do {
|
2020-03-21 19:25:58 +08:00
|
|
|
seq = read_seqcount_begin(&jiffies_seq);
|
2011-01-27 22:59:00 +08:00
|
|
|
ret = jiffies_64;
|
2020-03-21 19:25:58 +08:00
|
|
|
} while (read_seqcount_retry(&jiffies_seq, seq));
|
2011-01-27 22:59:00 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(get_jiffies_64);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
EXPORT_SYMBOL(jiffies);
|
|
|
|
|
2006-06-26 15:25:05 +08:00
|
|
|
static int __init init_jiffies_clocksource(void)
|
|
|
|
{
|
2015-03-12 12:16:37 +08:00
|
|
|
return __clocksource_register(&clocksource_jiffies);
|
2006-06-26 15:25:05 +08:00
|
|
|
}
|
|
|
|
|
2007-04-05 10:08:24 +08:00
|
|
|
core_initcall(init_jiffies_clocksource);
|
2009-08-14 21:47:21 +08:00
|
|
|
|
|
|
|
struct clocksource * __init __weak clocksource_default_clock(void)
|
|
|
|
{
|
|
|
|
return &clocksource_jiffies;
|
|
|
|
}
|
jiffies: Remove compile time assumptions about CLOCK_TICK_RATE
CLOCK_TICK_RATE is used to accurately caclulate exactly how
a tick will be at a given HZ.
This is useful, because while we'd expect NSEC_PER_SEC/HZ,
the underlying hardware will have some granularity limit,
so we won't be able to have exactly HZ ticks per second.
This slight error can cause timekeeping quality problems
when using the jiffies or other jiffies driven clocksources.
Thus we currently use compile time CLOCK_TICK_RATE value to
generate SHIFTED_HZ and NSEC_PER_JIFFIES, which we then use
to adjust the jiffies clocksource to correct this error.
Unfortunately though, since CLOCK_TICK_RATE is a compile
time value, and the jiffies clocksource is registered very
early during boot, there are a number of cases where there
are different possible hardware timers that have different
tick rates. This causes problems in cases like ARM where
there are numerous different types of hardware, each having
their own compile-time CLOCK_TICK_RATE, making it hard to
accurately support different hardware with a single kernel.
For the most part, this doesn't matter all that much, as not
too many systems actually utilize the jiffies or jiffies driven
clocksource. Usually there are other highres clocksources
who's granularity error is negligable.
Even so, we have some complicated calcualtions that we do
everywhere to handle these edge cases.
This patch removes the compile time SHIFTED_HZ value, and
introduces a register_refined_jiffies() function. This results
in the default jiffies clock as being assumed a perfect HZ
freq, and allows archtectures that care about jiffies accuracy
to call register_refined_jiffies() with the tick rate, specified
dynamically at boot.
This allows us, where necessary, to not have a compile time
CLOCK_TICK_RATE constant, simplifies the jiffies code, and
still provides a way to have an accurate jiffies clock.
NOTE: Since this patch does not add register_refinied_jiffies()
calls for every arch, it may cause time quality regressions
in some cases. Its likely these will not be noticable, but
if they are an issue, adding the following to the end of
setup_arch() should resolve the regression:
register_refinied_jiffies(CLOCK_TICK_RATE)
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: John Stultz <john.stultz@linaro.org>
2012-09-05 00:42:27 +08:00
|
|
|
|
2019-03-12 16:38:35 +08:00
|
|
|
static struct clocksource refined_jiffies;
|
jiffies: Remove compile time assumptions about CLOCK_TICK_RATE
CLOCK_TICK_RATE is used to accurately caclulate exactly how
a tick will be at a given HZ.
This is useful, because while we'd expect NSEC_PER_SEC/HZ,
the underlying hardware will have some granularity limit,
so we won't be able to have exactly HZ ticks per second.
This slight error can cause timekeeping quality problems
when using the jiffies or other jiffies driven clocksources.
Thus we currently use compile time CLOCK_TICK_RATE value to
generate SHIFTED_HZ and NSEC_PER_JIFFIES, which we then use
to adjust the jiffies clocksource to correct this error.
Unfortunately though, since CLOCK_TICK_RATE is a compile
time value, and the jiffies clocksource is registered very
early during boot, there are a number of cases where there
are different possible hardware timers that have different
tick rates. This causes problems in cases like ARM where
there are numerous different types of hardware, each having
their own compile-time CLOCK_TICK_RATE, making it hard to
accurately support different hardware with a single kernel.
For the most part, this doesn't matter all that much, as not
too many systems actually utilize the jiffies or jiffies driven
clocksource. Usually there are other highres clocksources
who's granularity error is negligable.
Even so, we have some complicated calcualtions that we do
everywhere to handle these edge cases.
This patch removes the compile time SHIFTED_HZ value, and
introduces a register_refined_jiffies() function. This results
in the default jiffies clock as being assumed a perfect HZ
freq, and allows archtectures that care about jiffies accuracy
to call register_refined_jiffies() with the tick rate, specified
dynamically at boot.
This allows us, where necessary, to not have a compile time
CLOCK_TICK_RATE constant, simplifies the jiffies code, and
still provides a way to have an accurate jiffies clock.
NOTE: Since this patch does not add register_refinied_jiffies()
calls for every arch, it may cause time quality regressions
in some cases. Its likely these will not be noticable, but
if they are an issue, adding the following to the end of
setup_arch() should resolve the regression:
register_refinied_jiffies(CLOCK_TICK_RATE)
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: John Stultz <john.stultz@linaro.org>
2012-09-05 00:42:27 +08:00
|
|
|
|
|
|
|
int register_refined_jiffies(long cycles_per_second)
|
|
|
|
{
|
|
|
|
u64 nsec_per_tick, shift_hz;
|
|
|
|
long cycles_per_tick;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
refined_jiffies = clocksource_jiffies;
|
|
|
|
refined_jiffies.name = "refined-jiffies";
|
|
|
|
refined_jiffies.rating++;
|
|
|
|
|
|
|
|
/* Calc cycles per tick */
|
|
|
|
cycles_per_tick = (cycles_per_second + HZ/2)/HZ;
|
|
|
|
/* shift_hz stores hz<<8 for extra accuracy */
|
|
|
|
shift_hz = (u64)cycles_per_second << 8;
|
|
|
|
shift_hz += cycles_per_tick/2;
|
|
|
|
do_div(shift_hz, cycles_per_tick);
|
|
|
|
/* Calculate nsec_per_tick using shift_hz */
|
2017-03-07 17:55:34 +08:00
|
|
|
nsec_per_tick = (u64)NSEC_PER_SEC << 8;
|
jiffies: Remove compile time assumptions about CLOCK_TICK_RATE
CLOCK_TICK_RATE is used to accurately caclulate exactly how
a tick will be at a given HZ.
This is useful, because while we'd expect NSEC_PER_SEC/HZ,
the underlying hardware will have some granularity limit,
so we won't be able to have exactly HZ ticks per second.
This slight error can cause timekeeping quality problems
when using the jiffies or other jiffies driven clocksources.
Thus we currently use compile time CLOCK_TICK_RATE value to
generate SHIFTED_HZ and NSEC_PER_JIFFIES, which we then use
to adjust the jiffies clocksource to correct this error.
Unfortunately though, since CLOCK_TICK_RATE is a compile
time value, and the jiffies clocksource is registered very
early during boot, there are a number of cases where there
are different possible hardware timers that have different
tick rates. This causes problems in cases like ARM where
there are numerous different types of hardware, each having
their own compile-time CLOCK_TICK_RATE, making it hard to
accurately support different hardware with a single kernel.
For the most part, this doesn't matter all that much, as not
too many systems actually utilize the jiffies or jiffies driven
clocksource. Usually there are other highres clocksources
who's granularity error is negligable.
Even so, we have some complicated calcualtions that we do
everywhere to handle these edge cases.
This patch removes the compile time SHIFTED_HZ value, and
introduces a register_refined_jiffies() function. This results
in the default jiffies clock as being assumed a perfect HZ
freq, and allows archtectures that care about jiffies accuracy
to call register_refined_jiffies() with the tick rate, specified
dynamically at boot.
This allows us, where necessary, to not have a compile time
CLOCK_TICK_RATE constant, simplifies the jiffies code, and
still provides a way to have an accurate jiffies clock.
NOTE: Since this patch does not add register_refinied_jiffies()
calls for every arch, it may cause time quality regressions
in some cases. Its likely these will not be noticable, but
if they are an issue, adding the following to the end of
setup_arch() should resolve the regression:
register_refinied_jiffies(CLOCK_TICK_RATE)
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: John Stultz <john.stultz@linaro.org>
2012-09-05 00:42:27 +08:00
|
|
|
nsec_per_tick += (u32)shift_hz/2;
|
|
|
|
do_div(nsec_per_tick, (u32)shift_hz);
|
|
|
|
|
|
|
|
refined_jiffies.mult = ((u32)nsec_per_tick) << JIFFIES_SHIFT;
|
|
|
|
|
2015-03-12 12:16:37 +08:00
|
|
|
__clocksource_register(&refined_jiffies);
|
jiffies: Remove compile time assumptions about CLOCK_TICK_RATE
CLOCK_TICK_RATE is used to accurately caclulate exactly how
a tick will be at a given HZ.
This is useful, because while we'd expect NSEC_PER_SEC/HZ,
the underlying hardware will have some granularity limit,
so we won't be able to have exactly HZ ticks per second.
This slight error can cause timekeeping quality problems
when using the jiffies or other jiffies driven clocksources.
Thus we currently use compile time CLOCK_TICK_RATE value to
generate SHIFTED_HZ and NSEC_PER_JIFFIES, which we then use
to adjust the jiffies clocksource to correct this error.
Unfortunately though, since CLOCK_TICK_RATE is a compile
time value, and the jiffies clocksource is registered very
early during boot, there are a number of cases where there
are different possible hardware timers that have different
tick rates. This causes problems in cases like ARM where
there are numerous different types of hardware, each having
their own compile-time CLOCK_TICK_RATE, making it hard to
accurately support different hardware with a single kernel.
For the most part, this doesn't matter all that much, as not
too many systems actually utilize the jiffies or jiffies driven
clocksource. Usually there are other highres clocksources
who's granularity error is negligable.
Even so, we have some complicated calcualtions that we do
everywhere to handle these edge cases.
This patch removes the compile time SHIFTED_HZ value, and
introduces a register_refined_jiffies() function. This results
in the default jiffies clock as being assumed a perfect HZ
freq, and allows archtectures that care about jiffies accuracy
to call register_refined_jiffies() with the tick rate, specified
dynamically at boot.
This allows us, where necessary, to not have a compile time
CLOCK_TICK_RATE constant, simplifies the jiffies code, and
still provides a way to have an accurate jiffies clock.
NOTE: Since this patch does not add register_refinied_jiffies()
calls for every arch, it may cause time quality regressions
in some cases. Its likely these will not be noticable, but
if they are an issue, adding the following to the end of
setup_arch() should resolve the regression:
register_refinied_jiffies(CLOCK_TICK_RATE)
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: John Stultz <john.stultz@linaro.org>
2012-09-05 00:42:27 +08:00
|
|
|
return 0;
|
|
|
|
}
|