aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Silva <andasilv@amd.com>2026-03-31 20:28:04 +0000
committerWarner Losh <imp@FreeBSD.org>2026-04-16 06:05:21 +0000
commitfbbf71f5813b041526c4d439d9961e8a8281d291 (patch)
tree15c68bd0be47ebfbd8f6560d8dec40cf71e38f10
parentaa462efde6dc009eed0e09272b5359950193b0be (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.cc5
-rw-r--r--lib/libpmc/pmclog.329
-rw-r--r--lib/libpmc/pmclog.c4
-rw-r--r--lib/libpmc/pmclog.h6
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
-