Subject: Set huge_page_size on 32bit system

From: Daria Shanina <[email-masked]>
Date: Thu, 25 Jun 2026 17:54:46 +0300

Hi all,

I found an error: on 32bit system (I tested on Debian 6.1.0-32-686-pae #1
SMP PREEMPT_DYNAMIC Debian 6.1.129-1 (2025-03-06) i686 GNU/Linux) when we
set huge_page_size = 1 TB postgres process fails with signal SIGFPE when
calculated hugepagesize_local = (Size) huge_page_size * 1024; the value
exceeds max for unsigned int = (2^32 – 1).
I attached a full backtrace and one small fix.

What do you think about this?
Thank you for your attention!

--
Best regards,
Daria Shanina
diff --git a/src/backend/port/sysv_shmem.c b/src/backend/port/sysv_shmem.c
index 2e3886cf9fe..8bb31698bd0 100644
--- a/src/backend/port/sysv_shmem.c
+++ b/src/backend/port/sysv_shmem.c
@@ -618,6 +618,13 @@ CreateAnonymousSegment(Size *size)
 
 		GetHugePageSize(&hugepagesize, &huge_mmap_flags);
 
+		if (hugepagesize == 0)
+			ereport(ERROR,
+				(errcode(ERRCODE_OUT_OF_MEMORY),
+				 errmsg("Cannot alocate %d bytes of memory", hugepagesize),
+				 errhint("It is necessary to reduce the amount of the configuration parameter \'huge_page_size\' (currently huge_page_size %d kB)", 
+					huge_page_size)));
+
 		if (allocsize % hugepagesize != 0)
 			allocsize = add_size(allocsize, hugepagesize - (allocsize % hugepagesize));

---

From: Kyotaro Horiguchi <[email-masked]>
Date: Fri, 26 Jun 2026 13:24:15 +0900 (JST)

Hello,

At Thu, 25 Jun 2026 17:54:46 +0300, Daria Shanina <[email-masked]> wrote in 
> I attached a full backtrace and one small fix.

Good catch.

> Thank you for your attention!

This would avoid the SIGFPE, but I wonder whether this should be
rejected earlier in check_huge_page_size() instead, with an error
like:

> "huge_page_size" is too large for this platform.

We could also make the later calculation use a wider integer type, but
such a value would not be usable anyway on a platform where it does
not fit in Size.  So it seems better to reject it earlier in
check_huge_page_size(), before reaching CreateAnonymousSegment().

Regards,

-- 
Kyotaro Horiguchi
NTT Open Source Software Center

---

From: Michael Paquier <[email-masked]>
Date: Fri, 26 Jun 2026 14:26:31 +0900

> check_huge_page_size(), before reaching CreateAnonymousSegment().

The top of guc.h includes the following thing:
/*
 * Maximum for integer GUC variables that are measured in kilobytes of memory.
 * This value is chosen to ensure that the corresponding number of bytes fits
 * into a variable of type size_t or ssize_t.  Be sure to compute the number
 * of bytes like "guc_var * (Size) 1024" to avoid int-width overflow.
 */
#if SIZEOF_SIZE_T > 4
#define MAX_KILOBYTES	INT_MAX
#else
#define MAX_KILOBYTES	(INT_MAX / 1024)
#endif

So it seems to me that the mistake is that huge_page_size uses INT_MAX
as upper bound.  We should use MAX_KILOBYTES instead; this definition
exists to exactly prevent this kind of computation mistake in 32b
environments.
--
Michael

---

From: Kyotaro Horiguchi <[email-masked]>
Date: Fri, 26 Jun 2026 17:13:07 +0900 (JST)

At Fri, 26 Jun 2026 14:26:31 +0900, Michael Paquier <[email-masked]> wrote in 
> exists to exactly prevent this kind of computation mistake in 32b

Ah, you're right. MAX_KILOBYTES exists for exactly this purpose.

Regards,

---

From: Michael Paquier <[email-masked]>
Date: Fri, 26 Jun 2026 17:16:23 +0900

> Ah, you're right. MAX_KILOBYTES exists for exactly this purpose.

Changing the states of the GUC tables in the stable branches would be
OK in this case.  Now, it took so many years for somebody to complain
that setting huge pages at 1TB on a 32b build does not work that I
cannot really get excited about a backpatch.  So I would just do the
switch on HEAD, and call it a day.
--
Michael

---

From: Michael Paquier <[email-masked]>
Date: Sat, 27 Jun 2026 11:50:05 +0900

> switch on HEAD, and call it a day.

And just applied a patch doing so, HEAD-only.
--
Michael

---

From: Daria Shanina <[email-masked]>
Date: Tue, 30 Jun 2026 16:23:59 +0300

Hello,
Kiyotaro and Michael, thank you so much for your answers!
Using MAX_KILOBYTES as the upper bound is indeed absolutely accurate, and
now everything is working correctly.

---
Best regards,
Daria Shanina

-- 
С уважением,
Шанина Дарья Александровна