Skip to content

Commit 02b2705

Browse files
captain5050acmel
authored andcommitted
perf callchain: Allow symbols to be optional when resolving a callchain
In uses like 'perf inject' it is not necessary to gather the symbol for each call chain location, the map for the sample IP is wanted so that build IDs and the like can be injected. Make gathering the symbol in the callchain_cursor optional. For a 'perf inject -B' command this lowers the peak RSS from 54.1MB to 29.6MB by avoiding loading symbols. Signed-off-by: Ian Rogers <[email protected]> Acked-by: Namhyung Kim <[email protected]> Cc: Adrian Hunter <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Anne Macedo <[email protected]> Cc: Casey Chen <[email protected]> Cc: Colin Ian King <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Kan Liang <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Sun Haiyong <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 64eed01 commit 02b2705

File tree

5 files changed

+85
-52
lines changed

5 files changed

+85
-52
lines changed

tools/perf/builtin-inject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -942,7 +942,7 @@ int perf_event__inject_buildid(const struct perf_tool *tool, union perf_event *e
942942
}
943943

944944
sample__for_each_callchain_node(thread, evsel, sample, PERF_MAX_STACK_DEPTH,
945-
mark_dso_hit_callback, &args);
945+
/*symbols=*/false, mark_dso_hit_callback, &args);
946946

947947
thread__put(thread);
948948
repipe:

tools/perf/util/callchain.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1800,7 +1800,7 @@ s64 callchain_avg_cycles(struct callchain_node *cnode)
18001800

18011801
int sample__for_each_callchain_node(struct thread *thread, struct evsel *evsel,
18021802
struct perf_sample *sample, int max_stack,
1803-
callchain_iter_fn cb, void *data)
1803+
bool symbols, callchain_iter_fn cb, void *data)
18041804
{
18051805
struct callchain_cursor *cursor = get_tls_callchain_cursor();
18061806
int ret;
@@ -1809,9 +1809,9 @@ int sample__for_each_callchain_node(struct thread *thread, struct evsel *evsel,
18091809
return -ENOMEM;
18101810

18111811
/* Fill in the callchain. */
1812-
ret = thread__resolve_callchain(thread, cursor, evsel, sample,
1813-
/*parent=*/NULL, /*root_al=*/NULL,
1814-
max_stack);
1812+
ret = __thread__resolve_callchain(thread, cursor, evsel, sample,
1813+
/*parent=*/NULL, /*root_al=*/NULL,
1814+
max_stack, symbols);
18151815
if (ret)
18161816
return ret;
18171817

tools/perf/util/callchain.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,6 @@ typedef int (*callchain_iter_fn)(struct callchain_cursor_node *node, void *data)
315315

316316
int sample__for_each_callchain_node(struct thread *thread, struct evsel *evsel,
317317
struct perf_sample *sample, int max_stack,
318-
callchain_iter_fn cb, void *data);
318+
bool symbols, callchain_iter_fn cb, void *data);
319319

320320
#endif /* __PERF_CALLCHAIN_H */

tools/perf/util/machine.c

Lines changed: 53 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2060,7 +2060,8 @@ static int add_callchain_ip(struct thread *thread,
20602060
bool branch,
20612061
struct branch_flags *flags,
20622062
struct iterations *iter,
2063-
u64 branch_from)
2063+
u64 branch_from,
2064+
bool symbols)
20642065
{
20652066
struct map_symbol ms = {};
20662067
struct addr_location al;
@@ -2099,7 +2100,8 @@ static int add_callchain_ip(struct thread *thread,
20992100
}
21002101
goto out;
21012102
}
2102-
thread__find_symbol(thread, *cpumode, ip, &al);
2103+
if (symbols)
2104+
thread__find_symbol(thread, *cpumode, ip, &al);
21032105
}
21042106

