Skip to content

Commit

Permalink
Merge tag 'perf-tools-fixes-2020-07-07' of git://git.kernel.org/pub/s…
Browse files Browse the repository at this point in the history
…cm/linux/kernel/git/acme/linux

Pull perf tooling fixes from Arnaldo Carvalho de Melo:

 - Intel PT fixes for PEBS-via-PT with registers

 - Fixes for Intel PT python based GUI

 - Avoid duplicated sideband events with Intel PT in system wide tracing

 - Remove needless 'dummy' event from TUI menu, used when synthesizing
   meta data events for pre-existing processes

 - Fix corner case segfault when pressing enter in a screen without
   entries in the TUI for report/top

 - Fixes for time stamp handling in libtraceevent

 - Explicitly set utf-8 encoding in perf flamegraph

 - Update arch/x86/lib/memcpy_64.S copy used in 'perf bench mem memcpy',
   silencing perf build warning

* tag 'perf-tools-fixes-2020-07-07' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux:
  perf report TUI: Remove needless 'dummy' event from menu
  perf intel-pt: Fix PEBS sample for XMM registers
  perf intel-pt: Fix displaying PEBS-via-PT with registers
  perf intel-pt: Fix recording PEBS-via-PT with registers
  perf report TUI: Fix segmentation fault in perf_evsel__hists_browse()
  tools lib traceevent: Add proper KBUFFER_TYPE_TIME_STAMP handling
  tools lib traceevent: Add API to read time information from kbuffer
  perf scripts python: exported-sql-viewer.py: Fix time chart call tree
  perf scripts python: exported-sql-viewer.py: Fix zero id in call tree 'Find' result
  perf scripts python: exported-sql-viewer.py: Fix zero id in call graph 'Find' result
  perf scripts python: exported-sql-viewer.py: Fix unexpanded 'Find' result
  perf record: Fix duplicated sideband events with Intel PT system wide tracing
  perf scripts python: export-to-postgresql.py: Fix struct.pack() int argument
  tools arch: Update arch/x86/lib/memcpy_64.S copy used in 'perf bench mem memcpy'
  perf flamegraph: Explicitly set utf-8 encoding
  • Loading branch information
torvalds committed Jul 7, 2020
2 parents 6d12075 + bee9ca1 commit dcde237
Show file tree
Hide file tree
Showing 15 changed files with 123 additions and 40 deletions.
4 changes: 4 additions & 0 deletions tools/arch/x86/lib/memcpy_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include <asm/alternative-asm.h>
#include <asm/export.h>

.pushsection .noinstr.text, "ax"

/*
* We build a jump to memcpy_orig by default which gets NOPped out on
* the majority of x86 CPUs which set REP_GOOD. In addition, CPUs which
Expand Down Expand Up @@ -184,6 +186,8 @@ SYM_FUNC_START(memcpy_orig)
retq
SYM_FUNC_END(memcpy_orig)

.popsection

#ifndef CONFIG_UML

MCSAFE_TEST_CTL
Expand Down
43 changes: 37 additions & 6 deletions tools/lib/traceevent/kbuffer-parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ translate_data(struct kbuffer *kbuf, void *data, void **rptr,
break;

case KBUFFER_TYPE_TIME_EXTEND:
case KBUFFER_TYPE_TIME_STAMP:
extend = read_4(kbuf, data);
data += 4;
extend <<= TS_SHIFT;
Expand All @@ -369,10 +370,6 @@ translate_data(struct kbuffer *kbuf, void *data, void **rptr,
*length = 0;
break;

case KBUFFER_TYPE_TIME_STAMP:
data += 12;
*length = 0;
break;
case 0:
*length = read_4(kbuf, data) - 4;
*length = (*length + 3) & ~3;
Expand All @@ -397,7 +394,11 @@ static unsigned int update_pointers(struct kbuffer *kbuf)

type_len = translate_data(kbuf, ptr, &ptr, &delta, &length);

kbuf->timestamp += delta;
if (type_len == KBUFFER_TYPE_TIME_STAMP)
kbuf->timestamp = delta;
else
kbuf->timestamp += delta;

kbuf->index = calc_index(kbuf, ptr);
kbuf->next = kbuf->index + length;

Expand Down Expand Up @@ -454,7 +455,9 @@ static int __next_event(struct kbuffer *kbuf)
if (kbuf->next >= kbuf->size)
return -1;
type = update_pointers(kbuf);
} while (type == KBUFFER_TYPE_TIME_EXTEND || type == KBUFFER_TYPE_PADDING);
} while (type == KBUFFER_TYPE_TIME_EXTEND ||
type == KBUFFER_TYPE_TIME_STAMP ||
type == KBUFFER_TYPE_PADDING);

return 0;
}
Expand Down Expand Up @@ -546,6 +549,34 @@ int kbuffer_load_subbuffer(struct kbuffer *kbuf, void *subbuffer)
return 0;
}

/**
* kbuffer_subbuf_timestamp - read the timestamp from a sub buffer
* @kbuf: The kbuffer to load
* @subbuf: The subbuffer to read from.
*
* Return the timestamp from a subbuffer.
*/
unsigned long long kbuffer_subbuf_timestamp(struct kbuffer *kbuf, void *subbuf)
{
return kbuf->read_8(subbuf);
}

