All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <arnaldo.melo@gmail.com>
To: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/2] perf thread-stack: Fix thread stack return from kernel for kernel-only case
Date: Mon, 24 Jun 2019 15:39:50 -0300	[thread overview]
Message-ID: <20190624183950.GA4181@kernel.org> (raw)
In-Reply-To: <20190619064429.14940-2-adrian.hunter@intel.com>

Em Wed, Jun 19, 2019 at 09:44:28AM +0300, Adrian Hunter escreveu:
> Commit f08046cb3082 ("perf thread-stack: Represent jmps to the start of a
> different symbol") had the side-effect of introducing more stack entries
> before return from kernel space. When user space is also traced, those
> entries are popped before entry to user space, but when user space is not
> traced, they get stuck at the bottom of the stack, making the stack grow
> progressively larger. Fix by detecting a return-from-kernel branch type,
> and popping kernel addresses from the stack then.
> 
> Note, the problem and fix affect the exported Call Graph / Tree but not
> the callindent option used by "perf script --call-trace".
> 
> Example:
> 
>   perf-with-kcore record example -e intel_pt//k -- ls
>   perf-with-kcore script --itrace=bep -s ~/libexec/perf-core/scripts/python/export-to-sqlite.py example.db branches calls
>   ~/libexec/perf-core/scripts/python/exported-sql-viewer.py example.db

Trying with you above instructions I hit some snags, 'perf-with-kcore'
expects the first arg to be the directory where it'll find the perf.data
file, etc, right? I.e. to work I had to do:

[root@quaco tmp]# rm -rf bep
[root@quaco tmp]# rm -rf example.db 
[root@quaco tmp]# perf-with-kcore record bep -e intel_pt//k -- ls
Recording
Using /root/bin/perf
perf version 5.2.rc4.gd1d5628fa057
/root/bin/perf record -o bep/perf.data -e intel_pt//k -- ls
<SNIP>
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.123 MB bep/perf.data ]
Copying kcore
Done
[root@quaco tmp]# perf-with-kcore script bep --itrace=bep -s ~acme/libexec/perf-core/scripts/python/export-to-sqlite.py example.db branches calls
Using /root/bin/perf
perf version 5.2.rc4.gd1d5628fa057
/root/bin/perf script -i bep/perf.data --kallsyms=bep/kcore_dir/kallsyms --itrace=bep -s /home/acme/libexec/perf-core/scripts/python/export-to-sqlite.py example.db branches calls
2019-06-24 15:29:54.910209 Creating database ...
2019-06-24 15:29:54.913351 Writing records...
2019-06-24 15:29:58.009226 Adding indexes
2019-06-24 15:29:58.024644 Done
[root@quaco tmp]#

I.e. add 'bep' after 'script' and before '--itrace-bep'.

I'm fixing this up in the comment, please check.

With that in place I can reproduce your results below.


Thanks,

- Arnaldo
 
>   Menu option: Reports -> Context-Sensitive Call Graph
> 
>   Before: (showing Call Path column only)
> 
>     Call Path
>     ▶ perf
>     ▼ ls
>       ▼ 12111:12111
>         ▶ setup_new_exec
>         ▶ __task_pid_nr_ns
>         ▶ perf_event_pid_type
>         ▶ perf_event_comm_output
>         ▶ perf_iterate_ctx
>         ▶ perf_iterate_sb
>         ▶ perf_event_comm
>         ▶ __set_task_comm
>         ▶ load_elf_binary
>         ▶ search_binary_handler
>         ▶ __do_execve_file.isra.41
>         ▶ __x64_sys_execve
>         ▶ do_syscall_64
>         ▼ entry_SYSCALL_64_after_hwframe
>           ▼ swapgs_restore_regs_and_return_to_usermode
>             ▼ native_iret
>               ▶ error_entry
>               ▶ do_page_fault
>               ▼ error_exit
>                 ▼ retint_user
>                   ▶ prepare_exit_to_usermode
>                   ▼ native_iret
>                     ▶ error_entry
>                     ▶ do_page_fault
>                     ▼ error_exit
>                       ▼ retint_user
>                         ▶ prepare_exit_to_usermode
>                         ▼ native_iret
>                           ▶ error_entry
>                           ▶ do_page_fault
>                           ▼ error_exit
>                             ▼ retint_user
>                               ▶ prepare_exit_to_usermode
>                               ▶ native_iret