21052107
if (al.sym != NULL) {
@@ -2228,7 +2230,8 @@ static int lbr_callchain_add_kernel_ip(struct thread *thread,
22282230
struct symbol **parent,
22292231
struct addr_location *root_al,
22302232
u64 branch_from,
2231-
bool callee, int end)
2233+
bool callee, int end,
2234+
bool symbols)
22322235
{
22332236
struct ip_callchain *chain = sample->callchain;
22342237
u8 cpumode = PERF_RECORD_MISC_USER;
@@ -2238,7 +2241,8 @@ static int lbr_callchain_add_kernel_ip(struct thread *thread,
22382241
for (i = 0; i < end + 1; i++) {
22392242
err = add_callchain_ip(thread, cursor, parent,
22402243
root_al, &cpumode, chain->ips[i],
2241-
false, NULL, NULL, branch_from);
2244+
false, NULL, NULL, branch_from,
2245+
symbols);
22422246
if (err)
22432247
return err;
22442248
}
@@ -2248,7 +2252,8 @@ static int lbr_callchain_add_kernel_ip(struct thread *thread,
22482252
for (i = end; i >= 0; i--) {
22492253
err = add_callchain_ip(thread, cursor, parent,
22502254
root_al, &cpumode, chain->ips[i],
2251-
false, NULL, NULL, branch_from);
2255+
false, NULL, NULL, branch_from,
2256+
symbols);
22522257
if (err)
22532258
return err;
22542259
}
@@ -2291,7 +2296,8 @@ static int lbr_callchain_add_lbr_ip(struct thread *thread,
22912296
struct symbol **parent,
22922297
struct addr_location *root_al,
22932298
u64 *branch_from,
2294-
bool callee)
2299+
bool callee,
2300+
bool symbols)
22952301
{
22962302
struct branch_stack *lbr_stack = sample->branch_stack;
22972303
struct branch_entry *entries = perf_sample__branch_entries(sample);
@@ -2324,7 +2330,7 @@ static int lbr_callchain_add_lbr_ip(struct thread *thread,
23242330
err = add_callchain_ip(thread, cursor, parent,
23252331
root_al, &cpumode, ip,
23262332
true, flags, NULL,
2327-
*branch_from);
2333+
*branch_from, symbols);
23282334
if (err)
23292335
return err;
23302336

@@ -2349,7 +2355,7 @@ static int lbr_callchain_add_lbr_ip(struct thread *thread,
23492355
err = add_callchain_ip(thread, cursor, parent,
23502356
root_al, &cpumode, ip,
23512357
true, flags, NULL,
2352-
*branch_from);
2358+
*branch_from, symbols);
23532359
if (err)
23542360
return err;
23552361
save_lbr_cursor_node(thread, cursor, i);
@@ -2364,7 +2370,7 @@ static int lbr_callchain_add_lbr_ip(struct thread *thread,
23642370
err = add_callchain_ip(thread, cursor, parent,
23652371
root_al, &cpumode, ip,
23662372
true, flags, NULL,
2367-
*branch_from);
2373+
*branch_from, symbols);
23682374
if (err)
23692375
return err;
23702376
save_lbr_cursor_node(thread, cursor, i);
@@ -2378,7 +2384,7 @@ static int lbr_callchain_add_lbr_ip(struct thread *thread,
23782384
err = add_callchain_ip(thread, cursor, parent,
23792385
root_al, &cpumode, ip,
23802386
true, flags, NULL,
2381-
*branch_from);
2387+
*branch_from, symbols);
23822388
if (err)
23832389
return err;
23842390
}
@@ -2545,7 +2551,8 @@ static int resolve_lbr_callchain_sample(struct thread *thread,
25452551
struct symbol **parent,
25462552
struct addr_location *root_al,
25472553
int max_stack,
2548-
unsigned int max_lbr)
2554+
unsigned int max_lbr,
2555+
bool symbols)
25492556
{
25502557
bool callee = (callchain_param.order == ORDER_CALLEE);
25512558
struct ip_callchain *chain = sample->callchain;
@@ -2587,12 +2594,12 @@ static int resolve_lbr_callchain_sample(struct thread *thread,
25872594
/* Add kernel ip */
25882595
err = lbr_callchain_add_kernel_ip(thread, cursor, sample,
25892596
parent, root_al, branch_from,
2590-
true, i);
2597+
true, i, symbols);
25912598
if (err)
25922599
goto error;
25932600

25942601
err = lbr_callchain_add_lbr_ip(thread, cursor, sample, parent,
2595-
root_al, &branch_from, true);
2602+
root_al, &branch_from, true, symbols);
25962603
if (err)
25972604
goto error;
25982605

@@ -2609,14 +2616,14 @@ static int resolve_lbr_callchain_sample(struct thread *thread,
26092616
goto error;
26102617
}
26112618
err = lbr_callchain_add_lbr_ip(thread, cursor, sample, parent,
2612-
root_al, &branch_from, false);
2619+
root_al, &branch_from, false, symbols);
26132620
if (err)
26142621
goto error;
26152622