/**
* kbuffer_ptr_delta - read the delta field from a record
* @kbuf: The kbuffer to load
* @ptr: The record in the buffe.
*
* Return the timestamp delta from a record
*/
unsigned int kbuffer_ptr_delta(struct kbuffer *kbuf, void *ptr)
{
unsigned int type_len_ts;

type_len_ts = read_4(kbuf, ptr);
return ts4host(kbuf, type_len_ts);
}


/**
* kbuffer_read_event - read the next event in the kbuffer subbuffer
* @kbuf: The kbuffer to read from
Expand Down
2 changes: 2 additions & 0 deletions tools/lib/traceevent/kbuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ int kbuffer_load_subbuffer(struct kbuffer *kbuf, void *subbuffer);
void *kbuffer_read_event(struct kbuffer *kbuf, unsigned long long *ts);
void *kbuffer_next_event(struct kbuffer *kbuf, unsigned long long *ts);
unsigned long long kbuffer_timestamp(struct kbuffer *kbuf);
unsigned long long kbuffer_subbuf_timestamp(struct kbuffer *kbuf, void *subbuf);
unsigned int kbuffer_ptr_delta(struct kbuffer *kbuf, void *ptr);

void *kbuffer_translate_data(int swap, void *data, unsigned int *size);

Expand Down
1 change: 1 addition & 0 deletions tools/perf/arch/x86/util/intel-pt.c
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
}
evsel->core.attr.freq = 0;
evsel->core.attr.sample_period = 1;
evsel->no_aux_samples = true;
intel_pt_evsel = evsel;
opts->full_auxtrace = true;
}
Expand Down
18 changes: 9 additions & 9 deletions tools/perf/builtin-record.c
Original file line number Diff line number Diff line change
Expand Up @@ -852,20 +852,20 @@ static int record__open(struct record *rec)
* event synthesis.
*/
if (opts->initial_delay || target__has_cpu(&opts->target)) {
if (perf_evlist__add_dummy(evlist))
return -ENOMEM;
pos = perf_evlist__get_tracking_event(evlist);
if (!evsel__is_dummy_event(pos)) {
/* Set up dummy event. */
if (perf_evlist__add_dummy(evlist))
return -ENOMEM;
pos = evlist__last(evlist);
perf_evlist__set_tracking_event(evlist, pos);
}

/* Disable tracking of mmaps on lead event. */
pos = evlist__first(evlist);
pos->tracking = 0;
/* Set up dummy event. */
pos = evlist__last(evlist);
pos->tracking = 1;
/*
* Enable the dummy event when the process is forked for
* initial_delay, immediately for system wide.
*/
if (opts->initial_delay)
if (opts->initial_delay && !pos->immediate)
pos->core.attr.enable_on_exec = 1;
else
pos->immediate = 1;
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/builtin-script.c
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ static int perf_evsel__check_attr(struct evsel *evsel, struct perf_session *sess
return -EINVAL;

if (PRINT_FIELD(IREGS) &&
evsel__check_stype(evsel, PERF_SAMPLE_REGS_INTR, "IREGS", PERF_OUTPUT_IREGS))
evsel__do_check_stype(evsel, PERF_SAMPLE_REGS_INTR, "IREGS", PERF_OUTPUT_IREGS, allow_user_set))
return -EINVAL;

if (PRINT_FIELD(UREGS) &&
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/scripts/python/export-to-postgresql.py
Original file line number Diff line number Diff line change
Expand Up @@ -1055,7 +1055,7 @@ def cbr(id, raw_buf):
cbr = data[0]
MHz = (data[4] + 500) / 1000
percent = ((cbr * 1000 / data[2]) + 5) / 10
value = struct.pack("!hiqiiiiii", 4, 8, id, 4, cbr, 4, MHz, 4, percent)
value = struct.pack("!hiqiiiiii", 4, 8, id, 4, cbr, 4, int(MHz), 4, int(percent))
cbr_file.write(value)

def mwait(id, raw_buf):
Expand Down
11 changes: 9 additions & 2 deletions tools/perf/scripts/python/exported-sql-viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -768,7 +768,8 @@ def DoFindSelect(self, query, match):
" FROM calls"
" INNER JOIN call_paths ON calls.call_path_id = call_paths.id"
" INNER JOIN symbols ON call_paths.symbol_id = symbols.id"
" WHERE symbols.name" + match +
" WHERE calls.id <> 0"
" AND symbols.name" + match +
" GROUP BY comm_id, thread_id, call_path_id"
" ORDER BY comm_id, thread_id, call_path_id")

Expand Down Expand Up @@ -963,7 +964,8 @@ def DoFindSelect(self, query, match):
" FROM calls"
" INNER JOIN call_paths ON calls.call_path_id = call_paths.id"
" INNER JOIN symbols ON call_paths.symbol_id = symbols.id"
" WHERE symbols.name" + match +
" WHERE calls.id <> 0"
" AND symbols.name" + match +
" ORDER BY comm_id, thread_id, call_time, calls.id")

