From: Ian Rogers <irogers@google.com>
To: irogers@google.com, acme@kernel.org, adrian.hunter@intel.com,
mingo@redhat.com, namhyung@kernel.org, peterz@infradead.org
Cc: ak@linux.intel.com, alexander.shishkin@linux.intel.com,
atrajeev@linux.ibm.com, dvyukov@google.com, fzczx123@gmail.com,
james.clark@linaro.org, jolsa@kernel.org, kjain@linux.ibm.com,
krzysztof.m.lopatowski@gmail.com, leo.yan@arm.com,
lihuafei1@huawei.com, linux-kernel@vger.kernel.org,
linux-perf-users@vger.kernel.org, linux@treblig.org,
m.liska@foxlink.cz, mark.rutland@arm.com, martin.liska@hey.com,
mpetlan@redhat.com, quic_zhonhan@quicinc.com,
scclevenger@os.amperecomputing.com, sesse@google.com,
stephen.s.brennan@oracle.com, thomas.falcon@intel.com,
yangyicong@hisilicon.com
Subject: [PATCH v2 2/8] perf/core: Add BUILD_ID_OFFSET to UAPI
Date: Fri, 2 Oct 2026 10:38:35 -0700 [thread overview]
Message-ID: <20261002173848.3228217-3-irogers@google.com> (raw)
In-Reply-To: <20261002173848.3228217-1-irogers@google.com>
Introduce PERF_SAMPLE_BUILD_ID_OFFSET and
PERF_SAMPLE_CALLCHAIN_BUILD_ID_OFFSET
Signed-off-by: Ian Rogers <irogers@google.com>
---
include/uapi/linux/perf_event.h | 34 +++++++++++++++++++++++----
tools/include/uapi/linux/perf_event.h | 34 +++++++++++++++++++++++----
tools/lib/perf/include/perf/event.h | 33 +++++++++++++++++++++++++-
tools/perf/util/session.c | 34 ++++++++++++++++++++++++++-
4 files changed, 125 insertions(+), 10 deletions(-)
diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index 035b4b416ce3..4157aa8a243a 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -165,8 +165,10 @@ enum perf_event_sample_format {
PERF_SAMPLE_DATA_PAGE_SIZE = 1U << 22,
PERF_SAMPLE_CODE_PAGE_SIZE = 1U << 23,
PERF_SAMPLE_WEIGHT_STRUCT = 1U << 24,
+ PERF_SAMPLE_BUILD_ID_OFFSET = 1U << 25,
+ PERF_SAMPLE_CALLCHAIN_BUILD_ID_OFFSET = 1U << 26,
- PERF_SAMPLE_MAX = 1U << 25, /* non-ABI */
+ PERF_SAMPLE_MAX = 1U << 27, /* non-ABI */
};
#define PERF_SAMPLE_WEIGHT_TYPE (PERF_SAMPLE_WEIGHT | PERF_SAMPLE_WEIGHT_STRUCT)
@@ -815,7 +817,8 @@ struct perf_event_mmap_page {
*
* PERF_RECORD_MISC_EXACT_IP - PERF_RECORD_SAMPLE of precise events
* PERF_RECORD_MISC_SWITCH_OUT_PREEMPT - PERF_RECORD_SWITCH* events
- * PERF_RECORD_MISC_MMAP_BUILD_ID - PERF_RECORD_MMAP2 event
+ * PERF_RECORD_MISC_MMAP_BUILD_ID - PERF_RECORD_MMAP2 and
+ * PERF_RECORD_CALLCHAIN_DEFERRED events
*
*
* PERF_RECORD_MISC_EXACT_IP:
@@ -827,7 +830,7 @@ struct perf_event_mmap_page {
* Indicates that thread was preempted in TASK_RUNNING state.
*
* PERF_RECORD_MISC_MMAP_BUILD_ID:
- * Indicates that mmap2 event carries build ID data.
+ * Indicates that mmap2 or deferred callchain event carries build ID data.
*/
#define PERF_RECORD_MISC_EXACT_IP (1 << 14)
#define PERF_RECORD_MISC_SWITCH_OUT_PREEMPT (1 << 14)
@@ -1054,6 +1057,23 @@ enum perf_event_type {
* { u64 code_page_size;} && PERF_SAMPLE_CODE_PAGE_SIZE
* { u64 size;
* char data[size]; } && PERF_SAMPLE_AUX
+ * { union {
+ * struct {
+ * struct perf_build_id bid;
+ * u64 offset;
+ * };
+ * struct {
+ * u64 zero;
+ * u64 context;
+ * u64 cookie;
+ * u64 ip;
+ * }; && attr.defer_callchain
+ * }; } && PERF_SAMPLE_BUILD_ID_OFFSET
+ * { u64 nr;
+ * struct {
+ * struct perf_build_id bid;
+ * u64 offset;
+ * }[nr]; } && PERF_SAMPLE_CALLCHAIN_BUILD_ID_OFFSET
* };
*/
PERF_RECORD_SAMPLE = 9,
@@ -1260,7 +1280,13 @@ enum perf_event_type {
* struct perf_event_header header;
* u64 cookie;
* u64 nr;
- * u64 ips[nr];
+ * union {
+ * u64 ips[nr];
+ * struct {
+ * struct perf_build_id bid;
+ * u64 offset;
+ * }[nr]; && (header.misc & PERF_RECORD_MISC_MMAP_BUILD_ID)
+ * };
* struct sample_id sample_id;
* };
*/
diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
index 63f8866479a3..56b0cd504a3d 100644
--- a/tools/include/uapi/linux/perf_event.h
+++ b/tools/include/uapi/linux/perf_event.h
@@ -165,8 +165,10 @@ enum perf_event_sample_format {
PERF_SAMPLE_DATA_PAGE_SIZE = 1U << 22,
PERF_SAMPLE_CODE_PAGE_SIZE = 1U << 23,
PERF_SAMPLE_WEIGHT_STRUCT = 1U << 24,
+ PERF_SAMPLE_BUILD_ID_OFFSET = 1U << 25,
+ PERF_SAMPLE_CALLCHAIN_BUILD_ID_OFFSET = 1U << 26,
- PERF_SAMPLE_MAX = 1U << 25, /* non-ABI */
+ PERF_SAMPLE_MAX = 1U << 27, /* non-ABI */
};
#define PERF_SAMPLE_WEIGHT_TYPE (PERF_SAMPLE_WEIGHT | PERF_SAMPLE_WEIGHT_STRUCT)
@@ -840,7 +842,8 @@ struct perf_event_mmap_page {
*
* PERF_RECORD_MISC_EXACT_IP - PERF_RECORD_SAMPLE of precise events
* PERF_RECORD_MISC_SWITCH_OUT_PREEMPT - PERF_RECORD_SWITCH* events
- * PERF_RECORD_MISC_MMAP_BUILD_ID - PERF_RECORD_MMAP2 event
+ * PERF_RECORD_MISC_MMAP_BUILD_ID - PERF_RECORD_MMAP2 and
+ * PERF_RECORD_CALLCHAIN_DEFERRED events
*
*
* PERF_RECORD_MISC_EXACT_IP:
@@ -852,7 +855,7 @@ struct perf_event_mmap_page {
* Indicates that thread was preempted in TASK_RUNNING state.
*
* PERF_RECORD_MISC_MMAP_BUILD_ID:
- * Indicates that mmap2 event carries build ID data.
+ * Indicates that mmap2 or deferred callchain event carries build ID data.
*/
#define PERF_RECORD_MISC_EXACT_IP (1 << 14)
#define PERF_RECORD_MISC_SWITCH_OUT_PREEMPT (1 << 14)
@@ -1095,6 +1098,23 @@ enum perf_event_type {
* { u64 code_page_size;} && PERF_SAMPLE_CODE_PAGE_SIZE
* { u64 size;
* char data[size]; } && PERF_SAMPLE_AUX
+ * { union {
+ * struct {
+ * struct perf_build_id bid;
+ * u64 offset;
+ * };
+ * struct {
+ * u64 zero;
+ * u64 context;
+ * u64 cookie;
+ * u64 ip;
+ * }; && attr.defer_callchain
+ * }; } && PERF_SAMPLE_BUILD_ID_OFFSET
+ * { u64 nr;
+ * struct {
+ * struct perf_build_id bid;
+ * u64 offset;
+ * }[nr]; } && PERF_SAMPLE_CALLCHAIN_BUILD_ID_OFFSET
* };
*/
PERF_RECORD_SAMPLE = 9,
@@ -1301,7 +1321,13 @@ enum perf_event_type {
* struct perf_event_header header;
* u64 cookie;
* u64 nr;
- * u64 ips[nr];
+ * union {
+ * u64 ips[nr];
+ * struct {
+ * struct perf_build_id bid;
+ * u64 offset;
+ * }[nr]; && (header.misc & PERF_RECORD_MISC_MMAP_BUILD_ID)
+ * };
* struct sample_id sample_id;
* };
*/
diff --git a/tools/lib/perf/include/perf/event.h b/tools/lib/perf/include/perf/event.h
index 173eab43c148..3d35a82cccb0 100644
--- a/tools/lib/perf/include/perf/event.h
+++ b/tools/lib/perf/include/perf/event.h
@@ -3,11 +3,24 @@
#define __LIBPERF_EVENT_H
#include <linux/perf_event.h>
+#include <linux/stddef.h>
#include <linux/types.h>
#include <linux/limits.h>
#include <linux/bpf.h>
#include <sys/types.h> /* pid_t */
+#ifndef __DECLARE_FLEX_ARRAY
+#ifdef __cplusplus
+#define __DECLARE_FLEX_ARRAY(T, member) T member[0]
+#else
+#define __DECLARE_FLEX_ARRAY(TYPE, NAME) \
+ struct { \
+ struct { } __empty_ ## NAME; \
+ TYPE NAME[]; \
+ }
+#endif
+#endif
+
/*
* Verify the full field fits within the event, not just its start offset.
* Only valid for fixed-size scalar fields — for trailing arrays like
@@ -162,6 +175,21 @@ struct perf_record_switch {
__u32 next_prev_tid;
};
+struct perf_sample_build_id_offset {
+ union {
+ struct perf_build_id bid;
+ struct {
+ __u64 zero;
+ __u64 context;
+ __u64 cookie;
+ };
+ };
+ union {
+ __u64 offset;
+ __u64 ip;
+ };
+};
+
struct perf_record_callchain_deferred {
struct perf_event_header header;
/*
@@ -171,7 +199,10 @@ struct perf_record_callchain_deferred {
*/
__u64 cookie;
__u64 nr;
- __u64 ips[];
+ union {
+ __DECLARE_FLEX_ARRAY(__u64, ips);
+ __DECLARE_FLEX_ARRAY(struct perf_sample_build_id_offset, bids);
+ };
};
struct perf_record_header_attr {
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 7fea9e72726c..5e113070b3c6 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1186,6 +1186,38 @@ static int perf_event__header_feature_swap(union perf_event *event,
return 0;
}
+static int perf_event__callchain_deferred_swap(union perf_event *event,
+ bool sample_id_all)
+{
+ u64 nr, max_nr;
+
+ if (!(event->header.misc & PERF_RECORD_MISC_MMAP_BUILD_ID))
+ return perf_event__all64_swap(event, sample_id_all);
+
+ if (event->header.size < sizeof(event->callchain_deferred))
+ return -1;
+
+ event->callchain_deferred.cookie = bswap_64(event->callchain_deferred.cookie);
+ event->callchain_deferred.nr = bswap_64(event->callchain_deferred.nr);
+
+ nr = event->callchain_deferred.nr;
+ max_nr = (event->header.size - sizeof(event->callchain_deferred)) /
+ sizeof(event->callchain_deferred.bids[0]);
+ if (nr > max_nr)
+ return -1;
+
+ for (u64 i = 0; i < nr; i++) {
+ struct perf_sample_build_id_offset *bid =
+ &event->callchain_deferred.bids[i];
+
+ bid->offset = bswap_64(bid->offset);
+ }
+
+ if (sample_id_all)
+ swap_sample_id_all(event, &event->callchain_deferred.bids[nr]);
+ return 0;
+}
+
typedef int (*perf_event__swap_op)(union perf_event *event,
bool sample_id_all);
@@ -1211,7 +1243,7 @@ static perf_event__swap_op perf_event__swap_ops[] = {
[PERF_RECORD_BPF_EVENT] = perf_event__bpf_event_swap,
[PERF_RECORD_TEXT_POKE] = perf_event__text_poke_swap,
[PERF_RECORD_AUX_OUTPUT_HW_ID] = perf_event__all64_swap,
- [PERF_RECORD_CALLCHAIN_DEFERRED] = perf_event__all64_swap,
+ [PERF_RECORD_CALLCHAIN_DEFERRED] = perf_event__callchain_deferred_swap,
[PERF_RECORD_HEADER_ATTR] = perf_event__hdr_attr_swap,
[PERF_RECORD_HEADER_EVENT_TYPE] = perf_event__event_type_swap,
[PERF_RECORD_HEADER_TRACING_DATA] = perf_event__tracing_data_swap,
--
2.56.0.rc1.315.gc6ed9934b7-goog
next prev parent reply other threads:[~2026-10-02 17:39 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-24 6:19 [PATCH v1 0/5] perf: Default use of build IDs and improvements Ian Rogers
2025-04-24 6:19 ` [PATCH v1 1/5] perf build-id: Reduce size of "size" variable Ian Rogers
2025-04-24 6:19 ` [PATCH v1 2/5] perf build-id: Truncate to avoid overflowing the build_id data Ian Rogers
2025-04-24 6:19 ` [PATCH v1 3/5] perf build-id: Change sprintf functions to snprintf Ian Rogers
2025-04-24 6:19 ` [PATCH v1 4/5] perf dso: Move build_id to dso_id Ian Rogers
2025-04-24 6:19 ` [PATCH v1 5/5] perf record: Make --buildid-mmap the default Ian Rogers
2025-04-24 7:20 ` Ian Rogers
2025-04-25 14:45 ` Arnaldo Carvalho de Melo
2025-04-25 14:59 ` Arnaldo Carvalho de Melo
2025-04-25 16:03 ` Ian Rogers
2026-10-02 17:38 ` [PATCH v2 0/8] perf/core, perf/tools: Add PERF_SAMPLE_BUILD_ID_OFFSET support Ian Rogers
2026-10-02 17:38 ` [PATCH v2 1/8] perf event: Factor build_id out into its own top-level struct Ian Rogers
2026-10-02 17:38 ` Ian Rogers [this message]
2026-10-02 17:38 ` [PATCH v2 3/8] perf/core: Implement BUILD_ID_OFFSET sample type Ian Rogers
2026-10-02 17:38 ` [PATCH v2 4/8] perf: Refactor thread map and symbol APIs to take perf_sample Ian Rogers
2026-10-02 17:38 ` [PATCH v2 5/8] perf tools: Internal support for BUILD_ID_OFFSET Ian Rogers
2026-10-02 17:38 ` [PATCH v2 6/8] perf inject: Extend perf inject to support bid_offset conversion Ian Rogers
2026-10-02 17:38 ` [PATCH v2 7/8] perf record: Add --buildid-offset option Ian Rogers
2026-10-02 17:38 ` [PATCH v2 8/8] perf tests: Add build_id_offset test coverage Ian Rogers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261002173848.3228217-3-irogers@google.com \
--to=irogers@google.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=ak@linux.intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=atrajeev@linux.ibm.com \
--cc=dvyukov@google.com \
--cc=fzczx123@gmail.com \
--cc=james.clark@linaro.org \
--cc=jolsa@kernel.org \
--cc=kjain@linux.ibm.com \
--cc=krzysztof.m.lopatowski@gmail.com \
--cc=leo.yan@arm.com \
--cc=lihuafei1@huawei.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=linux@treblig.org \
--cc=m.liska@foxlink.cz \
--cc=mark.rutland@arm.com \
--cc=martin.liska@hey.com \
--cc=mingo@redhat.com \
--cc=mpetlan@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
--cc=quic_zhonhan@quicinc.com \
--cc=scclevenger@os.amperecomputing.com \
--cc=sesse@google.com \
--cc=stephen.s.brennan@oracle.com \
--cc=thomas.falcon@intel.com \
--cc=yangyicong@hisilicon.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®