26162623
/* Add kernel ip */
26172624
err = lbr_callchain_add_kernel_ip(thread, cursor, sample,
26182625
parent, root_al, branch_from,
2619-
false, i);
2626+
false, i, symbols);
26202627
if (err)
26212628
goto error;
26222629
}
@@ -2630,7 +2637,7 @@ static int find_prev_cpumode(struct ip_callchain *chain, struct thread *thread,
26302637
struct callchain_cursor *cursor,
26312638
struct symbol **parent,
26322639
struct addr_location *root_al,
2633-
u8 *cpumode, int ent)
2640+
u8 *cpumode, int ent, bool symbols)
26342641
{
26352642
int err = 0;
26362643

@@ -2640,7 +2647,7 @@ static int find_prev_cpumode(struct ip_callchain *chain, struct thread *thread,
26402647
if (ip >= PERF_CONTEXT_MAX) {
26412648
err = add_callchain_ip(thread, cursor, parent,
26422649
root_al, cpumode, ip,
2643-
false, NULL, NULL, 0);
2650+
false, NULL, NULL, 0, symbols);
26442651
break;
26452652
}
26462653
}
@@ -2662,7 +2669,8 @@ static int thread__resolve_callchain_sample(struct thread *thread,
26622669
struct perf_sample *sample,
26632670
struct symbol **parent,
26642671
struct addr_location *root_al,
2665-
int max_stack)
2672+
int max_stack,
2673+
bool symbols)
26662674
{
26672675
struct branch_stack *branch = sample->branch_stack;
26682676
struct branch_entry *entries = perf_sample__branch_entries(sample);
@@ -2682,7 +2690,8 @@ static int thread__resolve_callchain_sample(struct thread *thread,
26822690

26832691
err = resolve_lbr_callchain_sample(thread, cursor, sample, parent,
26842692
root_al, max_stack,
2685-
!env ? 0 : env->max_branches);
2693+
!env ? 0 : env->max_branches,
2694+
symbols);
26862695
if (err)
26872696
return (err < 0) ? err : 0;
26882697
}
@@ -2747,13 +2756,14 @@ static int thread__resolve_callchain_sample(struct thread *thread,
27472756
root_al,
27482757
NULL, be[i].to,
27492758
true, &be[i].flags,
2750-
NULL, be[i].from);
2759+
NULL, be[i].from, symbols);
27512760

2752-
if (!err)
2761+
if (!err) {
27532762
err = add_callchain_ip(thread, cursor, parent, root_al,
27542763
NULL, be[i].from,
27552764
true, &be[i].flags,
2756-
&iter[i], 0);
2765+
&iter[i], 0, symbols);
2766+
}
27572767
if (err == -EINVAL)
27582768
break;
27592769
if (err)
@@ -2769,7 +2779,7 @@ static int thread__resolve_callchain_sample(struct thread *thread,
27692779
check_calls:
27702780
if (chain && callchain_param.order != ORDER_CALLEE) {
27712781
err = find_prev_cpumode(chain, thread, cursor, parent, root_al,
2772-
&cpumode, chain->nr - first_call);
2782+
&cpumode, chain->nr - first_call, symbols);
27732783
if (err)
27742784
return (err < 0) ? err : 0;
27752785
}
@@ -2791,7 +2801,7 @@ static int thread__resolve_callchain_sample(struct thread *thread,
27912801
++nr_entries;
27922802
else if (callchain_param.order != ORDER_CALLEE) {
27932803
err = find_prev_cpumode(chain, thread, cursor, parent,
2794-
root_al, &cpumode, j);
2804+
root_al, &cpumode, j, symbols);
27952805
if (err)
27962806
return (err < 0) ? err : 0;
27972807
continue;
@@ -2818,16 +2828,16 @@ static int thread__resolve_callchain_sample(struct thread *thread,
28182828
if (leaf_frame_caller && leaf_frame_caller != ip) {
28192829

28202830
err = add_callchain_ip(thread, cursor, parent,
2821-
root_al, &cpumode, leaf_frame_caller,
2822-
false, NULL, NULL, 0);
2831+
root_al, &cpumode, leaf_frame_caller,
2832+
false, NULL, NULL, 0, symbols);
28232833
if (err)
28242834
return (err < 0) ? err : 0;
28252835
}
28262836
}
28272837

