@@ -411,7 +411,27 @@ bool ZPhysicalMemoryBacking::tmpfs_supports_transparent_huge_pages() const {
411411 return access (ZFILENAME_SHMEM_ENABLED, R_OK) == 0 ;
412412}
413413
414- ZErrno ZPhysicalMemoryBacking::fallocate_compat_mmap_hugetlbfs (zbacking_offset offset, size_t length, bool touch) const {
414+ static bool safe_touch_mapping (void * addr, size_t length, size_t page_size) {
415+ char * const start = (char *)addr;
416+ char * const end = start + length;
417+
418+ // Touching a mapping that can't be backed by memory will generate a
419+ // SIGBUS. By using SafeFetch32 any SIGBUS will be safely caught and
420+ // handled. On tmpfs, doing a fetch (rather than a store) is enough
421+ // to cause backing pages to be allocated (there's no zero-page to
422+ // worry about).
423+ for (char *p = start; p < end; p += page_size) {
424+ if (SafeFetch32 ((int *)p, -1 ) == -1 ) {
425+ // Failed
426+ return false ;
427+ }
428+ }
429+
430+ // Success
431+ return true ;
432+ }
433+
434+ ZErrno ZPhysicalMemoryBacking::fallocate_compat_mmap_hugetlbfs (zbacking_offset offset, size_t length) const {
415435 // On hugetlbfs, mapping a file segment will fail immediately, without
416436 // the need to touch the mapped pages first, if there aren't enough huge
417437 // pages available to back the mapping.
@@ -424,11 +444,9 @@ ZErrno ZPhysicalMemoryBacking::fallocate_compat_mmap_hugetlbfs(zbacking_offset o
424444 // Once mapped, the huge pages are only reserved. We need to touch them
425445 // to associate them with the file segment. Note that we can not punch
426446 // hole in file segments which only have reserved pages.
427- if (touch) {
428- char * const start = (char *)addr;
429- char * const end = start + length;
430- os::pretouch_memory (start, end, _block_size);
431- }
447+
448+ // Touch the mapping (safely) to make sure it's backed by memory
449+ const bool backed = safe_touch_mapping (addr, length, _block_size);
432450
433451 // Unmap again. From now on, the huge pages that were mapped are allocated
434452 // to this file. There's no risk of getting a SIGBUS when mapping and
@@ -438,28 +456,8 @@ ZErrno ZPhysicalMemoryBacking::fallocate_compat_mmap_hugetlbfs(zbacking_offset o
438456 return errno;
439457 }
440458
441- // Success
442- return 0 ;
443- }
444-
445- static bool safe_touch_mapping (void * addr, size_t length, size_t page_size) {
446- char * const start = (char *)addr;
447- char * const end = start + length;
448-
449- // Touching a mapping that can't be backed by memory will generate a
450- // SIGBUS. By using SafeFetch32 any SIGBUS will be safely caught and
451- // handled. On tmpfs, doing a fetch (rather than a store) is enough
452- // to cause backing pages to be allocated (there's no zero-page to
453- // worry about).
454- for (char *p = start; p < end; p += page_size) {
455- if (SafeFetch32 ((int *)p, -1 ) == -1 ) {
456- // Failed
457- return false ;
458- }
459- }
460-
461- // Success
462- return true ;
459+ // Success?
460+ return backed ? 0 : ENOMEM;
463461}
464462
465463ZErrno ZPhysicalMemoryBacking::fallocate_compat_mmap_tmpfs (zbacking_offset offset, size_t length) const {
@@ -487,7 +485,7 @@ ZErrno ZPhysicalMemoryBacking::fallocate_compat_mmap_tmpfs(zbacking_offset offse
487485 return errno;
488486 }
489487
490- // Success
488+ // Success?
491489 return backed ? 0 : ENOMEM;
492490}
493491
@@ -512,7 +510,7 @@ ZErrno ZPhysicalMemoryBacking::fallocate_fill_hole_compat(zbacking_offset offset
512510 // mmap/munmap (for hugetlbfs and tmpfs with transparent huge pages) or pwrite
513511 // (for tmpfs without transparent huge pages and other filesystem types).
514512 if (ZLargePages::is_explicit ()) {
515- return fallocate_compat_mmap_hugetlbfs (offset, length, false /* touch */ );
513+ return fallocate_compat_mmap_hugetlbfs (offset, length);
516514 } else if (ZLargePages::is_transparent ()) {
517515 return fallocate_compat_mmap_tmpfs (offset, length);
518516 } else {
@@ -560,18 +558,6 @@ ZErrno ZPhysicalMemoryBacking::fallocate_fill_hole(zbacking_offset offset, size_
560558}
561559
562560ZErrno ZPhysicalMemoryBacking::fallocate_punch_hole (zbacking_offset offset, size_t length) const {
563- if (ZLargePages::is_explicit ()) {
564- // We can only punch hole in pages that have been touched. Non-touched
565- // pages are only reserved, and not associated with any specific file
566- // segment. We don't know which pages have been previously touched, so
567- // we always touch them here to guarantee that we can punch hole.
568- const ZErrno err = fallocate_compat_mmap_hugetlbfs (offset, length, true /* touch */ );
569- if (err) {
570- // Failed
571- return err;
572- }
573- }
574-
575561 const int mode = FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE;
576562 if (ZSyscall::fallocate (_fd, mode, untype (offset), length) == -1 ) {
577563 // Failed
@@ -695,9 +681,7 @@ size_t ZPhysicalMemoryBacking::commit_default(zbacking_offset offset, size_t len
695681}
696682
697683size_t ZPhysicalMemoryBacking::commit (zbacking_offset offset, size_t length, uint32_t numa_id) const {
698- if (ZNUMA::is_enabled () && !ZLargePages::is_explicit ()) {
699- // The memory is required to be preferred at the time it is paged in. As a
700- // consequence we must prefer the memory when committing non-large pages.
684+ if (ZNUMA::is_enabled ()) {
701685 return commit_numa_preferred (offset, length, numa_id);
702686 }
703687
0 commit comments