Skip to content

Commit 277980d

Browse files
bnoordhuiscodebytere
authored andcommitted
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: #31520 PR-URL: #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 f402649 commit 277980d

File tree

5 files changed

+47
-68
lines changed

5 files changed

+47
-68
lines changed

node.gyp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -845,7 +845,8 @@
845845
],
846846
}],
847847
[ 'OS in "linux freebsd mac" and '
848-
'target_arch=="x64"', {
848+
'target_arch=="x64" and '
849+
'node_target_type=="executable"', {
849850
'defines': [ 'NODE_ENABLE_LARGE_CODE_PAGES=1' ],
850851
'sources': [
851852
'src/large_pages/node_large_page.cc',

node.gypi

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -306,22 +306,6 @@
306306
'ldflags': [ '-Wl,-z,relro',
307307
'-Wl,-z,now' ]
308308
}],
309-
[ 'OS=="linux" and '
310-
'target_arch=="x64" and '
311-
'llvm_version=="0.0"', {
312-
'ldflags': [
313-
'-Wl,-T',
314-
'<!(echo "$(pwd)/src/large_pages/ld.implicit.script")',
315-
]
316-
}],
317-
[ 'OS=="linux" and '
318-
'target_arch=="x64" and '
319-
'llvm_version!="0.0"', {
320-
'ldflags': [
321-
'-Wl,-T',
322-
'<!(echo "$(pwd)/src/large_pages/ld.implicit.script.lld")',
323-
]
324-
}],
325309
[ 'node_use_openssl=="true"', {
326310
'defines': [ 'HAVE_OPENSSL=1' ],
327311
'conditions': [

src/large_pages/ld.implicit.script

Lines changed: 0 additions & 10 deletions
This file was deleted.

src/large_pages/ld.implicit.script.lld

Lines changed: 0 additions & 3 deletions
This file was deleted.

src/large_pages/node_large_page.cc

Lines changed: 45 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,11 @@
6565
// Use madvise with MADV_HUGEPAGE to use Anonymous 2M Pages
6666
// If successful copy the code there and unmap the original region.
6767

68-
extern char __nodetext;
68+
#if defined(__linux__)
69+
extern "C" {
70+
extern char __executable_start;
71+
} // extern "C"
72+
#endif // defined(__linux__)
6973

7074
namespace node {
7175

@@ -116,17 +120,6 @@ static struct text_region FindNodeTextRegion() {
116120
return nregion;
117121
}
118122

119-
std::string exename;
120-
{
121-
char selfexe[PATH_MAX];
122-
123-
size_t size = sizeof(selfexe);
124-
if (uv_exepath(selfexe, &size))
125-
return nregion;
126-
127-
exename = std::string(selfexe, size);
128-
}
129-
130123
while (std::getline(ifs, map_line)) {
131124
std::istringstream iss(map_line);
132125
iss >> std::hex >> start;
@@ -136,26 +129,42 @@ static struct text_region FindNodeTextRegion() {
136129
iss >> offset;
137130
iss >> dev;
138131
iss >> inode;
139-
if (inode != 0) {
140-
std::string pathname;
141-
iss >> pathname;
142-
if (pathname == exename && permission == "r-xp") {
143-
uintptr_t ntext = reinterpret_cast<uintptr_t>(&__nodetext);
144-
if (ntext >= start && ntext < end) {
145-
char* from = reinterpret_cast<char*>(hugepage_align_up(ntext));
146-
char* to = reinterpret_cast<char*>(hugepage_align_down(end));
147-
148-
if (from < to) {
149-
size_t size = to - from;
150-
nregion.found_text_region = true;
151-
nregion.from = from;
152-
nregion.to = to;
153-
nregion.total_hugepages = size / hps;
154-
}
155-
break;
156-
}
157-
}
158-
}
132+
133+
if (inode == 0)
134+
continue;
135+
136+
std::string pathname;
137+
iss >> pathname;
138+
139+
if (start != reinterpret_cast<uintptr_t>(&__executable_start))
140+
continue;
141+
142+
// The next line is our .text section.
143+
if (!std::getline(ifs, map_line))
144+
break;
145+
146+
iss = std::istringstream(map_line);
147+
iss >> std::hex >> start;
148+
iss >> dash;
149+
iss >> std::hex >> end;
150+
iss >> permission;
151+
152+
if (permission != "r-xp")
153+
break;
154+
155+
char* from = reinterpret_cast<char*>(hugepage_align_up(start));
156+
char* to = reinterpret_cast<char*>(hugepage_align_down(end));
157+
158+
if (from >= to)
159+
break;
160+
161+
size_t size = to - from;
162+
nregion.found_text_region = true;
163+
nregion.from = from;
164+
nregion.to = to;
165+
nregion.total_hugepages = size / hps;
166+
167+
break;
159168
}
160169

161170
ifs.close();
@@ -408,14 +417,12 @@ int MapStaticCodeToLargePages() {
408417
return -1;
409418
}
410419

411-
#if defined(__linux__) || defined(__FreeBSD__)
412-
if (r.from > reinterpret_cast<void*>(&MoveTextRegionToLargePages))
413-
return MoveTextRegionToLargePages(r);
420+
#if defined(__FreeBSD__)
421+
if (r.from < reinterpret_cast<void*>(&MoveTextRegionToLargePages))
422+
return -1;
423+
#endif
414424

415-
return -1;
416-
#elif defined(__APPLE__)
417425
return MoveTextRegionToLargePages(r);
418-
#endif
419426
}
420427

421428
bool IsLargePagesEnabled() {

0 commit comments

Comments
 (0)