|
22 | 22 |
|
23 | 23 | #include "node_internals.h"
|
24 | 24 | #include "node_large_page.h"
|
| 25 | + |
| 26 | +#include <cerrno> // NOLINT(build/include) |
| 27 | + |
| 28 | +// Besides returning ENOTSUP at runtime we do nothing if this define is missing. |
| 29 | +#if defined(NODE_ENABLE_LARGE_CODE_PAGES) && NODE_ENABLE_LARGE_CODE_PAGES |
25 | 30 | #include "util.h"
|
26 | 31 | #include "uv.h"
|
27 | 32 |
|
|
36 | 41 | #endif
|
37 | 42 | #include <unistd.h> // readlink
|
38 | 43 |
|
39 |
| -#include <cerrno> // NOLINT(build/include) |
40 | 44 | #include <climits> // PATH_MAX
|
41 | 45 | #include <clocale>
|
42 | 46 | #include <csignal>
|
@@ -79,7 +83,11 @@ extern char __executable_start;
|
79 | 83 | } // extern "C"
|
80 | 84 | #endif // defined(__linux__)
|
81 | 85 |
|
| 86 | +#endif // defined(NODE_ENABLE_LARGE_CODE_PAGES) && NODE_ENABLE_LARGE_CODE_PAGES |
82 | 87 | namespace node {
|
| 88 | +#if defined(NODE_ENABLE_LARGE_CODE_PAGES) && NODE_ENABLE_LARGE_CODE_PAGES |
| 89 | + |
| 90 | +namespace { |
83 | 91 |
|
84 | 92 | struct text_region {
|
85 | 93 | char* from;
|
@@ -111,7 +119,7 @@ inline uintptr_t hugepage_align_down(uintptr_t addr) {
|
111 | 119 | // 00400000-00452000 r-xp 00000000 08:02 173521 /usr/bin/dbus-daemon
|
112 | 120 | // This is also handling the case where the first line is not the binary.
|
113 | 121 |
|
114 |
| -static struct text_region FindNodeTextRegion() { |
| 122 | +struct text_region FindNodeTextRegion() { |
115 | 123 | struct text_region nregion;
|
116 | 124 | nregion.found_text_region = false;
|
117 | 125 | #if defined(__linux__)
|
@@ -271,7 +279,7 @@ static struct text_region FindNodeTextRegion() {
|
271 | 279 | }
|
272 | 280 |
|
273 | 281 | #if defined(__linux__)
|
274 |
| -static bool IsTransparentHugePagesEnabled() { |
| 282 | +bool IsTransparentHugePagesEnabled() { |
275 | 283 | std::ifstream ifs;
|
276 | 284 |
|
277 | 285 | ifs.open("/sys/kernel/mm/transparent_hugepage/enabled");
|
@@ -302,6 +310,8 @@ static bool IsSuperPagesEnabled() {
|
302 | 310 | }
|
303 | 311 | #endif
|
304 | 312 |
|
| 313 | +} // End of anonymous namespace |
| 314 | + |
305 | 315 | // Moving the text region to large pages. We need to be very careful.
|
306 | 316 | // 1: This function itself should not be moved.
|
307 | 317 | // We use a gcc attributes
|
@@ -416,32 +426,59 @@ MoveTextRegionToLargePages(const text_region& r) {
|
416 | 426 | if (-1 == munmap(nmem, size)) PrintSystemError(errno);
|
417 | 427 | return ret;
|
418 | 428 | }
|
| 429 | +#endif // defined(NODE_ENABLE_LARGE_CODE_PAGES) && NODE_ENABLE_LARGE_CODE_PAGES |
419 | 430 |
|
420 | 431 | // This is the primary API called from main.
|
421 | 432 | int MapStaticCodeToLargePages() {
|
| 433 | +#if defined(NODE_ENABLE_LARGE_CODE_PAGES) && NODE_ENABLE_LARGE_CODE_PAGES |
| 434 | + bool have_thp = false; |
| 435 | +#if defined(__linux__) |
| 436 | + have_thp = IsTransparentHugePagesEnabled(); |
| 437 | +#elif defined(__FreeBSD__) |
| 438 | + have_thp = IsSuperPagesEnabled(); |
| 439 | +#elif defined(__APPLE__) |
| 440 | + // pse-36 flag is present in recent mac x64 products. |
| 441 | + have_thp = true; |
| 442 | +#endif |
| 443 | + if (!have_thp) |
| 444 | + return EACCES; |
| 445 | + |
422 | 446 | struct text_region r = FindNodeTextRegion();
|
423 |
| - if (r.found_text_region == false) { |
424 |
| - PrintWarning("failed to find text region"); |
425 |
| - return -1; |
426 |
| - } |
| 447 | + if (r.found_text_region == false) |
| 448 | + return ENOENT; |
427 | 449 |
|
428 | 450 | #if defined(__FreeBSD__)
|
429 | 451 | if (r.from < reinterpret_cast<void*>(&MoveTextRegionToLargePages))
|
430 | 452 | return -1;
|
431 | 453 | #endif
|
432 | 454 |
|
433 | 455 | return MoveTextRegionToLargePages(r);
|
| 456 | +#else |
| 457 | + return ENOTSUP; |
| 458 | +#endif |
434 | 459 | }
|
435 | 460 |
|
436 |
| -bool IsLargePagesEnabled() { |
437 |
| -#if defined(__linux__) |
438 |
| - return IsTransparentHugePagesEnabled(); |
439 |
| -#elif defined(__FreeBSD__) |
440 |
| - return IsSuperPagesEnabled(); |
441 |
| -#elif defined(__APPLE__) |
442 |
| - // pse-36 flag is present in recent mac x64 products. |
443 |
| - return true; |
444 |
| -#endif |
| 461 | +const char* LargePagesError(int status) { |
| 462 | + switch (status) { |
| 463 | + case ENOTSUP: |
| 464 | + return "Mapping to large pages is not supported."; |
| 465 | + |
| 466 | + case EACCES: |
| 467 | + return "Large pages are not enabled."; |
| 468 | + |
| 469 | + case ENOENT: |
| 470 | + return "failed to find text region"; |
| 471 | + |
| 472 | + case -1: |
| 473 | + return "Mapping code to large pages failed. Reverting to default page " |
| 474 | + "size."; |
| 475 | + |
| 476 | + case 0: |
| 477 | + return "OK"; |
| 478 | + |
| 479 | + default: |
| 480 | + return "Unknown error"; |
| 481 | + } |
445 | 482 | }
|
446 | 483 |
|
447 | 484 | } // namespace node
|
0 commit comments