src: simplify large pages mapping code by gabrielschulhof · Pull Request #32396 · nodejs/node · GitHub
Skip to content

src: simplify large pages mapping code#32396

Closed
gabrielschulhof wants to merge 1 commit into
nodejs:masterfrom
gabrielschulhof:large-pages-simplify-code
Closed

src: simplify large pages mapping code#32396
gabrielschulhof wants to merge 1 commit into
nodejs:masterfrom
gabrielschulhof:large-pages-simplify-code

Conversation

@gabrielschulhof

Copy link
Copy Markdown
Contributor
  • Introduce OnScopeLeave handler for cleaning up mmap()ed range(s).
  • Factor out failure scenario at the bottom of the function with
    fail label for use with goto.
  • Do not allocate temporary range (nmem) on FreeBSD, because it is
    not used.

The intention is that the steps involved in re-mapping to large pages
become more clearly visible.

Signed-off-by: Gabriel Schulhof gabriel.schulhof@intel.com

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • commit message follows commit guidelines

@gabrielschulhof gabrielschulhof added the wip Issues and PRs that are still a work in progress. label Mar 20, 2020
@nodejs-github-bot nodejs-github-bot added the c++ Issues and PRs that require attention from people who are familiar with C++. label Mar 20, 2020
Comment thread src/large_pages/node_large_page.cc Outdated
@gabrielschulhof gabrielschulhof force-pushed the large-pages-simplify-code branch from 45c73c3 to 9f2adb5 Compare March 24, 2020 06:16
@gabrielschulhof gabrielschulhof changed the title [WIP] src: simplify large pages mapping code src: simplify large pages mapping code Mar 24, 2020
@gabrielschulhof gabrielschulhof removed the wip Issues and PRs that are still a work in progress. label Mar 24, 2020
@gabrielschulhof

Copy link
Copy Markdown
Contributor Author

* Introduce `OnScopeLeave` handler for cleaning up mmap()ed range(s).
* Factor out failure scenario at the bottom of the function with
  `fail` label for use with `goto`.
* Do not allocate temporary range (`nmem`) on FreeBSD, because it is
  not used.

The intention is that the steps involved in re-mapping to large pages
become more clearly visible.

Signed-off-by: Gabriel Schulhof <gabriel.schulhof@intel.com>
Co-authored-by: Ben Noordhuis <info@bnoordhuis.nl>
@gabrielschulhof gabrielschulhof force-pushed the large-pages-simplify-code branch from 9f2adb5 to 470d2d2 Compare March 24, 2020 20:38
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@gabrielschulhof

Copy link
Copy Markdown
Contributor Author

@devnexen is there a combination involving FreeBSD under which the mapping actually works?

@gabrielschulhof

Copy link
Copy Markdown
Contributor Author

@devnexen I tried building on test-digitalocean-freebsd11-x64-2 and on FreeBSD 12.1 from https://www.osboxes.org/freebsd/ and they both refuse to re-map because of the requirement that the region to map not precede the mapping function:

#if defined(__FreeBSD__)
if (r.from < reinterpret_cast<void*>(&MoveTextRegionToLargePages))
return -1;
#endif

@codecov-io

codecov-io commented Mar 25, 2020

Copy link
Copy Markdown

Codecov Report

Merging #32396 into master will increase coverage by 0.30%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff             @@
##           master   #32396      +/-   ##
==========================================
+ Coverage   97.16%   97.46%   +0.30%     
==========================================
  Files         197      195       -2     
  Lines       65781    65701      -80     
==========================================
+ Hits        63914    64037     +123     
+ Misses       1867     1664     -203     
Impacted Files Coverage Δ
lib/events.js 95.38% <0.00%> (-4.62%) ⬇️
lib/net.js 98.18% <0.00%> (-0.29%) ⬇️
lib/internal/modules/esm/loader.js 88.57% <0.00%> (-0.18%) ⬇️
lib/_http_server.js 98.27% <0.00%> (-0.12%) ⬇️
lib/_tls_wrap.js 95.45% <0.00%> (-0.02%) ⬇️
lib/zlib.js 98.36% <0.00%> (-0.01%) ⬇️
...l/bootstrap/switches/does_not_own_process_state.js
lib/internal/constants.js
lib/internal/console/global.js
lib/internal/bootstrap/environment.js 100.00% <0.00%> (ø)
... and 15 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c160073...470d2d2. Read the comment docs.

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@gabrielschulhof

Copy link
Copy Markdown
Contributor Author

