2018-10-31 21:21:09 +03:00
|
|
|
// SPDX-License-Identifier: GPL-2.0+
|
2018-10-31 21:21:12 +03:00
|
|
|
/*
|
|
|
|
* This file contains the jiffies based clocksource.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2004, 2005 IBM, John Stultz (johnstul@us.ibm.com)
|
|
|
|
*/
|
2006-06-26 11:25:05 +04:00
|
|
|
#include <linux/clocksource.h>
|
|
|
|
#include <linux/jiffies.h>
|
2011-01-27 17:59:00 +03:00
|
|
|
#include <linux/module.h>
|
2006-06-26 11:25:05 +04:00
|
|
|
#include <linux/init.h>
|
|
|
|
|
2015-03-25 15:06:04 +03:00
|
|
|
#include "timekeeping.h"
|
2011-01-27 18:00:32 +03:00
|
|
|
|
2006-06-26 11:25:05 +04:00
|
|
|
|
2017-01-31 06:09:16 +03:00
|
|
|
/* Since jiffies uses a simple TICK_NSEC multiplier
|
2006-06-26 11:25:05 +04:00
|
|
|
* conversion, the .shift value could be zero. However
|
|
|
|
* this would make NTP adjustments impossible as they are
|
|
|
|
* in units of 1/2^.shift. Thus we use JIFFIES_SHIFT to
|
|
|
|
* shift both the nominator and denominator the same
|
|
|
|
* amount, and give ntp adjustments in units of 1/2^8
|
|
|
|
*
|
|
|
|
* The value 8 is somewhat carefully chosen, as anything
|
2017-01-31 06:09:16 +03:00
|
|
|
* larger can result in overflows. TICK_NSEC grows as HZ
|
|
|
|
* shrinks, so values greater than 8 overflow 32bits when
|
2006-06-26 11:25:05 +04:00
|
|
|
* HZ=100.
|
|
|
|
*/
|
2014-01-25 01:41:36 +04:00
|
|
|
#if HZ < 34
|
|
|
|
#define JIFFIES_SHIFT 6
|
|
|
|
#elif HZ < 67
|
|
|
|
#define JIFFIES_SHIFT 7
|
|
|
|
#else
|
2006-06-26 11:25:05 +04:00
|
|
|
#define JIFFIES_SHIFT 8
|
2014-01-25 01:41:36 +04:00
|
|
|
#endif
|
2006-06-26 11:25:05 +04:00
|
|
|
|
2016-12-21 22:32:01 +03:00
|
|
|
static u64 jiffies_read(struct clocksource *cs)
|
2006-06-26 11:25:05 +04:00
|
|
|
{
|
2016-12-21 22:32:01 +03:00
|
|
|
return (u64) jiffies;
|
2006-06-26 11:25:05 +04:00
|
|
|
}
|
|
|
|
|
2017-01-31 06:09:16 +03: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
|
|
|
|
* interrupt hardware to accuratly tick at the
|
|
|
|
* requested HZ value. It is also not recommended
|
|
|
|
* for "tick-less" systems.
|
|
|
|
*/
|
2012-10-18 13:34:41 +04:00
|
|
|
static struct clocksource clocksource_jiffies = {
|
2006-06-26 11:25:05 +04:00
|
|
|
.name = "jiffies",
|
2006-10-17 11:09:32 +04:00
|
|
|
.rating = 1, /* lowest valid rating*/
|
2006-06-26 11:25:05 +04:00
|
|
|
.read = jiffies_read,
|
2016-02-27 06:14:14 +03:00
|
|
|
.mask = CLOCKSOURCE_MASK(32),
|
2017-01-31 06:09:16 +03:00
|
|
|
.mult = TICK_NSEC << JIFFIES_SHIFT, /* details above */
|
2006-06-26 11:25:05 +04:00
|
|
|
.shift = JIFFIES_SHIFT,
|
2015-03-12 07:16:32 +03:00
|
|
|
.max_cycles = 10,
|
2006-06-26 11:25:05 +04:00
|
|
|
};
|
|
|
|
|
2012-02-29 04:50:11 +04:00
|
|
|
__cacheline_aligned_in_smp DEFINE_SEQLOCK(jiffies_lock);
|
|
|
|
|
2011-01-27 17:59:00 +03:00
|
|
|
#if (BITS_PER_LONG < 64)
|
|
|
|
u64 get_jiffies_64(void)
|
|
|
|
{
|
|
|
|
unsigned long seq;
|
|
|
|
u64 ret;
|
|
|
|
|
|
|
|
do {
|
2012-02-29 04:50:11 +04:00
|
|
|
seq = read_seqbegin(&jiffies_lock);
|
2011-01-27 17:59:00 +03:00
|
|
|
ret = jiffies_64;
|
2012-02-29 04:50:11 +04:00
|
|
|
} while (read_seqretry(&jiffies_lock, seq));
|
2011-01-27 17:59:00 +03:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(get_jiffies_64);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
EXPORT_SYMBOL(jiffies);
|
|
|
|
|
2006-06-26 11:25:05 +04:00
|
|
|
static int __init init_jiffies_clocksource(void)
|
|
|
|
{
|
2015-03-12 07:16:37 +03:00
|
|
|
return __clocksource_register(&clocksource_jiffies);
|
2006-06-26 11:25:05 +04:00
|
|
|
}
|
|
|
|
|
2007-04-05 06:08:24 +04:00
|
|
|
core_initcall(init_jiffies_clocksource);
|
2009-08-14 17:47:21 +04: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-04 20:42:27 +04:00
|
|
|
|
|
|
|
struct clocksource refined_jiffies;
|
|
|
|
|
|
|
|
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 12:55:34 +03: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-04 20:42:27 +04: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 07:16:37 +03: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-04 20:42:27 +04:00
|
|
|
return 0;
|
|
|
|
}
|