@@ -578,8 +578,9 @@ GetHugePageSize(Size *hugepagesize, int *mmap_flags)
578578bool
579579check_huge_page_size (int * newval , void * * extra , GucSource source )
580580{
581- #if !(defined(MAP_HUGE_MASK ) && defined(MAP_HUGE_SHIFT ))
582- /* Recent enough Linux only, for now. See GetHugePageSize(). */
581+ #if !(defined(MAP_HUGE_MASK ) && defined(MAP_HUGE_SHIFT )) && \
582+ !defined(SHM_LARGEPAGE_ALLOC_DEFAULT )
583+ /* Recent enough Linux and FreeBSD only, for now. */
583584 if (* newval != 0 )
584585 {
585586 GUC_check_errdetail ("\"huge_page_size\" must be 0 on this platform." );
@@ -604,12 +605,9 @@ CreateAnonymousSegment(Size *size)
604605 int mmap_errno = 0 ;
605606 int mmap_flags = MAP_SHARED | MAP_ANONYMOUS | MAP_HASSEMAPHORE ;
606607
607- #ifndef MAP_HUGETLB
608- /* PGSharedMemoryCreate should have dealt with this case */
609- Assert (huge_pages != HUGE_PAGES_ON );
610- #else
611608 if (huge_pages == HUGE_PAGES_ON || huge_pages == HUGE_PAGES_TRY )
612609 {
610+ #ifdef MAP_HUGETLB
613611 /*
614612 * Round up the request size to a suitable large value.
615613 */
@@ -627,8 +625,52 @@ CreateAnonymousSegment(Size *size)
627625 if (huge_pages == HUGE_PAGES_TRY && ptr == MAP_FAILED )
628626 elog (DEBUG1 , "mmap(%zu) with MAP_HUGETLB failed, huge pages disabled: %m" ,
629627 allocsize );
630- }
631628#endif
629+ #ifdef SHM_LARGEPAGE_ALLOC_DEFAULT
630+ int nsizes ;
631+ size_t * page_sizes ;
632+ size_t page_size ;
633+ int page_size_index = -1 ;
634+
635+ /*
636+ * Find the matching page size index, or if huge_page_size wasn't set,
637+ * then skip the smallest size and take the next one after that.
638+ */
639+ nsizes = getpagesizes (NULL , 0 );
640+ page_sizes = palloc (nsizes * sizeof (* page_sizes ));
641+ getpagesizes (page_sizes , nsizes );
642+ for (int i = 0 ; i < nsizes ; ++ i )
643+ {
644+ if (huge_page_size * 1024 == page_sizes [i ] ||
645+ (huge_page_size == 0 && i > 0 ))
646+ {
647+ page_size = page_sizes [i ];
648+ page_size_index = i ;
649+ if (allocsize % page_size != 0 )
650+ allocsize += page_size - (allocsize % page_size );
651+ break ;
652+ }
653+ }
654+ pfree (page_sizes );
655+ if (index >= 0 )
656+ {
657+ int fd ;
658+
659+ fd = shm_create_largepage (SHM_ANON , O_RDWR , page_size_index ,
660+ SHM_LARGEPAGE_ALLOC_DEFAULT , 0 );
661+ if (fd >= 0 )
662+ {
663+ if (ftruncate (fd , allocsize ) == 0 )
664+ {
665+ ptr = mmap (NULL , allocsize , PROT_READ | PROT_WRITE ,
666+ MAP_SHARED , fd , 0 );
667+ mmap_errno = errno ;
668+ }
669+ close (fd );
670+ }
671+ }
672+ #endif
673+ }
632674
633675 /*
634676 * Report whether huge pages are in use. This needs to be tracked before
@@ -720,7 +762,7 @@ PGSharedMemoryCreate(Size size,
720762 DataDir )));
721763
722764 /* Complain if hugepages demanded but we can't possibly support them */
723- #if !defined(MAP_HUGETLB )
765+ #if !defined(MAP_HUGETLB ) && !defined( SHM_LARGEPAGE_ALLOC_DEFAULT )
724766 if (huge_pages == HUGE_PAGES_ON )
725767 ereport (ERROR ,
726768 (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
0 commit comments