28282838
err = add_callchain_ip(thread, cursor, parent,
28292839
root_al, &cpumode, ip,
2830-
false, NULL, NULL, 0);
2840+
false, NULL, NULL, 0, symbols);
28312841

28322842
if (err)
28332843
return (err < 0) ? err : 0;
@@ -2907,7 +2917,7 @@ static int thread__resolve_callchain_unwind(struct thread *thread,
29072917
struct callchain_cursor *cursor,
29082918
struct evsel *evsel,
29092919
struct perf_sample *sample,
2910-
int max_stack)
2920+
int max_stack, bool symbols)
29112921
{
29122922
/* Can we do dwarf post unwind? */
29132923
if (!((evsel->core.attr.sample_type & PERF_SAMPLE_REGS_USER) &&
@@ -2919,17 +2929,21 @@ static int thread__resolve_callchain_unwind(struct thread *thread,
29192929
(!sample->user_stack.size))
29202930
return 0;
29212931

2932+
if (!symbols)
2933+
pr_debug("Not resolving symbols with an unwinder isn't currently supported\n");
2934+
29222935
return unwind__get_entries(unwind_entry, cursor,
29232936
thread, sample, max_stack, false);
29242937
}
29252938

2926-
int thread__resolve_callchain(struct thread *thread,
2927-
struct callchain_cursor *cursor,
2928-
struct evsel *evsel,
2929-
struct perf_sample *sample,
2930-
struct symbol **parent,
2931-
struct addr_location *root_al,
2932-
int max_stack)
2939+
int __thread__resolve_callchain(struct thread *thread,
2940+
struct callchain_cursor *cursor,
2941+
struct evsel *evsel,
2942+
struct perf_sample *sample,
2943+
struct symbol **parent,
2944+
struct addr_location *root_al,
2945+
int max_stack,
2946+
bool symbols)
29332947
{
29342948
int ret = 0;
29352949

@@ -2942,22 +2956,22 @@ int thread__resolve_callchain(struct thread *thread,
29422956
ret = thread__resolve_callchain_sample(thread, cursor,
29432957
evsel, sample,
29442958
parent, root_al,
2945-
max_stack);
2959+
max_stack, symbols);
29462960
if (ret)
29472961
return ret;
29482962
ret = thread__resolve_callchain_unwind(thread, cursor,
29492963
evsel, sample,
2950-
max_stack);
2964+
max_stack, symbols);
29512965
} else {
29522966
ret = thread__resolve_callchain_unwind(thread, cursor,
29532967
evsel, sample,
2954-
max_stack);
2968+
max_stack, symbols);
29552969
if (ret)
29562970
return ret;
29572971
ret = thread__resolve_callchain_sample(thread, cursor,
29582972
evsel, sample,
29592973
parent, root_al,
2960-
max_stack);
2974+
max_stack, symbols);
29612975
}
29622976

29632977
return ret;

tools/perf/util/machine.h

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -178,13 +178,32 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample,
178178

179179
struct callchain_cursor;
180180

181-
int thread__resolve_callchain(struct thread *thread,
182-
struct callchain_cursor *cursor,
183-
struct evsel *evsel,
184-
struct perf_sample *sample,
185-
struct symbol **parent,
186-
struct addr_location *root_al,
187-
int max_stack);
181+
int __thread__resolve_callchain(struct thread *thread,
182+
struct callchain_cursor *cursor,
183+
struct evsel *evsel,
184+
struct perf_sample *sample,
185+
struct symbol **parent,
186+
struct addr_location *root_al,
187+
int max_stack,
188+
bool symbols);
189+
190+
static inline int thread__resolve_callchain(struct thread *thread,
191+
struct callchain_cursor *cursor,
192+
struct evsel *evsel,
193+
struct perf_sample *sample,
194+
struct symbol **parent,
195+
struct addr_location *root_al,
196+
int max_stack)
197+
{
198+
return __thread__resolve_callchain(thread,
199+
cursor,
200+
evsel,
201+
sample,
202+
parent,
203+
root_al,
204+
max_stack,
205+
/*symbols=*/true);
206+
}
188207

189208
/*
190209
* Default guest kernel is defined by parameter --guestkallsyms

0 commit comments

Comments
 (0)