From f8ce16d0d2645f3e223b1a68cd8f6b2fa3d56627 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas <heikki.linnakangas@iki.fi> 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 cf11306f6cb..065c1dbdcf0 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -1166,35 +1166,31 @@ include 'filename' </listitem> </varlistentry> - <varlistentry id="guc-huge-tlb-pages" xreflabel="huge_tlb_pages"> - <term><varname>huge_tlb_pages</varname> (<type>enum</type>)</term> + <varlistentry id="guc-huge-pages" xreflabel="huge_pages"> + <term><varname>huge_pages</varname> (<type>enum</type>)</term> <indexterm> - <primary><varname>huge_tlb_pages</> configuration parameter</primary> + <primary><varname>huge_pages</> configuration parameter</primary> </indexterm> <listitem> <para> - Enables/disables the use of huge TLB pages. Valid values are + Enables/disables the use of huge memory pages. Valid values are <literal>try</literal> (the default), <literal>on</literal>, and <literal>off</literal>. </para> <para> - 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 <literal>try</literal>. </para> <para> - 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 - <ulink url="https://wiki.debian.org/Hugepages">the Debian wiki</ulink>. - 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 <xref linkend="linux-huge-pages">. </para> <para> - With <varname>huge_tlb_pages</varname> set to <literal>try</literal>, + With <varname>huge_pages</varname> set to <literal>try</literal>, the server will try to use huge pages, but fall back to using normal allocation if that fails. With <literal>on</literal>, 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 bbb808fecb0..7f4a2358c45 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1307,6 +1307,57 @@ echo -1000 > /proc/self/oom_score_adj </para> </note> </sect2> + + <sect2 id="linux-huge-pages"> + <title>Linux huge pages</title> + + <para> + Using huge pages reduces overhead when using large contiguous chunks of + memory, like <productname>PostgreSQL</productname> does. To enable this + feature in <productname>PostgreSQL</productname> you need a kernel + with <varname>CONFIG_HUGETLBFS=y</varname> and + <varname>CONFIG_HUGETLB_PAGE=y</varname>. You also have to tune the system + setting <varname>vm.nr_hugepages</varname>. To estimate the number of + necessary huge pages start <productname>PostgreSQL</productname> without + huge pages enabled and check the <varname>VmPeak</varname> value from the + proc filesystem: +<programlisting> +$ <userinput>head -1 /path/to/data/directory/postmaster.pid</userinput> +4170 +$ <userinput>grep ^VmPeak /proc/4170/status</userinput> +VmPeak: 6490428 kB +</programlisting> + <literal>6490428</literal> / <literal>2048</literal> + (<varname>PAGE_SIZE</varname> is <literal>2MB</literal> in this case) are + roughly <literal>3169.154</literal> huge pages, so you will need at + least <literal>3170</literal> huge pages: +<programlisting> +$ <userinput>sysctl -w vm.nr_hugepages=3170</userinput> +</programlisting> + 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 <filename>/etc/sysctl.conf</filename> to persist + this setting through reboots. + </para> + + <para> + The default behavior for huge pages in + <productname>PostgreSQL</productname> is to use them when possible and + to fallback to normal pages when failing. To enforce the use of huge + pages, you can set + <link linkend="guc-huge-pages"><varname>huge_pages</varname></link> + to <literal>on</literal>. Note that in this case + <productname>PostgreSQL</productname> will fail to start if not enough huge + pages are available. + </para> + + <para> + For a detailed description of the <productname>Linux</productname> huge + pages feature have a look + at <ulink url="https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt">https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt</ulink>. + </para> + + </sect2> </sect1> diff --git a/src/backend/port/sysv_shmem.c b/src/backend/port/sysv_shmem.c index 65ad59570cb..51c1a2b71f8 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 9b0cceb5309..dca371cce62 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 b27cb89a289..c76edb48a9b 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 ce56059ceb2..3629a52c9fe 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 0d607298fbd..0dc960b597f 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; -- GitLab