From 1c15ef353cab40e872dc8fdcd1b6973545304c9e Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Wed, 26 Dec 2018 12:04:00 +1300 Subject: [PATCH 2/2] Add huge page support for AIX. When using shared_memory_type=sysv, provide support for huge pages on AIX. WIP: Not tested (I don't have AIX). Does it work? Is the retry logic right? Is the documentation good enough? Does AIX care about non-page-aligned sized? You could support sysv + huge page on Linux too (SHM_HUGETBL) but there doesn't appear to be any point, should we for completeness? Author: Thomas Munro, based on sketch code provided by Tony Reix Reported-by: Tony Reix Discussion: https://postgr.es/m/HE1PR0202MB28126DB4E0B6621CC6A1A91286D90%40HE1PR0202MB2812.eurprd02.prod.outlook.com --- doc/src/sgml/config.sgml | 14 +++++++++-- src/backend/port/sysv_shmem.c | 45 +++++++++++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 78d1c654d7..9449199177 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -1489,9 +1489,12 @@ include_dir 'conf.d' - At present, this setting is supported only on Linux and Windows. The + At present, this setting is supported only on Linux, AIX and Windows. The setting is ignored on other systems when set to - try. + try. On Linux, huge pages are only available when + shared_memory_type is set to mmap + (the default). On AIX, they are only available when + shared_memory_type is set to sysv. @@ -1512,6 +1515,13 @@ include_dir 'conf.d' command prompt revokes the user right Lock Pages in Memory when started. + + Huge pages are known as large page on AIX. To use them, the user account + that runs PostgreSQL must have the + CAP_BYPASS_RAC_VMM and CAP_PROPAGATE + capabilities. + + Note that this setting only affects the main shared memory area. Operating systems such as Linux, FreeBSD, and Illumos can also use diff --git a/src/backend/port/sysv_shmem.c b/src/backend/port/sysv_shmem.c index c4aaa08c6a..82a8e9734c 100644 --- a/src/backend/port/sysv_shmem.c +++ b/src/backend/port/sysv_shmem.c @@ -104,6 +104,7 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size) IpcMemoryId shmid; void *requestedAddress = NULL; void *memAddress; + int shmget_extra_flags = 0; /* * Normally we just pass requestedAddress = NULL to shmat(), allowing the @@ -124,7 +125,28 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size) } #endif - shmid = shmget(memKey, size, IPC_CREAT | IPC_EXCL | IPCProtection); + if (huge_pages == HUGE_PAGES_ON || huge_pages == HUGE_PAGES_TRY) + { +#if defined(SHM_LGPAGE) + /* AIX */ + shmget_extra_flags = SHM_LGPAGE | SHM_PIN; +#endif + } + + shmid = shmget(memKey, size, + IPC_CREAT | IPC_EXCL | IPCProtection | shmget_extra_flags); + + /* + * If we tried and failed to allocate huge pages, try again without the extra + * flags so that we ask for the default page size. + */ + if (huge_pages == HUGE_PAGES_TRY && shmget_extra_flags > 0 && shmid < 0 && + errno != EEXIST) + { + elog(DEBUG1, "shmget(%zu) with huge pages failed, huge pages disabled: %m", + size); + shmid = shmget(memKey, size, IPC_CREAT | IPC_EXCL | IPCProtection); + } if (shmid < 0) { @@ -561,12 +583,25 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port, Size sysvsize; /* Complain if hugepages demanded but we can't possibly support them */ -#if !defined(MAP_HUGETLB) if (huge_pages == HUGE_PAGES_ON) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("huge pages not supported on this platform"))); + { + if (shared_memory_type == SHMEM_TYPE_MMAP) + { +#if !defined(MAP_HUGETLB) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("huge pages not supported on this platform with this shared_memory_type"))); #endif + } + else if (shared_memory_type == SHMEM_TYPE_SYSV) + { +#if !defined(SHM_LGPAGE) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("huge pages not supported on this platform with this shared_memory_type"))); +#endif + } + } /* Room for a header? */ Assert(size > MAXALIGN(sizeof(PGShmemHeader))); -- 2.19.1