Skip to content

Commit d3aaf09

Browse files
author
Ingo Molnar
committed
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: New features: - Add 'L' hotkey to dynamicly set the percent threshold for histogram entries and callchains, i.e. dynamicly do what the --percent-limit command line option to 'top' and 'report' does. (Namhyung Kim) Infrastructure changes: - Per hists field and sort lists, that will be used, for instance, in the c2c tool (Jiri Olsa) Documentation changes: - Update documentation of --sort and --perf-limit options for 'perf report' (Namhyung Kim) Signed-off-by: Arnaldo Carvalho de Melo <[email protected]> Signed-off-by: Ingo Molnar <[email protected]>
2 parents b83ea91 + b62e8df commit d3aaf09

File tree

14 files changed

+425
-236
lines changed

14 files changed

+425
-236
lines changed

tools/perf/Documentation/perf-report.txt

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,22 @@ OPTIONS
117117
And default sort keys are changed to comm, dso_from, symbol_from, dso_to
118118
and symbol_to, see '--branch-stack'.
119119

120+
If the --mem-mode option is used, the following sort keys are also available
121+
(incompatible with --branch-stack):
122+
symbol_daddr, dso_daddr, locked, tlb, mem, snoop, dcacheline.
123+
124+
- symbol_daddr: name of data symbol being executed on at the time of sample
125+
- dso_daddr: name of library or module containing the data being executed
126+
on at the time of the sample
127+
- locked: whether the bus was locked at the time of the sample
128+
- tlb: type of tlb access for the data at the time of the sample
129+
- mem: type of memory access for the data at the time of the sample
130+
- snoop: type of snoop (if any) for the data at the time of the sample
131+
- dcacheline: the cacheline the data address is on at the time of the sample
132+
133+
And the default sort keys are changed to local_weight, mem, sym, dso,
134+
symbol_daddr, dso_daddr, snoop, tlb, locked, see '--mem-mode'.
135+
120136
If the data file has tracepoint event(s), following (dynamic) sort keys
121137
are also available:
122138
trace, trace_fields, [<event>.]<field>[/raw]
@@ -151,22 +167,6 @@ OPTIONS
151167
By default, every sort keys not specified in -F will be appended
152168
automatically.
153169

154-
If --mem-mode option is used, following sort keys are also available
155-
(incompatible with --branch-stack):
156-
symbol_daddr, dso_daddr, locked, tlb, mem, snoop, dcacheline.
157-
158-
- symbol_daddr: name of data symbol being executed on at the time of sample
159-
- dso_daddr: name of library or module containing the data being executed
160-
on at the time of sample
161-
- locked: whether the bus was locked at the time of sample
162-
- tlb: type of tlb access for the data at the time of sample
163-
- mem: type of memory access for the data at the time of sample
164-
- snoop: type of snoop (if any) for the data at the time of sample
165-
- dcacheline: the cacheline the data address is on at the time of sample
166-
167-
And default sort keys are changed to local_weight, mem, sym, dso,
168-
symbol_daddr, dso_daddr, snoop, tlb, locked, see '--mem-mode'.
169-
170170
-p::
171171
--parent=<regex>::
172172
A regex filter to identify parent. The parent is a caller of this
@@ -351,7 +351,10 @@ OPTIONS
351351

352352
--percent-limit::
353353
Do not show entries which have an overhead under that percent.
354-
(Default: 0).
354+
(Default: 0). Note that this option also sets the percent limit (threshold)
355+
of callchains. However the default value of callchain threshold is
356+
different than the default value of hist entries. Please see the
357+
--call-graph option for details.
355358

356359
--percentage::
357360
Determine how to display the overhead percentage of filtered entries.

tools/perf/builtin-annotate.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ static int __cmd_annotate(struct perf_annotate *ann)
245245
hists__collapse_resort(hists, NULL);
246246
/* Don't sort callchain */
247247
perf_evsel__reset_sample_bit(pos, CALLCHAIN);
248-
hists__output_resort(hists, NULL);
248+
perf_evsel__output_resort(pos, NULL);
249249

250250
if (symbol_conf.event_group &&
251251
!perf_evsel__is_group_leader(pos))

tools/perf/builtin-report.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ static void report__output_resort(struct report *rep)
507507
ui_progress__init(&prog, rep->nr_entries, "Sorting events for output...");
508508

