]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
.35 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Mon, 23 Aug 2010 23:40:24 +0000 (16:40 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 23 Aug 2010 23:40:24 +0000 (16:40 -0700)
queue-2.6.35/series
queue-2.6.35/time-workaround-gcc-loop-optimization-that-causes-64bit-div-errors.patch [new file with mode: 0644]
queue-2.6.35/timekeeping-fix-overflow-in-rawtime-tv_nsec-on-32-bit-archs.patch [new file with mode: 0644]

index 2e00867d3d0145bbd74fcec271c900dbc19b6b74..87323985e41e3dd29419a0d944473f818ffe26b3 100644 (file)
@@ -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 (file)
index 0000000..ba232bb
--- /dev/null
@@ -0,0 +1,49 @@
+From c7dcf87a6881bf796faee83003163eb3de41a309 Mon Sep 17 00:00:00 2001
+From: John Stultz <johnstul@us.ibm.com>
+Date: Fri, 13 Aug 2010 11:30:58 -0700
+Subject: time: Workaround gcc loop optimization that causes 64bit div errors
+
+From: John Stultz <johnstul@us.ibm.com>
+
+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 <johnstul@us.ibm.com>
+CC: Jason Wessel <jason.wessel@windriver.com>
+CC: Larry Finger <Larry.Finger@lwfinger.net>
+CC: Ingo Molnar <mingo@elte.hu>
+CC: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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 (file)
index 0000000..3606c93
--- /dev/null
@@ -0,0 +1,70 @@
+From deda2e81961e96be4f2c09328baca4710a2fd1a0 Mon Sep 17 00:00:00 2001
+From: Jason Wessel <jason.wessel@windriver.com>
+Date: Mon, 9 Aug 2010 14:20:09 -0700
+Subject: timekeeping: Fix overflow in rawtime tv_nsec on 32 bit archs
+
+From: Jason Wessel <jason.wessel@windriver.com>
+
+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 <jason.wessel@windriver.com>
+ [ Reworked variable names and simplified some of the code. - John ]
+Signed-off-by: John Stultz <johnstul@us.ibm.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: H. Peter Anvin <hpa@zytor.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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<<shift)
+@@ -752,12 +753,14 @@ static cycle_t logarithmic_accumulation(
+               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;