* [PATCH 0/2] Timekeeping Fixes
@ 2010-08-09 21:20 John Stultz
2010-08-09 21:20 ` [PATCH 1/2] timekeeping: Fix overflow in rawtime tv_nsec on 32 bit archs John Stultz
0 siblings, 1 reply; 3+ messages in thread
From: John Stultz @ 2010-08-09 21:20 UTC (permalink / raw)
To: linux-kernel; +Cc: John Stultz, Thomas Gleixner
Hey Thomas,
Chris and Jason provided some fixes that are needed for
the 2.6.36-rc tree. I'll backport the overflow issue for
2.6.35-stable once it is upstream.
thanks
-john
Cc: Thomas Gleixner <tglx@linutronix.de>
Chris Wilson (1):
x86/hpet: Use the FSEC_PER_SEC constant for femto-second periods
Jason Wessel (1):
timekeeping: Fix overflow in rawtime tv_nsec on 32 bit archs
arch/x86/kernel/hpet.c | 4 ++--
include/linux/time.h | 2 +-
kernel/time/timekeeping.c | 11 +++++++----
3 files changed, 10 insertions(+), 7 deletions(-)
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 1/2] timekeeping: Fix overflow in rawtime tv_nsec on 32 bit archs
2010-08-09 21:20 [PATCH 0/2] Timekeeping Fixes John Stultz
@ 2010-08-09 21:20 ` John Stultz
2010-08-09 21:20 ` [PATCH 2/2] x86/hpet: Use the FSEC_PER_SEC constant for femto-second periods John Stultz
0 siblings, 1 reply; 3+ messages in thread
From: John Stultz @ 2010-08-09 21:20 UTC (permalink / raw)
To: linux-kernel; +Cc: Jason Wessel, John Stultz, Thomas Gleixner, H. Peter Anvin
From: Jason Wessel <jason.wessel@windriver.com>
The tv_nsec is a long and when added to the shifted interval it can wrap
and become negative which later causes looping problems in the
getrawmonotonic(). The edge case occurs when the system has slept for
a short period of time of ~2 seconds.
A trace printk of the values in this patch illustrate the problem:
ftrace time stamp: log
43.716079: logarithmic_accumulation: raw: 3d0913 tv_nsec d687faa
43.718513: logarithmic_accumulation: raw: 3d0913 tv_nsec da588bd
43.722161: logarithmic_accumulation: raw: 3d0913 tv_nsec de291d0
46.349925: logarithmic_accumulation: raw: 7a122600 tv_nsec e1f9ae3
46.349930: logarithmic_accumulation: raw: 1e848980 tv_nsec 8831c0e3
The kernel starts looping at 46.349925 in the getrawmonotonic() due to
the negative value from adding the raw value to tv_nsec.
A simple solution is to accumulate into a u64, and then normalize it
to a timespec_t.
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
Reworked variable names and sipmlified some of the code.
Signed-off-by: John Stultz <johnstul@us.ibm.com>
CC: Thomas Gleixner <tglx@linutronix.de>
CC: H. Peter Anvin <hpa@zytor.com>
---
kernel/time/timekeeping.c | 11 +++++++----
1 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index e14c839..e960d82 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -690,6 +690,7 @@ static void timekeeping_adjust(s64 offset)
static cycle_t logarithmic_accumulation(cycle_t offset, int shift)
{
u64 nsecps = (u64)NSEC_PER_SEC << timekeeper.shift;
+ u64 raw_nsecs;
/* If the offset is smaller then a shifted interval, do nothing */
if (offset < timekeeper.cycle_interval<<shift)
@@ -706,12 +707,14 @@ static cycle_t logarithmic_accumulation(cycle_t offset, int shift)
second_overflow();
}
- /* Accumulate into raw time */
- raw_time.tv_nsec += timekeeper.raw_interval << shift;;
- while (raw_time.tv_nsec >= NSEC_PER_SEC) {
- raw_time.tv_nsec -= NSEC_PER_SEC;
+ /* Accumulate raw time */
+ raw_nsecs = timekeeper.raw_interval << shift;
+ raw_nsecs += raw_time.tv_nsec;
+ while (raw_nsecs >= NSEC_PER_SEC) {
+ raw_nsecs -= NSEC_PER_SEC;
raw_time.tv_sec++;
}
+ raw_time.tv_nsec = raw_nsecs;
/* Accumulate error between NTP and clock interval */
timekeeper.ntp_error += tick_length << shift;
--
1.6.0.4
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 2/2] x86/hpet: Use the FSEC_PER_SEC constant for femto-second periods
2010-08-09 21:20 ` [PATCH 1/2] timekeeping: Fix overflow in rawtime tv_nsec on 32 bit archs John Stultz
@ 2010-08-09 21:20 ` John Stultz
0 siblings, 0 replies; 3+ messages in thread
From: John Stultz @ 2010-08-09 21:20 UTC (permalink / raw)
To: linux-kernel; +Cc: Chris Wilson, John Stultz, Thomas Gleixner
From: Chris Wilson <chris@chris-wilson.co.uk>
The current computation, introduced with f12a15be63, of FSEC_PER_SEC using
the multiplication of (FSEC_PER_NSEC * NSEC_PER_SEC) is performed only
with 32bit integers on small machines, resulting in an overflow and a
*very* short intervals being programmed. An interrupt storm follows.
Note that we also have to specify FSEC_PER_SEC as being long long to
overcome the same limitations.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: John Stultz <johnstul@us.ibm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/kernel/hpet.c | 4 ++--
include/linux/time.h | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 33dbcc4..351f9c0 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -582,7 +582,7 @@ static void init_one_hpet_msi_clockevent(struct hpet_dev *hdev, int cpu)
* scaled math multiplication factor for nanosecond to hpet tick
* conversion.
*/
- hpet_freq = 1000000000000000ULL;
+ hpet_freq = FSEC_PER_SEC;
do_div(hpet_freq, hpet_period);
evt->mult = div_sc((unsigned long) hpet_freq,
NSEC_PER_SEC, evt->shift);
@@ -837,7 +837,7 @@ static int hpet_clocksource_register(void)
* cyc/sec = FSEC_PER_SEC/hpet_period(fsec/cyc)
* cyc/sec = (FSEC_PER_NSEC * NSEC_PER_SEC)/hpet_period
*/
- hpet_freq = FSEC_PER_NSEC * NSEC_PER_SEC;
+ hpet_freq = FSEC_PER_SEC;
do_div(hpet_freq, hpet_period);
clocksource_register_hz(&clocksource_hpet, (u32)hpet_freq);
diff --git a/include/linux/time.h b/include/linux/time.h
index cb34e35..1261270 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -38,7 +38,7 @@ extern struct timezone sys_tz;
#define NSEC_PER_MSEC 1000000L
#define USEC_PER_SEC 1000000L
#define NSEC_PER_SEC 1000000000L
-#define FSEC_PER_SEC 1000000000000000L
+#define FSEC_PER_SEC 1000000000000000LL
#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
--
1.6.0.4
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2010-08-09 21:20 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-09 21:20 [PATCH 0/2] Timekeeping Fixes John Stultz
2010-08-09 21:20 ` [PATCH 1/2] timekeeping: Fix overflow in rawtime tv_nsec on 32 bit archs John Stultz
2010-08-09 21:20 ` [PATCH 2/2] x86/hpet: Use the FSEC_PER_SEC constant for femto-second periods John Stultz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®