v20251015-0008-fix-handle-disabled-NUMA-partitioning-of-b.patch

text/x-patch

Filename: v20251015-0008-fix-handle-disabled-NUMA-partitioning-of-b.patch
Type: text/x-patch
Part: 7
Message: Re: Adding basic NUMA awareness

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: format-patch
Series: patch v20251015-0008
Subject: fix: handle disabled NUMA-partitioning of buffers
File+
src/backend/storage/buffer/buf_init.c 21 4
From 963e48dadc3ecc6941ee8e70d0f6d84d13ceb276 Mon Sep 17 00:00:00 2001
From: Tomas Vondra <tomas@vondra.me>
Date: Wed, 15 Oct 2025 17:42:23 +0200
Subject: [PATCH v20251015 08/12] fix: handle disabled NUMA-partitioning of
 buffers

We still partition the buffers, because we want to partition the
clock-sweep (and that relies on partitions). But we don't map the
partitions to NUMA nodes.

The NUMA partitioning may be disabled for a number of reasons. The build
may not have libnuma enabled, debug_numa may not include "buffers"
and/or the shared buffers are too small (especially with huge pages).
---
 src/backend/storage/buffer/buf_init.c | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/buf_init.c b/src/backend/storage/buffer/buf_init.c
index 65f45346bd1..d0efa102d82 100644
--- a/src/backend/storage/buffer/buf_init.c
+++ b/src/backend/storage/buffer/buf_init.c
@@ -301,6 +301,10 @@ BufferGetNode(Buffer buffer)
 	if (numa_buffers_per_node == -1)
 		return 0;
 
+	/* no NUMA-aware partitioning */
+	if ((numa_flags & NUMA_BUFFERS) == 0)
+		return 0;
+
 	return (buffer / numa_buffers_per_node);
 }
 
@@ -460,10 +464,15 @@ buffer_partitions_prepare(void)
 	numa_can_partition = true;	/* assume we can allocate to nodes */
 	if (numa_nodes > max_nodes)
 	{
-		elog(LOG, "shared buffers too small for %d nodes (max nodes %d)",
+		elog(NOTICE, "shared buffers too small for %d nodes (max nodes %d)",
 			 numa_nodes, max_nodes);
 		numa_can_partition = false;
 	}
+	else if ((numa_flags & NUMA_BUFFERS) == 0)
+	{
+		elog(NOTICE, "NUMA-partitioning of buffers disabled");
+		numa_can_partition = false;
+	}
 
 	/*
 	 * We know we can partition to the desired number of nodes, now it's time
@@ -483,8 +492,16 @@ buffer_partitions_prepare(void)
 
 	/*
 	 * Finally, calculate how many buffers we'll assign to a single NUMA node.
-	 * If we have only a single node, or can't map to that many nodes, just
-	 * take a "fair share" of buffers.
+	 * If we have only a single node, or when we can't partition for some
+	 * reason, just take a "fair share" of buffers. This can happen for a
+	 * number of reasons - missing NUMA support, partitioning of buffers not
+	 * enabled, or not enough buffers for this many nodes.
+	 *
+	 * We still build partitions, because we want to allow partitioning of
+	 * the clock-sweep later.
+	 *
+	 * The number of buffers for each partition is calculated later, once we
+	 * have allocated the shared memory (because that's where we store it).
 	 *
 	 * XXX In both cases the last node can get fewer buffers.
 	 */
@@ -599,7 +616,7 @@ buffer_partitions_init(void)
 			Assert((num_buffers > 0) && (num_buffers <= part_buffers));
 
 			/* XXX we should get the actual node ID from the mask */
-			if ((numa_flags & NUMA_BUFFERS) != 0)
+			if (numa_can_partition)
 				part->numa_node = n;
 			else
 				part->numa_node = -1;
-- 
2.51.0