Skip to content

Commit 9c6c3f4

Browse files
Kan Liangacmel
authored andcommitted
perf thread: Save previous sample for LBR stitching approach
To retrieve the overwritten LBRs from previous sample for LBR stitching approach, perf has to save the previous sample. Only allocate the struct lbr_stitch once, when LBR stitching approach is enabled and kernel supports hw_idx. Signed-off-by: Kan Liang <[email protected]> Reviewed-by: Andi Kleen <[email protected]> Acked-by: Jiri Olsa <[email protected]> Cc: Adrian Hunter <[email protected]> Cc: Alexey Budankov <[email protected]> Cc: Mathieu Poirier <[email protected]> Cc: Michael Ellerman <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Pavel Gerasimov <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Ravi Bangoria <[email protected]> Cc: Stephane Eranian <[email protected]> Cc: Vitaly Slobodskoy <[email protected]> Link: http://lore.kernel.org/lkml/[email protected] [ Use zalloc()/zfree() for thread->lbr_stitch ] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 771fd15 commit 9c6c3f4

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed

tools/perf/util/machine.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2292,6 +2292,21 @@ static int lbr_callchain_add_lbr_ip(struct thread *thread,
22922292
return 0;
22932293
}
22942294

2295+
static bool alloc_lbr_stitch(struct thread *thread)
2296+
{
2297+
if (thread->lbr_stitch)
2298+
return true;
2299+
2300+
thread->lbr_stitch = zalloc(sizeof(*thread->lbr_stitch));
2301+
if (!thread->lbr_stitch)
2302+
goto err;
2303+
2304+
err:
2305+
pr_warning("Failed to allocate space for stitched LBRs. Disable LBR stitch\n");
2306+
thread->lbr_stitch_enable = false;
2307+
return false;
2308+
}
2309+
22952310
/*
22962311
* Recolve LBR callstack chain sample
22972312
* Return:
@@ -2308,6 +2323,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread,
23082323
{
23092324
struct ip_callchain *chain = sample->callchain;
23102325
int chain_nr = min(max_stack, (int)chain->nr), i;
2326+
struct lbr_stitch *lbr_stitch;
23112327
u64 branch_from = 0;
23122328
int err;
23132329

@@ -2320,6 +2336,13 @@ static int resolve_lbr_callchain_sample(struct thread *thread,
23202336
if (i == chain_nr)
23212337
return 0;
23222338

2339+
if (thread->lbr_stitch_enable && !sample->no_hw_idx &&
2340+
alloc_lbr_stitch(thread)) {
2341+
lbr_stitch = thread->lbr_stitch;
2342+
2343+
memcpy(&lbr_stitch->prev_sample, sample, sizeof(*sample));
2344+
}
2345+
23232346
if (callchain_param.order == ORDER_CALLEE) {
23242347
/* Add kernel ip */
23252348
err = lbr_callchain_add_kernel_ip(thread, cursor, sample,

tools/perf/util/thread.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ void thread__delete(struct thread *thread)
111111

112112
exit_rwsem(&thread->namespaces_lock);
113113
exit_rwsem(&thread->comm_lock);
114+
thread__free_stitch_list(thread);
114115
free(thread);
115116
}
116117

tools/perf/util/thread.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <linux/refcount.h>
66
#include <linux/rbtree.h>
77
#include <linux/list.h>
8+
#include <linux/zalloc.h>
89
#include <stdio.h>
910
#include <unistd.h>
1011
#include <sys/types.h>
@@ -13,13 +14,18 @@
1314
#include <strlist.h>
1415
#include <intlist.h>
1516
#include "rwsem.h"
17+
#include "event.h"
1618

1719
struct addr_location;
1820
struct map;
1921
struct perf_record_namespaces;
2022
struct thread_stack;
2123
struct unwind_libunwind_ops;
2224

25+
struct lbr_stitch {
26+
struct perf_sample prev_sample;
27+
};
28+
2329
struct thread {
2430
union {
2531
struct rb_node rb_node;
@@ -49,6 +55,7 @@ struct thread {
4955

5056
/* LBR call stack stitch */
5157
bool lbr_stitch_enable;
58+
struct lbr_stitch *lbr_stitch;
5259
};
5360

5461
struct machine;
@@ -145,4 +152,9 @@ static inline bool thread__is_filtered(struct thread *thread)
145152
return false;
146153
}
147154

155+
static inline void thread__free_stitch_list(struct thread *thread)
156+
{
157+
zfree(&thread->lbr_stitch);
158+
}
159+
148160
#endif /* __PERF_THREAD_H */

0 commit comments

Comments
 (0)