509509
evlist__for_each(rep->session->evlist, pos)
510-
hists__output_resort(evsel__hists(pos), &prog);
510+
perf_evsel__output_resort(pos, &prog);
511511

512512
ui_progress__finish();
513513
}
@@ -912,15 +912,6 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
912912
symbol_conf.cumulate_callchain = false;
913913
}
914914

915-
if (setup_sorting(session->evlist) < 0) {
916-
if (sort_order)
917-
parse_options_usage(report_usage, options, "s", 1);
918-
if (field_order)
919-
parse_options_usage(sort_order ? NULL : report_usage,
920-
options, "F", 1);
921-
goto error;
922-
}
923-
924915
/* Force tty output for header output and per-thread stat. */
925916
if (report.header || report.header_only || report.show_threads)
926917
use_browser = 0;
@@ -930,6 +921,15 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
930921
else
931922
use_browser = 0;
932923

924+
if (setup_sorting(session->evlist) < 0) {
925+
if (sort_order)
926+
parse_options_usage(report_usage, options, "s", 1);
927+
if (field_order)
928+
parse_options_usage(sort_order ? NULL : report_usage,
929+
options, "F", 1);
930+
goto error;
931+
}
932+
933933
if (report.header || report.header_only) {
934934
perf_session__fprintf_info(session, stdout,
935935
report.show_full_info);

tools/perf/builtin-top.c

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,8 @@ static void perf_top__print_sym_table(struct perf_top *top)
252252
char bf[160];
253253
int printed = 0;
254254
const int win_width = top->winsize.ws_col - 1;
255-
struct hists *hists = evsel__hists(top->sym_evsel);
255+
struct perf_evsel *evsel = top->sym_evsel;
256+
struct hists *hists = evsel__hists(evsel);
256257

257258
puts(CONSOLE_CLEAR);
258259

@@ -288,7 +289,7 @@ static void perf_top__print_sym_table(struct perf_top *top)
288289
}
289290

290291
hists__collapse_resort(hists, NULL);
291-
hists__output_resort(hists, NULL);
292+
perf_evsel__output_resort(evsel, NULL);
292293

