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