v1-0002-Pass-the-target-LWLock-and-tranche-ID-to-LWLock-t.patch
application/x-patch
Filename: v1-0002-Pass-the-target-LWLock-and-tranche-ID-to-LWLock-t.patch
Type: application/x-patch
Part: 2
Patch
Format: format-patch
Series: patch v1-0002
Subject: Pass the target LWLock* and tranche ID to LWLock tracepoints
| File | + | − |
|---|---|---|
| src/backend/storage/lmgr/lwlock.c | 22 | 13 |
| src/backend/utils/probes.d | 10 | 8 |
From b9b93919d51710cbb3427f9d99764e013657bb3a Mon Sep 17 00:00:00 2001
From: Craig Ringer <craig.ringer@2ndquadrant.com>
Date: Thu, 19 Nov 2020 17:38:45 +0800
Subject: [PATCH v1 2/4] Pass the target LWLock* and tranche ID to LWLock
tracepoints
Previously the TRACE_POSTGRESQL_LWLOCK_ tracepoints only received a
pointer to the LWLock tranche name. This made it impossible to identify
individual locks.
Passing the lock pointer itself isn't perfect. If the lock is allocated inside
a DSM segment then it might be mapped at a different address in different
backends. It's safe to compare lock pointers between backends (assuming
!EXEC_BACKEND) if they're in the individual lock tranches or an
extension-requested named tranche, but not necessarily for tranches in
BuiltinTrancheIds or tranches >= LWTRANCHE_FIRST_USER_DEFINED that were
directly assigned with LWLockNewTrancheId(). Still, it's better than nothing;
the pointer is stable within a backend, and usually between backends.
---
src/backend/storage/lmgr/lwlock.c | 35 +++++++++++++++++++------------
src/backend/utils/probes.d | 18 +++++++++-------
2 files changed, 32 insertions(+), 21 deletions(-)
diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c
index 29e29707d7..63f1a619b0 100644
--- a/src/backend/storage/lmgr/lwlock.c
+++ b/src/backend/storage/lmgr/lwlock.c
@@ -1322,7 +1322,8 @@ LWLockAcquire(LWLock *lock, LWLockMode mode)
#endif
LWLockReportWaitStart(lock);
- TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), mode);
+ TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), mode, lock,
+ lock->tranche);
for (;;)
{
@@ -1344,7 +1345,8 @@ LWLockAcquire(LWLock *lock, LWLockMode mode)
}
#endif
- TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(T_NAME(lock), mode);
+ TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(T_NAME(lock), mode, lock,
+ lock->tranche);
LWLockReportWaitEnd();
LOG_LWDEBUG("LWLockAcquire", lock, "awakened");
@@ -1353,7 +1355,7 @@ LWLockAcquire(LWLock *lock, LWLockMode mode)
result = false;
}
- TRACE_POSTGRESQL_LWLOCK_ACQUIRE(T_NAME(lock), mode);
+ TRACE_POSTGRESQL_LWLOCK_ACQUIRE(T_NAME(lock), mode, lock, lock->tranche);
/* Add lock to list of locks held by this backend */
held_lwlocks[num_held_lwlocks].lock = lock;
@@ -1404,14 +1406,16 @@ LWLockConditionalAcquire(LWLock *lock, LWLockMode mode)
RESUME_INTERRUPTS();
LOG_LWDEBUG("LWLockConditionalAcquire", lock, "failed");
- TRACE_POSTGRESQL_LWLOCK_CONDACQUIRE_FAIL(T_NAME(lock), mode);
+ TRACE_POSTGRESQL_LWLOCK_CONDACQUIRE_FAIL(T_NAME(lock), mode, lock,
+ lock->tranche);
}
else
{
/* Add lock to list of locks held by this backend */
held_lwlocks[num_held_lwlocks].lock = lock;
held_lwlocks[num_held_lwlocks++].mode = mode;
- TRACE_POSTGRESQL_LWLOCK_CONDACQUIRE(T_NAME(lock), mode);
+ TRACE_POSTGRESQL_LWLOCK_CONDACQUIRE(T_NAME(lock), mode, lock,
+ lock->tranche);
}
return !mustwait;
}
@@ -1483,7 +1487,8 @@ LWLockAcquireOrWait(LWLock *lock, LWLockMode mode)
#endif
LWLockReportWaitStart(lock);
- TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), mode);
+ TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), mode, lock,
+ lock->tranche);
for (;;)
{
@@ -1501,7 +1506,8 @@ LWLockAcquireOrWait(LWLock *lock, LWLockMode mode)
Assert(nwaiters < MAX_BACKENDS);
}
#endif
- TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(T_NAME(lock), mode);
+ TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(T_NAME(lock), mode, lock,
+ lock->tranche);
LWLockReportWaitEnd();
LOG_LWDEBUG("LWLockAcquireOrWait", lock, "awakened");
@@ -1531,7 +1537,8 @@ LWLockAcquireOrWait(LWLock *lock, LWLockMode mode)
/* Failed to get lock, so release interrupt holdoff */
RESUME_INTERRUPTS();
LOG_LWDEBUG("LWLockAcquireOrWait", lock, "failed");
- TRACE_POSTGRESQL_LWLOCK_ACQUIRE_OR_WAIT_FAIL(T_NAME(lock), mode);
+ TRACE_POSTGRESQL_LWLOCK_ACQUIRE_OR_WAIT_FAIL(T_NAME(lock), mode, lock,
+ lock->tranche);
}
else
{
@@ -1539,7 +1546,8 @@ LWLockAcquireOrWait(LWLock *lock, LWLockMode mode)
/* Add lock to list of locks held by this backend */
held_lwlocks[num_held_lwlocks].lock = lock;
held_lwlocks[num_held_lwlocks++].mode = mode;
- TRACE_POSTGRESQL_LWLOCK_ACQUIRE_OR_WAIT(T_NAME(lock), mode);
+ TRACE_POSTGRESQL_LWLOCK_ACQUIRE_OR_WAIT(T_NAME(lock), mode, lock,
+ lock->tranche);
}
return !mustwait;
@@ -1699,7 +1707,8 @@ LWLockWaitForVar(LWLock *lock, uint64 *valptr, uint64 oldval, uint64 *newval)
#endif
LWLockReportWaitStart(lock);
- TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), LW_EXCLUSIVE);
+ TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), LW_EXCLUSIVE, lock,
+ lock->tranche);
for (;;)
{
@@ -1718,7 +1727,7 @@ LWLockWaitForVar(LWLock *lock, uint64 *valptr, uint64 oldval, uint64 *newval)
}
#endif
- TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(T_NAME(lock), LW_EXCLUSIVE);
+ TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(T_NAME(lock), LW_EXCLUSIVE, lock, lock->tranche);
LWLockReportWaitEnd();
LOG_LWDEBUG("LWLockWaitForVar", lock, "awakened");
@@ -1844,6 +1853,8 @@ LWLockRelease(LWLock *lock)
/* nobody else can have that kind of lock */
Assert(!(oldstate & LW_VAL_EXCLUSIVE));
+ /* Released, though not woken yet. All releases must fire this. */
+ TRACE_POSTGRESQL_LWLOCK_RELEASE(T_NAME(lock), mode, lock, lock->tranche);
/*
* We're still waiting for backends to get scheduled, don't wake them up
@@ -1867,8 +1878,6 @@ LWLockRelease(LWLock *lock)
LWLockWakeup(lock);
}
- TRACE_POSTGRESQL_LWLOCK_RELEASE(T_NAME(lock));
-
/*
* Now okay to allow cancel/die interrupts.
*/
diff --git a/src/backend/utils/probes.d b/src/backend/utils/probes.d
index a0b0458108..89805c3a89 100644
--- a/src/backend/utils/probes.d
+++ b/src/backend/utils/probes.d
@@ -17,6 +17,7 @@
#define LocalTransactionId unsigned int
#define LWLockMode int
#define LOCKMODE int
+#define LWLock void
#define BlockNumber unsigned int
#define Oid unsigned int
#define ForkNumber int
@@ -28,14 +29,15 @@ provider postgresql {
probe transaction__commit(LocalTransactionId);
probe transaction__abort(LocalTransactionId);
- probe lwlock__acquire(const char *, LWLockMode);
- probe lwlock__release(const char *);
- probe lwlock__wait__start(const char *, LWLockMode);
- probe lwlock__wait__done(const char *, LWLockMode);
- probe lwlock__condacquire(const char *, LWLockMode);
- probe lwlock__condacquire__fail(const char *, LWLockMode);
- probe lwlock__acquire__or__wait(const char *, LWLockMode);
- probe lwlock__acquire__or__wait__fail(const char *, LWLockMode);
+ probe lwlock__acquire(const char *, LWLockMode, LWLock*, int);
+ probe lwlock__release(const char *, LWLockMode, LWLock*, int);
+ probe lwlock__wait__start(const char *, LWLockMode, LWLock*, int);
+ probe lwlock__wait__done(const char *, LWLockMode, LWLock*, int);
+ probe lwlock__condacquire(const char *, LWLockMode, LWLock*, int);
+ probe lwlock__condacquire__fail(const char *, LWLockMode, LWLock*, int);
+ probe lwlock__acquire__or__wait(const char *, LWLockMode, LWLock*, int);
+ probe lwlock__acquire__or__wait__fail(const char *, LWLockMode, LWLock*, int);
+
probe lock__wait__start(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE);
probe lock__wait__done(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE);
--
2.29.2