[kernel] r19751 - in dists/squeeze/linux-2.6/debian: . patches/bugfix/s390 patches/series
Ben Hutchings
benh at alioth.debian.org
Sat Jan 19 19:57:58 UTC 2013
Author: benh
Date: Sat Jan 19 19:57:57 2013
New Revision: 19751
Log:
[s390] s390/time: fix sched_clock() overflow
Added:
dists/squeeze/linux-2.6/debian/patches/bugfix/s390/s390-time-fix-sched_clock-overflow.patch
dists/squeeze/linux-2.6/debian/patches/series/48
Modified:
dists/squeeze/linux-2.6/debian/changelog
Modified: dists/squeeze/linux-2.6/debian/changelog
==============================================================================
--- dists/squeeze/linux-2.6/debian/changelog Sat Jan 19 19:29:08 2013 (r19750)
+++ dists/squeeze/linux-2.6/debian/changelog Sat Jan 19 19:57:57 2013 (r19751)
@@ -1,3 +1,10 @@
+linux-2.6 (2.6.32-48) UNRELEASED; urgency=low
+
+ [ Ben Hutchings ]
+ * [s390] s390/time: fix sched_clock() overflow
+
+ -- Ben Hutchings <ben at decadent.org.uk> Sat, 19 Jan 2013 19:57:27 +0000
+
linux-2.6 (2.6.32-47) stable; urgency=low
[ Ben Hutchings ]
Added: dists/squeeze/linux-2.6/debian/patches/bugfix/s390/s390-time-fix-sched_clock-overflow.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/bugfix/s390/s390-time-fix-sched_clock-overflow.patch Sat Jan 19 19:57:57 2013 (r19751)
@@ -0,0 +1,84 @@
+From: Heiko Carstens <heiko.carstens at de.ibm.com>
+Date: Mon, 14 Jan 2013 16:55:55 +0100
+Subject: s390/time: fix sched_clock() overflow
+
+commit ed4f20943cd4c7b55105c04daedf8d63ab6d499c upstream.
+
+Converting a 64 Bit TOD format value to nanoseconds means that the value
+must be divided by 4.096. In order to achieve that we multiply with 125
+and divide by 512.
+When used within sched_clock() this triggers an overflow after appr.
+417 days. Resulting in a sched_clock() return value that is much smaller
+than previously and therefore may cause all sort of weird things in
+subsystems that rely on a monotonic sched_clock() behaviour.
+
+To fix this implement a tod_to_ns() helper function which converts TOD
+values without overflow and call this function from both places that
+open coded the conversion: sched_clock() and kvm_s390_handle_wait().
+
+Reviewed-by: Martin Schwidefsky <schwidefsky at de.ibm.com>
+Signed-off-by: Heiko Carstens <heiko.carstens at de.ibm.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky at de.ibm.com>
+---
+ arch/s390/include/asm/timex.h | 28 ++++++++++++++++++++++++++++
+ arch/s390/kernel/time.c | 2 +-
+ arch/s390/kvm/interrupt.c | 2 +-
+ 3 files changed, 30 insertions(+), 2 deletions(-)
+
+--- a/arch/s390/include/asm/timex.h
++++ b/arch/s390/include/asm/timex.h
+@@ -112,4 +112,32 @@ static inline unsigned long long get_clock_monotonic(void)
+ return get_clock_xt() - sched_clock_base_cc;
+ }
+
++/**
++ * tod_to_ns - convert a TOD format value to nanoseconds
++ * @todval: to be converted TOD format value
++ * Returns: number of nanoseconds that correspond to the TOD format value
++ *
++ * Converting a 64 Bit TOD format value to nanoseconds means that the value
++ * must be divided by 4.096. In order to achieve that we multiply with 125
++ * and divide by 512:
++ *
++ * ns = (todval * 125) >> 9;
++ *
++ * In order to avoid an overflow with the multiplication we can rewrite this.
++ * With a split todval == 2^32 * th + tl (th upper 32 bits, tl lower 32 bits)
++ * we end up with
++ *
++ * ns = ((2^32 * th + tl) * 125 ) >> 9;
++ * -> ns = (2^23 * th * 125) + ((tl * 125) >> 9);
++ *
++ */
++static inline unsigned long long tod_to_ns(unsigned long long todval)
++{
++ unsigned long long ns;
++
++ ns = ((todval >> 32) << 23) * 125;
++ ns += ((todval & 0xffffffff) * 125) >> 9;
++ return ns;
++}
++
+ #endif
+--- a/arch/s390/kernel/time.c
++++ b/arch/s390/kernel/time.c
+@@ -69,7 +69,7 @@ static DEFINE_PER_CPU(struct clock_event_device, comparators);
+ */
+ unsigned long long notrace sched_clock(void)
+ {
+- return (get_clock_monotonic() * 125) >> 9;
++ return tod_to_ns(get_clock_monotonic());
+ }
+
+ /*
+--- a/arch/s390/kvm/interrupt.c
++++ b/arch/s390/kvm/interrupt.c
+@@ -357,7 +357,7 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu)
+ return 0;
+ }
+
+- sltime = ((vcpu->arch.sie_block->ckc - now)*125)>>9;
++ sltime = tod_to_ns(vcpu->arch.sie_block->ckc - now);
+
+ hrtimer_start(&vcpu->arch.ckc_timer, ktime_set (0, sltime) , HRTIMER_MODE_REL);
+ VCPU_EVENT(vcpu, 5, "enabled wait via clock comparator: %llx ns", sltime);
Added: dists/squeeze/linux-2.6/debian/patches/series/48
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/series/48 Sat Jan 19 19:57:57 2013 (r19751)
@@ -0,0 +1 @@
++ bugfix/s390/s390-time-fix-sched_clock-overflow.patch
More information about the Kernel-svn-changes
mailing list