Re: Large Pages and Super Pages for PostgreSQL

2022-11-29 Thread ZHU XIAN WEN

Hi Thomas

Thank you very much for the work.

I just got latest FreeBSD 13.1 environment, and I'm going to test and 
verify it.


so would you please rebase latest patch?

best wishes

Tony

On 2022/11/8 06:59, Thomas Munro wrote:

On Sun, Jan 16, 2022 at 8:32 PM Thomas Munro  wrote:

On Sun, Jan 16, 2022 at 6:03 PM DEVOPS_WwIT  wrote:

Solaris and FreeBSD supports large/super pages, and can be used
automatically by applications.

Seems Postgres can't use the large/super pages on Solaris and FreeBSD
os(I think can't use the large/super page HPUX and AIX), is there anyone
could take a look?

3.  FreeBSD: FreeBSD does transparently migrate PostgreSQL memory to
"super" pages quite well in my experience, but there is also a new
facility in FreeBSD 13 to ask for specific page sizes explicitly.  I
wrote a quick and dirty patch to enable PostgreSQL's huge_pages and
huge_page_size settings to work with that interface, but I haven't yet
got as far as testing it very hard or proposing it...  but here it is,
if you like experimental code[2].

I was reminded to rebase that and tidy it up a bit, by recent
discussion of page table magic in other threads.  Documentation of
these interfaces is sparse to put it mildly (I may try to improve that
myself) but basically the terminology is "super" for pages subject to
promotion/demotion, and "large" when explicitly managed.  Not
proposing for commit right now as I need to learn more about all this
and there are some policy decisions lurking in here (eg synchronous
defrag vs nowait depending on flags), but the patch may be useful for
experimentation.  For example, it allows huge_page_size=1GB if your
system can handle that.


OpenPGP_0x6A40B0F18DBF5A23.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature


Re: Large Pages and Super Pages for PostgreSQL

2022-11-07 Thread Thomas Munro
On Sun, Jan 16, 2022 at 8:32 PM Thomas Munro  wrote:
> On Sun, Jan 16, 2022 at 6:03 PM DEVOPS_WwIT  wrote:
> > Solaris and FreeBSD supports large/super pages, and can be used
> > automatically by applications.
> >
> > Seems Postgres can't use the large/super pages on Solaris and FreeBSD
> > os(I think can't use the large/super page HPUX and AIX), is there anyone
> > could take a look?
>
> 3.  FreeBSD: FreeBSD does transparently migrate PostgreSQL memory to
> "super" pages quite well in my experience, but there is also a new
> facility in FreeBSD 13 to ask for specific page sizes explicitly.  I
> wrote a quick and dirty patch to enable PostgreSQL's huge_pages and
> huge_page_size settings to work with that interface, but I haven't yet
> got as far as testing it very hard or proposing it...  but here it is,
> if you like experimental code[2].

I was reminded to rebase that and tidy it up a bit, by recent
discussion of page table magic in other threads.  Documentation of
these interfaces is sparse to put it mildly (I may try to improve that
myself) but basically the terminology is "super" for pages subject to
promotion/demotion, and "large" when explicitly managed.  Not
proposing for commit right now as I need to learn more about all this
and there are some policy decisions lurking in here (eg synchronous
defrag vs nowait depending on flags), but the patch may be useful for
experimentation.  For example, it allows huge_page_size=1GB if your
system can handle that.
From b76dc0e5a472824aaa87de4f6c1f6db26c810c7f Mon Sep 17 00:00:00 2001
From: Thomas Munro 
Date: Thu, 3 Nov 2022 10:06:24 +1300
Subject: [PATCH] Support huge_pages and huge_page_size on FreeBSD.

FreeBSD often uses huge (super) pages due to automatic promotion, but it
may be useful to be able to request that explicitly, and to be able to
experiment with different page sizes by explicit request.

Discussion: https://postgr.es/m/3043b674-46d6-a8e9-3811-5a3007c8dceb%40ww-it.cn
---
 doc/src/sgml/config.sgml  |  6 ++--
 src/backend/port/sysv_shmem.c | 58 ++-
 2 files changed, 53 insertions(+), 11 deletions(-)

diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 559eb898a9..cd65916bb5 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1678,9 +1678,9 @@ 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, FreeBSD and Windows. The
 setting is ignored on other systems when set to
-try.  On Linux, it is only supported when
+try.  On Linux and FreeBSD, it is only supported when
 shared_memory_type is set to mmap
 (the default).

@@ -1742,7 +1742,7 @@ include_dir 'conf.d'
 about usage and support, see .


-Non-default settings are currently supported only on Linux.
+Non-default settings are currently supported only on Linux and FreeBSD.

   
  
diff --git a/src/backend/port/sysv_shmem.c b/src/backend/port/sysv_shmem.c
index 97ce7b7c49..0bb8c20c8d 100644
--- a/src/backend/port/sysv_shmem.c
+++ b/src/backend/port/sysv_shmem.c
@@ -576,8 +576,9 @@ GetHugePageSize(Size *hugepagesize, int *mmap_flags)
 bool
 check_huge_page_size(int *newval, void **extra, GucSource source)
 {
-#if !(defined(MAP_HUGE_MASK) && defined(MAP_HUGE_SHIFT))
-	/* Recent enough Linux only, for now.  See GetHugePageSize(). */
+#if !(defined(MAP_HUGE_MASK) && defined(MAP_HUGE_SHIFT)) && \
+	!defined(SHM_LARGEPAGE_ALLOC_DEFAULT)
+	/* Recent enough Linux and FreeBSD only, for now. */
 	if (*newval != 0)
 	{
 		GUC_check_errdetail("huge_page_size must be 0 on this platform.");
@@ -601,12 +602,9 @@ CreateAnonymousSegment(Size *size)
 	void	   *ptr = MAP_FAILED;
 	int			mmap_errno = 0;
 
-#ifndef MAP_HUGETLB
-	/* PGSharedMemoryCreate should have dealt with this case */
-	Assert(huge_pages != HUGE_PAGES_ON);
-#else
 	if (huge_pages == HUGE_PAGES_ON || huge_pages == HUGE_PAGES_TRY)
 	{
+#ifdef MAP_HUGETLB
 		/*
 		 * Round up the request size to a suitable large value.
 		 */
@@ -624,8 +622,52 @@ CreateAnonymousSegment(Size *size)
 		if (huge_pages == HUGE_PAGES_TRY && ptr == MAP_FAILED)
 			elog(DEBUG1, "mmap(%zu) with MAP_HUGETLB failed, huge pages disabled: %m",
  allocsize);
-	}
 #endif
+#ifdef SHM_LARGEPAGE_ALLOC_DEFAULT
+		int			nsizes;
+		size_t	   *page_sizes;
+		size_t		page_size;
+		int			page_size_index = -1;
+
+		/*
+		 * Find the matching page size index, or if huge_page_size wasn't set,
+		 * then skip the smallest size and take the next one after that.
+		 */
+		nsizes = getpagesizes(NULL, 0);
+		page_sizes = palloc(nsizes * sizeof(*page_sizes));
+		getpagesizes(page_sizes, nsizes);
+		for (int i = 0; i < nsizes; ++i)
+		{
+			if (huge_page_size * 1024 == page_sizes[i] ||
+(huge_page_size == 0 && i > 0))
+			{
+page_size = page_sizes[i];
+page_size_index = i;
+if 

Re: Large Pages and Super Pages for PostgreSQL

2022-01-15 Thread Thomas Munro
On Sun, Jan 16, 2022 at 6:03 PM DEVOPS_WwIT  wrote:
> Solaris and FreeBSD supports large/super pages, and can be used
> automatically by applications.
>
> Seems Postgres can't use the large/super pages on Solaris and FreeBSD
> os(I think can't use the large/super page HPUX and AIX), is there anyone
> could take a look?

Hello,

I can provide some clues and partial answers about page size on three
of the OSes you mentioned:

1.  Solaris:  I haven't used that OS for a long time, but I thought it
was supposed to promote memory to larger pages sizes transparently
with some heuristics.  To control page size explicitly, it *looks*
like memcntl(2) with command MHA_MAPSIZE_VA could be used; that's what
the man page says, anyway.  If someone is interested in writing a
patch to do that, I'd be happy to review it and test it on illumos...

2.  AIX:  We *nearly* made this work recently[1].  The summary is that
AIX doesn't have a way to control the page size of anonymous shared
mmap memory (our usual source of shared memory), so you have to use
SystemV shared memory if you want non-default page size for shared
memory.  We got as far as adding the option shared_memory_type=sysv,
and the next step is pretty easy: just pass in some magic flags.  This
just needs someone with access and motivation to pick up that work...

3.  FreeBSD: FreeBSD does transparently migrate PostgreSQL memory to
"super" pages quite well in my experience, but there is also a new
facility in FreeBSD 13 to ask for specific page sizes explicitly.  I
wrote a quick and dirty patch to enable PostgreSQL's huge_pages and
huge_page_size settings to work with that interface, but I haven't yet
got as far as testing it very hard or proposing it...  but here it is,
if you like experimental code[2].

I don't know about HP-UX.  I think it might be dead, Jim.

[1] 
https://www.postgresql.org/message-id/flat/HE1PR0202MB28126DB4E0B6621CC6A1A91286D90%40HE1PR0202MB2812.eurprd02.prod.outlook.com
[2] 
https://github.com/macdice/postgres/commit/a71aafe5582c2e61005af0d16ca82eed89445a67