diff options
| author | Andre Silva <andasilv@amd.com> | 2026-03-31 20:28:04 +0000 |
|---|---|---|
| committer | Warner Losh <imp@FreeBSD.org> | 2026-04-16 06:05:21 +0000 |
| commit | fbbf71f5813b041526c4d439d9961e8a8281d291 (patch) | |
| tree | 15c68bd0be47ebfbd8f6560d8dec40cf71e38f10 | |
| parent | aa462efde6dc009eed0e09272b5359950193b0be (diff) | |
libpmc: surface raw TSC in pmclog events
The pmclog record header carries the raw TSC for each event. Export it
in struct pmclog_ev, fix JSON output to emit it unsigned, and preserve
the installed header ABI by overlaying pl_tsc with the legacy pl_ts
storage.
Update pmclog(3) to document the TSC semantics and the legacy alias.
Sponsored by: AMD
Signed-off-by: Andre Silva <andasilv@amd.com>
Reviewed by: imp, mhorne, Ali Mashtizadeh
Pull Request: https://github.com/freebsd/freebsd-src/pull/2085
| -rw-r--r-- | lib/libpmc/libpmc_json.cc | 5 | ||||
| -rw-r--r-- | lib/libpmc/pmclog.3 | 29 | ||||
| -rw-r--r-- | lib/libpmc/pmclog.c | 4 | ||||
| -rw-r--r-- | lib/libpmc/pmclog.h | 6 |
4 files changed, 35 insertions, 9 deletions
diff --git a/lib/libpmc/libpmc_json.cc b/lib/libpmc/libpmc_json.cc index 90881f22971e..1ac0b3a50a6c 100644 --- a/lib/libpmc/libpmc_json.cc +++ b/lib/libpmc/libpmc_json.cc @@ -74,8 +74,8 @@ startentry(struct pmclog_ev *ev) { char eventbuf[128]; - snprintf(eventbuf, sizeof(eventbuf), "%s, \"tsc\": \"%jd\"", - typenames[ev->pl_type], (uintmax_t)ev->pl_ts.tv_sec); + snprintf(eventbuf, sizeof(eventbuf), "%s, \"tsc\": \"%ju\"", + typenames[ev->pl_type], (uintmax_t)ev->pl_tsc); return (string(eventbuf)); } @@ -393,4 +393,3 @@ event_to_json(struct pmclog_ev *ev){ errx(EX_USAGE, "ERROR: unrecognized event type: %d\n", ev->pl_type); } } - diff --git a/lib/libpmc/pmclog.3 b/lib/libpmc/pmclog.3 index 4af4150d60a9..452a14f42f55 100644 --- a/lib/libpmc/pmclog.3 +++ b/lib/libpmc/pmclog.3 @@ -77,7 +77,10 @@ struct pmclog_ev { enum pmclog_state pl_state; /* parser state after 'get_event()' */ off_t pl_offset; /* byte offset in stream */ size_t pl_count; /* count of records so far */ - struct timespec pl_ts; /* log entry timestamp */ + union { + uint64_t pl_tsc; /* TSC timestamp */ + struct timespec pl_ts; /* log entry timestamp (legacy) */ + }; enum pmclog_type pl_type; /* log entry kind */ union { /* log entry data */ struct pmclog_ev_callchain pl_cc; @@ -136,8 +139,30 @@ Field .Va pl_count contains the serial number of this event. Field +.Va pl_tsc +carries the raw CPU Time Stamp Counter (TSC) value recorded at the time +of the event. +This is not a wall-clock time; to convert to nanoseconds divide the TSC +delta between two events by the TSC frequency +.Pq Va pl_u.pl_i.pl_tsc_freq +reported in the +.Dv PMCLOG_TYPE_INITIALIZE +record. +The legacy .Va pl_ts -contains a timestamp with the system time when the event occurred. +member aliases the same storage for ABI compatibility, but its contents +no longer represent a wall-clock timestamp. +.Pp +Note that TSC-based timestamps and +.Va pl_u.pl_i.pl_tsc_freq +are only meaningful on x86 architectures +.Pq amd64 and i386 . +On all other architectures +.Pq including arm64 and powerpc , +.Va pl_tsc +and +.Va pl_u.pl_i.pl_tsc_freq +are set to zero. Field .Va pl_type denotes the kind of the event returned in argument diff --git a/lib/libpmc/pmclog.c b/lib/libpmc/pmclog.c index 22ff50b10ee0..c3587af46c7b 100644 --- a/lib/libpmc/pmclog.c +++ b/lib/libpmc/pmclog.c @@ -287,8 +287,8 @@ pmclog_get_event(void *cookie, char **data, ssize_t *len, return -1; } - /* copy out the time stamp */ - ev->pl_ts.tv_sec = ph->pl_tsc; + /* copy out the TSC from the event header */ + ev->pl_tsc = ph->pl_tsc; le += sizeof(*ph)/4; evlen = PMCLOG_HEADER_TO_LENGTH(h); diff --git a/lib/libpmc/pmclog.h b/lib/libpmc/pmclog.h index 72e73e3928d2..a79d33529890 100644 --- a/lib/libpmc/pmclog.h +++ b/lib/libpmc/pmclog.h @@ -169,7 +169,10 @@ struct pmclog_ev { enum pmclog_state pl_state; /* state after 'get_event()' */ off_t pl_offset; /* byte offset in stream */ size_t pl_count; /* count of records so far */ - struct timespec pl_ts; /* log entry timestamp */ + union { + uint64_t pl_tsc; /* TSC timestamp */ + struct timespec pl_ts; /* log entry timestamp (legacy) */ + }; enum pmclog_type pl_type; /* type of log entry */ void *pl_data; int pl_len; @@ -229,4 +232,3 @@ void pmclog_close(void *_cookie); __END_DECLS #endif - |
