v3-0001-Avoid-double-spinlock-release.patch
application/octet-stream
Filename: v3-0001-Avoid-double-spinlock-release.patch
Type: application/octet-stream
Part: 0
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 v3-0001
Subject: Avoid double spinlock release
| File | + | − |
|---|---|---|
| src/backend/storage/ipc/procsignal.c | 14 | 7 |
From d896d372b8acad33d278b9f6d131eb6db8cd5fe2 Mon Sep 17 00:00:00 2001
From: Maxim Orlov <orlovmg@gmail.com>
Date: Wed, 26 Feb 2025 09:42:43 +0300
Subject: [PATCH v3] Avoid double spinlock release
---
src/backend/storage/ipc/procsignal.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 7401b6e625..390e6da868 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -167,6 +167,7 @@ ProcSignalInit(bool cancel_key_valid, int32 cancel_key)
{
ProcSignalSlot *slot;
uint64 barrier_generation;
+ bool logit; /* log if we are taking over a used slot */
if (MyProcNumber < 0)
elog(ERROR, "MyProcNumber not set");
@@ -174,14 +175,13 @@ ProcSignalInit(bool cancel_key_valid, int32 cancel_key)
elog(ERROR, "unexpected MyProcNumber %d in ProcSignalInit (max %d)", MyProcNumber, NumProcSignalSlots);
slot = &ProcSignal->psh_slot[MyProcNumber];
- /* sanity check */
SpinLockAcquire(&slot->pss_mutex);
- if (pg_atomic_read_u32(&slot->pss_pid) != 0)
- {
- SpinLockRelease(&slot->pss_mutex);
- elog(LOG, "process %d taking over ProcSignal slot %d, but it's not empty",
- MyProcPid, MyProcNumber);
- }
+ /*
+ * Sanity check. We should warn is we are taking over a used slot. Since we
+ * are holding spin lock at this point, we cannot elog from here. So, we
+ * have to delay the log until the spin lock is released.
+ */
+ logit = pg_atomic_read_u32(&slot->pss_pid) != 0;
/* Clear out any leftover signal reasons */
MemSet(slot->pss_signalFlags, 0, NUM_PROCSIGNALS * sizeof(sig_atomic_t));
@@ -208,6 +208,13 @@ ProcSignalInit(bool cancel_key_valid, int32 cancel_key)
SpinLockRelease(&slot->pss_mutex);
+ /* Spin lock is released, now we can log. */
+ if (logit)
+ {
+ elog(LOG, "process %d taking over ProcSignal slot %d, but it's not empty",
+ MyProcPid, MyProcNumber);
+ }
+
/* Remember slot location for CheckProcSignal */
MyProcSignalSlot = slot;
--
2.43.0