From 525975fcb8c987196b94ff56ce0e83305e1967df Mon Sep 17 00:00:00 2001 From: Nik Samokhvalov Date: Wed, 18 Mar 2026 10:45:56 -0700 Subject: [PATCH] Add USDT static tracepoints to pgstat_report_wait_start/end Add wait__event__start and wait__event__end probes to the DTrace provider definition and invoke them from the static inline functions pgstat_report_wait_start() and pgstat_report_wait_end(). Because these functions are static inline, they get inlined at every call site (~100 locations across 36 files), leaving no function symbol for eBPF uprobes to attach to. USDT probes solve this: the compiler emits a nop instruction at each inlined site with ELF .note.stapsdt metadata, allowing eBPF tools to discover and attach to all call sites with a single probe definition. This enables full eBPF-based wait event tracing (e.g., with bpftrace) without requiring hardware watchpoints or PostgreSQL source patches beyond this change. When built without --enable-dtrace, the probes compile to do {} while(0) with zero overhead. PoC: covers all wait events via the two central inline functions. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/backend/utils/probes.d | 3 +++ src/include/utils/wait_event.h | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/src/backend/utils/probes.d b/src/backend/utils/probes.d index 1929521c6a56a..8b65353ea37fc 100644 --- a/src/backend/utils/probes.d +++ b/src/backend/utils/probes.d @@ -91,4 +91,7 @@ provider postgresql { probe wal__switch(); probe wal__buffer__write__dirty__start(); probe wal__buffer__write__dirty__done(); + + probe wait__event__start(unsigned int); + probe wait__event__end(); }; diff --git a/src/include/utils/wait_event.h b/src/include/utils/wait_event.h index 34c27cc3dc3e1..ca1af4b1c1fb4 100644 --- a/src/include/utils/wait_event.h +++ b/src/include/utils/wait_event.h @@ -12,6 +12,7 @@ /* enums for wait events */ #include "utils/wait_event_types.h" +#include "utils/probes.h" extern const char *pgstat_get_wait_event(uint32 wait_event_info); extern const char *pgstat_get_wait_event_type(uint32 wait_event_info); @@ -73,6 +74,8 @@ pgstat_report_wait_start(uint32 wait_event_info) * four-bytes, updates are atomic. */ *(volatile uint32 *) my_wait_event_info = wait_event_info; + + TRACE_POSTGRESQL_WAIT_EVENT_START(wait_event_info); } /* ---------- @@ -86,6 +89,8 @@ pgstat_report_wait_end(void) { /* see pgstat_report_wait_start() */ *(volatile uint32 *) my_wait_event_info = 0; + + TRACE_POSTGRESQL_WAIT_EVENT_END(); }