diff options
author | John Stultz <john.stultz@linaro.org> | 2011-10-31 17:06:35 -0400 |
---|---|---|
committer | John Stultz <john.stultz@linaro.org> | 2011-11-10 14:27:08 -0500 |
commit | d65670a78cdbfae94f20a9e05ec705871d7cdf2b (patch) | |
tree | 3c16dedb75fa5ab6c0fdc072cc8d73df01d43a17 /include/linux/clocksource.h | |
parent | e35f95b36e43f67a6f806172555a152c11ea0a78 (diff) |
clocksource: Avoid selecting mult values that might overflow when adjusted
For some frequencies, the clocks_calc_mult_shift() function will
unfortunately select mult values very close to 0xffffffff. This
has the potential to overflow when NTP adjusts the clock, adding
to the mult value.
This patch adds a clocksource.maxadj value, which provides
an approximation of an 11% adjustment(NTP limits adjustments to
500ppm and the tick adjustment is limited to 10%), which could
be made to the clocksource.mult value. This is then used to both
check that the current mult value won't overflow/underflow, as
well as warning us if the timekeeping_adjust() code pushes over
that 11% boundary.
v2: Fix max_adjustment calculation, and improve WARN_ONCE
messages.
v3: Don't warn before maxadj has actually been set
CC: Yong Zhang <yong.zhang0@gmail.com>
CC: David Daney <ddaney.cavm@gmail.com>
CC: Thomas Gleixner <tglx@linutronix.de>
CC: Chen Jie <chenj@lemote.com>
CC: zhangfx <zhangfx@lemote.com>
CC: stable@kernel.org
Reported-by: Chen Jie <chenj@lemote.com>
Reported-by: zhangfx <zhangfx@lemote.com>
Tested-by: Yong Zhang <yong.zhang0@gmail.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Diffstat (limited to 'include/linux/clocksource.h')
-rw-r--r-- | include/linux/clocksource.h | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index 139c4db55f17..c86c940d1de3 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h | |||
@@ -156,6 +156,7 @@ extern u64 timecounter_cyc2time(struct timecounter *tc, | |||
156 | * @mult: cycle to nanosecond multiplier | 156 | * @mult: cycle to nanosecond multiplier |
157 | * @shift: cycle to nanosecond divisor (power of two) | 157 | * @shift: cycle to nanosecond divisor (power of two) |
158 | * @max_idle_ns: max idle time permitted by the clocksource (nsecs) | 158 | * @max_idle_ns: max idle time permitted by the clocksource (nsecs) |
159 | * @maxadj maximum adjustment value to mult (~11%) | ||
159 | * @flags: flags describing special properties | 160 | * @flags: flags describing special properties |
160 | * @archdata: arch-specific data | 161 | * @archdata: arch-specific data |
161 | * @suspend: suspend function for the clocksource, if necessary | 162 | * @suspend: suspend function for the clocksource, if necessary |
@@ -172,7 +173,7 @@ struct clocksource { | |||
172 | u32 mult; | 173 | u32 mult; |
173 | u32 shift; | 174 | u32 shift; |
174 | u64 max_idle_ns; | 175 | u64 max_idle_ns; |
175 | 176 | u32 maxadj; | |
176 | #ifdef CONFIG_ARCH_CLOCKSOURCE_DATA | 177 | #ifdef CONFIG_ARCH_CLOCKSOURCE_DATA |
177 | struct arch_clocksource_data archdata; | 178 | struct arch_clocksource_data archdata; |
178 | #endif | 179 | #endif |