]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.cc] runtime: allow more address bits in lfstack on Power64
authorAustin Clements <austin@google.com>
Wed, 19 Nov 2014 16:30:58 +0000 (11:30 -0500)
committerAustin Clements <austin@google.com>
Wed, 19 Nov 2014 16:30:58 +0000 (11:30 -0500)
Previously, lfstack assumed Linux limited user space addresses
to 43 bits on Power64 based on a paper from 2001.  It turns
out the limit is now 46 bits, so lfstack was truncating
pointers.

Raise the limit to 48 bits (for some future proofing and to
make it match amd64) and add a self-test that will fail in a
useful way if ever unpack(pack(x)) != x.

With this change, dev.cc passes all.bash on power64le.

LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/174430043

src/runtime/lfstack.go
src/runtime/lfstack_linux_power64x.go

index 4a20fff9d80f1931e5a06fce01b4ac803398e718..8a36a67b35706d170df6229cecf4e7562d7a4fda 100644 (file)
@@ -12,6 +12,10 @@ import "unsafe"
 func lfstackpush(head *uint64, node *lfnode) {
        node.pushcnt++
        new := lfstackPack(node, node.pushcnt)
+       if node1, _ := lfstackUnpack(new); node1 != node {
+               println("runtime: lfstackpush invalid packing: node=", node, " cnt=", hex(node.pushcnt), " packed=", hex(new), " -> node=", node1, "\n")
+               gothrow("lfstackpush")
+       }
        for {
                old := atomicload64(head)
                node.next, _ = lfstackUnpack(old)
index 7a122bf92c12659d7b248515db12a8d9df03331f..89e389fc726f664768d250ea0bda9b9cc2ef2fd9 100644 (file)
@@ -9,18 +9,24 @@ package runtime
 
 import "unsafe"
 
-// On Power64, Linux limits the user address space to 43 bits.
-// (https://www.kernel.org/doc/ols/2001/ppc64.pdf)
-// In addition to the 21 bits taken from the top, we can take 3 from the
-// bottom, because node must be pointer-aligned, giving a total of 24 bits
+// On Power64, Linux limits the user address space to 46 bits (see
+// TASK_SIZE_USER64 in the Linux kernel).  This has grown over time,
+// so here we allow 48 bit addresses.
+//
+// In addition to the 16 bits taken from the top, we can take 3 from the
+// bottom, because node must be pointer-aligned, giving a total of 19 bits
 // of count.
+const (
+       addrBits = 48
+       cntBits  = 64 - addrBits + 3
+)
 
 func lfstackPack(node *lfnode, cnt uintptr) uint64 {
-       return uint64(uintptr(unsafe.Pointer(node)))<<21 | uint64(cnt&(1<<24-1))
+       return uint64(uintptr(unsafe.Pointer(node)))<<(64-addrBits) | uint64(cnt&(1<<cntBits-1))
 }
 
 func lfstackUnpack(val uint64) (node *lfnode, cnt uintptr) {
-       node = (*lfnode)(unsafe.Pointer(uintptr(val >> 24 << 3)))
-       cnt = uintptr(val & (1<<24 - 1))
+       node = (*lfnode)(unsafe.Pointer(uintptr(val >> cntBits << 3)))
+       cnt = uintptr(val & (1<<cntBits - 1))
        return
 }