< prev index next >

src/os/linux/vm/os_linux.cpp

Print this page




3367   addr = (char*)shmat(shmid, req_addr, 0);
3368   int err = errno;
3369 
3370   // Remove shmid. If shmat() is successful, the actual shared memory segment
3371   // will be deleted when it's detached by shmdt() or when the process
3372   // terminates. If shmat() is not successful this will remove the shared
3373   // segment immediately.
3374   shmctl(shmid, IPC_RMID, NULL);
3375 
3376   if ((intptr_t)addr == -1) {
3377     if (warn_on_failure) {
3378       jio_snprintf(msg, sizeof(msg), "Failed to attach shared memory (errno = %d).", err);
3379       warning("%s", msg);
3380     }
3381     return NULL;
3382   }
3383 
3384   return addr;
3385 }
3386 




































































































































































































3387 static void warn_on_large_pages_failure(char* req_addr, size_t bytes,
3388                                         int error) {
3389   assert(error == ENOMEM, "Only expect to fail if no memory is available");
3390 
3391   bool warn_on_failure = UseLargePages &&
3392       (!FLAG_IS_DEFAULT(UseLargePages) ||
3393        !FLAG_IS_DEFAULT(UseHugeTLBFS) ||
3394        !FLAG_IS_DEFAULT(LargePageSizeInBytes));
3395 
3396   if (warn_on_failure) {
3397     char msg[128];
3398     jio_snprintf(msg, sizeof(msg), "Failed to reserve large pages memory req_addr: "
3399                  PTR_FORMAT " bytes: " SIZE_FORMAT " (errno = %d).", req_addr, bytes, error);
3400     warning("%s", msg);
3401   }
3402 }
3403 
3404 char* os::Linux::reserve_memory_special_huge_tlbfs_only(size_t bytes,
3405                                                         char* req_addr,
3406                                                         bool exec) {




3367   addr = (char*)shmat(shmid, req_addr, 0);
3368   int err = errno;
3369 
3370   // Remove shmid. If shmat() is successful, the actual shared memory segment
3371   // will be deleted when it's detached by shmdt() or when the process
3372   // terminates. If shmat() is not successful this will remove the shared
3373   // segment immediately.
3374   shmctl(shmid, IPC_RMID, NULL);
3375 
3376   if ((intptr_t)addr == -1) {
3377     if (warn_on_failure) {
3378       jio_snprintf(msg, sizeof(msg), "Failed to attach shared memory (errno = %d).", err);
3379       warning("%s", msg);
3380     }
3381     return NULL;
3382   }
3383 
3384   return addr;
3385 }
3386 
3387 // Use 'fd' to reserve memory at the given address.
3388 // Retry 'max_tries' number of times
3389 // Return NULL if memory cannot be reserved at the requested address
3390 char* os::Linux::reserve_memory_with_backing_file_at(size_t bytes, char* requested_addr, int fd) {
3391   const int max_tries = 10;
3392   char* base[max_tries];
3393   size_t size[max_tries];
3394   const size_t gap = 0x000000;
3395   int prot = PROT_READ | PROT_WRITE;
3396   // Assert only that the size is a multiple of the page size, since
3397   // that's all that mmap requires, and since that's all we really know
3398   // about at this low abstraction level.  If we need higher alignment,
3399   // we can either pass an alignment to this method or verify alignment
3400   // in one of the methods further up the call chain.  See bug 5044738.
3401   assert(bytes % os::vm_page_size() == 0, "reserving unexpected size block");
3402 
3403   // Repeatedly allocate blocks until the block is allocated at the
3404   // right spot.
3405 
3406   // Linux mmap allows caller to pass an address as hint; give it a try first,
3407   // if kernel honors the hint then we can return immediately.
3408   char* addr = (char*)mmap(requested_addr, bytes, prot, MAP_SHARED | MAP_FIXED, fd, 0);
3409   if (addr == MAP_FAILED)
3410     return NULL;
3411   if (addr == requested_addr) {
3412     return requested_addr;
3413   }
3414 
3415   if (addr != NULL) {
3416     // mmap() is successful but it fails to reserve at the requested address
3417     anon_munmap(addr, bytes);
3418   }
3419 
3420   int i;
3421   for (i = 0; i < max_tries; ++i) {
3422     base[i] = (char*)mmap(NULL, bytes, prot, MAP_SHARED, fd, 0);
3423     
3424     if (base[i] != NULL) {
3425       // Is this the block we wanted?
3426       if (base[i] == requested_addr) {
3427         size[i] = bytes;
3428         break;
3429       }
3430 
3431       // Does this overlap the block we wanted? Give back the overlapped
3432       // parts and try again.
3433 
3434       ptrdiff_t top_overlap = requested_addr + (bytes + gap) - base[i];
3435       if (top_overlap >= 0 && (size_t)top_overlap < bytes) {
3436         munmap(base[i], top_overlap);
3437         base[i] += top_overlap;
3438         size[i] = bytes - top_overlap;
3439       }
3440       else {
3441         ptrdiff_t bottom_overlap = base[i] + bytes - requested_addr;
3442         if (bottom_overlap >= 0 && (size_t)bottom_overlap < bytes) {
3443           munmap(requested_addr, bottom_overlap);
3444           size[i] = bytes - bottom_overlap;
3445         }
3446         else {
3447           size[i] = bytes;
3448         }
3449       }
3450     }
3451   }
3452 
3453   // Give back the unused reserved pieces.
3454 
3455   for (int j = 0; j < i; ++j) {
3456     if (base[j] != NULL) {
3457       munmap(base[j], size[j]);
3458     }
3459   }
3460 
3461   if (i < max_tries) {
3462     return requested_addr;
3463   }
3464   else {
3465     return NULL;
3466   }
3467 }
3468 
3469 // Use 'fd' to reserve memory with the given alignment.
3470 // First attempt is made with the optimistic assumption that the OS will return a aligned pointer
3471 // For second attempt, we manually align the base pointer
3472 char* os::Linux::reserve_memory_with_backing_file_aligned(size_t size, size_t alignment, int fd) {
3473 
3474   int prot = PROT_READ | PROT_WRITE;
3475 
3476   // Optimistically assume that the OSes returns an aligned base pointer.
3477   char* addr = (char*)::mmap(NULL, size, prot, MAP_SHARED, fd, 0);
3478 
3479   if (addr == MAP_FAILED)
3480     return NULL;
3481 
3482   if ((((size_t)addr) & (alignment - 1)) == 0)
3483     return addr;
3484 
3485   munmap(addr, size);
3486   size = align_size_up(size, alignment);
3487 
3488   assert((alignment & (os::vm_allocation_granularity() - 1)) == 0,
3489     "Alignment must be a multiple of allocation granularity (page size)");
3490   assert((size & (alignment - 1)) == 0, "size must be 'alignment' aligned");
3491 
3492   size_t extra_size = size + alignment;
3493   assert(extra_size >= size, "overflow, size is too large to allow alignment");
3494 
3495   char* extra_base = (char*)::mmap(NULL, extra_size, prot, MAP_SHARED, fd, 0);
3496 
3497   if (extra_base == MAP_FAILED) {
3498     return NULL;
3499   }
3500 
3501   // Do manual alignment
3502   char* aligned_base = (char*)align_size_up((uintptr_t)extra_base, alignment);
3503 
3504   // [  |                                       |  ]
3505   // ^ extra_base
3506   //    ^ extra_base + begin_offset == aligned_base
3507   //     extra_base + begin_offset + size       ^
3508   //                       extra_base + extra_size ^
3509   // |<>| == begin_offset
3510   //                              end_offset == |<>|
3511   size_t begin_offset = aligned_base - extra_base;
3512   size_t end_offset = (extra_base + extra_size) - (aligned_base + size);
3513 
3514   if (begin_offset > 0) {
3515     munmap(extra_base, begin_offset);
3516   }
3517 
3518   if (end_offset > 0) {
3519     munmap(extra_base + begin_offset + size, end_offset);
3520   }
3521 
3522   return aligned_base;
3523   
3524 
3525 }
3526 
3527 // Reserve memory by creating a temporary file in the provided directory and using it for mmap() call
3528 char* os::Linux::reserve_memory_with_backing_file(size_t bytes, char* requested_addr,
3529                                                   size_t alignment, const char* backingFileDir) {
3530 
3531   int prot = PROT_READ | PROT_WRITE;
3532   char* addr = NULL;
3533   // Optimistically assume that the OSes returns an aligned base pointer.
3534   int fd = create_tmpfile(backingFileDir, bytes, false);
3535   if (fd == -1) {
3536     vm_exit_during_initialization(err_msg("Could not create temporary file in %s for object heap", backingFileDir));
3537     return NULL;
3538   }
3539   if (requested_addr!=0)
3540     addr = reserve_memory_with_backing_file_at(bytes, requested_addr, fd);
3541   else
3542     addr = reserve_memory_with_backing_file_aligned(bytes, alignment, fd);
3543 
3544   (void)close(fd);
3545 
3546   return addr;
3547 
3548 }
3549 
3550 // Helper function to create a temp file in the given directory
3551 int os::Linux::create_tmpfile(const char* dir, size_t size, bool exec) {
3552 
3553   static char name_template[] = "/jvmheap.XXXXXX";
3554 
3555   char fullname[strlen(dir) + sizeof(name_template)];
3556   (void)strcpy(fullname, dir);
3557   (void)strcat(fullname, name_template);
3558 
3559   sigset_t set, oldset;
3560   sigfillset(&set);
3561   (void)sigprocmask(SIG_BLOCK, &set, &oldset);
3562 
3563   mode_t new_mask = exec ? (S_IRUSR | S_IWUSR | S_IXUSR) : (S_IRUSR | S_IWUSR);
3564   mode_t prev_umask = umask(new_mask);
3565   int fd = mkstemp(fullname);
3566   umask(prev_umask);
3567   if (fd < 0) {
3568     warning("Could not create file for heap");
3569     return -1;
3570   }
3571 
3572   (void)unlink(fullname);
3573   (void)sigprocmask(SIG_SETMASK, &oldset, NULL);
3574 
3575   if ((errno = posix_fallocate(fd, 0, (off_t)size)) != 0) {
3576     warning("Could not allocate sufficient disk space for heap");
3577     return -1;
3578   }
3579 
3580   return fd;
3581 }
3582 
3583 static void warn_on_large_pages_failure(char* req_addr, size_t bytes,
3584                                         int error) {
3585   assert(error == ENOMEM, "Only expect to fail if no memory is available");
3586 
3587   bool warn_on_failure = UseLargePages &&
3588       (!FLAG_IS_DEFAULT(UseLargePages) ||
3589        !FLAG_IS_DEFAULT(UseHugeTLBFS) ||
3590        !FLAG_IS_DEFAULT(LargePageSizeInBytes));
3591 
3592   if (warn_on_failure) {
3593     char msg[128];
3594     jio_snprintf(msg, sizeof(msg), "Failed to reserve large pages memory req_addr: "
3595                  PTR_FORMAT " bytes: " SIZE_FORMAT " (errno = %d).", req_addr, bytes, error);
3596     warning("%s", msg);
3597   }
3598 }
3599 
3600 char* os::Linux::reserve_memory_special_huge_tlbfs_only(size_t bytes,
3601                                                         char* req_addr,
3602                                                         bool exec) {


< prev index next >