aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorDave Cheney <dave@cheney.net>2015-02-26 20:29:58 +1100
committerDave Cheney <dave@cheney.net>2015-02-26 20:11:17 +0000
commitf9cc72ccfef0e1aa68f8c726c430bb7e59b734a8 (patch)
tree96133569d659f3e4ad4bac9d985ef7bd06a54e9d /src/runtime
parent045f9df466ac6d12a2be66a1c5d4659d113719bd (diff)
downloadgo-f9cc72ccfef0e1aa68f8c726c430bb7e59b734a8.tar.xz
runtime: disable scavenger on 64k page size kernels
Update #9993 If the physical page size of the machine is larger than the logical heap size, for example 8k logical, 64k physical, then madvise(2) will round up the requested amount to a 64k boundary and may discard pages close to the page being madvised. This patch disables the scavenger in these situations, which at the moment is only ppc64 and ppc64le systems. NaCl also uses a 64k page size, but it's not clear if it is affected by this problem. Change-Id: Ib897f8d3df5bd915ddc0b510f2fd90a30ef329ca Reviewed-on: https://go-review.googlesource.com/6091 Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/debug/garbage_test.go4
-rw-r--r--src/runtime/mheap.go9
2 files changed, 13 insertions, 0 deletions
diff --git a/src/runtime/debug/garbage_test.go b/src/runtime/debug/garbage_test.go
index 54c33bd4f3..a392614b1f 100644
--- a/src/runtime/debug/garbage_test.go
+++ b/src/runtime/debug/garbage_test.go
@@ -88,6 +88,10 @@ func TestReadGCStats(t *testing.T) {
var big = make([]byte, 1<<20)
func TestFreeOSMemory(t *testing.T) {
+ switch runtime.GOARCH {
+ case "ppc64", "ppc64le", "nacl":
+ t.Skip("issue 9993; scavenger temporarily disabled on systems with 64k pages")
+ }
var ms1, ms2 runtime.MemStats
if big == nil {
diff --git a/src/runtime/mheap.go b/src/runtime/mheap.go
index a05a570ff1..94ef4de56a 100644
--- a/src/runtime/mheap.go
+++ b/src/runtime/mheap.go
@@ -717,6 +717,15 @@ func mHeap_FreeSpanLocked(h *mheap, s *mspan, acctinuse, acctidle bool, unusedsi
}
func scavengelist(list *mspan, now, limit uint64) uintptr {
+ if _PhysPageSize > _PageSize {
+ // golang.org/issue/9993
+ // If the physical page size of the machine is larger than
+ // our logical heap page size the kernel may round up the
+ // amount to be freed to its page size and corrupt the heap
+ // pages surrounding the unused block.
+ return 0
+ }
+
if mSpanList_IsEmpty(list) {
return 0
}