From 65145d500725db28c27abf1a4a73c535675abd1a Mon Sep 17 00:00:00 2001 From: Anthonin Bonnefoy Date: Mon, 27 Oct 2025 10:10:32 +0100 Subject: Extract HugePages_Free value in GetHugePageSize Currently, GetHugePageSize only extracts the huge page size from /proc/meminfo. This patch adds the extraction of HugePages_Free which will be necessary to auto-tune shared_buffers. --- src/backend/port/sysv_shmem.c | 23 ++++++++++++++++------- src/backend/port/win32_shmem.c | 4 +++- src/backend/storage/ipc/ipci.c | 2 +- src/backend/storage/ipc/shmem.c | 2 +- src/include/storage/pg_shmem.h | 2 +- 5 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/backend/port/sysv_shmem.c b/src/backend/port/sysv_shmem.c index de491897118..09a02271a15 100644 --- a/src/backend/port/sysv_shmem.c +++ b/src/backend/port/sysv_shmem.c @@ -470,18 +470,19 @@ PGSharedMemoryAttach(IpcMemoryId shmId, * hugepage sizes, we might want to think about more invasive strategies, * such as increasing shared_buffers to absorb the extra space. * - * Returns the (real, assumed or config provided) page size into - * *hugepagesize, and the hugepage-related mmap flags to use into - * *mmap_flags if requested by the caller. If huge pages are not supported, - * *hugepagesize and *mmap_flags are set to 0. + * Returns the (real, assumed or config provided) page size into *hugepagesize, + * the amount of free huge pages into *hugepagefree, and the hugepage-related + * mmap flags to use into *mmap_flags if requested by the caller. If huge pages + * are not supported, *hugepagesize, *hugepagefree and *mmap_flags are set to 0. */ void -GetHugePageSize(Size *hugepagesize, int *mmap_flags) +GetHugePageSize(Size *hugepagesize, Size *hugepagefree, int *mmap_flags) { #ifdef MAP_HUGETLB Size default_hugepagesize = 0; Size hugepagesize_local = 0; + Size hugepagefree_local = 0; int mmap_flags_local = 0; /* @@ -502,7 +503,11 @@ GetHugePageSize(Size *hugepagesize, int *mmap_flags) { while (fgets(buf, sizeof(buf), fp)) { - if (sscanf(buf, "Hugepagesize: %u %c", &sz, &ch) == 2) + if (sscanf(buf, "HugePages_Free: %u", &sz) == 1) + { + hugepagefree_local = sz; + } + else if (sscanf(buf, "Hugepagesize: %u %c", &sz, &ch) == 2) { if (ch == 'k') { @@ -560,11 +565,15 @@ GetHugePageSize(Size *hugepagesize, int *mmap_flags) *mmap_flags = mmap_flags_local; if (hugepagesize) *hugepagesize = hugepagesize_local; + if (hugepagefree) + *hugepagefree = hugepagefree_local * hugepagesize_local; #else if (hugepagesize) *hugepagesize = 0; + if (hugepagefree) + *hugepagefree = 0; if (mmap_flags) *mmap_flags = 0; @@ -614,7 +623,7 @@ CreateAnonymousSegment(Size *size) Size hugepagesize; int mmap_flags; - GetHugePageSize(&hugepagesize, &mmap_flags); + GetHugePageSize(&hugepagesize, NULL, &mmap_flags); if (allocsize % hugepagesize != 0) allocsize += hugepagesize - (allocsize % hugepagesize); diff --git a/src/backend/port/win32_shmem.c b/src/backend/port/win32_shmem.c index 7cb8b4c9b60..9402aa5da28 100644 --- a/src/backend/port/win32_shmem.c +++ b/src/backend/port/win32_shmem.c @@ -627,10 +627,12 @@ pgwin32_ReserveSharedMemoryRegion(HANDLE hChild) * use GetLargePageMinimum() instead. */ void -GetHugePageSize(Size *hugepagesize, int *mmap_flags) +GetHugePageSize(Size *hugepagesize, Size *hugepagefree, int *mmap_flags) { if (hugepagesize) *hugepagesize = 0; + if (hugepagefree) + *hugepagefree = 0; if (mmap_flags) *mmap_flags = 0; } diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c index 88e52664ebe..a4f182a9081 100644 --- a/src/backend/storage/ipc/ipci.c +++ b/src/backend/storage/ipc/ipci.c @@ -358,7 +358,7 @@ InitializeShmemGUCs(void) /* * Calculate the number of huge pages required. */ - GetHugePageSize(&hp_size, NULL); + GetHugePageSize(&hp_size, NULL, NULL); if (hp_size != 0) { Size hp_required; diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c index d2f4710f141..0972e9c16a4 100644 --- a/src/backend/storage/ipc/shmem.c +++ b/src/backend/storage/ipc/shmem.c @@ -746,7 +746,7 @@ pg_get_shmem_pagesize(void) Assert(huge_pages_status != HUGE_PAGES_UNKNOWN); if (huge_pages_status == HUGE_PAGES_ON) - GetHugePageSize(&os_page_size, NULL); + GetHugePageSize(&os_page_size, NULL, NULL); return os_page_size; } diff --git a/src/include/storage/pg_shmem.h b/src/include/storage/pg_shmem.h index 3aeada554b2..7b6efc9f306 100644 --- a/src/include/storage/pg_shmem.h +++ b/src/include/storage/pg_shmem.h @@ -89,6 +89,6 @@ extern PGShmemHeader *PGSharedMemoryCreate(Size size, PGShmemHeader **shim); extern bool PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2); extern void PGSharedMemoryDetach(void); -extern void GetHugePageSize(Size *hugepagesize, int *mmap_flags); +extern void GetHugePageSize(Size *hugepagesize, Size *hugepagefree, int *mmap_flags); #endif /* PG_SHMEM_H */ -- 2.52.0