mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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 3/8] perf/core: Implement BUILD_ID_OFFSET sample type
Date: Fri,  2 Oct 2026 10:38:36 -0700	[thread overview]
Message-ID: <20261002173848.3228217-4-irogers@google.com> (raw)
In-Reply-To: <20261002173848.3228217-1-irogers@google.com>

Implement PERF_SAMPLE_BUILD_ID_OFFSET and
PERF_SAMPLE_CALLCHAIN_BUILD_ID_OFFSET payload writing in the perf event
core by reusing BPF's stack_map_get_build_id_offset().

When attr.defer_callchain is set, user-space IPs and callchains request
a deferred unwind via unwind_deferred_request() and emit a
PERF_CONTEXT_USER_DEFERRED marker and cookie in the sample. In the
faultable task_work callback (perf_unwind_deferred_callback), the
unwound user IPs are resolved to build IDs and file offsets using
stack_map_get_build_id_offset(..., may_fault=true) and emitted in
PERF_RECORD_CALLCHAIN_DEFERRED with PERF_RECORD_MISC_MMAP_BUILD_ID set.

When attr.defer_callchain is not set (or if deferred unwinding is
unavailable), user-space IPs and callchains are resolved in-place during
perf_output_sample() using stack_map_get_build_id_offset(...,
may_fault=false). If the mmap_lock cannot be trylocked or the ELF
header/note pages are not present in the page cache (nor mlocked into
memory), resolution falls back to emitting a zero-sized build ID
(size = 0) with the virtual address as the offset. Using the deferred
approach (attr.defer_callchain and attr.defer_output) is therefore
preferred as it can fault in pages and wait on locks, resolving more
build IDs without requiring ELF header pages to be mlocked in the page
cache.

Kernel-space IPs and callchain entries are emitted with a zero-sized
build ID (size = 0) and the virtual address as the offset.

Signed-off-by: Ian Rogers <irogers@google.com>
---
 include/linux/bpf.h        |  14 ++
 include/linux/perf_event.h |   1 +
 kernel/bpf/stackmap.c      |   4 +-
 kernel/events/core.c       | 298 +++++++++++++++++++++++++++++++++++--
 4 files changed, 304 insertions(+), 13 deletions(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index e57af902560c..750133762436 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -4217,4 +4217,18 @@ static inline int bpf_map_check_op_flags(struct bpf_map *map, u64 flags, u64 all
 	return 0;
 }
 
+#if defined(CONFIG_BPF_SYSCALL) && defined(CONFIG_PERF_EVENTS)
+void stack_map_get_build_id_offset(struct bpf_stack_build_id *id_offs,
+				   u32 trace_nr, bool user, bool may_fault);
+#else
+static inline void stack_map_get_build_id_offset(struct bpf_stack_build_id *id_offs,
+						 u32 trace_nr, bool user, bool may_fault)
+{
+	for (u32 i = 0; i < trace_nr; i++) {
+		id_offs[i].status = BPF_STACK_BUILD_ID_IP;
+		memset(id_offs[i].build_id, 0, BPF_BUILD_ID_SIZE);
+	}
+}
+#endif
+
 #endif /* _LINUX_BPF_H */
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 5842552294c1..3868923f6a79 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1347,6 +1347,7 @@ struct perf_sample_data {
 	u64				data_page_size;
 	u64				code_page_size;
 	u64				aux_size;
+	u64				callchain_bid_nr;
 } ____cacheline_aligned;
 
 /* default value for data source */
diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c
index d09d4c3fe547..4e06c1697786 100644
--- a/kernel/bpf/stackmap.c
+++ b/kernel/bpf/stackmap.c
@@ -411,8 +411,8 @@ static void stack_map_get_build_id_offset_sleepable(struct bpf_stack_build_id *i
  *     id_offs[i].build_id is zeroed out and id_offs[i].status is set to
  *     BPF_STACK_BUILD_ID_IP.
  */
-static void stack_map_get_build_id_offset(struct bpf_stack_build_id *id_offs,
-					  u32 trace_nr, bool user, bool may_fault)
+void stack_map_get_build_id_offset(struct bpf_stack_build_id *id_offs,
+				   u32 trace_nr, bool user, bool may_fault)
 {
 	struct mmap_unlock_irq_work *work;
 	bool has_user_ctx = user && current && current->mm;
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 33210aff3ee6..7f6bf96f7473 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -460,6 +460,8 @@ static atomic_t nr_bpf_events __read_mostly;
 static atomic_t nr_cgroup_events __read_mostly;
 static atomic_t nr_text_poke_events __read_mostly;
 static atomic_t nr_build_id_events __read_mostly;
+static atomic_t nr_build_id_offset_events __read_mostly;
+static atomic_t nr_callchain_build_id_offset_events __read_mostly;
 
 static LIST_HEAD(pmus);
 static DEFINE_MUTEX(pmus_lock);
@@ -2048,6 +2050,14 @@ static int __perf_event_read_size(u64 read_format, int nr_siblings)
 	return size + nr * entry;
 }
 
+struct perf_sample_build_id_offset {
+	u8	size;
+	u8	res1;
+	u16	res2;
+	u8	build_id[BUILD_ID_SIZE_MAX];
+	u64	offset;
+};
+
 static void __perf_event_header_size(struct perf_event *event, u64 sample_type)
 {
 	struct perf_sample_data *data;
@@ -2086,6 +2096,9 @@ static void __perf_event_header_size(struct perf_event *event, u64 sample_type)
 	if (sample_type & PERF_SAMPLE_CODE_PAGE_SIZE)
 		size += sizeof(data->code_page_size);
 
+	if (sample_type & PERF_SAMPLE_BUILD_ID_OFFSET)
+		size += sizeof(struct perf_sample_build_id_offset);
+
 	event->header_size = size;
 }
 
@@ -5341,7 +5354,7 @@ static bool is_sb_event(struct perf_event *event)
 	    attr->comm || attr->comm_exec ||
 	    attr->task || attr->ksymbol ||
 	    attr->context_switch || attr->text_poke ||
-	    attr->bpf_event)
+	    attr->bpf_event || attr->defer_output)
 		return true;
 
 	return false;