def FindPath(self, query):
Expand Down Expand Up @@ -1050,6 +1052,7 @@ def DisplayFound(self, ids):
child = self.model.index(row, 0, parent)
if child.internalPointer().dbid == dbid:
found = True
self.view.setExpanded(parent, True)
self.view.setCurrentIndex(child)
parent = child
break
Expand Down Expand Up @@ -1127,6 +1130,7 @@ def DisplayThreadAtTime(self, comm_id, thread_id, time):
child = self.model.index(row, 0, parent)
if child.internalPointer().dbid == dbid:
found = True
self.view.setExpanded(parent, True)
self.view.setCurrentIndex(child)
parent = child
break
Expand All @@ -1139,6 +1143,7 @@ def DisplayThreadAtTime(self, comm_id, thread_id, time):
return
last_child = None
for row in xrange(n):
self.view.setExpanded(parent, True)
child = self.model.index(row, 0, parent)
child_call_time = child.internalPointer().call_time
if child_call_time < time:
Expand All @@ -1151,9 +1156,11 @@ def DisplayThreadAtTime(self, comm_id, thread_id, time):
if not last_child:
if not found:
child = self.model.index(0, 0, parent)
self.view.setExpanded(parent, True)
self.view.setCurrentIndex(child)
return
found = True
self.view.setExpanded(parent, True)
self.view.setCurrentIndex(last_child)
parent = last_child

Expand Down
8 changes: 5 additions & 3 deletions tools/perf/scripts/python/flamegraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from __future__ import print_function
import sys
import os
import io
import argparse
import json

Expand Down Expand Up @@ -81,7 +82,7 @@ def trace_end(self):

if self.args.format == "html":
try:
with open(self.args.template) as f:
with io.open(self.args.template, encoding="utf-8") as f:
output_str = f.read().replace("/** @flamegraph_json **/",
json_str)
except IOError as e:
Expand All @@ -93,11 +94,12 @@ def trace_end(self):
output_fn = self.args.output or "stacks.json"

if output_fn == "-":
sys.stdout.write(output_str)
with io.open(sys.stdout.fileno(), "w", encoding="utf-8", closefd=False) as out:
out.write(output_str)
else:
print("dumping data to {}".format(output_fn))
try:
with open(output_fn, "w") as out:
with io.open(output_fn, "w", encoding="utf-8") as out:
out.write(output_str)
except IOError as e:
print("Error writing output file: {}".format(e), file=sys.stderr)
Expand Down
36 changes: 29 additions & 7 deletions tools/perf/ui/browsers/hists.c
Original file line number Diff line number Diff line change
Expand Up @@ -2288,6 +2288,11 @@ static struct thread *hist_browser__selected_thread(struct hist_browser *browser
return browser->he_selection->thread;
}

static struct res_sample *hist_browser__selected_res_sample(struct hist_browser *browser)
{
return browser->he_selection ? browser->he_selection->res_samples : NULL;
}

/* Check whether the browser is for 'top' or 'report' */
static inline bool is_report_browser(void *timer)
{
Expand Down Expand Up @@ -3357,16 +3362,16 @@ static int perf_evsel__hists_browse(struct evsel *evsel, int nr_events,
&options[nr_options], NULL, NULL, evsel);
nr_options += add_res_sample_opt(browser, &actions[nr_options],
&options[nr_options],
hist_browser__selected_entry(browser)->res_samples,
evsel, A_NORMAL);
hist_browser__selected_res_sample(browser),
evsel, A_NORMAL);
nr_options += add_res_sample_opt(browser, &actions[nr_options],
&options[nr_options],
hist_browser__selected_entry(browser)->res_samples,
evsel, A_ASM);
hist_browser__selected_res_sample(browser),
evsel, A_ASM);
nr_options += add_res_sample_opt(browser, &actions[nr_options],
&options[nr_options],
hist_browser__selected_entry(browser)->res_samples,
evsel, A_SOURCE);
hist_browser__selected_res_sample(browser),
evsel, A_SOURCE);
nr_options += add_switch_opt(browser, &actions[nr_options],
&options[nr_options]);
skip_scripting:
Expand Down Expand Up @@ -3598,6 +3603,23 @@ static int __perf_evlist__tui_browse_hists(struct evlist *evlist,
hbt, warn_lost_event);
}

