Skip to content

Commit 09cd744

Browse files
Gabriel Schulhofbnoordhuis
authored andcommitted
src: simplify large pages mapping code
* 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>
1 parent 2f8f619 commit 09cd744

File tree

1 file changed

+25
-56
lines changed

1 file changed

+25
-56
lines changed

src/large_pages/node_large_page.cc

+25-56
Original file line numberDiff line numberDiff line change
@@ -339,20 +339,23 @@ __attribute__((__noinline__))
339339
MoveTextRegionToLargePages(const text_region& r) {
340340
void* nmem = nullptr;
341341
void* tmem = nullptr;
342-
int ret = 0;
343-
344-
size_t size = r.to - r.from;
345342
void* start = r.from;
343+
size_t size = r.to - r.from;
344+
345+
auto free_mems = OnScopeLeave([&nmem, &tmem, size]() {
346+
if (nmem != nullptr && nmem != MAP_FAILED && munmap(nmem, size) == -1)
347+
PrintSystemError(errno);
348+
if (tmem != nullptr && tmem != MAP_FAILED && munmap(tmem, size) == -1)
349+
PrintSystemError(errno);
350+
});
346351

347-
// Allocate temporary region preparing for copy.
352+
#if !defined (__FreeBSD__)
353+
// Allocate temporary region and back up the code we will re-map.
348354
nmem = mmap(nullptr, size,
349355
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
350-
if (nmem == MAP_FAILED) {
351-
PrintSystemError(errno);
352-
return -1;
353-
}
354-
356+
if (nmem == MAP_FAILED) goto fail;
355357
memcpy(nmem, r.from, size);
358+
#endif
356359

357360
#if defined(__linux__)
358361
// We already know the original page is r-xp
@@ -362,32 +365,15 @@ MoveTextRegionToLargePages(const text_region& r) {
362365
tmem = mmap(start, size,
363366
PROT_READ | PROT_WRITE | PROT_EXEC,
364367
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1 , 0);
365-
if (tmem == MAP_FAILED) {
366-
PrintSystemError(errno);
367-
return -1;
368-
}
369-
370-
ret = madvise(tmem, size, 14 /* MADV_HUGEPAGE */);
371-
if (ret == -1) {
372-
PrintSystemError(errno);
373-
ret = munmap(tmem, size);
374-
if (ret == -1) {
375-
PrintSystemError(errno);
376-
}
377-
if (-1 == munmap(nmem, size)) PrintSystemError(errno);
378-
return -1;
379-
}
368+
if (tmem == MAP_FAILED) goto fail;
369+
if (madvise(tmem, size, 14 /* MADV_HUGEPAGE */) == -1) goto fail;
380370
memcpy(start, nmem, size);
381371
#elif defined(__FreeBSD__)
382372
tmem = mmap(start, size,
383373
PROT_READ | PROT_WRITE | PROT_EXEC,
384374
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED |
385375
MAP_ALIGNED_SUPER, -1 , 0);
386-
if (tmem == MAP_FAILED) {
387-
PrintSystemError(errno);
388-
if (-1 == munmap(nmem, size)) PrintSystemError(errno);
389-
return -1;
390-
}
376+
if (tmem == MAP_FAILED) goto fail;
391377
#elif defined(__APPLE__)
392378
// There is not enough room to reserve the mapping close
393379
// to the region address so we content to give a hint
@@ -398,37 +384,20 @@ MoveTextRegionToLargePages(const text_region& r) {
398384
PROT_READ | PROT_WRITE | PROT_EXEC,
399385
MAP_PRIVATE | MAP_ANONYMOUS,
400386
VM_FLAGS_SUPERPAGE_SIZE_2MB, 0);
401-
if (tmem == MAP_FAILED) {
402-
PrintSystemError(errno);
403-
if (-1 == munmap(nmem, size)) PrintSystemError(errno);
404-
return -1;
405-
}
387+
if (tmem == MAP_FAILED) goto fail;
406388
memcpy(tmem, nmem, size);
407-
ret = mprotect(start, size, PROT_READ | PROT_WRITE | PROT_EXEC);
408-
if (ret == -1) {
409-
PrintSystemError(errno);
410-
ret = munmap(tmem, size);
411-
if (ret == -1) {
412-
PrintSystemError(errno);
413-
}
414-
if (-1 == munmap(nmem, size)) PrintSystemError(errno);
415-
return -1;
416-
}
389+
if (mprotect(start, size, PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
390+
goto fail;
417391
memcpy(start, tmem, size);
418392
#endif
419393

420-
ret = mprotect(start, size, PROT_READ | PROT_EXEC);
421-
if (ret == -1) {
422-
PrintSystemError(errno);
423-
ret = munmap(tmem, size);
424-
if (ret == -1) {
425-
PrintSystemError(errno);
426-
}
427-
if (-1 == munmap(nmem, size)) PrintSystemError(errno);
428-
return -1;
429-
}
430-
if (-1 == munmap(nmem, size)) PrintSystemError(errno);
431-
return ret;
394+
if (mprotect(start, size, PROT_READ | PROT_EXEC) == -1) goto fail;
395+
// We need not `munmap(tmem, size)` in the above `OnScopeLeave` on success.
396+
tmem = nullptr;
397+
return 0;
398+
fail:
399+
PrintSystemError(errno);
400+
return -1;
432401
}
433402
#endif // defined(NODE_ENABLE_LARGE_CODE_PAGES) && NODE_ENABLE_LARGE_CODE_PAGES
434403

0 commit comments

Comments
 (0)