From f8ce16d0d2645f3e223b1a68cd8f6b2fa3d56627 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Mon, 3 Mar 2014 20:52:48 +0200 Subject: [PATCH] Rename huge_tlb_pages to huge_pages, and improve docs. Christian Kruse --- doc/src/sgml/config.sgml | 24 ++++----- doc/src/sgml/runtime.sgml | 51 +++++++++++++++++++ src/backend/port/sysv_shmem.c | 14 ++--- src/backend/port/win32_shmem.c | 4 +- src/backend/utils/misc/guc.c | 30 +++++------ src/backend/utils/misc/postgresql.conf.sample | 2 +- src/include/storage/pg_shmem.h | 12 ++--- 7 files changed, 92 insertions(+), 45 deletions(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index cf11306f6c..065c1dbdcf 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -1166,35 +1166,31 @@ include 'filename' - - huge_tlb_pages (enum) + + huge_pages (enum) - huge_tlb_pages configuration parameter + huge_pages configuration parameter - Enables/disables the use of huge TLB pages. Valid values are + Enables/disables the use of huge memory pages. Valid values are try (the default), on, and off. - At present, this feature is supported only on Linux. The setting - is ignored on other systems. + At present, this feature is supported only on Linux. The setting is + ignored on other systems when set to try. - The use of huge TLB pages results in smaller page tables and - less CPU time spent on memory management, increasing performance. For - more details, see - the Debian wiki. - Remember that you will need at least shared_buffers / huge page size + - 1 huge TLB pages. So for example for a system with 6GB shared buffers - and a hugepage size of 2kb of you will need at least 3156 huge pages. + The use of huge pages results in smaller page tables and less CPU time + spent on memory management, increasing performance. For more details, + see . - With huge_tlb_pages set to try, + With huge_pages set to try, the server will try to use huge pages, but fall back to using normal allocation if that fails. With on, failure to use huge pages will prevent the server from starting up. With diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index bbb808fecb..7f4a2358c4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1307,6 +1307,57 @@ echo -1000 > /proc/self/oom_score_adj + + + Linux huge pages + + + Using huge pages reduces overhead when using large contiguous chunks of + memory, like PostgreSQL does. To enable this + feature in PostgreSQL you need a kernel + with CONFIG_HUGETLBFS=y and + CONFIG_HUGETLB_PAGE=y. You also have to tune the system + setting vm.nr_hugepages. To estimate the number of + necessary huge pages start PostgreSQL without + huge pages enabled and check the VmPeak value from the + proc filesystem: + +$ head -1 /path/to/data/directory/postmaster.pid +4170 +$ grep ^VmPeak /proc/4170/status +VmPeak: 6490428 kB + + 6490428 / 2048 + (PAGE_SIZE is 2MB in this case) are + roughly 3169.154 huge pages, so you will need at + least 3170 huge pages: + +$ sysctl -w vm.nr_hugepages=3170 + + Sometimes the kernel is not able to allocate the desired number of huge + pages, so it might be necessary to repeat that command or to reboot. Don't + forget to add an entry to /etc/sysctl.conf to persist + this setting through reboots. + + + + The default behavior for huge pages in + PostgreSQL is to use them when possible and + to fallback to normal pages when failing. To enforce the use of huge + pages, you can set + huge_pages + to on. Note that in this case + PostgreSQL will fail to start if not enough huge + pages are available. + + + + For a detailed description of the Linux huge + pages feature have a look + at https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt. + + + diff --git a/src/backend/port/sysv_shmem.c b/src/backend/port/sysv_shmem.c index 65ad59570c..51c1a2b71f 100644 --- a/src/backend/port/sysv_shmem.c +++ b/src/backend/port/sysv_shmem.c @@ -333,12 +333,12 @@ CreateAnonymousSegment(Size *size) int mmap_errno = 0; #ifndef MAP_HUGETLB - if (huge_tlb_pages == HUGE_TLB_ON) + if (huge_pages == HUGE_PAGES_ON) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("huge TLB pages not supported on this platform"))); #else - if (huge_tlb_pages == HUGE_TLB_ON || huge_tlb_pages == HUGE_TLB_TRY) + if (huge_pages == HUGE_PAGES_ON || huge_pages == HUGE_PAGES_TRY) { /* * Round up the request size to a suitable large value. @@ -364,13 +364,13 @@ CreateAnonymousSegment(Size *size) ptr = mmap(NULL, allocsize, PROT_READ | PROT_WRITE, PG_MMAP_FLAGS | MAP_HUGETLB, -1, 0); mmap_errno = errno; - if (huge_tlb_pages == HUGE_TLB_TRY && ptr == MAP_FAILED) + if (huge_pages == HUGE_PAGES_TRY && ptr == MAP_FAILED) elog(DEBUG1, "mmap with MAP_HUGETLB failed, huge pages disabled: %m"); } #endif - if (huge_tlb_pages == HUGE_TLB_OFF || - (huge_tlb_pages == HUGE_TLB_TRY && ptr == MAP_FAILED)) + if (huge_pages == HUGE_PAGES_OFF || + (huge_pages == HUGE_PAGES_TRY && ptr == MAP_FAILED)) { /* * use the original size, not the rounded up value, when falling @@ -431,10 +431,10 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port) Size sysvsize; #if defined(EXEC_BACKEND) || !defined(MAP_HUGETLB) - if (huge_tlb_pages == HUGE_TLB_ON) + if (huge_pages == HUGE_PAGES_ON) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("huge TLB pages not supported on this platform"))); + errmsg("huge pages not supported on this platform"))); #endif /* Room for a header? */ diff --git a/src/backend/port/win32_shmem.c b/src/backend/port/win32_shmem.c index 9b0cceb530..dca371cce6 100644 --- a/src/backend/port/win32_shmem.c +++ b/src/backend/port/win32_shmem.c @@ -128,10 +128,10 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port) DWORD size_high; DWORD size_low; - if (huge_tlb_pages == HUGE_TLB_ON) + if (huge_pages == HUGE_PAGES_ON) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("huge TLB pages not supported on this platform"))); + errmsg("huge pages not supported on this platform"))); /* Room for a header? */ Assert(size > MAXALIGN(sizeof(PGShmemHeader))); diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index b27cb89a28..c76edb48a9 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -393,16 +393,16 @@ static const struct config_enum_entry synchronous_commit_options[] = { * Although only "on", "off", "try" are documented, we accept all the likely * variants of "on" and "off". */ -static const struct config_enum_entry huge_tlb_options[] = { - {"off", HUGE_TLB_OFF, false}, - {"on", HUGE_TLB_ON, false}, - {"try", HUGE_TLB_TRY, false}, - {"true", HUGE_TLB_ON, true}, - {"false", HUGE_TLB_OFF, true}, - {"yes", HUGE_TLB_ON, true}, - {"no", HUGE_TLB_OFF, true}, - {"1", HUGE_TLB_ON, true}, - {"0", HUGE_TLB_OFF, true}, +static const struct config_enum_entry huge_pages_options[] = { + {"off", HUGE_PAGES_OFF, false}, + {"on", HUGE_PAGES_ON, false}, + {"try", HUGE_PAGES_TRY, false}, + {"true", HUGE_PAGES_ON, true}, + {"false", HUGE_PAGES_OFF, true}, + {"yes", HUGE_PAGES_ON, true}, + {"no", HUGE_PAGES_OFF, true}, + {"1", HUGE_PAGES_ON, true}, + {"0", HUGE_PAGES_OFF, true}, {NULL, 0, false} }; @@ -470,7 +470,7 @@ int tcp_keepalives_count; * This really belongs in pg_shmem.c, but is defined here so that it doesn't * need to be duplicated in all the different implementations of pg_shmem.c. */ -int huge_tlb_pages; +int huge_pages; /* * These variables are all dummies that don't do anything, except in some @@ -3497,12 +3497,12 @@ static struct config_enum ConfigureNamesEnum[] = }, { - {"huge_tlb_pages", PGC_POSTMASTER, RESOURCES_MEM, - gettext_noop("Use of huge TLB pages on Linux"), + {"huge_pages", PGC_POSTMASTER, RESOURCES_MEM, + gettext_noop("Use of huge pages on Linux"), NULL }, - &huge_tlb_pages, - HUGE_TLB_TRY, huge_tlb_options, + &huge_pages, + HUGE_PAGES_TRY, huge_pages_options, NULL, NULL, NULL }, diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index ce56059ceb..3629a52c9f 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -115,7 +115,7 @@ #shared_buffers = 32MB # min 128kB # (change requires restart) -#huge_tlb_pages = try # on, off, or try +#huge_pages = try # on, off, or try # (change requires restart) #temp_buffers = 8MB # min 800kB #max_prepared_transactions = 0 # zero disables the feature diff --git a/src/include/storage/pg_shmem.h b/src/include/storage/pg_shmem.h index 0d607298fb..0dc960b597 100644 --- a/src/include/storage/pg_shmem.h +++ b/src/include/storage/pg_shmem.h @@ -39,15 +39,15 @@ typedef struct PGShmemHeader /* standard header for all Postgres shmem */ } PGShmemHeader; /* GUC variable */ -extern int huge_tlb_pages; +extern int huge_pages; -/* Possible values for huge_tlb_pages */ +/* Possible values for huge_pages */ typedef enum { - HUGE_TLB_OFF, - HUGE_TLB_ON, - HUGE_TLB_TRY -} HugeTlbType; + HUGE_PAGES_OFF, + HUGE_PAGES_ON, + HUGE_PAGES_TRY +} HugePagesType; #ifndef WIN32 extern unsigned long UsedShmemSegID;