Skip to content

Commit f0c360c

Browse files
authored
[GC] Remove asserts for when calling madvise for huge pages fails. (#425)
The kernel doesn't always support MADV_HUGEPAGE or MADV_NOHUGEPAGE. In particular, the man page for madvise says: ``` The MADV_HUGEPAGE, MADV_NOHUGEPAGE, and MADV_COLLAPSE operations are available only if the kernel was configured with CONFIG_TRANSPARENT_HUGEPAGE ``` Since the madvise call doesn't have any material affect on the allocator, it's just advice on how to organize the page tables as an optimization for resident memory reduction, we can just ignore the error.
1 parent fdfac63 commit f0c360c

File tree

1 file changed

+56
-2
lines changed

1 file changed

+56
-2
lines changed

sdlib/d/gc/memmap.d

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,68 @@ void pages_zero(void* addr, size_t size) {
8686
}
8787
}
8888

89+
/**
90+
* Note about how we check the result of madvise in the following 2 functions.
91+
*
92+
* From madvise(2):
93+
*
94+
* The MADV_HUGEPAGE, MADV_NOHUGEPAGE, and MADV_COLLAPSE operations are
95+
* available only if the kernel was configured with
96+
* CONFIG_TRANSPARENT_HUGEPAGE
97+
*
98+
* This means that if a kernel is not configured with the right option, madvise
99+
* will fail with EINVAL. The cases where EINVAL happens are listed as follows:
100+
*
101+
* EINVAL addr is not page-aligned or size is negative.
102+
*
103+
* EINVAL advice is not a valid.
104+
*
105+
* EINVAL advice is MADV_COLD or MADV_PAGEOUT and the specified
106+
* address range includes locked, Huge TLB pages, or VM_PFNMAP
107+
* pages.
108+
*
109+
* EINVAL advice is MADV_DONTNEED or MADV_REMOVE and the specified
110+
* address range includes locked, Huge TLB pages, or VM_PFNMAP
111+
* pages.
112+
*
113+
* EINVAL advice is MADV_MERGEABLE or MADV_UNMERGEABLE, but the
114+
* kernel was not configured with CONFIG_KSM.
115+
*
116+
* EINVAL advice is MADV_FREE or MADV_WIPEONFORK but the specified
117+
* address range includes file, Huge TLB, MAP_SHARED, or
118+
* VM_PFNMAP ranges.
119+
*
120+
* EINVAL advice is MADV_POPULATE_READ or MADV_POPULATE_WRITE, but
121+
* the specified address range includes ranges with
122+
* insufficient permissions or special mappings, for example,
123+
* mappings marked with kernel-internal flags such a VM_IO or
124+
* VM_PFNMAP, or secret memory regions created using
125+
* memfd_secret(2).
126+
*
127+
* EINVAL advice is MADV_GUARD_INSTALL or MADV_GUARD_REMOVE, but the
128+
* specified address range contains an unsupported mapping.
129+
*
130+
* We do not have to worry about anything other than the first two. For a
131+
* kernel without the right configuration, EINVAL will happen for MADV_HUGEPAGE
132+
* and MADV_NOHUGEPAGE, because the advice is not valid. But we should also
133+
* check for the first case, that the page is not aligned or the size is
134+
* negative (which is odd, since size_t is unsigned, even in C).
135+
*/
136+
89137
void pages_hugify(void* addr, size_t size) {
138+
assert(isAligned(addr, PageSize), "Not aligned!");
139+
assert(cast(long) size > 0, "Negative size!");
90140
auto ret = madvise(addr, size, Madv.HugePage);
91-
assert(ret == 0, "madvise failed!");
141+
// See note above.
142+
// assert(ret == 0, "madvise failed!");
92143
}
93144

94145
void pages_dehugify(void* addr, size_t size) {
146+
assert(isAligned(addr, PageSize), "Not aligned!");
147+
assert(cast(long) size > 0, "Negative size!");
95148
auto ret = madvise(addr, size, Madv.NoHugePage);
96-
assert(ret == 0, "madvise failed!");
149+
// See note above.
150+
//assert(ret == 0, "madvise failed!");
97151
}
98152

99153
private:

0 commit comments

Comments
 (0)