Merge

Thu, 21 Apr 2011 01:16:20 -0700

author
ysr
date
Thu, 21 Apr 2011 01:16:20 -0700
changeset 2820
c0dcda80820f
parent 2819
c48ad6ab8bdf
parent 2818
139667d9836a
child 2821
b52782ae3880

Merge

     1.1 --- a/src/os/linux/vm/globals_linux.hpp	Wed Apr 20 19:19:30 2011 -0700
     1.2 +++ b/src/os/linux/vm/globals_linux.hpp	Thu Apr 21 01:16:20 2011 -0700
     1.3 @@ -29,13 +29,19 @@
     1.4  // Defines Linux specific flags. They are not available on other platforms.
     1.5  //
     1.6  #define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct) \
     1.7 -  product(bool, UseOprofile, false,                                 \
     1.8 -        "enable support for Oprofile profiler")                     \
     1.9 -                                                                    \
    1.10 -  product(bool, UseLinuxPosixThreadCPUClocks, true,                 \
    1.11 -          "enable fast Linux Posix clocks where available")
    1.12 -// NB: The default value of UseLinuxPosixThreadCPUClocks may be
    1.13 -// overridden in Arguments::parse_each_vm_init_arg.
    1.14 +  product(bool, UseOprofile, false,                                     \
    1.15 +        "enable support for Oprofile profiler")                         \
    1.16 +                                                                        \
    1.17 +  product(bool, UseLinuxPosixThreadCPUClocks, true,                     \
    1.18 +          "enable fast Linux Posix clocks where available")             \
    1.19 +/*  NB: The default value of UseLinuxPosixThreadCPUClocks may be        \
    1.20 +    overridden in Arguments::parse_each_vm_init_arg.  */                \
    1.21 +                                                                        \
    1.22 +  product(bool, UseHugeTLBFS, false,                                    \
    1.23 +          "Use MAP_HUGETLB for large pages")                            \
    1.24 +                                                                        \
    1.25 +  product(bool, UseSHM, false,                                          \
    1.26 +          "Use SYSV shared memory for large pages")
    1.27  
    1.28  //
    1.29  // Defines Linux-specific default values. The flags are available on all
     2.1 --- a/src/os/linux/vm/os_linux.cpp	Wed Apr 20 19:19:30 2011 -0700
     2.2 +++ b/src/os/linux/vm/os_linux.cpp	Thu Apr 21 01:16:20 2011 -0700
     2.3 @@ -2465,16 +2465,40 @@
     2.4    return res != (uintptr_t) MAP_FAILED;
     2.5  }
     2.6  
     2.7 +// Define MAP_HUGETLB here so we can build HotSpot on old systems.
     2.8 +#ifndef MAP_HUGETLB
     2.9 +#define MAP_HUGETLB 0x40000
    2.10 +#endif
    2.11 +
    2.12 +// Define MADV_HUGEPAGE here so we can build HotSpot on old systems.
    2.13 +#ifndef MADV_HUGEPAGE
    2.14 +#define MADV_HUGEPAGE 14
    2.15 +#endif
    2.16 +
    2.17  bool os::commit_memory(char* addr, size_t size, size_t alignment_hint,
    2.18                         bool exec) {
    2.19 +  if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
    2.20 +    int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
    2.21 +    uintptr_t res =
    2.22 +      (uintptr_t) ::mmap(addr, size, prot,
    2.23 +                         MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_HUGETLB,
    2.24 +                         -1, 0);
    2.25 +    return res != (uintptr_t) MAP_FAILED;
    2.26 +  }
    2.27 +
    2.28    return commit_memory(addr, size, exec);
    2.29  }
    2.30  
    2.31 -void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { }
    2.32 +void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
    2.33 +  if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
    2.34 +    // We don't check the return value: madvise(MADV_HUGEPAGE) may not
    2.35 +    // be supported or the memory may already be backed by huge pages.
    2.36 +    ::madvise(addr, bytes, MADV_HUGEPAGE);
    2.37 +  }
    2.38 +}
    2.39  
    2.40  void os::free_memory(char *addr, size_t bytes) {
    2.41 -  ::mmap(addr, bytes, PROT_READ | PROT_WRITE,
    2.42 -         MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
    2.43 +  ::madvise(addr, bytes, MADV_DONTNEED);
    2.44  }
    2.45  
    2.46  void os::numa_make_global(char *addr, size_t bytes) {
    2.47 @@ -2818,6 +2842,43 @@
    2.48    return linux_mprotect(addr, size, PROT_READ|PROT_WRITE);
    2.49  }
    2.50  
    2.51 +bool os::Linux::hugetlbfs_sanity_check(bool warn, size_t page_size) {
    2.52 +  bool result = false;
    2.53 +  void *p = mmap (NULL, page_size, PROT_READ|PROT_WRITE,
    2.54 +                  MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB,
    2.55 +                  -1, 0);
    2.56 +
    2.57 +  if (p != (void *) -1) {
    2.58 +    // We don't know if this really is a huge page or not.
    2.59 +    FILE *fp = fopen("/proc/self/maps", "r");
    2.60 +    if (fp) {
    2.61 +      while (!feof(fp)) {
    2.62 +        char chars[257];
    2.63 +        long x = 0;
    2.64 +        if (fgets(chars, sizeof(chars), fp)) {
    2.65 +          if (sscanf(chars, "%lx-%*lx", &x) == 1
    2.66 +              && x == (long)p) {
    2.67 +            if (strstr (chars, "hugepage")) {
    2.68 +              result = true;
    2.69 +              break;
    2.70 +            }
    2.71 +          }
    2.72 +        }
    2.73 +      }
    2.74 +      fclose(fp);
    2.75 +    }
    2.76 +    munmap (p, page_size);
    2.77 +    if (result)
    2.78 +      return true;
    2.79 +  }
    2.80 +
    2.81 +  if (warn) {
    2.82 +    warning("HugeTLBFS is not supported by the operating system.");
    2.83 +  }
    2.84 +
    2.85 +  return result;
    2.86 +}
    2.87 +
    2.88  /*
    2.89  * Set the coredump_filter bits to include largepages in core dump (bit 6)
    2.90  *
    2.91 @@ -2860,7 +2921,16 @@
    2.92  static size_t _large_page_size = 0;
    2.93  
    2.94  bool os::large_page_init() {
    2.95 -  if (!UseLargePages) return false;
    2.96 +  if (!UseLargePages) {
    2.97 +    UseHugeTLBFS = false;
    2.98 +    UseSHM = false;
    2.99 +    return false;
   2.100 +  }
   2.101 +
   2.102 +  if (FLAG_IS_DEFAULT(UseHugeTLBFS) && FLAG_IS_DEFAULT(UseSHM)) {
   2.103 +    // Our user has not expressed a preference, so we'll try both.
   2.104 +    UseHugeTLBFS = UseSHM = true;
   2.105 +  }
   2.106  
   2.107    if (LargePageSizeInBytes) {
   2.108      _large_page_size = LargePageSizeInBytes;
   2.109 @@ -2905,6 +2975,9 @@
   2.110      }
   2.111    }
   2.112  
   2.113 +  // print a warning if any large page related flag is specified on command line
   2.114 +  bool warn_on_failure = !FLAG_IS_DEFAULT(UseHugeTLBFS);
   2.115 +
   2.116    const size_t default_page_size = (size_t)Linux::page_size();
   2.117    if (_large_page_size > default_page_size) {
   2.118      _page_sizes[0] = _large_page_size;
   2.119 @@ -2912,6 +2985,14 @@
   2.120      _page_sizes[2] = 0;
   2.121    }
   2.122  
   2.123 +  UseHugeTLBFS = UseHugeTLBFS &&
   2.124 +                 Linux::hugetlbfs_sanity_check(warn_on_failure, _large_page_size);
   2.125 +
   2.126 +  if (UseHugeTLBFS)
   2.127 +    UseSHM = false;
   2.128 +
   2.129 +  UseLargePages = UseHugeTLBFS || UseSHM;
   2.130 +
   2.131    set_coredump_filter();
   2.132  
   2.133    // Large page support is available on 2.6 or newer kernel, some vendors
   2.134 @@ -2928,7 +3009,7 @@
   2.135  char* os::reserve_memory_special(size_t bytes, char* req_addr, bool exec) {
   2.136    // "exec" is passed in but not used.  Creating the shared image for
   2.137    // the code cache doesn't have an SHM_X executable permission to check.
   2.138 -  assert(UseLargePages, "only for large pages");
   2.139 +  assert(UseLargePages && UseSHM, "only for SHM large pages");
   2.140  
   2.141    key_t key = IPC_PRIVATE;
   2.142    char *addr;
   2.143 @@ -2995,16 +3076,15 @@
   2.144    return _large_page_size;
   2.145  }
   2.146  
   2.147 -// Linux does not support anonymous mmap with large page memory. The only way
   2.148 -// to reserve large page memory without file backing is through SysV shared
   2.149 -// memory API. The entire memory region is committed and pinned upfront.
   2.150 -// Hopefully this will change in the future...
   2.151 +// HugeTLBFS allows application to commit large page memory on demand;
   2.152 +// with SysV SHM the entire memory region must be allocated as shared
   2.153 +// memory.
   2.154  bool os::can_commit_large_page_memory() {
   2.155 -  return false;
   2.156 +  return UseHugeTLBFS;
   2.157  }
   2.158  
   2.159  bool os::can_execute_large_page_memory() {
   2.160 -  return false;
   2.161 +  return UseHugeTLBFS;
   2.162  }
   2.163  
   2.164  // Reserve memory at an arbitrary address, only if that area is
     3.1 --- a/src/os/linux/vm/os_linux.hpp	Wed Apr 20 19:19:30 2011 -0700
     3.2 +++ b/src/os/linux/vm/os_linux.hpp	Thu Apr 21 01:16:20 2011 -0700
     3.3 @@ -86,6 +86,9 @@
     3.4  
     3.5    static void rebuild_cpu_to_node_map();
     3.6    static GrowableArray<int>* cpu_to_node()    { return _cpu_to_node; }
     3.7 +
     3.8 +  static bool hugetlbfs_sanity_check(bool warn, size_t page_size);
     3.9 +
    3.10   public:
    3.11    static void init_thread_fpu_state();
    3.12    static int  get_fpu_control_word();

mercurial