From: Chris Wright <chrisw@sous-sol.org>
To: linux-kernel@vger.kernel.org, stable@kernel.org, greg@kroah.com
Cc: Justin Forbes <jmforbes@linuxtx.org>,
Zwane Mwaikambo <zwane@arm.linux.org.uk>,
"Theodore Ts'o" <tytso@mit.edu>,
Randy Dunlap <rdunlap@xenotime.net>,
Dave Jones <davej@redhat.com>,
Chuck Wolber <chuckw@quantumlinux.com>,
Chris Wedgwood <reviews@ml.cw.f00f.org>,
Michael Krufky <mkrufky@linuxtv.org>,
torvalds@osdl.org, akpm@osdl.org, alan@lxorguk.ukuu.org.uk,
Martin Schwidefsky <schwidefsky@de.ibm.com>,
Greg Kroah-Hartman <gregkh@suse.de>
Subject: [PATCH 03/61] [S390] __div64_32 for 31 bit.
Date: Tue, 31 Oct 2006 21:33:43 -0800 [thread overview]
Message-ID: <20061101053505.814495000@sous-sol.org> (raw)
In-Reply-To: 20061101053340.305569000@sous-sol.org
[-- Attachment #1: __div64_32-for-31-bit.patch --]
[-- Type: text/plain, Size: 7398 bytes --]
-stable review patch. If anyone has any objections, please let us know.
------------------
From: Martin Schwidefsky <schwidefsky@de.ibm.com>
The clocksource infrastructure introduced with commit
ad596171ed635c51a9eef829187af100cbf8dcf7 broke 31 bit s390.
The reason is that the do_div() primitive for 31 bit always
had a restriction: it could only divide an unsigned 64 bit
integer by an unsigned 31 bit integer. The clocksource code
now uses do_div() with a base value that has the most
significant bit set. The result is that clock->cycle_interval
has a funny value which causes the linux time to jump around
like mad.
The solution is "obvious": implement a proper __div64_32
function for 31 bit s390.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Chris Wright <chrisw@sous-sol.org>
---
arch/s390/Kconfig | 4 +
arch/s390/lib/Makefile | 1
arch/s390/lib/div64.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++
include/asm-s390/div64.h | 48 --------------
4 files changed, 156 insertions(+), 48 deletions(-)
--- linux-2.6.18.1.orig/arch/s390/Kconfig
+++ linux-2.6.18.1/arch/s390/Kconfig
@@ -51,6 +51,10 @@ config 64BIT
Select this option if you have a 64 bit IBM zSeries machine
and want to use the 64 bit addressing mode.
+config 32BIT
+ bool
+ default y if !64BIT
+
config SMP
bool "Symmetric multi-processing support"
---help---
--- linux-2.6.18.1.orig/arch/s390/lib/Makefile
+++ linux-2.6.18.1/arch/s390/lib/Makefile
@@ -7,3 +7,4 @@ EXTRA_AFLAGS := -traditional
lib-y += delay.o string.o
lib-y += $(if $(CONFIG_64BIT),uaccess64.o,uaccess.o)
lib-$(CONFIG_SMP) += spinlock.o
+lib-$(CONFIG_32BIT) += div64.o
--- /dev/null
+++ linux-2.6.18.1/arch/s390/lib/div64.c
@@ -0,0 +1,151 @@
+/*
+ * arch/s390/lib/div64.c
+ *
+ * __div64_32 implementation for 31 bit.
+ *
+ * Copyright (C) IBM Corp. 2006
+ * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
+ */
+
+#include <linux/types.h>
+#include <linux/module.h>
+
+#ifdef CONFIG_MARCH_G5
+
+/*
+ * Function to divide an unsigned 64 bit integer by an unsigned
+ * 31 bit integer using signed 64/32 bit division.
+ */
+static uint32_t __div64_31(uint64_t *n, uint32_t base)
+{
+ register uint32_t reg2 asm("2");
+ register uint32_t reg3 asm("3");
+ uint32_t *words = (uint32_t *) n;
+ uint32_t tmp;
+
+ /* Special case base==1, remainder = 0, quotient = n */
+ if (base == 1)
+ return 0;
+ /*
+ * Special case base==0 will cause a fixed point divide exception
+ * on the dr instruction and may not happen anyway. For the
+ * following calculation we can assume base > 1. The first
+ * signed 64 / 32 bit division with an upper half of 0 will
+ * give the correct upper half of the 64 bit quotient.
+ */
+ reg2 = 0UL;
+ reg3 = words[0];
+ asm volatile(
+ " dr %0,%2\n"
+ : "+d" (reg2), "+d" (reg3) : "d" (base) : "cc" );
+ words[0] = reg3;
+ reg3 = words[1];
+ /*
+ * To get the lower half of the 64 bit quotient and the 32 bit
+ * remainder we have to use a little trick. Since we only have
+ * a signed division the quotient can get too big. To avoid this
+ * the 64 bit dividend is halved, then the signed division will
+ * work. Afterwards the quotient and the remainder are doubled.
+ * If the last bit of the dividend has been one the remainder
+ * is increased by one then checked against the base. If the
+ * remainder has overflown subtract base and increase the
+ * quotient. Simple, no ?
+ */
+ asm volatile(
+ " nr %2,%1\n"
+ " srdl %0,1\n"
+ " dr %0,%3\n"
+ " alr %0,%0\n"
+ " alr %1,%1\n"
+ " alr %0,%2\n"
+ " clr %0,%3\n"
+ " jl 0f\n"
+ " slr %0,%3\n"
+ " alr %1,%2\n"
+ "0:\n"
+ : "+d" (reg2), "+d" (reg3), "=d" (tmp)
+ : "d" (base), "2" (1UL) : "cc" );
+ words[1] = reg3;
+ return reg2;
+}
+
+/*
+ * Function to divide an unsigned 64 bit integer by an unsigned
+ * 32 bit integer using the unsigned 64/31 bit division.
+ */
+uint32_t __div64_32(uint64_t *n, uint32_t base)
+{
+ uint32_t r;
+
+ /*
+ * If the most significant bit of base is set, divide n by
+ * (base/2). That allows to use 64/31 bit division and gives a
+ * good approximation of the result: n = (base/2)*q + r. The
+ * result needs to be corrected with two simple transformations.
+ * If base is already < 2^31-1 __div64_31 can be used directly.
+ */
+ r = __div64_31(n, ((signed) base < 0) ? (base/2) : base);
+ if ((signed) base < 0) {
+ uint64_t q = *n;
+ /*
+ * First transformation:
+ * n = (base/2)*q + r
+ * = ((base/2)*2)*(q/2) + ((q&1) ? (base/2) : 0) + r
+ * Since r < (base/2), r + (base/2) < base.
+ * With q1 = (q/2) and r1 = r + ((q&1) ? (base/2) : 0)
+ * n = ((base/2)*2)*q1 + r1 with r1 < base.
+ */
+ if (q & 1)
+ r += base/2;
+ q >>= 1;
+ /*
+ * Second transformation. ((base/2)*2) could have lost the
+ * last bit.
+ * n = ((base/2)*2)*q1 + r1
+ * = base*q1 - ((base&1) ? q1 : 0) + r1
+ */
+ if (base & 1) {
+ int64_t rx = r - q;
+ /*
+ * base is >= 2^31. The worst case for the while
+ * loop is n=2^64-1 base=2^31+1. That gives a
+ * maximum for q=(2^64-1)/2^31 = 0x1ffffffff. Since
+ * base >= 2^31 the loop is finished after a maximum
+ * of three iterations.
+ */
+ while (rx < 0) {
+ rx += base;
+ q--;
+ }
+ r = rx;
+ }
+ *n = q;
+ }
+ return r;
+}
+
+#else /* MARCH_G5 */
+
+uint32_t __div64_32(uint64_t *n, uint32_t base)
+{
+ register uint32_t reg2 asm("2");
+ register uint32_t reg3 asm("3");
+ uint32_t *words = (uint32_t *) n;
+
+ reg2 = 0UL;
+ reg3 = words[0];
+ asm volatile(
+ " dlr %0,%2\n"
+ : "+d" (reg2), "+d" (reg3) : "d" (base) : "cc" );
+ words[0] = reg3;
+ reg3 = words[1];
+ asm volatile(
+ " dlr %0,%2\n"
+ : "+d" (reg2), "+d" (reg3) : "d" (base) : "cc" );
+ words[1] = reg3;
+ return reg2;
+}
+
+#endif /* MARCH_G5 */
+
+EXPORT_SYMBOL(__div64_32);
--- linux-2.6.18.1.orig/include/asm-s390/div64.h
+++ linux-2.6.18.1/include/asm-s390/div64.h
@@ -1,49 +1 @@
-#ifndef __S390_DIV64
-#define __S390_DIV64
-
-#ifndef __s390x__
-
-/* for do_div "base" needs to be smaller than 2^31-1 */
-#define do_div(n, base) ({ \
- unsigned long long __n = (n); \
- unsigned long __r; \
- \
- asm (" slr 0,0\n" \
- " l 1,%1\n" \
- " srdl 0,1\n" \
- " dr 0,%2\n" \
- " alr 1,1\n" \
- " alr 0,0\n" \
- " lhi 2,1\n" \
- " n 2,%1\n" \
- " alr 0,2\n" \
- " clr 0,%2\n" \
- " jl 0f\n" \
- " slr 0,%2\n" \
- " ahi 1,1\n" \
- "0: st 1,%1\n" \
- " l 1,4+%1\n" \
- " srdl 0,1\n" \
- " dr 0,%2\n" \
- " alr 1,1\n" \
- " alr 0,0\n" \
- " lhi 2,1\n" \
- " n 2,4+%1\n" \
- " alr 0,2\n" \
- " clr 0,%2\n" \
- " jl 1f\n" \
- " slr 0,%2\n" \
- " ahi 1,1\n" \
- "1: st 1,4+%1\n" \
- " lr %0,0" \
- : "=d" (__r), "=m" (__n) \
- : "d" (base), "m" (__n) : "0", "1", "2", "cc" ); \
- (n) = (__n); \
- __r; \
-})
-
-#else /* __s390x__ */
#include <asm-generic/div64.h>
-#endif /* __s390x__ */
-
-#endif
--
next prev parent reply other threads:[~2006-11-01 5:36 UTC|newest]
Thread overview: 92+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-11-01 5:33 [PATCH 00/61] 2.6.18-stable review Chris Wright
2006-11-01 5:33 ` [PATCH 01/61] [DECNET]: Fix sfuzz hanging on 2.6.18 Chris Wright
2006-11-01 5:33 ` [PATCH 02/61] splice: fix pipe_to_file() ->prepare_write() error path Chris Wright
2006-11-01 5:33 ` Chris Wright [this message]
2006-11-01 5:33 ` [PATCH 04/61] mm: fix a race condition under SMC + COW Chris Wright
2006-11-01 5:33 ` [PATCH 05/61] sky2: MSI test race and message Chris Wright
2006-11-01 5:33 ` [PATCH 06/61] sky2: pause parameter adjustment Chris Wright
2006-11-01 5:33 ` [PATCH 07/61] sky2: turn off PHY IRQ on shutdown Chris Wright
2006-11-01 5:33 ` [PATCH 08/61] ALSA: emu10k1: Fix outl() in snd_emu10k1_resume_regs() Chris Wright
2006-11-01 5:33 ` [PATCH 09/61] ALSA: powermac - Fix Oops when conflicting with aoa driver Chris Wright
2006-11-01 5:33 ` [PATCH 10/61] sound/pci/au88x0/au88x0.c: ioremap balanced with iounmap Chris Wright
2006-11-01 5:33 ` [PATCH 11/61] ALSA: Dereference after free in snd_hwdep_release() Chris Wright
2006-11-01 5:33 ` [PATCH 12/61] ALSA: Fix bug in snd-usb-usx2ys usX2Y_pcms_lock_check() Chris Wright
2006-11-01 5:33 ` [PATCH 13/61] ALSA: Repair snd-usb-usx2y for usb 2.6.18 Chris Wright
2006-11-01 5:33 ` [PATCH 14/61] sky2: accept multicast pause frames Chris Wright
2006-11-01 5:33 ` [PATCH 15/61] sky2: GMAC pause frame Chris Wright
2006-11-01 5:33 ` [PATCH 16/61] uml: fix processor selection to exclude unsupported processors and features Chris Wright
2006-11-01 5:33 ` [PATCH 17/61] SCSI: DAC960: PCI id table fixup Chris Wright
2006-11-01 5:33 ` [PATCH 18/61] Fix uninitialised spinlock in via-pmu-backlight code Chris Wright
2006-11-01 5:33 ` [PATCH 19/61] SERIAL: Fix resume handling bug Chris Wright
2006-11-01 5:34 ` [PATCH 20/61] SERIAL: Fix oops when removing suspended serial port Chris Wright
2006-11-01 5:34 ` [PATCH 21/61] Bluetooth: Check if DLC is still attached to the TTY Chris Wright
2006-11-01 5:34 ` [PATCH 22/61] JFS: pageno needs to be long Chris Wright
2006-11-01 5:34 ` [PATCH 23/61] SPARC64: Fix central/FHC bus handling on Ex000 systems Chris Wright
2006-11-01 5:34 ` [PATCH 24/61] SPARC64: Fix memory corruption in pci_4u_free_consistent() Chris Wright
2006-11-01 5:34 ` [PATCH 25/61] bcm43xx: fix watchdog timeouts Chris Wright
2006-11-01 15:13 ` John W. Linville
2006-11-01 5:34 ` [PATCH 26/61] DVB: fix dvb_pll_attach for mt352/zl10353 in cx88-dvb, and nxt200x Chris Wright
2006-11-01 5:34 ` [PATCH 27/61] ALSA: Fix re-use of va_list Chris Wright
2006-11-01 5:34 ` [PATCH 28/61] md: Fix bug where spares dont always get rebuilt properly when they become live Chris Wright
2006-11-01 5:34 ` [PATCH 29/61] md: Fix calculation of ->degraded for multipath and raid10 Chris Wright
2006-11-01 5:34 ` [PATCH 30/61] knfsd: Fix race that can disable NFS server Chris Wright
2006-11-01 5:34 ` Chris Wright
2006-11-01 7:11 ` Willy Tarreau
2006-11-04 21:06 ` Willy Tarreau
2006-11-05 23:55 ` Neil Brown
2006-11-06 4:11 ` Willy Tarreau
2006-11-01 5:34 ` [PATCH 31/61] SCSI: aic7xxx: avoid checking SBLKCTL register for certain cards Chris Wright
2006-11-01 5:34 ` [PATCH 32/61] IPoIB: Rejoin all multicast groups after a port event Chris Wright
2006-11-01 5:34 ` [PATCH 33/61] IB/mthca: Use mmiowb after doorbell ring Chris Wright
2006-11-01 5:34 ` [PATCH 34/61] fuse: fix hang on SMP Chris Wright
2006-11-01 5:34 ` [PATCH 35/61] Fix potential interrupts during alternative patching Chris Wright
2006-11-01 5:34 ` [PATCH 36/61] sky2: 88E803X transmit lockup (2.6.18) Chris Wright
2006-11-01 5:34 ` [PATCH 37/61] SCSI: aic7xxx: pause sequencer before touching SBLKCTL Chris Wright
2006-11-01 5:34 ` [PATCH 38/61] Audit: fix missing ifdefs in syscall classes hookup for generic targets Chris Wright
2006-11-01 5:34 ` [PATCH 39/61] NET: Fix skb_segment() handling of fully linear SKBs Chris Wright
2006-11-01 5:34 ` [PATCH 40/61] SCTP: Always linearise packet on input Chris Wright
2006-11-01 7:17 ` Willy Tarreau
2006-11-01 6:23 ` David Miller
2006-11-01 5:34 ` [PATCH 41/61] x86-64: Fix C3 timer test Chris Wright
2006-11-01 6:19 ` Len Brown
2006-11-01 5:34 ` [PATCH 42/61] uml: make Uml compile on FC6 kernel headers Chris Wright
2006-11-01 5:34 ` [PATCH 43/61] uml: remove warnings added by previous -stable patch Chris Wright
2006-11-01 5:34 ` [PATCH 44/61] ALSA: snd_rtctimer: handle RTC interrupts with a tasklet Chris Wright
2006-11-01 5:34 ` [PATCH 45/61] Watchdog: sc1200wdt - fix missing pnp_unregister_driver() Chris Wright
2006-11-01 7:45 ` Willy Tarreau
2006-11-01 13:14 ` Wim Van Sebroeck
2006-11-01 5:34 ` [PATCH 46/61] fix Intel RNG detection Chris Wright
2006-11-20 23:45 ` Dave Jones
2006-11-21 2:21 ` [stable] " Chris Wright
2006-11-21 9:32 ` Jan Beulich
2006-11-22 1:50 ` Chris Wright
2006-11-22 7:53 ` Jan Beulich
2006-11-24 20:27 ` Dave Jones
2006-11-27 8:30 ` Jan Beulich
2006-11-29 8:46 ` Jan Beulich
2006-12-13 19:50 ` dean gaudet
2006-12-13 20:33 ` Chris Wright
2006-12-13 23:00 ` dean gaudet
2006-12-14 7:54 ` Jan Beulich
2006-12-14 8:40 ` dean gaudet
2006-12-14 10:12 ` Jan Beulich
2006-11-21 9:05 ` Michael Buesch
2006-11-01 5:34 ` [PATCH 47/61] posix-cpu-timers: prevent signal delivery starvation Chris Wright
2006-11-01 5:34 ` [PATCH 48/61] rtc-max6902: month conversion fix Chris Wright
2006-11-01 5:34 ` [PATCH 49/61] ISDN: fix drivers, by handling errors thrown by ->readstat() Chris Wright
2006-11-01 6:02 ` Jeff Garzik
2006-11-01 7:49 ` Willy Tarreau
2006-11-01 9:18 ` Karsten Keil
2006-11-01 5:34 ` [PATCH 50/61] SPARC64: Fix PCI memory space root resource on Hummingbird Chris Wright
2006-11-01 5:34 ` [PATCH 51/61] PCI: Remove quirk_via_abnormal_poweroff Chris Wright
2006-11-01 6:20 ` Len Brown
2006-11-01 5:34 ` [PATCH 52/61] Reintroduce NODES_SPAN_OTHER_NODES for powerpc Chris Wright
2006-11-01 5:34 ` [PATCH 53/61] NFS: nfs_lookup - dont hash dentry when optimising away the lookup Chris Wright
2006-11-01 5:34 ` [PATCH 54/61] vmscan: Fix temp_priority race Chris Wright
2006-11-01 5:34 ` [PATCH 55/61] Use min of two prio settings in calculating distress for reclaim Chris Wright
2006-11-01 5:34 ` [PATCH 56/61] fill_tgid: fix task_struct leak and possible oops Chris Wright
2006-11-01 5:34 ` [PATCH 57/61] JMB 368 PATA detection Chris Wright
2006-11-01 5:34 ` [PATCH 58/61] tcp: cubic scaling error Chris Wright
2006-11-01 5:34 ` [PATCH 59/61] IPV6: fix lockup via /proc/net/ip6_flowlabel [CVE-2006-5619] Chris Wright
2006-11-01 5:34 ` [PATCH 60/61] md: check bio address after mapping through partitions Chris Wright
2006-11-01 5:34 ` [PATCH 61/61] usbfs: private mutex for open, release, and remove Chris Wright
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20061101053505.814495000@sous-sol.org \
--to=chrisw@sous-sol.org \
--cc=akpm@osdl.org \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=chuckw@quantumlinux.com \
--cc=davej@redhat.com \
--cc=greg@kroah.com \
--cc=gregkh@suse.de \
--cc=jmforbes@linuxtx.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mkrufky@linuxtv.org \
--cc=rdunlap@xenotime.net \
--cc=reviews@ml.cw.f00f.org \
--cc=schwidefsky@de.ibm.com \
--cc=stable@kernel.org \
--cc=torvalds@osdl.org \
--cc=tytso@mit.edu \
--cc=zwane@arm.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.