Re: [PATCH v3 15/19] perf: Add deferred user callchains

Jens Remus <[email protected]>
Newsgroups org.kernel.vger.linux-toolchains,org.kernel.vger.linux-kernel,org.kernel.vger.linux-perf-users
Organization IBM Deutschland Research & Development GmbH
Message-ID <[email protected]>
On 28.10.2024 22:48, Josh Poimboeuf wrote:
...
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index ebf143aa427b..bf97b2fa8a9c 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
...
> @@ -6955,6 +6958,53 @@ static void perf_pending_irq(struct irq_work *entry)
>   		perf_swevent_put_recursion_context(rctx);
>   }
>   
> +static void perf_pending_unwind_irq(struct irq_work *entry)
> +{
> +	struct perf_event *event = container_of(entry, struct perf_event, pending_unwind_irq);
> +
> +	if (event->pending_unwind) {
> +		unwind_user_deferred(&perf_unwind_callback_cb, NULL, event);
> +		event->pending_unwind = 0;
> +	}
> +}
> +
> +struct perf_callchain_deferred_event {
> +	struct perf_event_header	header;
> +	u64				ctx_cookie;

This introduces ctx_cookie in the struct used to produce deferred events but misses to do so in the struct used to consume them. This causes the ctx_cookie value to erroneously get interpreted as nr (number of IPs) in perf:

Core was generated by `perf record -F 99 --call-graph fp /opt/binutils-sframe2/bin/objdump --sframe /opt/binutils-sframe2/bin/objdump'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  __GI_memcpy () at ../sysdeps/s390/memcpy-z900.S:209
209             mvc     0(256,%r1),0(%r3)
[Current thread is 1 (Thread 0x3ff8bb5fe80 (LWP 16554))]
(gdb) bt
#0  __GI_memcpy () at ../sysdeps/s390/memcpy-z900.S:209
#1  0x00000000012ad0ca in sample__merge_deferred_callchain (sample_orig=0x3ffd2ff53c8, sample_callchain=0x3ffd2ff5b18) at util/callchain.c:1853
...
(gdb) p/x sample_callchain->callchain->nr
$2 = 0x489cb

With debug output from perf_event_callchain_deferred() (see below):

DEBUG: perf_event_callchain_deferred: ctx_cookie=0x00000000000489cb, nr=2

> +	u64				nr;
> +	u64				ips[];
> +};
> +
> +static void perf_event_callchain_deferred(struct unwind_stacktrace *trace,
> +					  u64 ctx_cookie, void *_data)
> +{
> +	struct perf_callchain_deferred_event deferred_event;
> +	u64 callchain_context = PERF_CONTEXT_USER;
> +	struct perf_output_handle handle;
> +	struct perf_event *event = _data;
> +	struct perf_sample_data data;
> +	u64 nr = trace->nr + 1 /* callchain_context */;
> +
> +	deferred_event.header.type = PERF_RECORD_CALLCHAIN_DEFERRED;
> +	deferred_event.header.misc = PERF_RECORD_MISC_USER;
> +	deferred_event.header.size = sizeof(deferred_event) + (nr * sizeof(u64));
> +
> +	deferred_event.ctx_cookie = ctx_cookie;
> +	deferred_event.nr = nr;
> +
> +	perf_event_header__init_id(&deferred_event.header, &data, event);

	pr_info_ratelimited("DEBUG: perf_event_callchain_deferred: ctx_cookie=0x%016llx, nr=%llu\n",
		deferred_event.ctx_cookie, deferred_event.nr);

> +
> +	if (perf_output_begin(&handle, &data, event, deferred_event.header.size))
> +		return;
> +
> +	perf_output_put(&handle, deferred_event);
> +	perf_output_put(&handle, callchain_context);
> +	perf_output_copy(&handle, trace->entries, trace->nr * sizeof(u64));
> +	perf_event__output_id_sample(event, &handle, &data);
> +
> +	perf_output_end(&handle);
> +}
> +
>   static void perf_pending_task(struct callback_head *head)
>   {
>   	struct perf_event *event = container_of(head, struct perf_event, pending_task);
...

Regards,
Jens
-- 
Jens Remus
Linux on Z Development (D3303) and z/VSE Support
+49-7031-16-1128 Office
[email protected]

IBM

IBM Deutschland Research & Development GmbH; Vorsitzender des Aufsichtsrats: Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der Gesellschaft: Böblingen; Registergericht: Amtsgericht Stuttgart, HRB 243294
IBM Data Privacy Statement: https://www.ibm.com/privacy/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.