mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Add huge_page_size setting for use on Linux.
This allows the huge page size to be set explicitly. The default is 0, meaning it will use the system default, as before. Author: Odin Ugedal <odin@ugedal.com> Discussion: https://postgr.es/m/20200608154639.20254-1-odin%40ugedal.com
This commit is contained in:
@ -32,6 +32,7 @@
|
||||
#endif
|
||||
|
||||
#include "miscadmin.h"
|
||||
#include "port/pg_bitutils.h"
|
||||
#include "portability/mem.h"
|
||||
#include "storage/dsm.h"
|
||||
#include "storage/fd.h"
|
||||
@ -448,7 +449,7 @@ PGSharedMemoryAttach(IpcMemoryId shmId,
|
||||
#ifdef MAP_HUGETLB
|
||||
|
||||
/*
|
||||
* Identify the huge page size to use.
|
||||
* Identify the huge page size to use, and compute the related mmap flags.
|
||||
*
|
||||
* Some Linux kernel versions have a bug causing mmap() to fail on requests
|
||||
* that are not a multiple of the hugepage size. Versions without that bug
|
||||
@ -464,25 +465,13 @@ PGSharedMemoryAttach(IpcMemoryId shmId,
|
||||
* hugepage sizes, we might want to think about more invasive strategies,
|
||||
* such as increasing shared_buffers to absorb the extra space.
|
||||
*
|
||||
* Returns the (real or assumed) page size into *hugepagesize,
|
||||
* Returns the (real, assumed or config provided) page size into *hugepagesize,
|
||||
* and the hugepage-related mmap flags to use into *mmap_flags.
|
||||
*
|
||||
* Currently *mmap_flags is always just MAP_HUGETLB. Someday, on systems
|
||||
* that support it, we might OR in additional bits to specify a particular
|
||||
* non-default huge page size.
|
||||
*/
|
||||
static void
|
||||
GetHugePageSize(Size *hugepagesize, int *mmap_flags)
|
||||
{
|
||||
/*
|
||||
* If we fail to find out the system's default huge page size, assume it
|
||||
* is 2MB. This will work fine when the actual size is less. If it's
|
||||
* more, we might get mmap() or munmap() failures due to unaligned
|
||||
* requests; but at this writing, there are no reports of any non-Linux
|
||||
* systems being picky about that.
|
||||
*/
|
||||
*hugepagesize = 2 * 1024 * 1024;
|
||||
*mmap_flags = MAP_HUGETLB;
|
||||
Size default_hugepagesize = 0;
|
||||
|
||||
/*
|
||||
* System-dependent code to find out the default huge page size.
|
||||
@ -491,6 +480,7 @@ GetHugePageSize(Size *hugepagesize, int *mmap_flags)
|
||||
* nnnn kB". Ignore any failures, falling back to the preset default.
|
||||
*/
|
||||
#ifdef __linux__
|
||||
|
||||
{
|
||||
FILE *fp = AllocateFile("/proc/meminfo", "r");
|
||||
char buf[128];
|
||||
@ -505,7 +495,7 @@ GetHugePageSize(Size *hugepagesize, int *mmap_flags)
|
||||
{
|
||||
if (ch == 'k')
|
||||
{
|
||||
*hugepagesize = sz * (Size) 1024;
|
||||
default_hugepagesize = sz * (Size) 1024;
|
||||
break;
|
||||
}
|
||||
/* We could accept other units besides kB, if needed */
|
||||
@ -515,6 +505,44 @@ GetHugePageSize(Size *hugepagesize, int *mmap_flags)
|
||||
}
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
|
||||
if (huge_page_size != 0)
|
||||
{
|
||||
/* If huge page size is requested explicitly, use that. */
|
||||
*hugepagesize = (Size) huge_page_size * 1024;
|
||||
}
|
||||
else if (default_hugepagesize != 0)
|
||||
{
|
||||
/* Otherwise use the system default, if we have it. */
|
||||
*hugepagesize = default_hugepagesize;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If we fail to find out the system's default huge page size, or no
|
||||
* huge page size is requested explicitly, assume it is 2MB. This will
|
||||
* work fine when the actual size is less. If it's more, we might get
|
||||
* mmap() or munmap() failures due to unaligned requests; but at this
|
||||
* writing, there are no reports of any non-Linux systems being picky
|
||||
* about that.
|
||||
*/
|
||||
*hugepagesize = 2 * 1024 * 1024;
|
||||
}
|
||||
|
||||
*mmap_flags = MAP_HUGETLB;
|
||||
|
||||
/*
|
||||
* On recent enough Linux, also include the explicit page size, if
|
||||
* necessary.
|
||||
*/
|
||||
#if defined(MAP_HUGE_MASK) && defined(MAP_HUGE_SHIFT)
|
||||
if (*hugepagesize != default_hugepagesize)
|
||||
{
|
||||
int shift = pg_ceil_log2_64(*hugepagesize);
|
||||
|
||||
*mmap_flags |= (shift & MAP_HUGE_MASK) << MAP_HUGE_SHIFT;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* MAP_HUGETLB */
|
||||
@ -583,7 +611,7 @@ CreateAnonymousSegment(Size *size)
|
||||
"(currently %zu bytes), reduce PostgreSQL's shared "
|
||||
"memory usage, perhaps by reducing shared_buffers or "
|
||||
"max_connections.",
|
||||
*size) : 0));
|
||||
allocsize) : 0));
|
||||
}
|
||||
|
||||
*size = allocsize;
|
||||
|
Reference in New Issue
Block a user