From 2251179e6ad3a865d2f55e1832fab34608fcce43 Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Fri, 29 Jan 2016 09:44:29 -0500
Subject: [PATCH] Migrate replication slot I/O locks into a separate tranche.

This is following in a long train of similar changes and for the same
reasons - see b319356f0e94a6482c726cf4af96597c211d8d6e and
fe702a7b3f9f2bc5bf6d173166d7d55226af82c8 inter alia.

Author: Amit Kapila
Reviewed-by: Alexander Korotkov, Robert Haas
---
 src/backend/replication/slot.c    | 14 +++++++++++---
 src/backend/storage/lmgr/lwlock.c |  3 ---
 src/include/replication/slot.h    |  2 +-
 src/include/storage/lwlock.h      |  1 +
 4 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index c12e4128665..251b549768d 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -97,6 +97,7 @@ ReplicationSlot *MyReplicationSlot = NULL;
 int			max_replication_slots = 0;	/* the maximum number of replication
 										 * slots */
 
+static LWLockTranche ReplSlotIOLWLockTranche;
 static void ReplicationSlotDropAcquired(void);
 
 /* internal persistency functions */
@@ -137,6 +138,13 @@ ReplicationSlotsShmemInit(void)
 		ShmemInitStruct("ReplicationSlot Ctl", ReplicationSlotsShmemSize(),
 						&found);
 
+	ReplSlotIOLWLockTranche.name = "Replication Slot IO Locks";
+	ReplSlotIOLWLockTranche.array_base =
+		((char *) ReplicationSlotCtl) + offsetof(ReplicationSlotCtlData, replication_slots) +offsetof(ReplicationSlot, io_in_progress_lock);
+	ReplSlotIOLWLockTranche.array_stride = sizeof(ReplicationSlot);
+	LWLockRegisterTranche(LWTRANCHE_REPLICATION_SLOT_IO_IN_PROGRESS,
+						  &ReplSlotIOLWLockTranche);
+
 	if (!found)
 	{
 		int			i;
@@ -150,7 +158,7 @@ ReplicationSlotsShmemInit(void)
 
 			/* everything else is zeroed by the memset above */
 			SpinLockInit(&slot->mutex);
-			slot->io_in_progress_lock = LWLockAssign();
+			LWLockInitialize(&slot->io_in_progress_lock, LWTRANCHE_REPLICATION_SLOT_IO_IN_PROGRESS);
 		}
 	}
 }
@@ -1008,7 +1016,7 @@ SaveSlotToPath(ReplicationSlot *slot, const char *dir, int elevel)
 	if (!was_dirty)
 		return;
 
-	LWLockAcquire(slot->io_in_progress_lock, LW_EXCLUSIVE);
+	LWLockAcquire(&slot->io_in_progress_lock, LW_EXCLUSIVE);
 
 	/* silence valgrind :( */
 	memset(&cp, 0, sizeof(ReplicationSlotOnDisk));
@@ -1101,7 +1109,7 @@ SaveSlotToPath(ReplicationSlot *slot, const char *dir, int elevel)
 		slot->dirty = false;
 	SpinLockRelease(&slot->mutex);
 
-	LWLockRelease(slot->io_in_progress_lock);
+	LWLockRelease(&slot->io_in_progress_lock);
 }
 
 /*
diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c
index 5e276a08da3..d087139c286 100644
--- a/src/backend/storage/lmgr/lwlock.c
+++ b/src/backend/storage/lmgr/lwlock.c
@@ -353,9 +353,6 @@ NumLWLocks(void)
 	/* Predefined LWLocks */
 	numLocks = NUM_FIXED_LWLOCKS;
 
-	/* slot.c needs one for each slot */
-	numLocks += max_replication_slots;
-
 	/*
 	 * Add any requested by loadable modules; for backwards-compatibility
 	 * reasons, allocate at least NUM_USER_DEFINED_LWLOCKS of them even if
diff --git a/src/include/replication/slot.h b/src/include/replication/slot.h
index 80ad02aba03..8be8ab62a0f 100644
--- a/src/include/replication/slot.h
+++ b/src/include/replication/slot.h
@@ -109,7 +109,7 @@ typedef struct ReplicationSlot
 	ReplicationSlotPersistentData data;
 
 	/* is somebody performing io on this slot? */
-	LWLock	   *io_in_progress_lock;
+	LWLock		io_in_progress_lock;
 
 	/* all the remaining data is only used for logical slots */
 
diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h
index 3f1da5155ef..9e4f512e2c8 100644
--- a/src/include/storage/lwlock.h
+++ b/src/include/storage/lwlock.h
@@ -213,6 +213,7 @@ typedef enum BuiltinTrancheIds
 	LWTRANCHE_WAL_INSERT,
 	LWTRANCHE_BUFFER_CONTENT,
 	LWTRANCHE_BUFFER_IO_IN_PROGRESS,
+	LWTRANCHE_REPLICATION_SLOT_IO_IN_PROGRESS,
 	LWTRANCHE_PROC,
 	LWTRANCHE_FIRST_USER_DEFINED
 }	BuiltinTrancheIds;
-- 
GitLab