GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||||||
GeezerVison is showing github.com — src: use _init as the start of large pages by gabrielschulhof · Pull Request #31947 · nodejs/node Conversation
Contributor
The assumption that the .text section starts at the mapping following OTOH, The symbol We also rename the section into which we place the remapping code to Checklist
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Contributor
Author
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Collaborator
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Member
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
|
There was an error while loading. Please reload this page.
|
@bnoordhuis I tried keeping |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@bnoordhuis just looking at |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
@bnoordhuis got any particular combination of Linux version/clang version where clang doesn't produce |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
I'm testing with clang 9 but even after grepping through the llvm+clang+lld source tree I haven't really narrowed down what causes clang to emit them or not. 🤷♂ At any rate, does it matter where |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Could you remind me why we are not using the linker script? The default linker script with @gabrielschulhof werent you trying an alternate way to use an assembly file to provide this as part of the first node build file? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Yes it matters where |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
They're hard to keep portable across ld.bfd, ld.gold and ld.ldd.
We scan /proc/self/maps for a mapping that contains a symbol. I don't see why it matters if that symbol is at the start, the end or somewhere in the middle of that segment; it's copied whole. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
I thought node is build only with gcc and ld. Are all these supported as valid linkers?
The symbol is used to determine the start address of the region that we are copying from. The original code with the ld script was using it like this. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@suresh-srinivas I was, based on https://bugzilla.redhat.com/show_bug.cgi?id=927573, but it's really difficult to get the object file to be the very first file passed to the linker, and even then I was unable to get the symbol to go all the way to the beginning of the .text section. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Actually, we cannot copy the whole thing. For example, on Skylake there is a significant distance between The mapping may include multiple executable sections. We only want to relocate the .text section. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@bnoordhuis another way of looking at this is that it's not so much a question of whether or not clang generates I also checked and it is distro-related rather than processor-related. I ran Ubuntu 18.04 on my laptop in a VM and it also produces the same kind of mapping as on the Skylake machine I ran it on earlier. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
6e66ea5 to
b2a0512
Compare
|
@bnoordhuis @devnexen @lundibundi I changed the implementation to not use |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
The assumption that the .text section starts at the mapping following the one that contains `__executable_start` is not valid on 64-bit Ubuntu 18.04 where the whole code resides in one mapping. OTOH, The symbol `_init` is usually located at the beginning of the .text section and it does not need the assumption that the next mapping has the .text section. Thus, we use the symbol, if available, to perform the mapping on Ubuntu 18.04. We also rename the section into which we place the remapping code to `lpstub`. This causes the linker to produce symbols `__start_lpstub` and `__stop_lpstub`, the latter of which we do not use. Still, `__start_lpstub` helps us find the end of the .text section because on Ubuntu 18.04 this section is inserted before the end of the sole mapping, so we use `__start_lpstub` as the end instead of the end of the mapping.
b2a0512 to
11f675c
Compare
Sorry, something went wrong.
There was an error while loading. Please reload this page.
You have to walk me through this. Ultimately, at least on Linux, the goal is to call diff --git a/src/node_main.cc b/src/node_main.cc index e92c0df942..1a163ec2a6 100644 --- a/src/node_main.cc +++ b/src/node_main.cc @@ -75,6 +75,7 @@ int wmain(int argc, wchar_t* wargv[]) { // UNIX #ifdef __linux__ #include <elf.h> +#include <sys/mman.h> #ifdef __LP64__ #define Elf_auxv_t Elf64_auxv_t #else @@ -94,6 +95,12 @@ extern bool linux_at_secure; } // namespace node int main(int argc, char* argv[]) { +#if defined(__linux__) + constexpr uintptr_t k2MB = 1 << 21; + void* const addr = + reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(&main) & -k2MB); + if (-1 == madvise(addr, k2MB, MADV_HUGEPAGE)) perror("madvise"); +#endif // __linux__ #if defined(__POSIX__) && defined(NODE_SHARED_MODE) // In node::PlatformInit(), we squash all signal handlers for non-shared lib // build. In order to run test cases against shared lib build, we also need Apart from the lack of sophistication, isn't that sufficient to turn on THP? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@bnoordhuis currently the Node.js .text section takes up about 14-20 MiB, depending on whether you're using clang or gcc. The order in which the functions appear in the .text section is uncertain. We would like to capture as much of the .text section as possible, while leaving out the section containing the code that does the remapping itself. If we do not capture as much of .text as possible, we risk leaving the hot parts of the code mapped onto 4KiB pages, thereby forfeiting the benefits of re-mapping to large pages. I believe, and @suresh-srinivas can give more detail, that we cannot simply At any rate, please also have a look at #31981 which is an alternative implementation. Basically, instead of a linker script, it uses an object file compiled from an assembly file. The assembly introduces a symbol into the text section, much as the linker script did before. Since we cannot use a linker script to ensure that the symbol is placed at the beginning of the .text section, we must ensure that the object file resulting from the assembly file is the first item to be linked on the linker's command line. Assuming the linker places the code more or less in the order it encounters the object/archive files ones gives it, the symbol should end up at or near the beginning of the .text section and still give us a good chunk of it for remapping. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Closing in favour of #31981. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.