@@ -5619,6 +5632,10 @@ static void unaccount_event(struct perf_event *event)
 		atomic_dec(&nr_mmap_events);
 	if (event->attr.build_id)
 		atomic_dec(&nr_build_id_events);
+	if (event->attr.sample_type & PERF_SAMPLE_BUILD_ID_OFFSET)
+		atomic_dec(&nr_build_id_offset_events);
+	if (event->attr.sample_type & PERF_SAMPLE_CALLCHAIN_BUILD_ID_OFFSET)
+		atomic_dec(&nr_callchain_build_id_offset_events);
 	if (event->attr.comm)
 		atomic_dec(&nr_comm_events);
 	if (event->attr.namespaces)
@@ -8276,6 +8293,155 @@ static void perf_output_read(struct perf_output_handle *handle,
 		perf_output_read_one(handle, event, enabled, running);
 }
 
+static struct unwind_work perf_unwind_work;
+
+struct perf_bpf_build_id_buf {
+	local_t active;
+	struct bpf_stack_build_id bids[PERF_MAX_STACK_DEPTH + 1];
+};
+
+static DEFINE_PER_CPU(struct perf_bpf_build_id_buf, perf_bpf_build_id_buf);
+
+static void perf_bpf_to_sample_bid_offset(struct bpf_stack_build_id *bpf_bid)
+{
+	struct perf_sample_build_id_offset *bid = (void *)bpf_bid;
+	u8 size = 0;
+
+	static_assert(sizeof(*bid) == sizeof(*bpf_bid));
+	static_assert(offsetof(struct perf_sample_build_id_offset, build_id) ==
+		      offsetof(struct bpf_stack_build_id, build_id));
+	static_assert(offsetof(struct perf_sample_build_id_offset, offset) ==
+		      offsetof(struct bpf_stack_build_id, offset));
+
+	if (bpf_bid->status == BPF_STACK_BUILD_ID_VALID)
+		size = BUILD_ID_SIZE_MAX;
+	else
+		memset(bid->build_id, 0, sizeof(bid->build_id));
+
+	bid->size = size;
+	bid->res1 = 0;
+	bid->res2 = 0;
+}
+
+static void perf_output_sample_build_id(struct perf_output_handle *handle,
+					struct perf_event_header *header,
+					struct perf_sample_data *data,
+					struct perf_event *event)
+{
+	u64 sample_type = data->type;
+	bool sample_bid = sample_type & PERF_SAMPLE_BUILD_ID_OFFSET;
+	bool callchain_bid = sample_type & PERF_SAMPLE_CALLCHAIN_BUILD_ID_OFFSET;
+	bool crosstask = event->ctx->task && event->ctx->task != current;
+	bool has_user_ctx = is_user_task(current) && current->mm && !crosstask;
+	bool is_user = (header->misc & PERF_RECORD_MISC_CPUMODE_MASK) ==
+		       PERF_RECORD_MISC_USER;
+	u64 defer_cookie = 0;
+	u64 callchain_nr = callchain_bid ? data->callchain_bid_nr : 0;
+	u64 user_start = callchain_nr;
+	u32 resolve_ip_nr = 0, resolve_cc_nr = 0, total_resolve_nr;
+	struct perf_bpf_build_id_buf *buf = NULL;
+
+	if (sample_bid) {
+		bool defer_user = IS_ENABLED(CONFIG_UNWIND_USER) &&
+				  is_user && has_user_ctx &&
+				  event->attr.defer_callchain &&
+				  !(sample_type & PERF_SAMPLE_CALLCHAIN);
+
+		if (defer_user &&
+		    unwind_deferred_request(&perf_unwind_work, &defer_cookie) < 0)
+			defer_cookie = 0;
+
+		if (!defer_cookie && is_user && has_user_ctx)
+			resolve_ip_nr = 1;
+	}
+
+	if (callchain_bid && has_user_ctx) {
+		for (u64 i = 0; i < callchain_nr; i++) {
+			if (data->callchain->ip[i] == PERF_CONTEXT_USER) {
+				user_start = i + 1;
+				break;
+			}
+		}
+		if (user_start < callchain_nr) {
+			resolve_cc_nr = min_t(u64, callchain_nr - user_start,
+					      PERF_MAX_STACK_DEPTH);
+		}
+	}
+
+	total_resolve_nr = resolve_ip_nr + resolve_cc_nr;
+	if (total_resolve_nr) {
+		buf = get_cpu_ptr(&perf_bpf_build_id_buf);
+		if (local_cmpxchg(&buf->active, 0, 1) == 0) {
+			if (resolve_ip_nr)
+				buf->bids[0].ip = data->ip;
+			for (u32 i = 0; i < resolve_cc_nr; i++) {
+				buf->bids[resolve_ip_nr + i].ip =
+					data->callchain->ip[user_start + i];
+			}
+			stack_map_get_build_id_offset(buf->bids,
+						      total_resolve_nr,
+						      true, false);
+			for (u32 i = 0; i < total_resolve_nr; i++)
+				perf_bpf_to_sample_bid_offset(&buf->bids[i]);
+		} else {
+			put_cpu_ptr(&perf_bpf_build_id_buf);
+			buf = NULL;
+		}
+	}
+
+	if (sample_bid) {
+		if (defer_cookie) {
+			u64 deferred_bid[4] = {
+				0,
+				PERF_CONTEXT_USER_DEFERRED,
+				defer_cookie,
+				data->ip,
+			};
+
+			perf_output_put(handle, deferred_bid);
+		} else if (buf && resolve_ip_nr) {
+			perf_output_copy(handle, &buf->bids[0],
+					 sizeof(buf->bids[0]));
+		} else {
+			struct perf_sample_build_id_offset bid_offset = {
+				.offset = data->ip,
+			};
+
+			perf_output_put(handle, bid_offset);
+		}
+	}
+
+	if (callchain_bid) {
+		u64 unres_prefix = buf ? user_start : callchain_nr;
+		u64 resolved_end = unres_prefix + (buf ? resolve_cc_nr : 0);
+
+		perf_output_put(handle, callchain_nr);
+		for (u64 i = 0; i < unres_prefix; i++) {
+			struct perf_sample_build_id_offset bid_offset = {
+				.offset = data->callchain->ip[i],
+			};
+
+			perf_output_put(handle, bid_offset);
+		}
+		if (buf && resolve_cc_nr) {
+			perf_output_copy(handle, &buf->bids[resolve_ip_nr],
+					 resolve_cc_nr * sizeof(buf->bids[0]));
+		}
+		for (u64 i = resolved_end; i < callchain_nr; i++) {
+			struct perf_sample_build_id_offset bid_offset = {
+				.offset = data->callchain->ip[i],
+			};
+
+			perf_output_put(handle, bid_offset);
+		}
+	}
+
+	if (buf) {
+		local_set(&buf->active, 0);
+		put_cpu_ptr(&perf_bpf_build_id_buf);
+	}
+}
+
 void perf_output_sample(struct perf_output_handle *handle,
 			struct perf_event_header *header,
 			struct perf_sample_data *data,
@@ -8455,6 +8621,10 @@ void perf_output_sample(struct perf_output_handle *handle,
 			perf_aux_sample_output(event, handle, data);
 	}
 
+	if (sample_type &
+	    (PERF_SAMPLE_BUILD_ID_OFFSET | PERF_SAMPLE_CALLCHAIN_BUILD_ID_OFFSET))
+		perf_output_sample_build_id(handle, header, data, event);
+
 	if (!event->attr.watermark) {
 		int wakeup_events = event->attr.wakeup_events;
 
@@ -8598,8 +8768,6 @@ static u64 perf_get_page_size(unsigned long addr)
 
 static struct perf_callchain_entry __empty_callchain = { .nr = 0, };
 
-static struct unwind_work perf_unwind_work;
-
 struct perf_callchain_entry *
 perf_callchain(struct perf_event *event, struct pt_regs *regs)
 {
@@ -8663,7 +8831,7 @@ void perf_prepare_sample(struct perf_sample_data *data,
 
 	__perf_event_header__init_id(data, event, filtered_sample_type);
 
-	if (filtered_sample_type & PERF_SAMPLE_IP) {
+	if (filtered_sample_type & (PERF_SAMPLE_IP | PERF_SAMPLE_BUILD_ID_OFFSET)) {
 		data->ip = perf_instruction_pointer(event, regs);
 		data->sample_flags |= PERF_SAMPLE_IP;
 	}
@@ -8671,6 +8839,14 @@ void perf_prepare_sample(struct perf_sample_data *data,
 	if (filtered_sample_type & PERF_SAMPLE_CALLCHAIN)
 		perf_sample_save_callchain(data, event, regs);
 
+	if (filtered_sample_type & PERF_SAMPLE_CALLCHAIN_BUILD_ID_OFFSET) {
+		if (!(data->sample_flags & PERF_SAMPLE_CALLCHAIN))
+			data->callchain = perf_callchain(event, regs);
+
+		data->dyn_size += sizeof(u64);
+	}
+
+
 	if (filtered_sample_type & PERF_SAMPLE_RAW) {
 		data->raw = NULL;
 		data->dyn_size += sizeof(u64);
@@ -8820,6 +8996,20 @@ void perf_prepare_sample(struct perf_sample_data *data,
 		data->dyn_size += size + sizeof(u64); /* size above */
 		data->sample_flags |= PERF_SAMPLE_AUX;
 	}
+
+	if (filtered_sample_type & PERF_SAMPLE_CALLCHAIN_BUILD_ID_OFFSET) {
+		u32 header_size = perf_sample_data_size(data, event);
+		u64 max_nr = 0, nr;
+
+		if (header_size < U16_MAX) {
+			max_nr = (U16_MAX - header_size) /
+				 sizeof(struct perf_sample_build_id_offset);
+		}
+		nr = min_t(u64, data->callchain->nr, max_nr);
+		data->callchain_bid_nr = nr;
+		data->dyn_size += nr * sizeof(struct perf_sample_build_id_offset);
+		data->sample_flags |= PERF_SAMPLE_CALLCHAIN_BUILD_ID_OFFSET;
+	}
 }
 
 void perf_prepare_header(struct perf_event_header *header,
@@ -10414,6 +10604,8 @@ void perf_event_bpf_event(struct bpf_prog *prog,
 
 struct perf_callchain_deferred_event {
 	struct unwind_stacktrace *trace;
+	struct perf_sample_build_id_offset *bids;
+	u16 nr_bids;
 	struct {
 		struct perf_event_header	header;
 		u64				cookie;
@@ -10422,17 +10614,83 @@ struct perf_callchain_deferred_event {
 	} event;
 };
 
+static struct perf_sample_build_id_offset *
+perf_resolve_build_id_offsets(struct unwind_stacktrace *trace, u16 *nr_bids_out)
+{
+	struct perf_sample_build_id_offset *bids;
+	struct bpf_stack_build_id *bpf_bids;
+	u16 nr = trace->nr;
+
+	*nr_bids_out = 0;
+	if (!nr || !current->mm)
+		return NULL;
+
+	if (!atomic_read(&nr_callchain_build_id_offset_events)) {
+		if (!atomic_read(&nr_build_id_offset_events))
+			return NULL;
+		nr = 1;
+	}
+
+	bids = kcalloc(nr, sizeof(*bids), GFP_KERNEL);
+	if (!bids)
+		return NULL;
+
+	bpf_bids = (struct bpf_stack_build_id *)bids;
+	for (u16 i = 0; i < nr; i++)
+		bpf_bids[i].ip = trace->entries[i];
+
+	stack_map_get_build_id_offset(bpf_bids, nr, true, true);
+
+	for (u16 i = 0; i < nr; i++)
+		perf_bpf_to_sample_bid_offset(&bpf_bids[i]);
+
+	*nr_bids_out = nr;
+	return bids;
+}
+
 static void perf_callchain_deferred_output(struct perf_event *event, void *data)
 {
 	struct perf_callchain_deferred_event *deferred_event = data;
 	struct perf_output_handle handle;
 	struct perf_sample_data sample;
-	int ret, size = deferred_event->event.header.size;
+	u64 nr = deferred_event->trace->nr;
+	size_t elem_size;
+	bool use_bid;
+	u16 header_size, orig_misc, id_size;
+	int ret;
 
 	if (!event->attr.defer_output)
 		return;
 
+	if (event->attr.sample_type & PERF_SAMPLE_CALLCHAIN_BUILD_ID_OFFSET) {
+		use_bid = deferred_event->bids != NULL;
+		if (use_bid)
+			nr = min_t(u64, nr, deferred_event->nr_bids);
+	} else if ((event->attr.sample_type & PERF_SAMPLE_BUILD_ID_OFFSET) &&
+		   !(event->attr.sample_type & PERF_SAMPLE_CALLCHAIN)) {
+		nr = min_t(u64, nr, 1);
+		use_bid = deferred_event->bids != NULL;
+		if (use_bid)
+			nr = min_t(u64, nr, deferred_event->nr_bids);
+	} else {
+		use_bid = false;
+	}
+
+	elem_size = use_bid ? sizeof(struct perf_sample_build_id_offset) :
+			      sizeof(u64);
+	id_size = event->attr.sample_id_all ? event->id_header_size : 0;
+	nr = min_t(u64, nr,
+		   (U16_MAX - sizeof(deferred_event->event) - id_size) / elem_size);
+
+	orig_misc = deferred_event->event.header.misc;
+	if (use_bid)
+		deferred_event->event.header.misc |= PERF_RECORD_MISC_MMAP_BUILD_ID;
+	header_size = sizeof(deferred_event->event) + (nr * elem_size);
+	deferred_event->event.header.size = header_size;
+	deferred_event->event.nr = nr;
+
 	/* XXX do we really need sample_id_all for this ??? */
+	perf_sample_data_init(&sample, 0, 0);
 	perf_event_header__init_id(&deferred_event->event.header, &sample, event);
 
 	ret = perf_output_begin(&handle, &sample, event,
@@ -10441,22 +10699,33 @@ static void perf_callchain_deferred_output(struct perf_event *event, void *data)
 		goto out;
 
 	perf_output_put(&handle, deferred_event->event);
-	for (int i = 0; i < deferred_event->trace->nr; i++) {
-		u64 entry = deferred_event->trace->entries[i];
-		perf_output_put(&handle, entry);
+	if (use_bid) {
+		for (u64 i = 0; i < nr; i++)
+			perf_output_put(&handle, deferred_event->bids[i]);
+	} else {
+		for (u64 i = 0; i < nr; i++) {
+			u64 entry = deferred_event->trace->entries[i];
+
+			perf_output_put(&handle, entry);
+		}
 	}
 	perf_event__output_id_sample(event, &handle, &sample);
 
 	perf_output_end(&handle);
 out:
-	deferred_event->event.header.size = size;
+	deferred_event->event.header.misc = orig_misc;
 }
 
 static void perf_unwind_deferred_callback(struct unwind_work *work,
 					 struct unwind_stacktrace *trace, u64 cookie)
 {
+	u16 nr_bids = 0;
+	struct perf_sample_build_id_offset *bids =
+		perf_resolve_build_id_offsets(trace, &nr_bids);
 	struct perf_callchain_deferred_event deferred_event = {
 		.trace = trace,
+		.bids = bids,
+		.nr_bids = nr_bids,
 		.event = {
 			.header = {
 				.type = PERF_RECORD_CALLCHAIN_DEFERRED,
@@ -10470,6 +10739,7 @@ static void perf_unwind_deferred_callback(struct unwind_work *work,
 	};
 
 	perf_iterate_sb(perf_callchain_deferred_output, &deferred_event, NULL);
+	kfree(bids);
 }
 
 struct perf_text_poke_event {
@@ -13314,6 +13584,10 @@ static void account_event(struct perf_event *event)
 		atomic_inc(&nr_mmap_events);
 	if (event->attr.build_id)
 		atomic_inc(&nr_build_id_events);
+	if (event->attr.sample_type & PERF_SAMPLE_BUILD_ID_OFFSET)
+		atomic_inc(&nr_build_id_offset_events);
+	if (event->attr.sample_type & PERF_SAMPLE_CALLCHAIN_BUILD_ID_OFFSET)
+		atomic_inc(&nr_callchain_build_id_offset_events);
 	if (event->attr.comm)
 		atomic_inc(&nr_comm_events);
 	if (event->attr.namespaces)
@@ -13582,7 +13856,8 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
 	}
 
 	if (!event->parent) {
-		if (event->attr.sample_type & PERF_SAMPLE_CALLCHAIN) {
+		if (event->attr.sample_type &
+		    (PERF_SAMPLE_CALLCHAIN | PERF_SAMPLE_CALLCHAIN_BUILD_ID_OFFSET)) {
 			err = get_callchain_buffers(attr->sample_max_stack);
 			if (err)
 				return ERR_PTR(err);
@@ -13943,7 +14218,8 @@ SYSCALL_DEFINE5(perf_event_open,
 		return err;
 
 	if (!attr.exclude_kernel ||
-	    ((attr.sample_type & PERF_SAMPLE_CALLCHAIN) &&
+	    ((attr.sample_type &
+	      (PERF_SAMPLE_CALLCHAIN | PERF_SAMPLE_CALLCHAIN_BUILD_ID_OFFSET)) &&
 	     !attr.exclude_callchain_kernel)) {
 		err = perf_allow_kernel();
 		if (err)
-- 
2.56.0.rc1.315.gc6ed9934b7-goog


  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   ` [PATCH v2 2/8] perf/core: Add BUILD_ID_OFFSET to UAPI Ian Rogers
2026-10-02 17:38   ` Ian Rogers [this message]
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-4-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®