From 0bd305ee1d427ef29f5fa4fa20567e3b3f5ff792 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Mon, 6 Sep 2021 10:59:20 +0900 Subject: [PATCH] Move the shared memory size calculation to its own function This change refactors the shared memory size calculation in CreateSharedMemoryAndSemaphores() to its own function. This is intended for use in a future change related to the setup of huge pages and shared memory with some GUCs, while useful on its own for extensions. Author: Nathan Bossart Discussion: https://postgr.es/m/F2772387-CE0F-46BF-B5F1-CC55516EB885@amazon.com --- src/backend/storage/ipc/ipci.c | 142 +++++++++++++++++++-------------- src/include/storage/ipc.h | 1 + 2 files changed, 84 insertions(+), 59 deletions(-) diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c index 3e4ec53a97..64bc16fa84 100644 --- a/src/backend/storage/ipc/ipci.c +++ b/src/backend/storage/ipc/ipci.c @@ -75,6 +75,87 @@ RequestAddinShmemSpace(Size size) total_addin_request = add_size(total_addin_request, size); } +/* + * CalculateShmemSize + * Calculates the amount of shared memory and number of semaphores needed. + * + * If num_semaphores is not NULL, it will be set to the number of semaphores + * required. + * + * Note that this function freezes the additional shared memory request size + * from loadable modules. + */ +Size +CalculateShmemSize(int *num_semaphores) +{ + Size size; + int numSemas; + + /* Compute number of semaphores we'll need */ + numSemas = ProcGlobalSemas(); + numSemas += SpinlockSemas(); + + /* Return the number of semaphores if requested by the caller */ + if (num_semaphores) + *num_semaphores = numSemas; + + /* + * Size of the Postgres shared-memory block is estimated via moderately- + * accurate estimates for the big hogs, plus 100K for the stuff that's too + * small to bother with estimating. + * + * We take some care to ensure that the total size request doesn't + * overflow size_t. If this gets through, we don't need to be so careful + * during the actual allocation phase. + */ + size = 100000; + size = add_size(size, PGSemaphoreShmemSize(numSemas)); + size = add_size(size, SpinlockSemaSize()); + size = add_size(size, hash_estimate_size(SHMEM_INDEX_SIZE, + sizeof(ShmemIndexEnt))); + size = add_size(size, dsm_estimate_size()); + size = add_size(size, BufferShmemSize()); + size = add_size(size, LockShmemSize()); + size = add_size(size, PredicateLockShmemSize()); + size = add_size(size, ProcGlobalShmemSize()); + size = add_size(size, XLOGShmemSize()); + size = add_size(size, CLOGShmemSize()); + size = add_size(size, CommitTsShmemSize()); + size = add_size(size, SUBTRANSShmemSize()); + size = add_size(size, TwoPhaseShmemSize()); + size = add_size(size, BackgroundWorkerShmemSize()); + size = add_size(size, MultiXactShmemSize()); + size = add_size(size, LWLockShmemSize()); + size = add_size(size, ProcArrayShmemSize()); + size = add_size(size, BackendStatusShmemSize()); + size = add_size(size, SInvalShmemSize()); + size = add_size(size, PMSignalShmemSize()); + size = add_size(size, ProcSignalShmemSize()); + size = add_size(size, CheckpointerShmemSize()); + size = add_size(size, AutoVacuumShmemSize()); + size = add_size(size, ReplicationSlotsShmemSize()); + size = add_size(size, ReplicationOriginShmemSize()); + size = add_size(size, WalSndShmemSize()); + size = add_size(size, WalRcvShmemSize()); + size = add_size(size, PgArchShmemSize()); + size = add_size(size, ApplyLauncherShmemSize()); + size = add_size(size, SnapMgrShmemSize()); + size = add_size(size, BTreeShmemSize()); + size = add_size(size, SyncScanShmemSize()); + size = add_size(size, AsyncShmemSize()); +#ifdef EXEC_BACKEND + size = add_size(size, ShmemBackendArraySize()); +#endif + + /* freeze the addin request size and include it */ + addin_request_allowed = false; + size = add_size(size, total_addin_request); + + /* might as well round it off to a multiple of a typical page size */ + size = add_size(size, 8192 - (size % 8192)); + + return size; +} /* * CreateSharedMemoryAndSemaphores @@ -102,65 +183,8 @@ CreateSharedMemoryAndSemaphores(void) Size size; int numSemas; - /* Compute number of semaphores we'll need */ - numSemas = ProcGlobalSemas(); - numSemas += SpinlockSemas(); - - /* - * Size of the Postgres shared-memory block is estimated via - * moderately-accurate estimates for the big hogs, plus 100K for the - * stuff that's too small to bother with estimating. - * - * We take some care during this phase to ensure that the total size - * request doesn't overflow size_t. If this gets through, we don't - * need to be so careful during the actual allocation phase. - */ - size = 100000; - size = add_size(size, PGSemaphoreShmemSize(numSemas)); - size = add_size(size, SpinlockSemaSize()); - size = add_size(size, hash_estimate_size(SHMEM_INDEX_SIZE, - sizeof(ShmemIndexEnt))); - size = add_size(size, dsm_estimate_size()); - size = add_size(size, BufferShmemSize()); - size = add_size(size, LockShmemSize()); - size = add_size(size, PredicateLockShmemSize()); - size = add_size(size, ProcGlobalShmemSize()); - size = add_size(size, XLOGShmemSize()); - size = add_size(size, CLOGShmemSize()); - size = add_size(size, CommitTsShmemSize()); - size = add_size(size, SUBTRANSShmemSize()); - size = add_size(size, TwoPhaseShmemSize()); - size = add_size(size, BackgroundWorkerShmemSize()); - size = add_size(size, MultiXactShmemSize()); - size = add_size(size, LWLockShmemSize()); - size = add_size(size, ProcArrayShmemSize()); - size = add_size(size, BackendStatusShmemSize()); - size = add_size(size, SInvalShmemSize()); - size = add_size(size, PMSignalShmemSize()); - size = add_size(size, ProcSignalShmemSize()); - size = add_size(size, CheckpointerShmemSize()); - size = add_size(size, AutoVacuumShmemSize()); - size = add_size(size, ReplicationSlotsShmemSize()); - size = add_size(size, ReplicationOriginShmemSize()); - size = add_size(size, WalSndShmemSize()); - size = add_size(size, WalRcvShmemSize()); - size = add_size(size, PgArchShmemSize()); - size = add_size(size, ApplyLauncherShmemSize()); - size = add_size(size, SnapMgrShmemSize()); - size = add_size(size, BTreeShmemSize()); - size = add_size(size, SyncScanShmemSize()); - size = add_size(size, AsyncShmemSize()); -#ifdef EXEC_BACKEND - size = add_size(size, ShmemBackendArraySize()); -#endif - - /* freeze the addin request size and include it */ - addin_request_allowed = false; - size = add_size(size, total_addin_request); - - /* might as well round it off to a multiple of a typical page size */ - size = add_size(size, 8192 - (size % 8192)); - + /* Compute the size of the shared-memory block */ + size = CalculateShmemSize(&numSemas); elog(DEBUG3, "invoking IpcMemoryCreate(size=%zu)", size); /* diff --git a/src/include/storage/ipc.h b/src/include/storage/ipc.h index 753a6dd4d7..80e191d407 100644 --- a/src/include/storage/ipc.h +++ b/src/include/storage/ipc.h @@ -77,6 +77,7 @@ extern void check_on_shmem_exit_lists_are_empty(void); /* ipci.c */ extern PGDLLIMPORT shmem_startup_hook_type shmem_startup_hook; +extern Size CalculateShmemSize(int *num_semaphores); extern void CreateSharedMemoryAndSemaphores(void); #endif /* IPC_H */