From acd630d6785d977511067110bcf978f9c1e3f01f Mon Sep 17 00:00:00 2001 From: Octavian Moraru Date: Mon, 19 Jun 2017 13:16:13 -0700 Subject: [PATCH] Enable hot static code mapping onto huge pages This diff enables mapping of hot static code onto huge pages for open source builds. It defines __hot_start and __hot_end at link time using the first and last functions from the linker script. This feature can be turned off by setting the CMake option MAP_TEXT_HUGE_PAGES to 'Off'. hugifyText was aligned to 2MB so that we maximize the amount of hot code we can map if __hot_end is placed just before it. Solves https://github.com/facebook/hhvm/issues/5269 --- CMake/Options.cmake | 4 ++++ hphp/hhvm/CMakeLists.txt | 15 +++++++++++++-- hphp/runtime/base/program-functions.cpp | 16 ++++++++-------- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/CMake/Options.cmake b/CMake/Options.cmake index ad1659ffee7042..787ce51dee1776 100644 --- a/CMake/Options.cmake +++ b/CMake/Options.cmake @@ -34,6 +34,10 @@ option(ENABLE_PROXYGEN_SERVER "Build the Proxygen HTTP server" ON) option(ENABLE_SPLIT_DWARF "Reduce linker memory usage by putting debugging information into .dwo files" OFF) +IF (LINUX) + option(MAP_TEXT_HUGE_PAGES "Remap hot static code onto huge pages" ON) +ENDIF() + IF (NOT DEFAULT_CONFIG_DIR) set(DEFAULT_CONFIG_DIR "/etc/hhvm/" CACHE STRING "Default directory to find php.ini") diff --git a/hphp/hhvm/CMakeLists.txt b/hphp/hhvm/CMakeLists.txt index a7f63807ecf3e8..5559fa0f579a66 100644 --- a/hphp/hhvm/CMakeLists.txt +++ b/hphp/hhvm/CMakeLists.txt @@ -11,6 +11,17 @@ endif() option(ENABLE_LD_GOLD "Enable Hot Linker script using ld-gold" On) set(SECTION_ORDERING_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../tools/oss_hot_section_ordering CACHE FILEPATH "File used by ld-gold for the relocation of sections") + +if (MAP_TEXT_HUGE_PAGES) + file(STRINGS "${SECTION_ORDERING_FILE}" SECTION_ORDERING_CONTENTS) + list(GET SECTION_ORDERING_CONTENTS 0 HOT_START) + list(GET SECTION_ORDERING_CONTENTS -1 HOT_END) + string(REGEX REPLACE "\\.text\\.(.*)\\*" "\\1" HOT_START ${HOT_START}) + string(REGEX REPLACE "\\.text\\.(.*)\\*" "\\1" HOT_END ${HOT_END}) + set(DEFSYM_HOT_START "--defsym=__hot_start=${HOT_START},") + set(DEFSYM_HOT_END "--defsym=__hot_end=${HOT_END},") +endif() + if (ENABLE_LD_GOLD) find_package(Gold) endif() @@ -21,9 +32,9 @@ target_link_libraries(hhvm ${HHVM_LINK_LIBRARIES} ${EZC_LINK_LIBRARIES} ${HRE_LI link_object_libraries(hhvm ${HHVM_WHOLE_ARCHIVE_LIBRARIES}) if (GOLD_FOUND AND ENABLE_LD_GOLD) if (CMAKE_CONFIGURATION_TYPES) - SET(LINKER_SCRIPT -fuse-ld=gold;-Wl,--icf=all,--gc-sections;release;-Wl,--section-ordering-file,${SECTION_ORDERING_FILE};default) + SET(LINKER_SCRIPT -fuse-ld=gold;-Wl,--icf=all,--gc-sections;release;-Wl,${DEFSYM_HOT_START}${DEFSYM_HOT_END}--section-ordering-file,${SECTION_ORDERING_FILE};default) elseif(NOT CMAKE_BUILD_TYPE MATCHES "Debug") - SET(LINKER_SCRIPT -fuse-ld=gold -Wl,--section-ordering-file,${SECTION_ORDERING_FILE},--icf=all,--gc-sections) + SET(LINKER_SCRIPT -fuse-ld=gold -Wl,${DEFSYM_HOT_START}${DEFSYM_HOT_END}--section-ordering-file,${SECTION_ORDERING_FILE},--icf=all,--gc-sections) else() SET(LINKER_SCRIPT -fuse-ld=gold -Wl,--icf=all,--gc-sections) endif() diff --git a/hphp/runtime/base/program-functions.cpp b/hphp/runtime/base/program-functions.cpp index 451e7c81fe636c..b58aec17ca8e45 100644 --- a/hphp/runtime/base/program-functions.cpp +++ b/hphp/runtime/base/program-functions.cpp @@ -755,16 +755,12 @@ void execute_command_line_end(int xhprof, bool coverage, const char *program) { const void* __hot_start = nullptr; const void* __hot_end = nullptr; #endif - -#if FACEBOOK # define AT_END_OF_TEXT __attribute__((__section__(".stub"))) -#else -# define AT_END_OF_TEXT -#endif +# define ALIGN_HUGE_PAGE __attribute__((aligned(2 * 1024 * 1024))) -static void NEVER_INLINE AT_END_OF_TEXT __attribute__((__optimize__("2"))) +static void NEVER_INLINE AT_END_OF_TEXT ALIGN_HUGE_PAGE __attribute__((__optimize__("2"))) hugifyText(char* from, char* to) { -#if FACEBOOK && !defined FOLLY_SANITIZE_ADDRESS && defined MADV_HUGEPAGE +#if !defined FOLLY_SANITIZE_ADDRESS && defined MADV_HUGEPAGE if (from > to || (to - from) < sizeof(uint64_t)) { // This shouldn't happen if HHVM is behaving correctly (I think), // but if it does then there is nothing to do and we should bail @@ -796,6 +792,10 @@ hugifyText(char* from, char* to) { free(mem); mlock(from, to - from); Debug::DebugInfo::setPidMapOverlay(from, to); + std::stringstream ss; + ss << "Mapped text section onto huge pages from " << + std::hex << (uint64_t*)from << " to " << (uint64_t*)to; + Logger::Info(ss.str()); #endif } @@ -854,7 +854,7 @@ static void pagein_self(void) { if (to - from > maxHugeHotTextBytes) { to = from + maxHugeHotTextBytes; } - if (to < (void*)hugifyText) { + if (to <= (void*)hugifyText) { hugifyText(from, to); } }