|
21 | 21 | // SPDX-License-Identifier: MIT
|
22 | 22 |
|
23 | 23 | #include "node_large_page.h"
|
| 24 | + |
| 25 | +#include <cerrno> // NOLINT(build/include) |
| 26 | + |
| 27 | +// Besides returning ENOTSUP at runtime we do nothing if this define is missing. |
| 28 | +#if defined(NODE_ENABLE_LARGE_CODE_PAGES) && NODE_ENABLE_LARGE_CODE_PAGES |
24 | 29 | #include "util.h"
|
25 | 30 | #include "uv.h"
|
26 | 31 |
|
|
35 | 40 | #endif
|
36 | 41 | #include <unistd.h> // readlink
|
37 | 42 |
|
38 |
| -#include <cerrno> // NOLINT(build/include) |
39 | 43 | #include <climits> // PATH_MAX
|
40 | 44 | #include <clocale>
|
41 | 45 | #include <csignal>
|
@@ -71,7 +75,11 @@ extern char __executable_start;
|
71 | 75 | } // extern "C"
|
72 | 76 | #endif // defined(__linux__)
|
73 | 77 |
|
| 78 | +#endif // defined(NODE_ENABLE_LARGE_CODE_PAGES) && NODE_ENABLE_LARGE_CODE_PAGES |
74 | 79 | namespace node {
|
| 80 | +#if defined(NODE_ENABLE_LARGE_CODE_PAGES) && NODE_ENABLE_LARGE_CODE_PAGES |
| 81 | + |
| 82 | +namespace { |
75 | 83 |
|
76 | 84 | struct text_region {
|
77 | 85 | char* from;
|
@@ -103,7 +111,7 @@ inline uintptr_t hugepage_align_down(uintptr_t addr) {
|
103 | 111 | // 00400000-00452000 r-xp 00000000 08:02 173521 /usr/bin/dbus-daemon
|
104 | 112 | // This is also handling the case where the first line is not the binary.
|
105 | 113 |
|
106 |
| -static struct text_region FindNodeTextRegion() { |
| 114 | +struct text_region FindNodeTextRegion() { |
107 | 115 | struct text_region nregion;
|
108 | 116 | nregion.found_text_region = false;
|
109 | 117 | #if defined(__linux__)
|
@@ -263,7 +271,7 @@ static struct text_region FindNodeTextRegion() {
|
263 | 271 | }
|
264 | 272 |
|
265 | 273 | #if defined(__linux__)
|
266 |
| -static bool IsTransparentHugePagesEnabled() { |
| 274 | +bool IsTransparentHugePagesEnabled() { |
267 | 275 | std::ifstream ifs;
|
268 | 276 |
|
269 | 277 | ifs.open("/sys/kernel/mm/transparent_hugepage/enabled");
|
@@ -294,6 +302,8 @@ static bool IsSuperPagesEnabled() {
|
294 | 302 | }
|
295 | 303 | #endif
|
296 | 304 |
|
| 305 | +} // End of anonymous namespace |
| 306 | + |
297 | 307 | // Moving the text region to large pages. We need to be very careful.
|
298 | 308 | // 1: This function itself should not be moved.
|
299 | 309 | // We use a gcc attributes
|
@@ -408,32 +418,59 @@ MoveTextRegionToLargePages(const text_region& r) {
|
408 | 418 | if (-1 == munmap(nmem, size)) PrintSystemError(errno);
|
409 | 419 | return ret;
|
410 | 420 | }
|
| 421 | +#endif // defined(NODE_ENABLE_LARGE_CODE_PAGES) && NODE_ENABLE_LARGE_CODE_PAGES |
411 | 422 |
|
412 | 423 | // This is the primary API called from main.
|
413 | 424 | int MapStaticCodeToLargePages() {
|
| 425 | +#if defined(NODE_ENABLE_LARGE_CODE_PAGES) && NODE_ENABLE_LARGE_CODE_PAGES |
| 426 | + bool have_thp = false; |
| 427 | +#if defined(__linux__) |
| 428 | + have_thp = IsTransparentHugePagesEnabled(); |
| 429 | +#elif defined(__FreeBSD__) |
| 430 | + have_thp = IsSuperPagesEnabled(); |
| 431 | +#elif defined(__APPLE__) |
| 432 | + // pse-36 flag is present in recent mac x64 products. |
| 433 | + have_thp = true; |
| 434 | +#endif |
| 435 | + if (!have_thp) |
| 436 | + return EACCES; |
| 437 | + |
414 | 438 | struct text_region r = FindNodeTextRegion();
|
415 |
| - if (r.found_text_region == false) { |
416 |
| - PrintWarning("failed to find text region"); |
417 |
| - return -1; |
418 |
| - } |
| 439 | + if (r.found_text_region == false) |
| 440 | + return ENOENT; |
419 | 441 |
|
420 | 442 | #if defined(__FreeBSD__)
|
421 | 443 | if (r.from < reinterpret_cast<void*>(&MoveTextRegionToLargePages))
|
422 | 444 | return -1;
|
423 | 445 | #endif
|
424 | 446 |
|
425 | 447 | return MoveTextRegionToLargePages(r);
|
| 448 | +#else |
| 449 | + return ENOTSUP; |
| 450 | +#endif |
426 | 451 | }
|
427 | 452 |
|
428 |
| -bool IsLargePagesEnabled() { |
429 |
| -#if defined(__linux__) |
430 |
| - return IsTransparentHugePagesEnabled(); |
431 |
| -#elif defined(__FreeBSD__) |
432 |
| - return IsSuperPagesEnabled(); |
433 |
| -#elif defined(__APPLE__) |
434 |
| - // pse-36 flag is present in recent mac x64 products. |
435 |
| - return true; |
436 |
| -#endif |
| 453 | +const char* LargePagesError(int status) { |
| 454 | + switch (status) { |
| 455 | + case ENOTSUP: |
| 456 | + return "Mapping to large pages is not supported."; |
| 457 | + |
| 458 | + case EACCES: |
| 459 | + return "Large pages are not enabled."; |
| 460 | + |
| 461 | + case ENOENT: |
| 462 | + return "failed to find text region"; |
| 463 | + |
| 464 | + case -1: |
| 465 | + return "Mapping code to large pages failed. Reverting to default page " |
| 466 | + "size."; |
| 467 | + |
| 468 | + case 0: |
| 469 | + return "OK"; |
| 470 | + |
| 471 | + default: |
| 472 | + return "Unknown error"; |
| 473 | + } |
437 | 474 | }
|
438 | 475 |
|
439 | 476 | } // namespace node
|
0 commit comments