summaryrefslogtreecommitdiff
path: root/src/backend/utils/misc/guc.c
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2014-01-29 13:44:45 +0200
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2014-01-29 14:08:30 +0200
commit1a3458b6d8d202715a83c88474a1b63726d0929e (patch)
treeea1f7c5a36cefc7b5b5dee50ac1b99fe082ed9c9 /src/backend/utils/misc/guc.c
parentb7643b19f0fdbfb1636db52e39db4be6f0174ce0 (diff)
Allow using huge TLB pages on Linux (MAP_HUGETLB)
This patch adds an option, huge_tlb_pages, which allows requesting the shared memory segment to be allocated using huge pages, by using the MAP_HUGETLB flag in mmap(). This can improve performance. The default is 'try', which means that we will attempt using huge pages, and fall back to non-huge pages if it doesn't work. Currently, only Linux has MAP_HUGETLB. On other platforms, the default 'try' behaves the same as 'off'. In the passing, don't try to round the mmap() size to a multiple of pagesize. mmap() doesn't require that, and there's no particular reason for PostgreSQL to do that either. When using MAP_HUGETLB, however, round the request size up to nearest 2MB boundary. This is to work around a bug in some Linux kernel versions, but also to avoid wasting memory, because the kernel will round the size up anyway. Many people were involved in writing this patch, including Christian Kruse, Richard Poole, Abhijit Menon-Sen, reviewed by Peter Geoghegan, Andres Freund and me.
Diffstat (limited to 'src/backend/utils/misc/guc.c')
-rw-r--r--src/backend/utils/misc/guc.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 2cc8f90e6d4..a9b9794965b 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -64,6 +64,7 @@
#include "storage/dsm_impl.h"
#include "storage/standby.h"
#include "storage/fd.h"
+#include "storage/pg_shmem.h"
#include "storage/proc.h"
#include "storage/predicate.h"
#include "tcop/tcopprot.h"
@@ -388,6 +389,23 @@ 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},
+ {NULL, 0, false}
+};
+
+/*
* Options for enum values stored in other modules
*/
extern const struct config_enum_entry wal_level_options[];
@@ -448,6 +466,12 @@ int tcp_keepalives_interval;
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;
+
+/*
* These variables are all dummies that don't do anything, except in some
* cases provide the value for SHOW to display. The real state is elsewhere
* and is kept in sync by assign_hooks.
@@ -3430,6 +3454,15 @@ static struct config_enum ConfigureNamesEnum[] =
NULL, NULL, NULL
},
+ {
+ {"huge_tlb_pages", PGC_POSTMASTER, RESOURCES_MEM,
+ gettext_noop("Use of huge TLB pages on Linux"),
+ NULL
+ },
+ &huge_tlb_pages,
+ HUGE_TLB_TRY, huge_tlb_options,
+ NULL, NULL, NULL
+ },
/* End-of-list marker */
{