T

 
>   After: (showing Call Path column only)
> 
>     Call Path
>     ▶ perf
>     ▼ ls
>       ▼ 12111:12111
>         ▶ setup_new_exec
>         ▶ __task_pid_nr_ns
>         ▶ perf_event_pid_type
>         ▶ perf_event_comm_output
>         ▶ perf_iterate_ctx
>         ▶ perf_iterate_sb
>         ▶ perf_event_comm
>         ▶ __set_task_comm
>         ▶ load_elf_binary
>         ▶ search_binary_handler
>         ▶ __do_execve_file.isra.41
>         ▶ __x64_sys_execve
>         ▶ do_syscall_64
>         ▶ entry_SYSCALL_64_after_hwframe
>         ▶ page_fault
>         ▼ entry_SYSCALL_64
>           ▼ do_syscall_64
>             ▶ __x64_sys_brk
>             ▶ __x64_sys_access
>             ▶ __x64_sys_openat
>             ▶ __x64_sys_newfstat
>             ▶ __x64_sys_mmap
>             ▶ __x64_sys_close
>             ▶ __x64_sys_read
>             ▶ __x64_sys_mprotect
>             ▶ __x64_sys_arch_prctl
>             ▶ __x64_sys_munmap
>             ▶ exit_to_usermode_loop
>             ▶ __x64_sys_set_tid_address
>             ▶ __x64_sys_set_robust_list
>             ▶ __x64_sys_rt_sigaction
>             ▶ __x64_sys_rt_sigprocmask
>             ▶ __x64_sys_prlimit64
>             ▶ __x64_sys_statfs
>             ▶ __x64_sys_ioctl
>             ▶ __x64_sys_getdents64
>             ▶ __x64_sys_write
>             ▶ __x64_sys_exit_group
> 
> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
> Fixes: f08046cb3082 ("perf thread-stack: Represent jmps to the start of a different symbol")
> Cc: stable@vger.kernel.org
> ---
>  tools/perf/util/thread-stack.c | 30 +++++++++++++++++++++++++++++-
>  1 file changed, 29 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/perf/util/thread-stack.c b/tools/perf/util/thread-stack.c
> index 8e390f78486f..f91c00dfe23b 100644
> --- a/tools/perf/util/thread-stack.c
> +++ b/tools/perf/util/thread-stack.c
> @@ -637,6 +637,23 @@ static int thread_stack__bottom(struct thread_stack *ts,
>  				     true, false);
>  }
>  
> +static int thread_stack__pop_ks(struct thread *thread, struct thread_stack *ts,
> +				struct perf_sample *sample, u64 ref)
> +{
> +	u64 tm = sample->time;
> +	int err;
> +
> +	/* Return to userspace, so pop all kernel addresses */
> +	while (thread_stack__in_kernel(ts)) {
> +		err = thread_stack__call_return(thread, ts, --ts->cnt,
> +						tm, ref, true);
> +		if (err)
> +			return err;
> +	}
> +
> +	return 0;
> +}
> +
>  static int thread_stack__no_call_return(struct thread *thread,
>  					struct thread_stack *ts,
>  					struct perf_sample *sample,
> @@ -919,7 +936,18 @@ int thread_stack__process(struct thread *thread, struct comm *comm,
>  			ts->rstate = X86_RETPOLINE_DETECTED;
>  
>  	} else if (sample->flags & PERF_IP_FLAG_RETURN) {
> -		if (!sample->ip || !sample->addr)
> +		if (!sample->addr) {
> +			u32 return_from_kernel = PERF_IP_FLAG_SYSCALLRET |
> +						 PERF_IP_FLAG_INTERRUPT;
> +
> +			if (!(sample->flags & return_from_kernel))
> +				return 0;
> +
> +			/* Pop kernel stack */
> +			return thread_stack__pop_ks(thread, ts, sample, ref);
> +		}
> +
> +		if (!sample->ip)
>  			return 0;
>  
>  		/* x86 retpoline 'return' doesn't match the stack */
> -- 
> 2.17.1

-- 

- Arnaldo

  reply	other threads:[~2019-06-24 18:40 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-19  6:44 [PATCH 0/2] perf thread-stack: Fix thread stack return from kernel for kernel-only case Adrian Hunter
2019-06-19  6:44 ` [PATCH 1/2] " Adrian Hunter
2019-06-24 18:39   ` Arnaldo Carvalho de Melo [this message]
2019-07-03 14:01   ` [tip:perf/core] " tip-bot for Adrian Hunter
2019-06-19  6:44 ` [PATCH 2/2] perf thread-stack: Eliminate code duplicating thread_stack__pop_ks() Adrian Hunter
2019-07-03 14:02   ` [tip:perf/core] " tip-bot for Adrian Hunter
2019-06-24 18:44 ` [PATCH 0/2] perf thread-stack: Fix thread stack return from kernel for kernel-only case Arnaldo Carvalho de Melo

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=20190624183950.GA4181@kernel.org \
    --to=arnaldo.melo@gmail.com \
    --cc=adrian.hunter@intel.com \
    --cc=jolsa@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.