1 /* 2 * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 #include "precompiled.hpp" 25 #include "gc/z/zAddress.inline.hpp" 26 #include "gc/z/zBackingFile_linux_x86.hpp" 27 #include "gc/z/zErrno.hpp" 28 #include "gc/z/zLargePages.inline.hpp" 29 #include "gc/z/zMemory.hpp" 30 #include "gc/z/zNUMA.hpp" 31 #include "gc/z/zPhysicalMemory.inline.hpp" 32 #include "gc/z/zPhysicalMemoryBacking_linux_x86.hpp" 33 #include "logging/log.hpp" 34 #include "runtime/os.hpp" 35 #include "utilities/align.hpp" 36 #include "utilities/debug.hpp" 37 38 #include <stdio.h> 39 #include <sys/mman.h> 40 #include <sys/types.h> 41 42 // Support for building on older Linux systems 43 #ifndef MADV_HUGEPAGE 44 #define MADV_HUGEPAGE 14 45 #endif 46 47 // Proc file entry for max map mount 48 #define ZFILENAME_PROC_MAX_MAP_COUNT "/proc/sys/vm/max_map_count" 49 50 ZPhysicalMemoryBacking::ZPhysicalMemoryBacking(size_t max_capacity, size_t granule_size) : 51 _manager(), 52 _file(), 53 _granule_size(granule_size) { 54 55 if (!_file.is_initialized()) { 56 return; 57 } 58 59 // Check and warn if max map count is too low 60 check_max_map_count(max_capacity, granule_size); 61 62 // Check and warn if available space on filesystem is too low 63 check_available_space_on_filesystem(max_capacity); 64 } 65 66 void ZPhysicalMemoryBacking::check_max_map_count(size_t max_capacity, size_t granule_size) const { 67 const char* const filename = ZFILENAME_PROC_MAX_MAP_COUNT; 68 FILE* const file = fopen(filename, "r"); 69 if (file == NULL) { 70 // Failed to open file, skip check 71 log_debug(gc, init)("Failed to open %s", filename); 72 return; 73 } 74 75 size_t actual_max_map_count = 0; 76 const int result = fscanf(file, SIZE_FORMAT, &actual_max_map_count); 77 fclose(file); 78 if (result != 1) { 79 // Failed to read file, skip check 80 log_debug(gc, init)("Failed to read %s", filename); 81 return; 82 } 83 84 // The required max map count is impossible to calculate exactly since subsystems 85 // other than ZGC are also creating memory mappings, and we have no control over that. 86 // However, ZGC tends to create the most mappings and dominate the total count. 87 // In the worst cases, ZGC will map each granule three times, i.e. once per heap view. 88 // We speculate that we need another 20% to allow for non-ZGC subsystems to map memory. 89 const size_t required_max_map_count = (max_capacity / granule_size) * 3 * 1.2; 90 if (actual_max_map_count < required_max_map_count) { 91 log_warning(gc, init)("***** WARNING! INCORRECT SYSTEM CONFIGURATION DETECTED! *****"); 92 log_warning(gc, init)("The system limit on number of memory mappings per process might be too low " 93 "for the given"); 94 log_warning(gc, init)("max Java heap size (" SIZE_FORMAT "M). Please adjust %s to allow for at", 95 max_capacity / M, filename); 96 log_warning(gc, init)("least " SIZE_FORMAT " mappings (current limit is " SIZE_FORMAT "). Continuing " 97 "execution with the current", required_max_map_count, actual_max_map_count); 98 log_warning(gc, init)("limit could lead to a fatal error, due to failure to map memory."); 99 } 100 } 101 102 void ZPhysicalMemoryBacking::check_available_space_on_filesystem(size_t max_capacity) const { 103 // Note that the available space on a tmpfs or a hugetlbfs filesystem 104 // will be zero if no size limit was specified when it was mounted. 105 const size_t available = _file.available(); 106 if (available == 0) { 107 // No size limit set, skip check 108 log_info(gc, init)("Available space on backing filesystem: N/A"); 109 return; 118 if (available < max_capacity) { 119 log_warning(gc, init)("***** WARNING! INCORRECT SYSTEM CONFIGURATION DETECTED! *****"); 120 log_warning(gc, init)("Not enough space available on the backing filesystem to hold the current " 121 "max Java heap"); 122 log_warning(gc, init)("size (" SIZE_FORMAT "M). Please adjust the size of the backing filesystem " 123 "accordingly (available", max_capacity / M); 124 log_warning(gc, init)("space is currently " SIZE_FORMAT "M). Continuing execution with the current " 125 "filesystem size could", available / M); 126 log_warning(gc, init)("lead to a premature OutOfMemoryError being thrown, due to failure to map " 127 "memory."); 128 } 129 } 130 131 bool ZPhysicalMemoryBacking::is_initialized() const { 132 return _file.is_initialized(); 133 } 134 135 size_t ZPhysicalMemoryBacking::try_expand(size_t old_capacity, size_t new_capacity) { 136 assert(old_capacity < new_capacity, "Invalid old/new capacity"); 137 138 const size_t capacity = _file.try_expand(old_capacity, new_capacity - old_capacity, _granule_size); 139 if (capacity > old_capacity) { 140 // Add expanded capacity to free list 141 _manager.free(old_capacity, capacity - old_capacity); 142 } 143 144 return capacity; 145 } 146 147 ZPhysicalMemory ZPhysicalMemoryBacking::alloc(size_t size) { 148 assert(is_aligned(size, _granule_size), "Invalid size"); 149 150 ZPhysicalMemory pmem; 151 152 // Allocate segments 153 for (size_t allocated = 0; allocated < size; allocated += _granule_size) { 154 const uintptr_t start = _manager.alloc_from_front(_granule_size); 155 assert(start != UINTPTR_MAX, "Allocation should never fail"); 156 pmem.add_segment(ZPhysicalMemorySegment(start, _granule_size)); 157 } 158 159 return pmem; 160 } 161 162 void ZPhysicalMemoryBacking::free(ZPhysicalMemory pmem) { 163 const size_t nsegments = pmem.nsegments(); 164 165 // Free segments 166 for (size_t i = 0; i < nsegments; i++) { 167 const ZPhysicalMemorySegment segment = pmem.segment(i); 168 _manager.free(segment.start(), segment.size()); 169 } 170 } 171 172 void ZPhysicalMemoryBacking::map_failed(ZErrno err) const { 173 if (err == ENOMEM) { 174 fatal("Failed to map memory. Please check the system limit on number of " 175 "memory mappings allowed per process (see %s)", ZFILENAME_PROC_MAX_MAP_COUNT); 176 } else { | 1 /* 2 * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 #include "precompiled.hpp" 25 #include "gc/z/zAddress.inline.hpp" 26 #include "gc/z/zBackingFile_linux_x86.hpp" 27 #include "gc/z/zErrno.hpp" 28 #include "gc/z/zGlobals.hpp" 29 #include "gc/z/zLargePages.inline.hpp" 30 #include "gc/z/zMemory.hpp" 31 #include "gc/z/zNUMA.hpp" 32 #include "gc/z/zPhysicalMemory.inline.hpp" 33 #include "gc/z/zPhysicalMemoryBacking_linux_x86.hpp" 34 #include "logging/log.hpp" 35 #include "runtime/os.hpp" 36 #include "utilities/align.hpp" 37 #include "utilities/debug.hpp" 38 39 #include <stdio.h> 40 #include <sys/mman.h> 41 #include <sys/types.h> 42 43 // Support for building on older Linux systems 44 #ifndef MADV_HUGEPAGE 45 #define MADV_HUGEPAGE 14 46 #endif 47 48 // Proc file entry for max map mount 49 #define ZFILENAME_PROC_MAX_MAP_COUNT "/proc/sys/vm/max_map_count" 50 51 ZPhysicalMemoryBacking::ZPhysicalMemoryBacking(size_t max_capacity) : 52 _manager(), 53 _file() { 54 55 if (!_file.is_initialized()) { 56 return; 57 } 58 59 // Check and warn if max map count is too low 60 check_max_map_count(max_capacity); 61 62 // Check and warn if available space on filesystem is too low 63 check_available_space_on_filesystem(max_capacity); 64 } 65 66 void ZPhysicalMemoryBacking::check_max_map_count(size_t max_capacity) const { 67 const char* const filename = ZFILENAME_PROC_MAX_MAP_COUNT; 68 FILE* const file = fopen(filename, "r"); 69 if (file == NULL) { 70 // Failed to open file, skip check 71 log_debug(gc, init)("Failed to open %s", filename); 72 return; 73 } 74 75 size_t actual_max_map_count = 0; 76 const int result = fscanf(file, SIZE_FORMAT, &actual_max_map_count); 77 fclose(file); 78 if (result != 1) { 79 // Failed to read file, skip check 80 log_debug(gc, init)("Failed to read %s", filename); 81 return; 82 } 83 84 // The required max map count is impossible to calculate exactly since subsystems 85 // other than ZGC are also creating memory mappings, and we have no control over that. 86 // However, ZGC tends to create the most mappings and dominate the total count. 87 // In the worst cases, ZGC will map each granule three times, i.e. once per heap view. 88 // We speculate that we need another 20% to allow for non-ZGC subsystems to map memory. 89 const size_t required_max_map_count = (max_capacity / ZGranuleSize) * 3 * 1.2; 90 if (actual_max_map_count < required_max_map_count) { 91 log_warning(gc, init)("***** WARNING! INCORRECT SYSTEM CONFIGURATION DETECTED! *****"); 92 log_warning(gc, init)("The system limit on number of memory mappings per process might be too low " 93 "for the given"); 94 log_warning(gc, init)("max Java heap size (" SIZE_FORMAT "M). Please adjust %s to allow for at", 95 max_capacity / M, filename); 96 log_warning(gc, init)("least " SIZE_FORMAT " mappings (current limit is " SIZE_FORMAT "). Continuing " 97 "execution with the current", required_max_map_count, actual_max_map_count); 98 log_warning(gc, init)("limit could lead to a fatal error, due to failure to map memory."); 99 } 100 } 101 102 void ZPhysicalMemoryBacking::check_available_space_on_filesystem(size_t max_capacity) const { 103 // Note that the available space on a tmpfs or a hugetlbfs filesystem 104 // will be zero if no size limit was specified when it was mounted. 105 const size_t available = _file.available(); 106 if (available == 0) { 107 // No size limit set, skip check 108 log_info(gc, init)("Available space on backing filesystem: N/A"); 109 return; 118 if (available < max_capacity) { 119 log_warning(gc, init)("***** WARNING! INCORRECT SYSTEM CONFIGURATION DETECTED! *****"); 120 log_warning(gc, init)("Not enough space available on the backing filesystem to hold the current " 121 "max Java heap"); 122 log_warning(gc, init)("size (" SIZE_FORMAT "M). Please adjust the size of the backing filesystem " 123 "accordingly (available", max_capacity / M); 124 log_warning(gc, init)("space is currently " SIZE_FORMAT "M). Continuing execution with the current " 125 "filesystem size could", available / M); 126 log_warning(gc, init)("lead to a premature OutOfMemoryError being thrown, due to failure to map " 127 "memory."); 128 } 129 } 130 131 bool ZPhysicalMemoryBacking::is_initialized() const { 132 return _file.is_initialized(); 133 } 134 135 size_t ZPhysicalMemoryBacking::try_expand(size_t old_capacity, size_t new_capacity) { 136 assert(old_capacity < new_capacity, "Invalid old/new capacity"); 137 138 const size_t capacity = _file.try_expand(old_capacity, new_capacity - old_capacity, ZGranuleSize); 139 if (capacity > old_capacity) { 140 // Add expanded capacity to free list 141 _manager.free(old_capacity, capacity - old_capacity); 142 } 143 144 return capacity; 145 } 146 147 ZPhysicalMemory ZPhysicalMemoryBacking::alloc(size_t size) { 148 assert(is_aligned(size, ZGranuleSize), "Invalid size"); 149 150 ZPhysicalMemory pmem; 151 152 // Allocate segments 153 for (size_t allocated = 0; allocated < size; allocated += ZGranuleSize) { 154 const uintptr_t start = _manager.alloc_from_front(ZGranuleSize); 155 assert(start != UINTPTR_MAX, "Allocation should never fail"); 156 pmem.add_segment(ZPhysicalMemorySegment(start, ZGranuleSize)); 157 } 158 159 return pmem; 160 } 161 162 void ZPhysicalMemoryBacking::free(ZPhysicalMemory pmem) { 163 const size_t nsegments = pmem.nsegments(); 164 165 // Free segments 166 for (size_t i = 0; i < nsegments; i++) { 167 const ZPhysicalMemorySegment segment = pmem.segment(i); 168 _manager.free(segment.start(), segment.size()); 169 } 170 } 171 172 void ZPhysicalMemoryBacking::map_failed(ZErrno err) const { 173 if (err == ENOMEM) { 174 fatal("Failed to map memory. Please check the system limit on number of " 175 "memory mappings allowed per process (see %s)", ZFILENAME_PROC_MAX_MAP_COUNT); 176 } else { |