|
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