comparison src/os/linux/vm/os_linux.cpp @ 3464:be4ca325525a

Merge.
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Wed, 27 Jul 2011 17:32:44 -0700
parents 0654ee04b214 97b64f73103b
children 04b9a2566eec
comparison
equal deleted inserted replaced
3239:7c4b4daac19b 3464:be4ca325525a
2463 uintptr_t res = (uintptr_t) ::mmap(addr, size, prot, 2463 uintptr_t res = (uintptr_t) ::mmap(addr, size, prot,
2464 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0); 2464 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
2465 return res != (uintptr_t) MAP_FAILED; 2465 return res != (uintptr_t) MAP_FAILED;
2466 } 2466 }
2467 2467
2468 // Define MAP_HUGETLB here so we can build HotSpot on old systems.
2469 #ifndef MAP_HUGETLB
2470 #define MAP_HUGETLB 0x40000
2471 #endif
2472
2473 // Define MADV_HUGEPAGE here so we can build HotSpot on old systems.
2474 #ifndef MADV_HUGEPAGE
2475 #define MADV_HUGEPAGE 14
2476 #endif
2477
2468 bool os::commit_memory(char* addr, size_t size, size_t alignment_hint, 2478 bool os::commit_memory(char* addr, size_t size, size_t alignment_hint,
2469 bool exec) { 2479 bool exec) {
2480 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
2481 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
2482 uintptr_t res =
2483 (uintptr_t) ::mmap(addr, size, prot,
2484 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_HUGETLB,
2485 -1, 0);
2486 return res != (uintptr_t) MAP_FAILED;
2487 }
2488
2470 return commit_memory(addr, size, exec); 2489 return commit_memory(addr, size, exec);
2471 } 2490 }
2472 2491
2473 void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { } 2492 void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
2493 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
2494 // We don't check the return value: madvise(MADV_HUGEPAGE) may not
2495 // be supported or the memory may already be backed by huge pages.
2496 ::madvise(addr, bytes, MADV_HUGEPAGE);
2497 }
2498 }
2474 2499
2475 void os::free_memory(char *addr, size_t bytes) { 2500 void os::free_memory(char *addr, size_t bytes) {
2476 ::mmap(addr, bytes, PROT_READ | PROT_WRITE, 2501 ::madvise(addr, bytes, MADV_DONTNEED);
2477 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
2478 } 2502 }
2479 2503
2480 void os::numa_make_global(char *addr, size_t bytes) { 2504 void os::numa_make_global(char *addr, size_t bytes) {
2481 Linux::numa_interleave_memory(addr, bytes); 2505 Linux::numa_interleave_memory(addr, bytes);
2482 } 2506 }
2808 return linux_mprotect(addr, size, PROT_NONE); 2832 return linux_mprotect(addr, size, PROT_NONE);
2809 } 2833 }
2810 2834
2811 bool os::unguard_memory(char* addr, size_t size) { 2835 bool os::unguard_memory(char* addr, size_t size) {
2812 return linux_mprotect(addr, size, PROT_READ|PROT_WRITE); 2836 return linux_mprotect(addr, size, PROT_READ|PROT_WRITE);
2837 }
2838
2839 bool os::Linux::hugetlbfs_sanity_check(bool warn, size_t page_size) {
2840 bool result = false;
2841 void *p = mmap (NULL, page_size, PROT_READ|PROT_WRITE,
2842 MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB,
2843 -1, 0);
2844
2845 if (p != (void *) -1) {
2846 // We don't know if this really is a huge page or not.
2847 FILE *fp = fopen("/proc/self/maps", "r");
2848 if (fp) {
2849 while (!feof(fp)) {
2850 char chars[257];
2851 long x = 0;
2852 if (fgets(chars, sizeof(chars), fp)) {
2853 if (sscanf(chars, "%lx-%*x", &x) == 1
2854 && x == (long)p) {
2855 if (strstr (chars, "hugepage")) {
2856 result = true;
2857 break;
2858 }
2859 }
2860 }
2861 }
2862 fclose(fp);
2863 }
2864 munmap (p, page_size);
2865 if (result)
2866 return true;
2867 }
2868
2869 if (warn) {
2870 warning("HugeTLBFS is not supported by the operating system.");
2871 }
2872
2873 return result;
2813 } 2874 }
2814 2875
2815 /* 2876 /*
2816 * Set the coredump_filter bits to include largepages in core dump (bit 6) 2877 * Set the coredump_filter bits to include largepages in core dump (bit 6)
2817 * 2878 *
2851 2912
2852 // Large page support 2913 // Large page support
2853 2914
2854 static size_t _large_page_size = 0; 2915 static size_t _large_page_size = 0;
2855 2916
2856 bool os::large_page_init() { 2917 void os::large_page_init() {
2857 if (!UseLargePages) return false; 2918 if (!UseLargePages) {
2919 UseHugeTLBFS = false;
2920 UseSHM = false;
2921 return;
2922 }
2923
2924 if (FLAG_IS_DEFAULT(UseHugeTLBFS) && FLAG_IS_DEFAULT(UseSHM)) {
2925 // If UseLargePages is specified on the command line try both methods,
2926 // if it's default, then try only HugeTLBFS.
2927 if (FLAG_IS_DEFAULT(UseLargePages)) {
2928 UseHugeTLBFS = true;
2929 } else {
2930 UseHugeTLBFS = UseSHM = true;
2931 }
2932 }
2858 2933
2859 if (LargePageSizeInBytes) { 2934 if (LargePageSizeInBytes) {
2860 _large_page_size = LargePageSizeInBytes; 2935 _large_page_size = LargePageSizeInBytes;
2861 } else { 2936 } else {
2862 // large_page_size on Linux is used to round up heap size. x86 uses either 2937 // large_page_size on Linux is used to round up heap size. x86 uses either
2897 } 2972 }
2898 fclose(fp); 2973 fclose(fp);
2899 } 2974 }
2900 } 2975 }
2901 2976
2977 // print a warning if any large page related flag is specified on command line
2978 bool warn_on_failure = !FLAG_IS_DEFAULT(UseHugeTLBFS);
2979
2902 const size_t default_page_size = (size_t)Linux::page_size(); 2980 const size_t default_page_size = (size_t)Linux::page_size();
2903 if (_large_page_size > default_page_size) { 2981 if (_large_page_size > default_page_size) {
2904 _page_sizes[0] = _large_page_size; 2982 _page_sizes[0] = _large_page_size;
2905 _page_sizes[1] = default_page_size; 2983 _page_sizes[1] = default_page_size;
2906 _page_sizes[2] = 0; 2984 _page_sizes[2] = 0;
2907 } 2985 }
2986 UseHugeTLBFS = UseHugeTLBFS &&
2987 Linux::hugetlbfs_sanity_check(warn_on_failure, _large_page_size);
2988
2989 if (UseHugeTLBFS)
2990 UseSHM = false;
2991
2992 UseLargePages = UseHugeTLBFS || UseSHM;
2908 2993
2909 set_coredump_filter(); 2994 set_coredump_filter();
2910
2911 // Large page support is available on 2.6 or newer kernel, some vendors
2912 // (e.g. Redhat) have backported it to their 2.4 based distributions.
2913 // We optimistically assume the support is available. If later it turns out
2914 // not true, VM will automatically switch to use regular page size.
2915 return true;
2916 } 2995 }
2917 2996
2918 #ifndef SHM_HUGETLB 2997 #ifndef SHM_HUGETLB
2919 #define SHM_HUGETLB 04000 2998 #define SHM_HUGETLB 04000
2920 #endif 2999 #endif
2921 3000
2922 char* os::reserve_memory_special(size_t bytes, char* req_addr, bool exec) { 3001 char* os::reserve_memory_special(size_t bytes, char* req_addr, bool exec) {
2923 // "exec" is passed in but not used. Creating the shared image for 3002 // "exec" is passed in but not used. Creating the shared image for
2924 // the code cache doesn't have an SHM_X executable permission to check. 3003 // the code cache doesn't have an SHM_X executable permission to check.
2925 assert(UseLargePages, "only for large pages"); 3004 assert(UseLargePages && UseSHM, "only for SHM large pages");
2926 3005
2927 key_t key = IPC_PRIVATE; 3006 key_t key = IPC_PRIVATE;
2928 char *addr; 3007 char *addr;
2929 3008
2930 bool warn_on_failure = UseLargePages && 3009 bool warn_on_failure = UseLargePages &&
2987 3066
2988 size_t os::large_page_size() { 3067 size_t os::large_page_size() {
2989 return _large_page_size; 3068 return _large_page_size;
2990 } 3069 }
2991 3070
2992 // Linux does not support anonymous mmap with large page memory. The only way 3071 // HugeTLBFS allows application to commit large page memory on demand;
2993 // to reserve large page memory without file backing is through SysV shared 3072 // with SysV SHM the entire memory region must be allocated as shared
2994 // memory API. The entire memory region is committed and pinned upfront. 3073 // memory.
2995 // Hopefully this will change in the future...
2996 bool os::can_commit_large_page_memory() { 3074 bool os::can_commit_large_page_memory() {
2997 return false; 3075 return UseHugeTLBFS;
2998 } 3076 }
2999 3077
3000 bool os::can_execute_large_page_memory() { 3078 bool os::can_execute_large_page_memory() {
3001 return false; 3079 return UseHugeTLBFS;
3002 } 3080 }
3003 3081
3004 // Reserve memory at an arbitrary address, only if that area is 3082 // Reserve memory at an arbitrary address, only if that area is
3005 // available (and not reserved for something else). 3083 // available (and not reserved for something else).
3006 3084
4043 if(Verbose && PrintMiscellaneous) 4121 if(Verbose && PrintMiscellaneous)
4044 tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page); 4122 tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page);
4045 #endif 4123 #endif
4046 } 4124 }
4047 4125
4048 FLAG_SET_DEFAULT(UseLargePages, os::large_page_init()); 4126 os::large_page_init();
4049 4127
4050 // initialize suspend/resume support - must do this before signal_sets_init() 4128 // initialize suspend/resume support - must do this before signal_sets_init()
4051 if (SR_initialize() != 0) { 4129 if (SR_initialize() != 0) {
4052 perror("SR_initialize failed"); 4130 perror("SR_initialize failed");
4053 return JNI_ERR; 4131 return JNI_ERR;
4092 if (!Linux::libnuma_init()) { 4170 if (!Linux::libnuma_init()) {
4093 UseNUMA = false; 4171 UseNUMA = false;
4094 } else { 4172 } else {
4095 if ((Linux::numa_max_node() < 1)) { 4173 if ((Linux::numa_max_node() < 1)) {
4096 // There's only one node(they start from 0), disable NUMA. 4174 // There's only one node(they start from 0), disable NUMA.
4175 UseNUMA = false;
4176 }
4177 }
4178 // With SHM large pages we cannot uncommit a page, so there's not way
4179 // we can make the adaptive lgrp chunk resizing work. If the user specified
4180 // both UseNUMA and UseLargePages (or UseSHM) on the command line - warn and
4181 // disable adaptive resizing.
4182 if (UseNUMA && UseLargePages && UseSHM) {
4183 if (!FLAG_IS_DEFAULT(UseNUMA)) {
4184 if (FLAG_IS_DEFAULT(UseLargePages) && FLAG_IS_DEFAULT(UseSHM)) {
4185 UseLargePages = false;
4186 } else {
4187 warning("UseNUMA is not fully compatible with SHM large pages, disabling adaptive resizing");
4188 UseAdaptiveSizePolicy = false;
4189 UseAdaptiveNUMAChunkSizing = false;
4190 }
4191 } else {
4097 UseNUMA = false; 4192 UseNUMA = false;
4098 } 4193 }
4099 } 4194 }
4100 if (!UseNUMA && ForceNUMA) { 4195 if (!UseNUMA && ForceNUMA) {
4101 UseNUMA = true; 4196 UseNUMA = true;