author | Rich Burridge <rich.burridge@oracle.com> |
Tue, 20 Sep 2016 08:35:58 -0700 | |
changeset 6933 | e1fa2aa7bad7 |
parent 5331 | 9c955076ffe3 |
permissions | -rw-r--r-- |
5331
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
1 |
From 244294f821c9256394d29218ee1f17ab4313551f Mon Sep 17 00:00:00 2001 |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
2 |
From: Austin Clements <[email protected]> |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
3 |
Date: Wed, 30 Sep 2015 11:52:54 -0400 |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
4 |
Subject: [PATCH 37/63] [release-branch.go1.5] runtime: adjust huge page flags |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
5 |
only on huge page granularity |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
6 |
|
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
7 |
This fixes an issue where the runtime panics with "out of memory" or |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
8 |
"cannot allocate memory" even though there's ample memory by reducing |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
9 |
the number of memory mappings created by the memory allocator. |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
10 |
|
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
11 |
Commit 7e1b61c worked around issue #8832 where Linux's transparent |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
12 |
huge page support could dramatically increase the RSS of a Go process |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
13 |
by setting the MADV_NOHUGEPAGE flag on any regions of pages released |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
14 |
to the OS with MADV_DONTNEED. This had the side effect of also |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
15 |
increasing the number of VMAs (memory mappings) in a Go address space |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
16 |
because a separate VMA is needed for every region of the virtual |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
17 |
address space with different flags. Unfortunately, by default, Linux |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
18 |
limits the number of VMAs in an address space to 65530, and a large |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
19 |
heap can quickly reach this limit when the runtime starts scavenging |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
20 |
memory. |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
21 |
|
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
22 |
This commit dramatically reduces the number of VMAs. It does this |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
23 |
primarily by only adjusting the huge page flag at huge page |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
24 |
granularity. With this change, on amd64, even a pessimal heap that |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
25 |
alternates between MADV_NOHUGEPAGE and MADV_HUGEPAGE must reach 128GB |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
26 |
to reach the VMA limit. Because of this rounding to huge page |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
27 |
granularity, this change is also careful to leave large used and |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
28 |
unused regions huge page-enabled. |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
29 |
|
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
30 |
This change reduces the maximum number of VMAs during the runtime |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
31 |
benchmarks with GODEBUG=scavenge=1 from 692 to 49. |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
32 |
|
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
33 |
Fixes #12233. |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
34 |
|
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
35 |
Change-Id: Ic397776d042f20d53783a1cacf122e2e2db00584 |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
36 |
Reviewed-on: https://go-review.googlesource.com/15191 |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
37 |
Reviewed-by: Keith Randall <[email protected]> |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
38 |
Reviewed-on: https://go-review.googlesource.com/16980 |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
39 |
Run-TryBot: Austin Clements <[email protected]> |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
40 |
Reviewed-by: Ian Lance Taylor <[email protected]> |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
41 |
Reviewed-by: Russ Cox <[email protected]> |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
42 |
--- |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
43 |
src/runtime/mem_linux.go | 94 +++++++++++++++++++++++++++++++++++++++--------- |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
44 |
1 file changed, 77 insertions(+), 17 deletions(-) |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
45 |
|
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
46 |
diff --git a/src/runtime/mem_linux.go b/src/runtime/mem_linux.go |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
47 |
index f988e75..e8c8999 100644 |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
48 |
--- a/src/runtime/mem_linux.go |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
49 |
+++ b/src/runtime/mem_linux.go |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
50 |
@@ -69,29 +69,89 @@ func sysAlloc(n uintptr, sysStat *uint64) unsafe.Pointer { |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
51 |
} |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
52 |
|
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
53 |
func sysUnused(v unsafe.Pointer, n uintptr) { |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
54 |
- var s uintptr = hugePageSize // division by constant 0 is a compile-time error :( |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
55 |
- if s != 0 && (uintptr(v)%s != 0 || n%s != 0) { |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
56 |
- // See issue 8832 |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
57 |
- // Linux kernel bug: https://bugzilla.kernel.org/show_bug.cgi?id=93111 |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
58 |
- // Mark the region as NOHUGEPAGE so the kernel's khugepaged |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
59 |
- // doesn't undo our DONTNEED request. khugepaged likes to migrate |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
60 |
- // regions which are only partially mapped to huge pages, including |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
61 |
- // regions with some DONTNEED marks. That needlessly allocates physical |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
62 |
- // memory for our DONTNEED regions. |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
63 |
- madvise(v, n, _MADV_NOHUGEPAGE) |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
64 |
+ // By default, Linux's "transparent huge page" support will |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
65 |
+ // merge pages into a huge page if there's even a single |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
66 |
+ // present regular page, undoing the effects of the DONTNEED |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
67 |
+ // below. On amd64, that means khugepaged can turn a single |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
68 |
+ // 4KB page to 2MB, bloating the process's RSS by as much as |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
69 |
+ // 512X. (See issue #8832 and Linux kernel bug |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
70 |
+ // https://bugzilla.kernel.org/show_bug.cgi?id=93111) |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
71 |
+ // |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
72 |
+ // To work around this, we explicitly disable transparent huge |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
73 |
+ // pages when we release pages of the heap. However, we have |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
74 |
+ // to do this carefully because changing this flag tends to |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
75 |
+ // split the VMA (memory mapping) containing v in to three |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
76 |
+ // VMAs in order to track the different values of the |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
77 |
+ // MADV_NOHUGEPAGE flag in the different regions. There's a |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
78 |
+ // default limit of 65530 VMAs per address space (sysctl |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
79 |
+ // vm.max_map_count), so we must be careful not to create too |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
80 |
+ // many VMAs (see issue #12233). |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
81 |
+ // |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
82 |
+ // Since huge pages are huge, there's little use in adjusting |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
83 |
+ // the MADV_NOHUGEPAGE flag on a fine granularity, so we avoid |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
84 |
+ // exploding the number of VMAs by only adjusting the |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
85 |
+ // MADV_NOHUGEPAGE flag on a large granularity. This still |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
86 |
+ // gets most of the benefit of huge pages while keeping the |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
87 |
+ // number of VMAs under control. With hugePageSize = 2MB, even |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
88 |
+ // a pessimal heap can reach 128GB before running out of VMAs. |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
89 |
+ if hugePageSize != 0 { |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
90 |
+ var s uintptr = hugePageSize // division by constant 0 is a compile-time error :( |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
91 |
+ |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
92 |
+ // If it's a large allocation, we want to leave huge |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
93 |
+ // pages enabled. Hence, we only adjust the huge page |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
94 |
+ // flag on the huge pages containing v and v+n-1, and |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
95 |
+ // only if those aren't aligned. |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
96 |
+ var head, tail uintptr |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
97 |
+ if uintptr(v)%s != 0 { |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
98 |
+ // Compute huge page containing v. |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
99 |
+ head = uintptr(v) &^ (s - 1) |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
100 |
+ } |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
101 |
+ if (uintptr(v)+n)%s != 0 { |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
102 |
+ // Compute huge page containing v+n-1. |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
103 |
+ tail = (uintptr(v) + n - 1) &^ (s - 1) |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
104 |
+ } |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
105 |
+ |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
106 |
+ // Note that madvise will return EINVAL if the flag is |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
107 |
+ // already set, which is quite likely. We ignore |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
108 |
+ // errors. |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
109 |
+ if head != 0 && head+hugePageSize == tail { |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
110 |
+ // head and tail are different but adjacent, |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
111 |
+ // so do this in one call. |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
112 |
+ madvise(unsafe.Pointer(head), 2*hugePageSize, _MADV_NOHUGEPAGE) |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
113 |
+ } else { |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
114 |
+ // Advise the huge pages containing v and v+n-1. |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
115 |
+ if head != 0 { |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
116 |
+ madvise(unsafe.Pointer(head), hugePageSize, _MADV_NOHUGEPAGE) |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
117 |
+ } |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
118 |
+ if tail != 0 && tail != head { |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
119 |
+ madvise(unsafe.Pointer(tail), hugePageSize, _MADV_NOHUGEPAGE) |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
120 |
+ } |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
121 |
+ } |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
122 |
} |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
123 |
+ |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
124 |
madvise(v, n, _MADV_DONTNEED) |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
125 |
} |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
126 |
|
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
127 |
func sysUsed(v unsafe.Pointer, n uintptr) { |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
128 |
if hugePageSize != 0 { |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
129 |
- // Undo the NOHUGEPAGE marks from sysUnused. There is no alignment check |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
130 |
- // around this call as spans may have been merged in the interim. |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
131 |
- // Note that this might enable huge pages for regions which were |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
132 |
- // previously disabled. Unfortunately there is no easy way to detect |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
133 |
- // what the previous state was, and in any case we probably want huge |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
134 |
- // pages to back our heap if the kernel can arrange that. |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
135 |
- madvise(v, n, _MADV_HUGEPAGE) |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
136 |
+ // Partially undo the NOHUGEPAGE marks from sysUnused |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
137 |
+ // for whole huge pages between v and v+n. This may |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
138 |
+ // leave huge pages off at the end points v and v+n |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
139 |
+ // even though allocations may cover these entire huge |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
140 |
+ // pages. We could detect this and undo NOHUGEPAGE on |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
141 |
+ // the end points as well, but it's probably not worth |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
142 |
+ // the cost because when neighboring allocations are |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
143 |
+ // freed sysUnused will just set NOHUGEPAGE again. |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
144 |
+ var s uintptr = hugePageSize |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
145 |
+ |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
146 |
+ // Round v up to a huge page boundary. |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
147 |
+ beg := (uintptr(v) + (s - 1)) &^ (s - 1) |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
148 |
+ // Round v+n down to a huge page boundary. |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
149 |
+ end := (uintptr(v) + n) &^ (s - 1) |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
150 |
+ |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
151 |
+ if beg < end { |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
152 |
+ madvise(unsafe.Pointer(beg), end-beg, _MADV_HUGEPAGE) |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
153 |
+ } |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
154 |
} |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
155 |
} |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
156 |
|
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
157 |
-- |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
158 |
2.6.1 |
9c955076ffe3
PSARC/2015/203 Google Go version 1.5
Shawn Walker-Salas <shawn.walker@oracle.com>
parents:
diff
changeset
|
159 |