@devnexen NM - I got it to work.

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Comment on lines +346 to +349
if (nmem != nullptr && nmem != MAP_FAILED && munmap(nmem, size) == -1)
PrintSystemError(errno);
if (tmem != nullptr && tmem != MAP_FAILED && munmap(tmem, size) == -1)
PrintSystemError(errno);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (nmem != nullptr && nmem != MAP_FAILED && munmap(nmem, size) == -1)
PrintSystemError(errno);
if (tmem != nullptr && tmem != MAP_FAILED && munmap(tmem, size) == -1)
PrintSystemError(errno);
if ((nmem != nullptr && nmem != MAP_FAILED && munmap(nmem, size) == -1) ||
(tmem != nullptr && tmem != MAP_FAILED && munmap(tmem, size) == -1)) {
PrintSystemError(errno);
}

Alternatively, it may be a bit cleaner to use a custom smart pointer with a deleter for these...

e.g. bit more verbose...

  struct Mmap {
    void* mem = nullptr;
    size_t size = 0;
    Mmap(void* start, size_t size, int prot, int flags) {
      mem = mmap(start, size, prot, flags, -1, 0);
    }
  };
  struct MmapDeleter {
    void operator()(Mmap* ptr) const noexcept {
      if (ptr.mem != nullptr &&
          ptr.mem != MAP_FAILED &&
          munmap(ptr.mem, ptr.size) == -1)
        PrintSystemError(errno); 
    }
  };
  using MmapPointer = std::unique_ptr<Mmap, MmapDeleter>;

then...

  MmapPointer nmem;
  MmapPointer tmem;

  // ...
  size_t size = r.to - r.from; 

  // ...
  nmem = std::make_unique(nullptr, size,
                          PROT_READ | PROT_WRITE,
                          MAP_PRIVATE | MAP_ANONYMOUS);
  if (nmem.mem == MAP_FAILED)
    goto fail;

  // ...
  tmem = std::make_unique(start, size,
                          PROT_READ | PROT_WRITE,
                          MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED);
  if (tmem.mem == MAP_FAILED)
    goto fail;

@gabrielschulhof

Copy link
Copy Markdown
Contributor Author

@jasnell I've left #32532 as a todo for myself.

@gabrielschulhof

Copy link
Copy Markdown
Contributor Author

Landed in fa3fd78.

gabrielschulhof pushed a commit that referenced this pull request Mar 28, 2020
* Introduce `OnScopeLeave` handler for cleaning up mmap()ed range(s).
* Factor out failure scenario at the bottom of the function with
  `fail` label for use with `goto`.
* Do not allocate temporary range (`nmem`) on FreeBSD, because it is
  not used.

The intention is that the steps involved in re-mapping to large pages
become more clearly visible.

Signed-off-by: Gabriel Schulhof <gabriel.schulhof@intel.com>
Co-authored-by: Ben Noordhuis <info@bnoordhuis.nl>
PR-URL: #32396
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: David Carlier <devnexen@gmail.com>
addaleax pushed a commit that referenced this pull request Mar 30, 2020
* Introduce `OnScopeLeave` handler for cleaning up mmap()ed range(s).
* Factor out failure scenario at the bottom of the function with
  `fail` label for use with `goto`.
* Do not allocate temporary range (`nmem`) on FreeBSD, because it is
  not used.

The intention is that the steps involved in re-mapping to large pages
become more clearly visible.

Signed-off-by: Gabriel Schulhof <gabriel.schulhof@intel.com>
Co-authored-by: Ben Noordhuis <info@bnoordhuis.nl>
PR-URL: #32396
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: David Carlier <devnexen@gmail.com>
@gabrielschulhof gabrielschulhof deleted the large-pages-simplify-code branch April 21, 2020 02:58
@targos

targos commented Apr 22, 2020

Copy link
Copy Markdown
Member

targos pushed a commit to targos/node that referenced this pull request Apr 25, 2020
* Introduce `OnScopeLeave` handler for cleaning up mmap()ed range(s).
* Factor out failure scenario at the bottom of the function with
  `fail` label for use with `goto`.
* Do not allocate temporary range (`nmem`) on FreeBSD, because it is
  not used.

The intention is that the steps involved in re-mapping to large pages
become more clearly visible.

Signed-off-by: Gabriel Schulhof <gabriel.schulhof@intel.com>
Co-authored-by: Ben Noordhuis <info@bnoordhuis.nl>
PR-URL: nodejs#32396
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: David Carlier <devnexen@gmail.com>
targos pushed a commit that referenced this pull request Apr 28, 2020
* Introduce `OnScopeLeave` handler for cleaning up mmap()ed range(s).
* Factor out failure scenario at the bottom of the function with
  `fail` label for use with `goto`.
* Do not allocate temporary range (`nmem`) on FreeBSD, because it is
  not used.

The intention is that the steps involved in re-mapping to large pages
become more clearly visible.

Signed-off-by: Gabriel Schulhof <gabriel.schulhof@intel.com>
Co-authored-by: Ben Noordhuis <info@bnoordhuis.nl>
PR-URL: #32396
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: David Carlier <devnexen@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ Issues and PRs that require attention from people who are familiar with C++.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants