From e8f69161eb459f89c8befd2da052f7a6bc0598ea Mon Sep 17 00:00:00 2001
From: Tomas Vondra <tomas@vondra.me>
Date: Wed, 15 Oct 2025 16:52:53 +0200
Subject: [PATCH v20251015 10/12] fix: pgproc partitioning - align size

I'm not sure this is actually required. The libnuma docs say:

  The size argument will be rounded up to a multiple of the system page size.

so why should it be up to us to round it like that?

Discussion: bf95094a-77c2-46cf-913a-443f7419bc79@postgrespro.ru
---
 src/backend/storage/lmgr/proc.c | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 56812a05860..fc5e1969c36 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -392,6 +392,9 @@ InitProcGlobal(void)
 		Assert(numa_procs_per_node > 0);
 		Assert(numa_nodes > 0);
 
+		/* make sure to align the PGPROC array to memory page */
+		ptr = (char *) TYPEALIGN(numa_page_size, ptr);
+
 		/*
 		 * Now initialize the PGPROC partition registry with one partition
 		 * per NUMA node (and then one extra partition for auxiliary procs).
@@ -401,9 +404,6 @@ InitProcGlobal(void)
 			/* the last NUMA node may get fewer PGPROC entries, but meh */
 			node_procs = Min(numa_procs_per_node, MaxBackends - total_procs);
 
-			/* make sure to align the PGPROC array to memory page */
-			ptr = (char *) TYPEALIGN(numa_page_size, ptr);
-
 			/* fill in the partition info */
 			partitions[i].num_procs = node_procs;
 			partitions[i].numa_node = i;
@@ -411,6 +411,9 @@ InitProcGlobal(void)
 
 			ptr = pgproc_partition_init(ptr, node_procs, total_procs, i);
 
+			/* should have been aligned */
+			Assert(ptr == (char *) TYPEALIGN(numa_page_size, ptr));
+
 			total_procs += node_procs;
 
 			/* don't underflow/overflow the allocation */
@@ -425,9 +428,6 @@ InitProcGlobal(void)
 		 */
 		node_procs = (NUM_AUXILIARY_PROCS + max_prepared_xacts);
 
-		/* make sure to align the PGPROC array to memory page */
-		ptr = (char *) TYPEALIGN(numa_page_size, ptr);
-
 		/* fill in the partition info */
 		partitions[numa_nodes].num_procs = node_procs;
 		partitions[numa_nodes].numa_node = -1;
@@ -2452,7 +2452,7 @@ pgproc_partitions_prepare(void)
 }
 
 /*
- * doesn't do alignment
+ *
  */
 static char *
 pgproc_partition_init(char *ptr, int num_procs, int allprocs_index, int node)
@@ -2465,15 +2465,20 @@ pgproc_partition_init(char *ptr, int num_procs, int allprocs_index, int node)
 	/* pointer right after this array */
 	ptr = (char *) ptr + num_procs * sizeof(PGPROC);
 
-	elog(DEBUG1, "NUMA: pgproc_init_partition procs %p endptr %p num_procs %d node %d",
-		 procs_node, ptr, num_procs, node);
-
 	/*
 	 * if node specified, move to node - do this before we start touching the
 	 * memory, to make sure it's not mapped to any node yet
 	 */
 	if (node != -1)
+	{
+		/* align the pointer to the next page */
+		ptr = (char *) TYPEALIGN(numa_page_size, ptr);
+
 		pg_numa_move_to_node((char *) procs_node, ptr, node);
+	}
+
+	elog(DEBUG1, "NUMA: pgproc_init_partition procs %p endptr %p num_procs %d node %d",
+		 procs_node, ptr, num_procs, node);
 
 	/* add pointers to the PGPROC entries to allProcs */
 	for (int i = 0; i < num_procs; i++)
-- 
2.51.0