293294
hists__output_recalc_col_len(hists, top->print_entries - printed);
294295
putchar('\n');
@@ -540,14 +541,15 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c)
540541
static void perf_top__sort_new_samples(void *arg)
541542
{
542543
struct perf_top *t = arg;
544+
struct perf_evsel *evsel = t->sym_evsel;
543545
struct hists *hists;
544546

545547
perf_top__reset_sample_counters(t);
546548

547549
if (t->evlist->selected != NULL)
548550
t->sym_evsel = t->evlist->selected;
549551

550-
hists = evsel__hists(t->sym_evsel);
552+
hists = evsel__hists(evsel);
551553

552554
if (t->evlist->enabled) {
553555
if (t->zero) {
@@ -559,7 +561,7 @@ static void perf_top__sort_new_samples(void *arg)
559561
}
560562

561563
hists__collapse_resort(hists, NULL);
562-
hists__output_resort(hists, NULL);
564+
perf_evsel__output_resort(evsel, NULL);
563565
}
564566

565567
static void *display_thread_tui(void *arg)
@@ -1243,6 +1245,13 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
12431245
/* display thread wants entries to be collapsed in a different tree */
12441246
sort__need_collapse = 1;
12451247

1248+
if (top.use_stdio)
1249+
use_browser = 0;
1250+
else if (top.use_tui)
1251+
use_browser = 1;
1252+
1253+
setup_browser(false);
1254+
12461255
if (setup_sorting(top.evlist) < 0) {
12471256
if (sort_order)
12481257
parse_options_usage(top_usage, options, "s", 1);
@@ -1252,13 +1261,6 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
12521261
goto out_delete_evlist;
12531262
}
12541263

1255-
if (top.use_stdio)
1256-
use_browser = 0;
1257-
else if (top.use_tui)
1258-
use_browser = 1;
1259-
1260-
setup_browser(false);
1261-
12621264
status = target__validate(target);
12631265
if (status) {
12641266
target__strerror(target, status, errbuf, BUFSIZ);

tools/perf/tests/hists_cumulate.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ static int do_test(struct hists *hists, struct result *expected, size_t nr_expec
191191
* function since TEST_ASSERT_VAL() returns in case of failure.
192192
*/
193193
hists__collapse_resort(hists, NULL);
194-
hists__output_resort(hists, NULL);
194+
perf_evsel__output_resort(hists_to_evsel(hists), NULL);
195195

196196
if (verbose > 2) {
197197
pr_info("use callchain: %d, cumulate callchain: %d\n",

tools/perf/tests/hists_filter.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ int test__hists_filter(int subtest __maybe_unused)
145145
struct hists *hists = evsel__hists(evsel);
146146

147147
hists__collapse_resort(hists, NULL);
148-
hists__output_resort(hists, NULL);
148+
perf_evsel__output_resort(evsel, NULL);
149149

150150
if (verbose > 2) {
151151
pr_info("Normal histogram\n");

tools/perf/tests/hists_output.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ static int test1(struct perf_evsel *evsel, struct machine *machine)
156156
goto out;
157157

158158
hists__collapse_resort(hists, NULL);
159-
hists__output_resort(hists, NULL);
159+
perf_evsel__output_resort(evsel, NULL);
160160

161161
if (verbose > 2) {
162162
pr_info("[fields = %s, sort = %s]\n", field_order, sort_order);
@@ -256,7 +256,7 @@ static int test2(struct perf_evsel *evsel, struct machine *machine)
256256
goto out;
257257

258258
hists__collapse_resort(hists, NULL);
259-
hists__output_resort(hists, NULL);
259+
perf_evsel__output_resort(evsel, NULL);
260260

261261
if (verbose > 2) {
262262
pr_info("[fields = %s, sort = %s]\n", field_order, sort_order);
@@ -310,7 +310,7 @@ static int test3(struct perf_evsel *evsel, struct machine *machine)
310310
goto out;
311311

312312
hists__collapse_resort(hists, NULL);
313-
hists__output_resort(hists, NULL);
313+
perf_evsel__output_resort(evsel, NULL);
314314

315315
if (verbose > 2) {
316316
pr_info("[fields = %s, sort = %s]\n", field_order, sort_order);
@@ -388,7 +388,7 @@ static int test4(struct perf_evsel *evsel, struct machine *machine)
388388
goto out;
389389

390390
hists__collapse_resort(hists, NULL);
391-
hists__output_resort(hists, NULL);
391+
perf_evsel__output_resort(evsel, NULL);
392392

393393
if (verbose > 2) {
394394
pr_info("[fields = %s, sort = %s]\n", field_order, sort_order);
@@ -491,7 +491,7 @@ static int test5(struct perf_evsel *evsel, struct machine *machine)
491491
goto out;
492492

493493
hists__collapse_resort(hists, NULL);
494-
hists__output_resort(hists, NULL);
494+
perf_evsel__output_resort(evsel, NULL);
495495

496496
if (verbose > 2) {
497497
pr_info("[fields = %s, sort = %s]\n", field_order, sort_order);

tools/perf/ui/browsers/hists.c

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,7 +1095,7 @@ static int hist_browser__show_entry(struct hist_browser *browser,
10951095

10961096
hist_browser__gotorc(browser, row, 0);
10971097

1098-
perf_hpp__for_each_format(fmt) {
1098+
hists__for_each_format(browser->hists, fmt) {
10991099
if (perf_hpp__should_skip(fmt, entry->hists) ||
11001100
column++ < browser->b.horiz_scroll)
11011101
continue;
@@ -1175,7 +1175,7 @@ static int hists_browser__scnprintf_headers(struct hist_browser *browser, char *
11751175
return ret;
11761176
}
11771177

1178-
perf_hpp__for_each_format(fmt) {
1178+
hists__for_each_format(browser->hists, fmt) {
11791179
if (perf_hpp__should_skip(fmt, hists) || column++ < browser->b.horiz_scroll)
11801180
continue;
11811181

@@ -1441,7 +1441,7 @@ static int hist_browser__fprintf_entry(struct hist_browser *browser,
14411441
if (symbol_conf.use_callchain)
14421442
printed += fprintf(fp, "%c ", folded_sign);
14431443

1444-
perf_hpp__for_each_format(fmt) {
1444+
hists__for_each_format(browser->hists, fmt) {
14451445
if (perf_hpp__should_skip(fmt, he->hists))
14461446
continue;
14471447

@@ -2029,6 +2029,42 @@ static void hist_browser__update_nr_entries(struct hist_browser *hb)
20292029
hb->nr_non_filtered_entries = nr_entries;
20302030
}
20312031

2032+
static void hist_browser__update_percent_limit(struct hist_browser *hb,
2033+
double percent)
2034+
{
2035+
struct hist_entry *he;
2036+
struct rb_node *nd = rb_first(&hb->hists->entries);
2037+
u64 total = hists__total_period(hb->hists);
2038+
u64 min_callchain_hits = total * (percent / 100);
2039+
2040+
hb->min_pcnt = callchain_param.min_percent = percent;
2041+
2042+
if (!symbol_conf.use_callchain)
2043+
return;
2044+
2045+
while ((nd = hists__filter_entries(nd, hb->min_pcnt)) != NULL) {
2046+
he = rb_entry(nd, struct hist_entry, rb_node);
2047+
2048+
if (callchain_param.mode == CHAIN_GRAPH_REL) {
2049+
total = he->stat.period;
2050+
2051+
if (symbol_conf.cumulate_callchain)
2052+
total = he->stat_acc->period;
2053+
2054+
min_callchain_hits = total * (percent / 100);
2055+
}
2056+
2057+
callchain_param.sort(&he->sorted_chain, he->callchain,
2058+
min_callchain_hits, &callchain_param);
2059+
2060+
/* force to re-evaluate folding state of callchains */
2061+
he->init_have_children = false;
2062+
hist_entry__set_folding(he, false);
2063+
2064+
nd = rb_next(nd);
2065+
}
2066+
}
2067+
20322068
static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
20332069
const char *helpline,
20342070
bool left_exits,
@@ -2064,6 +2100,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
20642100
"E Expand all callchains\n" \
20652101
"F Toggle percentage of filtered entries\n" \
20662102
"H Display column headers\n" \
2103+
"L Change percent limit\n" \
20672104
"m Display context menu\n" \
20682105
"S Zoom into current Processor Socket\n" \
20692106

@@ -2104,7 +2141,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
21042141
memset(options, 0, sizeof(options));
21052142
memset(actions, 0, sizeof(actions));
21062143

2107-
perf_hpp__for_each_format(fmt) {
2144+
hists__for_each_format(browser->hists, fmt) {
21082145
perf_hpp__reset_width(fmt, hists);
21092146
/*
21102147
* This is done just once, and activates the horizontal scrolling
@@ -2219,6 +2256,24 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
22192256
top->zero = !top->zero;
22202257
}
22212258
continue;
2259+
case 'L':
2260+
if (ui_browser__input_window("Percent Limit",
2261+
"Please enter the value you want to hide entries under that percent.",
2262+
buf, "ENTER: OK, ESC: Cancel",
2263+
delay_secs * 2) == K_ENTER) {
2264+
char *end;
2265+
double new_percent = strtod(buf, &end);
2266+
2267+
if (new_percent < 0 || new_percent > 100) {
2268+
ui_browser__warning(&browser->b, delay_secs * 2,
2269+
"Invalid percent: %.2f", new_percent);
2270+
continue;
2271+
}
2272+
2273+
hist_browser__update_percent_limit(browser, new_percent);
2274+
hist_browser__reset(browser);
2275+
}
2276+
continue;
22222277
case K_F1:
22232278
case 'h':
22242279
case '?':

tools/perf/ui/gtk/hists.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists,
306306

307307
nr_cols = 0;
308308

309-
perf_hpp__for_each_format(fmt)
309+
hists__for_each_format(hists, fmt)
310310
col_types[nr_cols++] = G_TYPE_STRING;
311311

312312
store = gtk_tree_store_newv(nr_cols, col_types);
@@ -317,7 +317,7 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists,
317317

318318
col_idx = 0;
319319

320-
perf_hpp__for_each_format(fmt) {
320+
hists__for_each_format(hists, fmt) {
321321
if (perf_hpp__should_skip(fmt, hists))
322322
continue;
323323

@@ -367,7 +367,7 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists,
367367

368368
col_idx = 0;
369369

370-
perf_hpp__for_each_format(fmt) {
370+
hists__for_each_format(hists, fmt) {
371371
if (perf_hpp__should_skip(fmt, h->hists))
372372
continue;
373373

0 commit comments

Comments
 (0)