comparison src/os/linux/vm/os_linux.cpp @ 10969:a837fa3d3f86

8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint Summary: Detect mmap() commit failures in Linux and Solaris os::commit_memory() impls and call vm_exit_out_of_memory(). Add os::commit_memory_or_exit(). Also tidy up some NMT accounting and some mmap() return value checking. Reviewed-by: zgu, stefank, dholmes, dsamersoff
author dcubed
date Thu, 13 Jun 2013 11:16:38 -0700
parents f2110083203d
children 1f4355cee9a2
comparison
equal deleted inserted replaced
10405:f2110083203d 10969:a837fa3d3f86
2610 ::close(fd); 2610 ::close(fd);
2611 unlink(buf); 2611 unlink(buf);
2612 } 2612 }
2613 } 2613 }
2614 2614
2615 static bool recoverable_mmap_error(int err) {
2616 // See if the error is one we can let the caller handle. This
2617 // list of errno values comes from JBS-6843484. I can't find a
2618 // Linux man page that documents this specific set of errno
2619 // values so while this list currently matches Solaris, it may
2620 // change as we gain experience with this failure mode.
2621 switch (err) {
2622 case EBADF:
2623 case EINVAL:
2624 case ENOTSUP:
2625 // let the caller deal with these errors
2626 return true;
2627
2628 default:
2629 // Any remaining errors on this OS can cause our reserved mapping
2630 // to be lost. That can cause confusion where different data
2631 // structures think they have the same memory mapped. The worst
2632 // scenario is if both the VM and a library think they have the
2633 // same memory mapped.
2634 return false;
2635 }
2636 }
2637
2638 static void warn_fail_commit_memory(char* addr, size_t size, bool exec,
2639 int err) {
2640 warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
2641 ", %d) failed; error='%s' (errno=%d)", addr, size, exec,
2642 strerror(err), err);
2643 }
2644
2645 static void warn_fail_commit_memory(char* addr, size_t size,
2646 size_t alignment_hint, bool exec,
2647 int err) {
2648 warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
2649 ", " SIZE_FORMAT ", %d) failed; error='%s' (errno=%d)", addr, size,
2650 alignment_hint, exec, strerror(err), err);
2651 }
2652
2615 // NOTE: Linux kernel does not really reserve the pages for us. 2653 // NOTE: Linux kernel does not really reserve the pages for us.
2616 // All it does is to check if there are enough free pages 2654 // All it does is to check if there are enough free pages
2617 // left at the time of mmap(). This could be a potential 2655 // left at the time of mmap(). This could be a potential
2618 // problem. 2656 // problem.
2619 bool os::pd_commit_memory(char* addr, size_t size, bool exec) { 2657 int os::Linux::commit_memory_impl(char* addr, size_t size, bool exec) {
2620 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; 2658 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
2621 uintptr_t res = (uintptr_t) ::mmap(addr, size, prot, 2659 uintptr_t res = (uintptr_t) ::mmap(addr, size, prot,
2622 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0); 2660 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
2623 if (res != (uintptr_t) MAP_FAILED) { 2661 if (res != (uintptr_t) MAP_FAILED) {
2624 if (UseNUMAInterleaving) { 2662 if (UseNUMAInterleaving) {
2625 numa_make_global(addr, size); 2663 numa_make_global(addr, size);
2626 } 2664 }
2627 return true; 2665 return 0;
2628 } 2666 }
2629 return false; 2667
2668 int err = errno; // save errno from mmap() call above
2669
2670 if (!recoverable_mmap_error(err)) {
2671 warn_fail_commit_memory(addr, size, exec, err);
2672 vm_exit_out_of_memory(size, OOM_MMAP_ERROR, "committing reserved memory.");
2673 }
2674
2675 return err;
2676 }
2677
2678 bool os::pd_commit_memory(char* addr, size_t size, bool exec) {
2679 return os::Linux::commit_memory_impl(addr, size, exec) == 0;
2680 }
2681
2682 void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec,
2683 const char* mesg) {
2684 assert(mesg != NULL, "mesg must be specified");
2685 int err = os::Linux::commit_memory_impl(addr, size, exec);
2686 if (err != 0) {
2687 // the caller wants all commit errors to exit with the specified mesg:
2688 warn_fail_commit_memory(addr, size, exec, err);
2689 vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg);
2690 }
2630 } 2691 }
2631 2692
2632 // Define MAP_HUGETLB here so we can build HotSpot on old systems. 2693 // Define MAP_HUGETLB here so we can build HotSpot on old systems.
2633 #ifndef MAP_HUGETLB 2694 #ifndef MAP_HUGETLB
2634 #define MAP_HUGETLB 0x40000 2695 #define MAP_HUGETLB 0x40000
2637 // Define MADV_HUGEPAGE here so we can build HotSpot on old systems. 2698 // Define MADV_HUGEPAGE here so we can build HotSpot on old systems.
2638 #ifndef MADV_HUGEPAGE 2699 #ifndef MADV_HUGEPAGE
2639 #define MADV_HUGEPAGE 14 2700 #define MADV_HUGEPAGE 14
2640 #endif 2701 #endif
2641 2702
2642 bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint, 2703 int os::Linux::commit_memory_impl(char* addr, size_t size,
2643 bool exec) { 2704 size_t alignment_hint, bool exec) {
2705 int err;
2644 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) { 2706 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
2645 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; 2707 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
2646 uintptr_t res = 2708 uintptr_t res =
2647 (uintptr_t) ::mmap(addr, size, prot, 2709 (uintptr_t) ::mmap(addr, size, prot,
2648 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_HUGETLB, 2710 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_HUGETLB,
2649 -1, 0); 2711 -1, 0);
2650 if (res != (uintptr_t) MAP_FAILED) { 2712 if (res != (uintptr_t) MAP_FAILED) {
2651 if (UseNUMAInterleaving) { 2713 if (UseNUMAInterleaving) {
2652 numa_make_global(addr, size); 2714 numa_make_global(addr, size);
2653 } 2715 }
2654 return true; 2716 return 0;
2717 }
2718
2719 err = errno; // save errno from mmap() call above
2720
2721 if (!recoverable_mmap_error(err)) {
2722 // However, it is not clear that this loss of our reserved mapping
2723 // happens with large pages on Linux or that we cannot recover
2724 // from the loss. For now, we just issue a warning and we don't
2725 // call vm_exit_out_of_memory(). This issue is being tracked by
2726 // JBS-8007074.
2727 warn_fail_commit_memory(addr, size, alignment_hint, exec, err);
2728 // vm_exit_out_of_memory(size, OOM_MMAP_ERROR,
2729 // "committing reserved memory.");
2655 } 2730 }
2656 // Fall through and try to use small pages 2731 // Fall through and try to use small pages
2657 } 2732 }
2658 2733
2659 if (commit_memory(addr, size, exec)) { 2734 err = os::Linux::commit_memory_impl(addr, size, exec);
2735 if (err == 0) {
2660 realign_memory(addr, size, alignment_hint); 2736 realign_memory(addr, size, alignment_hint);
2661 return true; 2737 }
2662 } 2738 return err;
2663 return false; 2739 }
2740
2741 bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
2742 bool exec) {
2743 return os::Linux::commit_memory_impl(addr, size, alignment_hint, exec) == 0;
2744 }
2745
2746 void os::pd_commit_memory_or_exit(char* addr, size_t size,
2747 size_t alignment_hint, bool exec,
2748 const char* mesg) {
2749 assert(mesg != NULL, "mesg must be specified");
2750 int err = os::Linux::commit_memory_impl(addr, size, alignment_hint, exec);
2751 if (err != 0) {
2752 // the caller wants all commit errors to exit with the specified mesg:
2753 warn_fail_commit_memory(addr, size, alignment_hint, exec, err);
2754 vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg);
2755 }
2664 } 2756 }
2665 2757
2666 void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { 2758 void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
2667 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) { 2759 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
2668 // We don't check the return value: madvise(MADV_HUGEPAGE) may not 2760 // We don't check the return value: madvise(MADV_HUGEPAGE) may not
2676 // the existing pages. However it won't work for SHM-based large pages that cannot be 2768 // the existing pages. However it won't work for SHM-based large pages that cannot be
2677 // uncommitted at all. We don't do anything in this case to avoid creating a segment with 2769 // uncommitted at all. We don't do anything in this case to avoid creating a segment with
2678 // small pages on top of the SHM segment. This method always works for small pages, so we 2770 // small pages on top of the SHM segment. This method always works for small pages, so we
2679 // allow that in any case. 2771 // allow that in any case.
2680 if (alignment_hint <= (size_t)os::vm_page_size() || !UseSHM) { 2772 if (alignment_hint <= (size_t)os::vm_page_size() || !UseSHM) {
2681 commit_memory(addr, bytes, alignment_hint, false); 2773 commit_memory(addr, bytes, alignment_hint, !ExecMem);
2682 } 2774 }
2683 } 2775 }
2684 2776
2685 void os::numa_make_global(char *addr, size_t bytes) { 2777 void os::numa_make_global(char *addr, size_t bytes) {
2686 Linux::numa_interleave_memory(addr, bytes); 2778 Linux::numa_interleave_memory(addr, bytes);
2929 "growable stack in non-initial thread"); 3021 "growable stack in non-initial thread");
2930 if (stack_extent < (uintptr_t)addr) 3022 if (stack_extent < (uintptr_t)addr)
2931 ::munmap((void*)stack_extent, (uintptr_t)addr - stack_extent); 3023 ::munmap((void*)stack_extent, (uintptr_t)addr - stack_extent);
2932 } 3024 }
2933 3025
2934 return os::commit_memory(addr, size); 3026 return os::commit_memory(addr, size, !ExecMem);
2935 } 3027 }
2936 3028
2937 // If this is a growable mapping, remove the guard pages entirely by 3029 // If this is a growable mapping, remove the guard pages entirely by
2938 // munmap()ping them. If not, just call uncommit_memory(). This only 3030 // munmap()ping them. If not, just call uncommit_memory(). This only
2939 // affects the main/initial thread, but guard against future OS changes 3031 // affects the main/initial thread, but guard against future OS changes
3051 bool result = false; 3143 bool result = false;
3052 void *p = mmap (NULL, page_size, PROT_READ|PROT_WRITE, 3144 void *p = mmap (NULL, page_size, PROT_READ|PROT_WRITE,
3053 MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB, 3145 MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB,
3054 -1, 0); 3146 -1, 0);
3055 3147
3056 if (p != (void *) -1) { 3148 if (p != MAP_FAILED) {
3057 // We don't know if this really is a huge page or not. 3149 // We don't know if this really is a huge page or not.
3058 FILE *fp = fopen("/proc/self/maps", "r"); 3150 FILE *fp = fopen("/proc/self/maps", "r");
3059 if (fp) { 3151 if (fp) {
3060 while (!feof(fp)) { 3152 while (!feof(fp)) {
3061 char chars[257]; 3153 char chars[257];
4391 tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page); 4483 tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page);
4392 #endif 4484 #endif
4393 4485
4394 if (!UseMembar) { 4486 if (!UseMembar) {
4395 address mem_serialize_page = (address) ::mmap(NULL, Linux::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 4487 address mem_serialize_page = (address) ::mmap(NULL, Linux::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
4396 guarantee( mem_serialize_page != NULL, "mmap Failed for memory serialize page"); 4488 guarantee( mem_serialize_page != MAP_FAILED, "mmap Failed for memory serialize page");
4397 os::set_memory_serialize_page( mem_serialize_page ); 4489 os::set_memory_serialize_page( mem_serialize_page );
4398 4490
4399 #ifndef PRODUCT 4491 #ifndef PRODUCT
4400 if(Verbose && PrintMiscellaneous) 4492 if(Verbose && PrintMiscellaneous)
4401 tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page); 4493 tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page);