From b01ee117f99d3258d5801580b27ab14bc1798df7 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 23 Aug 2010 16:40:24 -0700 Subject: [PATCH] .35 patches --- queue-2.6.35/series | 2 + ...ization-that-causes-64bit-div-errors.patch | 49 +++++++++++++ ...w-in-rawtime-tv_nsec-on-32-bit-archs.patch | 70 +++++++++++++++++++ 3 files changed, 121 insertions(+) create mode 100644 queue-2.6.35/time-workaround-gcc-loop-optimization-that-causes-64bit-div-errors.patch create mode 100644 queue-2.6.35/timekeeping-fix-overflow-in-rawtime-tv_nsec-on-32-bit-archs.patch diff --git a/queue-2.6.35/series b/queue-2.6.35/series index 2e00867d3d0..87323985e41 100644 --- a/queue-2.6.35/series +++ b/queue-2.6.35/series @@ -77,3 +77,5 @@ isdn-gigaset-add-missing-unlock.patch oprofile-change-cpuids-from-decimal-to-hex-and-add-some-comments.patch oprofile-add-support-for-intel-processor-model-30.patch drm-agp-i915-trim-stolen-space-to-32m.patch +timekeeping-fix-overflow-in-rawtime-tv_nsec-on-32-bit-archs.patch +time-workaround-gcc-loop-optimization-that-causes-64bit-div-errors.patch diff --git a/queue-2.6.35/time-workaround-gcc-loop-optimization-that-causes-64bit-div-errors.patch b/queue-2.6.35/time-workaround-gcc-loop-optimization-that-causes-64bit-div-errors.patch new file mode 100644 index 00000000000..ba232bbf749 --- /dev/null +++ b/queue-2.6.35/time-workaround-gcc-loop-optimization-that-causes-64bit-div-errors.patch @@ -0,0 +1,49 @@ +From c7dcf87a6881bf796faee83003163eb3de41a309 Mon Sep 17 00:00:00 2001 +From: John Stultz +Date: Fri, 13 Aug 2010 11:30:58 -0700 +Subject: time: Workaround gcc loop optimization that causes 64bit div errors + +From: John Stultz + +commit c7dcf87a6881bf796faee83003163eb3de41a309 upstream. + +Early 4.3 versions of gcc apparently aggressively optimize the raw +time accumulation loop, replacing it with a divide. + +On 32bit systems, this causes the following link errors: + undefined reference to `__umoddi3' + undefined reference to `__udivdi3' + +The gcc issue has been fixed in 4.4 and greater. + +This patch replaces the accumulation loop with a do_div, as suggested +by Linus. + +Signed-off-by: John Stultz +CC: Jason Wessel +CC: Larry Finger +CC: Ingo Molnar +CC: Linus Torvalds +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/time/timekeeping.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/kernel/time/timekeeping.c ++++ b/kernel/time/timekeeping.c +@@ -756,9 +756,10 @@ static cycle_t logarithmic_accumulation( + /* 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++; ++ if (raw_nsecs >= NSEC_PER_SEC) { ++ u64 raw_secs = raw_nsecs; ++ raw_nsecs = do_div(raw_secs, NSEC_PER_SEC); ++ raw_time.tv_sec += raw_secs; + } + raw_time.tv_nsec = raw_nsecs; + diff --git a/queue-2.6.35/timekeeping-fix-overflow-in-rawtime-tv_nsec-on-32-bit-archs.patch b/queue-2.6.35/timekeeping-fix-overflow-in-rawtime-tv_nsec-on-32-bit-archs.patch new file mode 100644 index 00000000000..3606c9324ad --- /dev/null +++ b/queue-2.6.35/timekeeping-fix-overflow-in-rawtime-tv_nsec-on-32-bit-archs.patch @@ -0,0 +1,70 @@ +From deda2e81961e96be4f2c09328baca4710a2fd1a0 Mon Sep 17 00:00:00 2001 +From: Jason Wessel +Date: Mon, 9 Aug 2010 14:20:09 -0700 +Subject: timekeeping: Fix overflow in rawtime tv_nsec on 32 bit archs + +From: Jason Wessel + +commit deda2e81961e96be4f2c09328baca4710a2fd1a0 upstream. + +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 + [ Reworked variable names and simplified some of the code. - John ] +Signed-off-by: John Stultz +Cc: Thomas Gleixner +Cc: H. Peter Anvin +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/time/timekeeping.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +--- a/kernel/time/timekeeping.c ++++ b/kernel/time/timekeeping.c +@@ -736,6 +736,7 @@ static void timekeeping_adjust(s64 offse + 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<= 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; -- 2.47.3