[kernel] r19753 - in dists/sid/linux/debian: . patches patches/bugfix/s390
Ben Hutchings
benh at alioth.debian.org
Sat Jan 19 20:00:26 UTC 2013
Author: benh
Date: Sat Jan 19 20:00:24 2013
New Revision: 19753
Log:
[s390] s390/time: fix sched_clock() overflow (Closes: #698382)
Added:
dists/sid/linux/debian/patches/bugfix/s390/s390-time-fix-sched_clock-overflow.patch
Modified:
dists/sid/linux/debian/changelog
dists/sid/linux/debian/patches/series
Modified: dists/sid/linux/debian/changelog
==============================================================================
--- dists/sid/linux/debian/changelog Sat Jan 19 19:59:07 2013 (r19752)
+++ dists/sid/linux/debian/changelog Sat Jan 19 20:00:24 2013 (r19753)
@@ -90,6 +90,7 @@
- sched: Adjust sched_reset_on_fork when nothing else changes
- sched: Queue RT tasks to head when prio drops
- sched: Consider pi boosting in setscheduler
+ * [s390] s390/time: fix sched_clock() overflow (Closes: #698382)
[ Aurelien Jarno ]
* [armhf/vexpress] Add kernel udebs.
Added: dists/sid/linux/debian/patches/bugfix/s390/s390-time-fix-sched_clock-overflow.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/bugfix/s390/s390-time-fix-sched_clock-overflow.patch Sat Jan 19 20:00:24 2013 (r19753)
@@ -0,0 +1,90 @@
+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(-)
+
+diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h
+index fba4d66..4c060bb 100644
+--- a/arch/s390/include/asm/timex.h
++++ b/arch/s390/include/asm/timex.h
+@@ -128,4 +128,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
+diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
+index aff0e35..a5f4f5a 100644
+--- a/arch/s390/kernel/time.c
++++ b/arch/s390/kernel/time.c
+@@ -63,7 +63,7 @@ static DEFINE_PER_CPU(struct clock_event_device, comparators);
+ */
+ unsigned long long notrace __kprobes sched_clock(void)
+ {
+- return (get_clock_monotonic() * 125) >> 9;
++ return tod_to_ns(get_clock_monotonic());
+ }
+
+ /*
+diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
+index c30615e..82c481d 100644
+--- a/arch/s390/kvm/interrupt.c
++++ b/arch/s390/kvm/interrupt.c
+@@ -408,7 +408,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);
Modified: dists/sid/linux/debian/patches/series
==============================================================================
--- dists/sid/linux/debian/patches/series Sat Jan 19 19:59:07 2013 (r19752)
+++ dists/sid/linux/debian/patches/series Sat Jan 19 20:00:24 2013 (r19753)
@@ -466,3 +466,4 @@
bugfix/all/vt6656-Fix-inconsistent-structure-packing.patch
bugfix/all/fs-cachefiles-add-support-for-large-files-in-filesys.patch
bugfix/x86/xen-Fix-stack-corruption-in-xen_failsafe_callback-fo.patch
+bugfix/s390/s390-time-fix-sched_clock-overflow.patch
More information about the Kernel-svn-changes
mailing list