From d896d372b8acad33d278b9f6d131eb6db8cd5fe2 Mon Sep 17 00:00:00 2001 From: Maxim Orlov 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