From cbf276f0b79fdaa08efa7aa8fd1c56ab53acc796 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Tue, 28 Jan 2020 11:01:32 +0100 Subject: [PATCH 1/3] 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: https://github.com/nodejs/node/issues/31520 --- node.gypi | 16 ------ src/large_pages/ld.implicit.script | 10 ---- src/large_pages/ld.implicit.script.lld | 3 - src/large_pages/node_large_page.cc | 80 +++++++++++++------------- 4 files changed, 41 insertions(+), 68 deletions(-) delete mode 100644 src/large_pages/ld.implicit.script delete mode 100644 src/large_pages/ld.implicit.script.lld diff --git a/node.gypi b/node.gypi index e6f5872cc75460..a83c63e23da7f7 100644 --- a/node.gypi +++ b/node.gypi @@ -306,22 +306,6 @@ 'ldflags': [ '-Wl,-z,relro', '-Wl,-z,now' ] }], - [ 'OS=="linux" and ' - 'target_arch=="x64" and ' - 'llvm_version=="0.0"', { - 'ldflags': [ - '-Wl,-T', - '> std::hex >> start; @@ -136,26 +129,42 @@ static struct text_region FindNodeTextRegion() { iss >> offset; iss >> dev; iss >> inode; - if (inode != 0) { - std::string pathname; - iss >> pathname; - if (pathname == exename && permission == "r-xp") { - uintptr_t ntext = reinterpret_cast(&__nodetext); - if (ntext >= start && ntext < end) { - char* from = reinterpret_cast(hugepage_align_up(ntext)); - char* to = reinterpret_cast(hugepage_align_down(end)); - - if (from < to) { - size_t size = to - from; - nregion.found_text_region = true; - nregion.from = from; - nregion.to = to; - nregion.total_hugepages = size / hps; - } - break; - } - } - } + + if (inode == 0) + continue; + + std::string pathname; + iss >> pathname; + + if (start != reinterpret_cast(&__executable_start)) + continue; + + // The next line is our .text section. + if (!std::getline(ifs, map_line)) + break; + + iss = std::istringstream(map_line); + iss >> std::hex >> start; + iss >> dash; + iss >> std::hex >> end; + iss >> permission; + + if (permission != "r-xp") + break; + + char* from = reinterpret_cast(hugepage_align_up(start)); + char* to = reinterpret_cast(hugepage_align_down(end)); + + if (from >= to) + break; + + size_t size = to - from; + nregion.found_text_region = true; + nregion.from = from; + nregion.to = to; + nregion.total_hugepages = size / hps; + + break; } ifs.close(); @@ -408,14 +417,7 @@ int MapStaticCodeToLargePages() { return -1; } -#if defined(__linux__) || defined(__FreeBSD__) - if (r.from > reinterpret_cast(&MoveTextRegionToLargePages)) - return MoveTextRegionToLargePages(r); - - return -1; -#elif defined(__APPLE__) return MoveTextRegionToLargePages(r); -#endif } bool IsLargePagesEnabled() { From 569c1e0785e09fbcb8be797be7a8797e10f7bc16 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Tue, 28 Jan 2020 11:38:00 +0100 Subject: [PATCH 2/3] fixup! enable large pages only for executable --- node.gyp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/node.gyp b/node.gyp index 529a36ba83c113..31f95e03a26964 100644 --- a/node.gyp +++ b/node.gyp @@ -841,7 +841,8 @@ ], }], [ 'OS in "linux freebsd mac" and ' - 'target_arch=="x64"', { + 'target_arch=="x64" and ' + 'node_target_type=="executable"', { 'defines': [ 'NODE_ENABLE_LARGE_CODE_PAGES=1' ], 'sources': [ 'src/large_pages/node_large_page.cc', From 6d3851904c57e2c3e586a44de1fd535307901252 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Tue, 28 Jan 2020 15:34:17 +0100 Subject: [PATCH 3/3] fixup! reinstate freebsd check --- src/large_pages/node_large_page.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/large_pages/node_large_page.cc b/src/large_pages/node_large_page.cc index 9419cb797f241e..ce58e32e719bc8 100644 --- a/src/large_pages/node_large_page.cc +++ b/src/large_pages/node_large_page.cc @@ -417,6 +417,11 @@ int MapStaticCodeToLargePages() { return -1; } +#if defined(__FreeBSD__) + if (r.from < reinterpret_cast(&MoveTextRegionToLargePages)) + return -1; +#endif + return MoveTextRegionToLargePages(r); }