Skip to content

Commit 56305ee

Browse files
bnoordhuisGabriel Schulhof
authored and
Gabriel Schulhof
committed
src: use __executable_start for linux hugepages
`__executable_start` is provided by GNU's and LLVM's default linker scripts, obviating the need to plug in a custom linker script. The problem with our bespoke linker script is that it works with ld.bfd but not ld.gold and cannot easily be ported because the latter linker doesn't understand the `INSERT BEFORE` directive. The /proc/self/maps scanner is updated to account for the fact that there are a number of sections between `&__executable_start` and the start of the .text section. Fortunately, those sections are all mapped into the same memory segment so we only need to look at the next line to find the start of our text segment. Fixes: nodejs#31520 PR-URL: nodejs#31547 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: David Carlier <[email protected]>
1 parent 2693510 commit 56305ee

File tree

5 files changed

+47
-68
lines changed

5 files changed

+47
-68
lines changed

node.gyp

+2-1
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,8 @@
607607
],
608608
}],
609609
[ 'OS in "linux freebsd mac" and '
610-
'target_arch=="x64"', {
610+
'target_arch=="x64" and '
611+
'node_target_type=="executable"', {
611612
'defines': [ 'NODE_ENABLE_LARGE_CODE_PAGES=1' ],
612613
'sources': [
613614
'src/large_pages/node_large_page.cc',

node.gypi

-16
Original file line numberDiff line numberDiff line change
@@ -304,22 +304,6 @@
304304
'ldflags': [ '-Wl,-z,relro',
305305
'-Wl,-z,now' ]
306306
}],
307-
[ 'OS=="linux" and '
308-
'target_arch=="x64" and '
309-
'llvm_version==0', {
310-
'ldflags': [
311-
'-Wl,-T',
312-
'<!(echo "$(pwd)/src/large_pages/ld.implicit.script")',
313-
]
314-
}],
315-
[ 'OS=="linux" and '
316-
'target_arch=="x64" and '
317-
'llvm_version!=0', {
318-
'ldflags': [
319-
'-Wl,-T',
320-
'<!(echo "$(pwd)/src/large_pages/ld.implicit.script.lld")',
321-
]
322-
}],
323307
[ 'node_use_openssl=="true"', {
324308
'defines': [ 'HAVE_OPENSSL=1' ],
325309
'conditions': [

src/large_pages/ld.implicit.script

-10
This file was deleted.

src/large_pages/ld.implicit.script.lld

-3
This file was deleted.

src/large_pages/node_large_page.cc

+45-38
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,11 @@
7373
// Use madvise with MADV_HUGEPAGE to use Anonymous 2M Pages
7474
// If successful copy the code there and unmap the original region.
7575

76-
extern char __nodetext;
76+
#if defined(__linux__)
77+
extern "C" {
78+
extern char __executable_start;
79+
} // extern "C"
80+
#endif // defined(__linux__)
7781

7882
namespace node {
7983

@@ -124,17 +128,6 @@ static struct text_region FindNodeTextRegion() {
124128
return nregion;
125129
}
126130

127-
std::string exename;
128-
{
129-
char selfexe[PATH_MAX];
130-
131-
size_t size = sizeof(selfexe);
132-
if (uv_exepath(selfexe, &size))
133-
return nregion;
134-
135-
exename = std::string(selfexe, size);
136-
}
137-
138131
while (std::getline(ifs, map_line)) {
139132
std::istringstream iss(map_line);
140133
iss >> std::hex >> start;
@@ -144,26 +137,42 @@ static struct text_region FindNodeTextRegion() {
144137
iss >> offset;
145138
iss >> dev;
146139
iss >> inode;
147-
if (inode != 0) {
148-
std::string pathname;
149-
iss >> pathname;
150-
if (pathname == exename && permission == "r-xp") {
151-
uintptr_t ntext = reinterpret_cast<uintptr_t>(&__nodetext);
152-
if (ntext >= start && ntext < end) {
153-
char* from = reinterpret_cast<char*>(hugepage_align_up(ntext));
154-
char* to = reinterpret_cast<char*>(hugepage_align_down(end));
155-
156-
if (from < to) {
157-
size_t size = to - from;
158-
nregion.found_text_region = true;
159-
nregion.from = from;
160-
nregion.to = to;
161-
nregion.total_hugepages = size / hps;
162-
}
163-
break;
164-
}
165-
}
166-
}
140+
141+
if (inode == 0)
142+
continue;
143+
144+
std::string pathname;
145+
iss >> pathname;
146+
147+
if (start != reinterpret_cast<uintptr_t>(&__executable_start))
148+
continue;
149+
150+
// The next line is our .text section.
151+
if (!std::getline(ifs, map_line))
152+
break;
153+
154+
iss = std::istringstream(map_line);
155+
iss >> std::hex >> start;
156+
iss >> dash;
157+
iss >> std::hex >> end;
158+
iss >> permission;
159+
160+
if (permission != "r-xp")
161+
break;
162+
163+
char* from = reinterpret_cast<char*>(hugepage_align_up(start));
164+
char* to = reinterpret_cast<char*>(hugepage_align_down(end));
165+
166+
if (from >= to)
167+
break;
168+
169+
size_t size = to - from;
170+
nregion.found_text_region = true;
171+
nregion.from = from;
172+
nregion.to = to;
173+
nregion.total_hugepages = size / hps;
174+
175+
break;
167176
}
168177

169178
ifs.close();
@@ -416,14 +425,12 @@ int MapStaticCodeToLargePages() {
416425
return -1;
417426
}
418427

419-
#if defined(__linux__) || defined(__FreeBSD__)
420-
if (r.from > reinterpret_cast<void*>(&MoveTextRegionToLargePages))
421-
return MoveTextRegionToLargePages(r);
428+
#if defined(__FreeBSD__)
429+
if (r.from < reinterpret_cast<void*>(&MoveTextRegionToLargePages))
430+
return -1;
431+
#endif
422432

423-
return -1;
424-
#elif defined(__APPLE__)
425433
return MoveTextRegionToLargePages(r);
426-
#endif
427434
}
428435

429436
bool IsLargePagesEnabled() {

0 commit comments

Comments
 (0)