static bool perf_evlist__single_entry(struct evlist *evlist)
{
int nr_entries = evlist->core.nr_entries;

if (nr_entries == 1)
return true;

if (nr_entries == 2) {
struct evsel *last = evlist__last(evlist);

if (evsel__is_dummy_event(last))
return true;
}

return false;
}

int perf_evlist__tui_browse_hists(struct evlist *evlist, const char *help,
struct hist_browser_timer *hbt,
float min_pcnt,
Expand All @@ -3608,7 +3630,7 @@ int perf_evlist__tui_browse_hists(struct evlist *evlist, const char *help,
int nr_entries = evlist->core.nr_entries;

single_entry:
if (nr_entries == 1) {
if (perf_evlist__single_entry(evlist)) {
struct evsel *first = evlist__first(evlist);

return perf_evsel__hists_browse(first, nr_entries, help,
Expand Down
12 changes: 12 additions & 0 deletions tools/perf/util/evlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -1566,6 +1566,18 @@ void perf_evlist__to_front(struct evlist *evlist,
list_splice(&move, &evlist->core.entries);
}

struct evsel *perf_evlist__get_tracking_event(struct evlist *evlist)
{
struct evsel *evsel;

evlist__for_each_entry(evlist, evsel) {
if (evsel->tracking)
return evsel;
}

return evlist__first(evlist);
}

void perf_evlist__set_tracking_event(struct evlist *evlist,
struct evsel *tracking_evsel)
{
Expand Down
1 change: 1 addition & 0 deletions tools/perf/util/evlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ void perf_evlist__to_front(struct evlist *evlist,
evlist__cpu_iter_start(evlist); \
perf_cpu_map__for_each_cpu (cpu, index, (evlist)->core.all_cpus)

struct evsel *perf_evlist__get_tracking_event(struct evlist *evlist);
void perf_evlist__set_tracking_event(struct evlist *evlist,
struct evsel *tracking_evsel);

Expand Down
12 changes: 3 additions & 9 deletions tools/perf/util/evsel.c
Original file line number Diff line number Diff line change
Expand Up @@ -898,12 +898,6 @@ static void evsel__apply_config_terms(struct evsel *evsel,
}
}

static bool is_dummy_event(struct evsel *evsel)
{
return (evsel->core.attr.type == PERF_TYPE_SOFTWARE) &&
(evsel->core.attr.config == PERF_COUNT_SW_DUMMY);
}

struct evsel_config_term *__evsel__get_config_term(struct evsel *evsel, enum evsel_term_type type)
{
struct evsel_config_term *term, *found_term = NULL;
Expand Down Expand Up @@ -1020,12 +1014,12 @@ void evsel__config(struct evsel *evsel, struct record_opts *opts,
if (callchain && callchain->enabled && !evsel->no_aux_samples)
evsel__config_callchain(evsel, opts, callchain);

if (opts->sample_intr_regs) {
if (opts->sample_intr_regs && !evsel->no_aux_samples) {
attr->sample_regs_intr = opts->sample_intr_regs;
evsel__set_sample_bit(evsel, REGS_INTR);
}

if (opts->sample_user_regs) {
if (opts->sample_user_regs && !evsel->no_aux_samples) {
attr->sample_regs_user |= opts->sample_user_regs;
evsel__set_sample_bit(evsel, REGS_USER);
}
Expand Down Expand Up @@ -1161,7 +1155,7 @@ void evsel__config(struct evsel *evsel, struct record_opts *opts,
* The software event will trigger -EOPNOTSUPP error out,
* if BRANCH_STACK bit is set.
*/
if (is_dummy_event(evsel))
if (evsel__is_dummy_event(evsel))
evsel__reset_sample_bit(evsel, BRANCH_STACK);
}

Expand Down
6 changes: 6 additions & 0 deletions tools/perf/util/evsel.h
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,12 @@ static inline bool evsel__has_br_stack(const struct evsel *evsel)
evsel->synth_sample_type & PERF_SAMPLE_BRANCH_STACK;
}

static inline bool evsel__is_dummy_event(struct evsel *evsel)
{
return (evsel->core.attr.type == PERF_TYPE_SOFTWARE) &&
(evsel->core.attr.config == PERF_COUNT_SW_DUMMY);
}

struct perf_env *evsel__env(struct evsel *evsel);

int evsel__store_ids(struct evsel *evsel, struct evlist *evlist);
Expand Down
Loading

0 comments on commit dcde237

Please sign in to comment.