From 411ad22ecf0281d666a82aa7f4de90c70365da7d Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Tue, 2 May 2023 15:38:36 -0700 Subject: perf parse-events: Add pmu filter To support the cputype argument added to "perf stat" for hybrid it is necessary to filter events during wildcard matching. Add a scanner argument for the filter and checking it when wildcard matching. Signed-off-by: Ian Rogers Tested-by: Kan Liang Cc: Adrian Hunter Cc: Ahmad Yasin Cc: Alexander Shishkin Cc: Andi Kleen Cc: Athira Rajeev Cc: Caleb Biggers Cc: Edward Baker Cc: Florian Fischer Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: John Garry Cc: Kajol Jain Cc: Kang Minchul Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Perry Taylor Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Rob Herring Cc: Samantha Alt Cc: Stephane Eranian Cc: Sumanth Korikkar Cc: Suzuki Poulouse Cc: Thomas Richter Cc: Tiezhu Yang Cc: Weilin Wang Cc: Xing Zhengjun Cc: Yang Jihong Link: https://lore.kernel.org/r/20230502223851.2234828-30-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'tools/perf/builtin-trace.c') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 8ee3a45c3c54..b49d3abb1203 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -4591,8 +4591,11 @@ do_concat: err = 0; if (lists[0]) { + struct parse_events_option_args parse_events_option_args = { + .evlistp = &trace->evlist, + }; struct option o = { - .value = &trace->evlist, + .value = &parse_events_option_args, }; err = parse_events_option(&o, lists[0], 0); } -- cgit From 60995604d11a5588ddd813030e2adc3b77e9af50 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Fri, 26 May 2023 11:33:49 -0700 Subject: perf trace: Make some large static arrays const to move it to .data.rel.ro Allows the movement of 33,128 bytes from .data to .data.rel.ro. Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ingo Molnar Cc: Jiri Olsa Cc: K Prateek Nayak Cc: Kan Liang Cc: Leo Yan Cc: Mark Rutland Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Paolo Bonzini Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Ross Zwisler Cc: Sean Christopherson Cc: Steven Rostedt (VMware) Cc: Tiezhu Yang Cc: Yang Jihong Link: https://lore.kernel.org/r/20230526183401.2326121-5-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'tools/perf/builtin-trace.c') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index b49d3abb1203..62c7c99a0fe4 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -914,7 +914,7 @@ static size_t syscall_arg__scnprintf_getrandom_flags(char *bf, size_t size, #include "trace/beauty/socket_type.c" #include "trace/beauty/waitid_options.c" -static struct syscall_fmt syscall_fmts[] = { +static const struct syscall_fmt syscall_fmts[] = { { .name = "access", .arg = { [1] = { .scnprintf = SCA_ACCMODE, /* mode */ }, }, }, { .name = "arch_prctl", @@ -1176,18 +1176,21 @@ static int syscall_fmt__cmp(const void *name, const void *fmtp) return strcmp(name, fmt->name); } -static struct syscall_fmt *__syscall_fmt__find(struct syscall_fmt *fmts, const int nmemb, const char *name) +static const struct syscall_fmt *__syscall_fmt__find(const struct syscall_fmt *fmts, + const int nmemb, + const char *name) { return bsearch(name, fmts, nmemb, sizeof(struct syscall_fmt), syscall_fmt__cmp); } -static struct syscall_fmt *syscall_fmt__find(const char *name) +static const struct syscall_fmt *syscall_fmt__find(const char *name) { const int nmemb = ARRAY_SIZE(syscall_fmts); return __syscall_fmt__find(syscall_fmts, nmemb, name); } -static struct syscall_fmt *__syscall_fmt__find_by_alias(struct syscall_fmt *fmts, const int nmemb, const char *alias) +static const struct syscall_fmt *__syscall_fmt__find_by_alias(const struct syscall_fmt *fmts, + const int nmemb, const char *alias) { int i; @@ -1199,7 +1202,7 @@ static struct syscall_fmt *__syscall_fmt__find_by_alias(struct syscall_fmt *fmts return NULL; } -static struct syscall_fmt *syscall_fmt__find_by_alias(const char *alias) +static const struct syscall_fmt *syscall_fmt__find_by_alias(const char *alias) { const int nmemb = ARRAY_SIZE(syscall_fmts); return __syscall_fmt__find_by_alias(syscall_fmts, nmemb, alias); @@ -1224,7 +1227,7 @@ struct syscall { bool nonexistent; struct tep_format_field *args; const char *name; - struct syscall_fmt *fmt; + const struct syscall_fmt *fmt; struct syscall_arg_fmt *arg_fmt; }; @@ -1673,7 +1676,7 @@ static int syscall__alloc_arg_fmts(struct syscall *sc, int nr_args) return 0; } -static struct syscall_arg_fmt syscall_arg_fmts__by_name[] = { +static const struct syscall_arg_fmt syscall_arg_fmts__by_name[] = { { .name = "msr", .scnprintf = SCA_X86_MSR, .strtoul = STUL_X86_MSR, }, { .name = "vector", .scnprintf = SCA_X86_IRQ_VECTORS, .strtoul = STUL_X86_IRQ_VECTORS, }, }; @@ -1684,13 +1687,14 @@ static int syscall_arg_fmt__cmp(const void *name, const void *fmtp) return strcmp(name, fmt->name); } -static struct syscall_arg_fmt * -__syscall_arg_fmt__find_by_name(struct syscall_arg_fmt *fmts, const int nmemb, const char *name) +static const struct syscall_arg_fmt * +__syscall_arg_fmt__find_by_name(const struct syscall_arg_fmt *fmts, const int nmemb, + const char *name) { return bsearch(name, fmts, nmemb, sizeof(struct syscall_arg_fmt), syscall_arg_fmt__cmp); } -static struct syscall_arg_fmt *syscall_arg_fmt__find_by_name(const char *name) +static const struct syscall_arg_fmt *syscall_arg_fmt__find_by_name(const char *name) { const int nmemb = ARRAY_SIZE(syscall_arg_fmts__by_name); return __syscall_arg_fmt__find_by_name(syscall_arg_fmts__by_name, nmemb, name); @@ -1735,8 +1739,9 @@ syscall_arg_fmt__init_array(struct syscall_arg_fmt *arg, struct tep_format_field * 7 unsigned long */ arg->scnprintf = SCA_FD; - } else { - struct syscall_arg_fmt *fmt = syscall_arg_fmt__find_by_name(field->name); + } else { + const struct syscall_arg_fmt *fmt = + syscall_arg_fmt__find_by_name(field->name); if (fmt) { arg->scnprintf = fmt->scnprintf; @@ -4458,7 +4463,7 @@ static void evsel__set_syscall_arg_fmt(struct evsel *evsel, const char *name) struct syscall_arg_fmt *fmt = evsel__syscall_arg_fmt(evsel); if (fmt) { - struct syscall_fmt *scfmt = syscall_fmt__find(name); + const struct syscall_fmt *scfmt = syscall_fmt__find(name); if (scfmt) { int skip = 0; @@ -4525,7 +4530,7 @@ static int trace__parse_events_option(const struct option *opt, const char *str, int len = strlen(str) + 1, err = -1, list, idx; char *strace_groups_dir = system_path(STRACE_GROUPS_DIR); char group_name[PATH_MAX]; - struct syscall_fmt *fmt; + const struct syscall_fmt *fmt; if (strace_groups_dir == NULL) return -1; -- cgit From 7ee227f674028435c01cb6fa02fa268ae48b1823 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Thu, 8 Jun 2023 16:27:59 -0700 Subject: perf thread: Make threads rbtree non-invasive Separate the rbtree out of thread and into a new struct thread_rb_node. The refcnt is in thread and the rbtree is responsible for a single count. Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Ali Saidi Cc: Andi Kleen Cc: Athira Rajeev Cc: Brian Robbins Cc: Changbin Du Cc: Dmitrii Dolgov <9erthalion6@gmail.com> Cc: Fangrui Song Cc: German Gomez Cc: Ingo Molnar Cc: Ivan Babrou Cc: James Clark Cc: Jing Zhang Cc: Jiri Olsa Cc: John Garry Cc: K Prateek Nayak Cc: Kan Liang Cc: Leo Yan Cc: Liam Howlett Cc: Mark Rutland Cc: Miguel Ojeda Cc: Mike Leach Cc: Namhyung Kim Cc: Naveen N. Rao Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Sean Christopherson Cc: Steinar H. Gunderson Cc: Suzuki Poulouse Cc: Wenyu Liu Cc: Will Deacon Cc: Yang Jihong Cc: Ye Xingchen Cc: Yuan Can Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: https://lore.kernel.org/r/20230608232823.4027869-3-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/perf/builtin-trace.c') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 62c7c99a0fe4..b0dd202d14eb 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -4348,7 +4348,7 @@ DEFINE_RESORT_RB(threads, (thread__nr_events(a->thread->priv) < thread__nr_event struct thread *thread; ) { - entry->thread = rb_entry(nd, struct thread, rb_node); + entry->thread = rb_entry(nd, struct thread_rb_node, rb_node)->thread; } static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp) -- cgit From ee84a3032b74055feed192a727e872b0a18d1140 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Thu, 8 Jun 2023 16:28:00 -0700 Subject: perf thread: Add accessor functions for thread Using accessors will make it easier to add reference count checking in later patches. Committer notes: thread->nsinfo wasn't wrapped as it is used together with nsinfo__zput(), where does a trick to set the field with a refcount being dropped to NULL, and that doesn't work well with using thread__nsinfo(thread), that loses the &thread->nsinfo pointer. When refcount checking is added to 'struct thread', later in this series, nsinfo__zput(RC_CHK_ACCESS(thread)->nsinfo) will be used to check the thread pointer. Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Ali Saidi Cc: Andi Kleen Cc: Athira Rajeev Cc: Brian Robbins Cc: Changbin Du Cc: Dmitrii Dolgov <9erthalion6@gmail.com> Cc: Fangrui Song Cc: German Gomez Cc: Ingo Molnar Cc: Ivan Babrou Cc: James Clark Cc: Jing Zhang Cc: Jiri Olsa Cc: John Garry Cc: K Prateek Nayak Cc: Kan Liang Cc: Leo Yan Cc: Liam Howlett Cc: Mark Rutland Cc: Miguel Ojeda Cc: Mike Leach Cc: Namhyung Kim Cc: Naveen N. Rao Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Sean Christopherson Cc: Steinar H. Gunderson Cc: Suzuki Poulouse Cc: Wenyu Liu Cc: Will Deacon Cc: Yang Jihong Cc: Ye Xingchen Cc: Yuan Can Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: https://lore.kernel.org/r/20230608232823.4027869-4-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'tools/perf/builtin-trace.c') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index b0dd202d14eb..4c9bec39423b 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1386,12 +1386,13 @@ static int thread__read_fd_path(struct thread *thread, int fd) struct stat st; int ret; - if (thread->pid_ == thread->tid) { + if (thread__pid(thread) == thread__tid(thread)) { scnprintf(linkname, sizeof(linkname), - "/proc/%d/fd/%d", thread->pid_, fd); + "/proc/%d/fd/%d", thread__pid(thread), fd); } else { scnprintf(linkname, sizeof(linkname), - "/proc/%d/task/%d/fd/%d", thread->pid_, thread->tid, fd); + "/proc/%d/task/%d/fd/%d", + thread__pid(thread), thread__tid(thread), fd); } if (lstat(linkname, &st) < 0 || st.st_size + 1 > (off_t)sizeof(pathname)) @@ -1559,7 +1560,7 @@ static size_t trace__fprintf_comm_tid(struct trace *trace, struct thread *thread if (trace->multiple_threads) { if (trace->show_comm) printed += fprintf(fp, "%.14s/", thread__comm_str(thread)); - printed += fprintf(fp, "%d ", thread->tid); + printed += fprintf(fp, "%d ", thread__tid(thread)); } return printed; @@ -2205,7 +2206,8 @@ static void thread__update_stats(struct thread *thread, struct thread_trace *ttr memset(new_errnos + stats->max_errno, 0, (err - stats->max_errno) * sizeof(u32)); } else { pr_debug("Not enough memory for errno stats for thread \"%s\"(%d/%d), results will be incomplete\n", - thread__comm_str(thread), thread->pid_, thread->tid); + thread__comm_str(thread), thread__pid(thread), + thread__tid(thread)); return; } @@ -2550,7 +2552,7 @@ errno_print: { if (child != NULL) { fprintf(trace->output, "%ld", ret); - if (child->comm_set) + if (thread__comm_set(child)) fprintf(trace->output, " (%s)", thread__comm_str(child)); thread__put(child); } @@ -3616,14 +3618,16 @@ static int trace__set_filter_loop_pids(struct trace *trace) struct thread *thread = machine__find_thread(trace->host, pids[0], pids[0]); while (thread && nr < ARRAY_SIZE(pids)) { - struct thread *parent = machine__find_thread(trace->host, thread->ppid, thread->ppid); + struct thread *parent = machine__find_thread(trace->host, + thread__ppid(thread), + thread__ppid(thread)); if (parent == NULL) break; if (!strcmp(thread__comm_str(parent), "sshd") || strstarts(thread__comm_str(parent), "gnome-terminal")) { - pids[nr++] = parent->tid; + pids[nr++] = thread__tid(parent); break; } thread = parent; @@ -4322,7 +4326,7 @@ static size_t trace__fprintf_thread(FILE *fp, struct thread *thread, struct trac ratio = (double)ttrace->nr_events / trace->nr_events * 100.0; - printed += fprintf(fp, " %s (%d), ", thread__comm_str(thread), thread->tid); + printed += fprintf(fp, " %s (%d), ", thread__comm_str(thread), thread__tid(thread)); printed += fprintf(fp, "%lu events, ", ttrace->nr_events); printed += fprintf(fp, "%.1f%%", ratio); if (ttrace->pfmaj) @@ -4344,7 +4348,9 @@ static unsigned long thread__nr_events(struct thread_trace *ttrace) return ttrace ? ttrace->nr_events : 0; } -DEFINE_RESORT_RB(threads, (thread__nr_events(a->thread->priv) < thread__nr_events(b->thread->priv)), +DEFINE_RESORT_RB(threads, + (thread__nr_events(thread__priv(a->thread)) < + thread__nr_events(thread__priv(b->thread))), struct thread *thread; ) { -- cgit From 0dd5041c9a0eaf8c5c3fd46df4ee60f877799f44 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Thu, 8 Jun 2023 16:28:03 -0700 Subject: perf addr_location: Add init/exit/copy functions struct addr_location holds references to multiple reference counted objects. Add init/exit functions to make maintenance of those more consistent with the rest of the code and to try to avoid leaks. Modification of thread reference counts isn't included in this change. Committer notes: I needed to initialize result to sample->ip to make sure is set to something, fixing a compile time error, mostly keeping the previous logic as build_alloc_func_list() already does debugging/error prints about what went wrong if it takes the 'goto out'. Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Ali Saidi Cc: Andi Kleen Cc: Athira Rajeev Cc: Brian Robbins Cc: Changbin Du Cc: Dmitrii Dolgov <9erthalion6@gmail.com> Cc: Fangrui Song Cc: German Gomez Cc: Ingo Molnar Cc: Ivan Babrou Cc: James Clark Cc: Jing Zhang Cc: Jiri Olsa Cc: John Garry Cc: K Prateek Nayak Cc: Kan Liang Cc: Leo Yan Cc: Liam Howlett Cc: Mark Rutland Cc: Miguel Ojeda Cc: Mike Leach Cc: Namhyung Kim Cc: Naveen N. Rao Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Sean Christopherson Cc: Steinar H. Gunderson Cc: Suzuki Poulouse Cc: Wenyu Liu Cc: Will Deacon Cc: Yang Jihong Cc: Ye Xingchen Cc: Yuan Can Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: https://lore.kernel.org/r/20230608232823.4027869-7-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'tools/perf/builtin-trace.c') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 4c9bec39423b..6a1e75f06832 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2418,13 +2418,15 @@ static int trace__resolve_callchain(struct trace *trace, struct evsel *evsel, int max_stack = evsel->core.attr.sample_max_stack ? evsel->core.attr.sample_max_stack : trace->max_stack; - int err; + int err = -1; + addr_location__init(&al); if (machine__resolve(trace->host, &al, sample) < 0) - return -1; + goto out; err = thread__resolve_callchain(al.thread, cursor, evsel, sample, NULL, NULL, max_stack); - addr_location__put(&al); +out: + addr_location__exit(&al); return err; } @@ -2893,6 +2895,7 @@ static int trace__pgfault(struct trace *trace, int err = -1; int callchain_ret = 0; + addr_location__init(&al); thread = machine__findnew_thread(trace->host, sample->pid, sample->tid); if (sample->callchain) { @@ -2953,6 +2956,7 @@ out: err = 0; out_put: thread__put(thread); + addr_location__exit(&al); return err; } -- cgit From 8ab12a2038e36beda4062a8e7562a8cfe9655553 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Thu, 8 Jun 2023 16:28:21 -0700 Subject: perf callchain: Use pthread keys for tls callchain_cursor Pthread keys are more portable than __thread and allow the association of a destructor with the key. Use the destructor to clean up TLS callchain cursors to aid understanding memory leaks. Committer notes: Had to fixup a series of unconverted places and also check for the return of get_tls_callchain_cursor() as it may fail and return NULL. In that unlikely case we now either print something to a file, if the caller was expecting to print a callchain, or return an error code to state that resolving the callchain isn't possible. In some cases this was made easier because thread__resolve_callchain() already can fail for other reasons, so this new one (cursor == NULL) can be added and the callers don't have to explicitely check for this new condition. Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Ali Saidi Cc: Andi Kleen Cc: Athira Rajeev Cc: Brian Robbins Cc: Changbin Du Cc: Dmitrii Dolgov <9erthalion6@gmail.com> Cc: Fangrui Song Cc: German Gomez Cc: Ingo Molnar Cc: Ivan Babrou Cc: James Clark Cc: Jing Zhang Cc: Jiri Olsa Cc: John Garry Cc: K Prateek Nayak Cc: Kan Liang Cc: Leo Yan Cc: Liam Howlett Cc: Mark Rutland Cc: Miguel Ojeda Cc: Mike Leach Cc: Namhyung Kim Cc: Naveen N. Rao Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Sean Christopherson Cc: Steinar H. Gunderson Cc: Suzuki Poulouse Cc: Wenyu Liu Cc: Will Deacon Cc: Yang Jihong Cc: Ye Xingchen Cc: Yuan Can Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: https://lore.kernel.org/r/20230608232823.4027869-25-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'tools/perf/builtin-trace.c') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 6a1e75f06832..6e73d0e95715 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2437,7 +2437,7 @@ static int trace__fprintf_callchain(struct trace *trace, struct perf_sample *sam EVSEL__PRINT_DSO | EVSEL__PRINT_UNKNOWN_AS_ADDR; - return sample__fprintf_callchain(sample, 38, print_opts, &callchain_cursor, symbol_conf.bt_stop_list, trace->output); + return sample__fprintf_callchain(sample, 38, print_opts, get_tls_callchain_cursor(), symbol_conf.bt_stop_list, trace->output); } static const char *errno_to_name(struct evsel *evsel, int err) @@ -2491,9 +2491,11 @@ static int trace__sys_exit(struct trace *trace, struct evsel *evsel, goto out; if (sample->callchain) { - callchain_ret = trace__resolve_callchain(trace, evsel, sample, &callchain_cursor); + struct callchain_cursor *cursor = get_tls_callchain_cursor(); + + callchain_ret = trace__resolve_callchain(trace, evsel, sample, cursor); if (callchain_ret == 0) { - if (callchain_cursor.nr < trace->min_stack) + if (cursor->nr < trace->min_stack) goto out; callchain_ret = 1; } @@ -2795,9 +2797,11 @@ static int trace__event_handler(struct trace *trace, struct evsel *evsel, thread = machine__findnew_thread(trace->host, sample->pid, sample->tid); if (sample->callchain) { - callchain_ret = trace__resolve_callchain(trace, evsel, sample, &callchain_cursor); + struct callchain_cursor *cursor = get_tls_callchain_cursor(); + + callchain_ret = trace__resolve_callchain(trace, evsel, sample, cursor); if (callchain_ret == 0) { - if (callchain_cursor.nr < trace->min_stack) + if (cursor->nr < trace->min_stack) goto out; callchain_ret = 1; } @@ -2899,9 +2903,11 @@ static int trace__pgfault(struct trace *trace, thread = machine__findnew_thread(trace->host, sample->pid, sample->tid); if (sample->callchain) { - callchain_ret = trace__resolve_callchain(trace, evsel, sample, &callchain_cursor); + struct callchain_cursor *cursor = get_tls_callchain_cursor(); + + callchain_ret = trace__resolve_callchain(trace, evsel, sample, cursor); if (callchain_ret == 0) { - if (callchain_cursor.nr < trace->min_stack) + if (cursor->nr < trace->min_stack) goto out_put; callchain_ret = 1; } -- cgit