Skip to content

Commit

Permalink
Merge tag 'perf-core-for-mingo-2' of git://git.kernel.org/pub/scm/lin…
Browse files Browse the repository at this point in the history
…ux/kernel/git/acme/linux into perf/core

Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:

User visible changes:

  - List perf probes to stdout. (Masami Hiramatsu)

  - Return error when none of the requested probes were
    installed. (Masami Hiramatsu)

  - Cut off the gcc optimization postfixes from
    function name in 'perf probe'. (Masami Hiramatsu)

  - Allow disabling/enabling events dynamicly in 'perf top':
    a 'perf top' session can instantly become a 'perf report'
    one, i.e. going from dynamic analysis to a static one,
    returning to a dynamic one is possible, to toogle the
    modes, just press CTRL+z. (Arnaldo Carvalho de Melo)

  - Greatly speed up 'perf probe --list' by caching debuginfo.
    (Masami Hiramatsu)

  - Fix 'perf trace' race condition at the end of started
    workloads. (Sukadev Bhattiprolu)

  - Fix a problem when opening old perf.data with different
    byte order. (Wang Nan)

Infrastructure changes:

  - Replace map->referenced & maps->removed_maps with
    map->refcnt. (Arnaldo Carvalho de Melo)

  - Introduce the xyarray__reset() function. (Jiri Olsa)

  - Add thread_map__(alloc|realloc)() helpers. (Jiri Olsa)

  - Move perf_evsel__(alloc|free|reset)_counts into stat object. (Jiri Olsa)

  - Introduce perf_counts__(new|delete|reset)() functions. (Jiri Olsa)

  - Ignore .config-detected in .gitignore. (Wang Nan)

  - Move libtraceevent dynamic list to separated LDFLAGS
    variable. (Wang Nan)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
Ingo Molnar committed Jun 18, 2015
2 parents 61d67d5 + 5d484f9 commit 7992892
Show file tree
Hide file tree
Showing 22 changed files with 378 additions and 223 deletions.
1 change: 1 addition & 0 deletions tools/perf/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ config.mak.autogen
*-flex.*
*.pyc
*.pyo
.config-detected
10 changes: 6 additions & 4 deletions tools/perf/Makefile.perf
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ LIBTRACEEVENT = $(TE_PATH)libtraceevent.a
export LIBTRACEEVENT

LIBTRACEEVENT_DYNAMIC_LIST = $(TE_PATH)libtraceevent-dynamic-list
LDFLAGS += -Xlinker --dynamic-list=$(LIBTRACEEVENT_DYNAMIC_LIST)
LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS = -Xlinker --dynamic-list=$(LIBTRACEEVENT_DYNAMIC_LIST)

LIBAPI = $(LIB_PATH)libapi.a
export LIBAPI
Expand All @@ -190,8 +190,9 @@ python-clean := $(call QUIET_CLEAN, python) $(RM) -r $(PYTHON_EXTBUILD) $(OUTPUT
PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources)
PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBTRACEEVENT) $(LIBAPI)

$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS)
$(QUIET_GEN)CFLAGS='$(CFLAGS)' $(PYTHON_WORD) util/setup.py \
$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) $(LIBTRACEEVENT_DYNAMIC_LIST)
$(QUIET_GEN)CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS)' \
$(PYTHON_WORD) util/setup.py \
--quiet build_ext; \
mkdir -p $(OUTPUT)python && \
cp $(PYTHON_EXTBUILD_LIB)perf.so $(OUTPUT)python/
Expand Down Expand Up @@ -282,7 +283,8 @@ $(PERF_IN): $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h FORCE
$(Q)$(MAKE) $(build)=perf

$(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(LIBTRACEEVENT_DYNAMIC_LIST)
$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(PERF_IN) $(LIBS) -o $@
$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS) \
$(PERF_IN) $(LIBS) -o $@

$(GTK_IN): FORCE
$(Q)$(MAKE) $(build)=gtk
Expand Down
19 changes: 7 additions & 12 deletions tools/perf/builtin-stat.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,24 +178,19 @@ static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)

static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel)
{
void *addr;
size_t sz;
struct perf_counts *counts;

sz = sizeof(*evsel->counts) +
(perf_evsel__nr_cpus(evsel) * sizeof(struct perf_counts_values));
counts = perf_counts__new(perf_evsel__nr_cpus(evsel));
if (counts)
evsel->prev_raw_counts = counts;

addr = zalloc(sz);
if (!addr)
return -ENOMEM;

evsel->prev_raw_counts = addr;

return 0;
return counts ? 0 : -ENOMEM;
}

static void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel)
{
zfree(&evsel->prev_raw_counts);
perf_counts__delete(evsel->prev_raw_counts);
evsel->prev_raw_counts = NULL;
}

static void perf_evlist__free_stats(struct perf_evlist *evlist)
Expand Down
52 changes: 36 additions & 16 deletions tools/perf/builtin-top.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,13 @@ static void perf_top__show_details(struct perf_top *top)

more = symbol__annotate_printf(symbol, he->ms.map, top->sym_evsel,
0, top->sym_pcnt_filter, top->print_entries, 4);
if (top->zero)
symbol__annotate_zero_histogram(symbol, top->sym_evsel->idx);
else
symbol__annotate_decay_histogram(symbol, top->sym_evsel->idx);

if (top->evlist->enabled) {
if (top->zero)
symbol__annotate_zero_histogram(symbol, top->sym_evsel->idx);
else
symbol__annotate_decay_histogram(symbol, top->sym_evsel->idx);
}
if (more != 0)
printf("%d lines not displayed, maybe increase display entries [e]\n", more);
out_unlock:
Expand Down Expand Up @@ -276,11 +279,13 @@ static void perf_top__print_sym_table(struct perf_top *top)
return;
}

if (top->zero) {
hists__delete_entries(hists);
} else {
hists__decay_entries(hists, top->hide_user_symbols,
top->hide_kernel_symbols);
if (top->evlist->enabled) {
if (top->zero) {
hists__delete_entries(hists);
} else {
hists__decay_entries(hists, top->hide_user_symbols,
top->hide_kernel_symbols);
}
}

hists__collapse_resort(hists, NULL);
Expand Down Expand Up @@ -545,11 +550,13 @@ static void perf_top__sort_new_samples(void *arg)

hists = evsel__hists(t->sym_evsel);

if (t->zero) {
hists__delete_entries(hists);
} else {
hists__decay_entries(hists, t->hide_user_symbols,
t->hide_kernel_symbols);
if (t->evlist->enabled) {
if (t->zero) {
hists__delete_entries(hists);
} else {
hists__decay_entries(hists, t->hide_user_symbols,
t->hide_kernel_symbols);
}
}

hists__collapse_resort(hists, NULL);
Expand Down Expand Up @@ -579,8 +586,21 @@ static void *display_thread_tui(void *arg)
hists->uid_filter_str = top->record_opts.target.uid_str;
}

perf_evlist__tui_browse_hists(top->evlist, help, &hbt, top->min_percent,
&top->session->header.env);
while (true) {
int key = perf_evlist__tui_browse_hists(top->evlist, help, &hbt,
top->min_percent,
&top->session->header.env);

if (key != CTRL('z'))
break;

perf_evlist__toggle_enable(top->evlist);
/*
* No need to refresh, resort/decay histogram entries
* if we are not collecting samples:
*/
hbt.refresh = top->evlist->enabled ? top->delay_secs : 0;
}

done = 1;
return NULL;
Expand Down
1 change: 1 addition & 0 deletions tools/perf/tests/openat-syscall-all-cpus.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "thread_map.h"
#include "cpumap.h"
#include "debug.h"
#include "stat.h"

int test__openat_syscall_event_on_all_cpus(void)
{
Expand Down
2 changes: 2 additions & 0 deletions tools/perf/ui/browsers/hists.c
Original file line number Diff line number Diff line change
Expand Up @@ -1736,6 +1736,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
"t Zoom into current Thread\n"
"V Verbose (DSO names in callchains, etc)\n"
"z Toggle zeroing of samples\n"
"CTRL+z Enable/Disable events\n"
"/ Filter symbol by name";

if (browser == NULL)
Expand Down Expand Up @@ -1900,6 +1901,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
/* Fall thru */
case 'q':
case CTRL('c'):
case CTRL('z'):
goto out_free_stack;
default:
continue;
Expand Down
18 changes: 17 additions & 1 deletion tools/perf/util/evlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,8 @@ void perf_evlist__disable(struct perf_evlist *evlist)
PERF_EVENT_IOC_DISABLE, 0);
}
}

evlist->enabled = false;
}

void perf_evlist__enable(struct perf_evlist *evlist)
Expand All @@ -316,6 +318,13 @@ void perf_evlist__enable(struct perf_evlist *evlist)
PERF_EVENT_IOC_ENABLE, 0);
}
}

evlist->enabled = true;
}

void perf_evlist__toggle_enable(struct perf_evlist *evlist)
{
(evlist->enabled ? perf_evlist__disable : perf_evlist__enable)(evlist);
}

int perf_evlist__disable_event(struct perf_evlist *evlist,
Expand Down Expand Up @@ -634,11 +643,18 @@ static struct perf_evsel *perf_evlist__event2evsel(struct perf_evlist *evlist,
union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
{
struct perf_mmap *md = &evlist->mmap[idx];
u64 head = perf_mmap__read_head(md);
u64 head;
u64 old = md->prev;
unsigned char *data = md->base + page_size;
union perf_event *event = NULL;

/*
* Check if event was unmapped due to a POLLHUP/POLLERR.
*/
if (!atomic_read(&md->refcnt))
return NULL;

head = perf_mmap__read_head(md);
if (evlist->overwrite) {
/*
* If we're further behind than half the buffer, there's a chance
Expand Down
2 changes: 2 additions & 0 deletions tools/perf/util/evlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ struct perf_evlist {
int nr_groups;
int nr_mmaps;
bool overwrite;
bool enabled;
size_t mmap_len;
int id_pos;
int is_pos;
Expand Down Expand Up @@ -139,6 +140,7 @@ void perf_evlist__munmap(struct perf_evlist *evlist);

void perf_evlist__disable(struct perf_evlist *evlist);
void perf_evlist__enable(struct perf_evlist *evlist);
void perf_evlist__toggle_enable(struct perf_evlist *evlist);

int perf_evlist__disable_event(struct perf_evlist *evlist,
struct perf_evsel *evsel);
Expand Down
19 changes: 1 addition & 18 deletions tools/perf/util/evsel.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "perf_regs.h"
#include "debug.h"
#include "trace-event.h"
#include "stat.h"

static struct {
bool sample_id_all;
Expand Down Expand Up @@ -851,19 +852,6 @@ int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads)
return 0;
}

void perf_evsel__reset_counts(struct perf_evsel *evsel, int ncpus)
{
memset(evsel->counts, 0, (sizeof(*evsel->counts) +
(ncpus * sizeof(struct perf_counts_values))));
}

int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus)
{
evsel->counts = zalloc((sizeof(*evsel->counts) +
(ncpus * sizeof(struct perf_counts_values))));
return evsel->counts != NULL ? 0 : -ENOMEM;
}

static void perf_evsel__free_fd(struct perf_evsel *evsel)
{
xyarray__delete(evsel->fd);
Expand Down Expand Up @@ -891,11 +879,6 @@ void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
}
}

void perf_evsel__free_counts(struct perf_evsel *evsel)
{
zfree(&evsel->counts);
}

void perf_evsel__exit(struct perf_evsel *evsel)
{
assert(list_empty(&evsel->node));
Expand Down
3 changes: 0 additions & 3 deletions tools/perf/util/evsel.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,6 @@ const char *perf_evsel__group_name(struct perf_evsel *evsel);
int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size);

int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads);
int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus);
void perf_evsel__reset_counts(struct perf_evsel *evsel, int ncpus);
void perf_evsel__free_counts(struct perf_evsel *evsel);
void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads);

void __perf_evsel__set_sample_bit(struct perf_evsel *evsel,
Expand Down
37 changes: 22 additions & 15 deletions tools/perf/util/hist.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,7 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template,
memset(&he->stat, 0, sizeof(he->stat));
}

if (he->ms.map)
he->ms.map->referenced = true;
map__get(he->ms.map);

if (he->branch_info) {
/*
Expand All @@ -324,6 +323,7 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template,
*/
he->branch_info = malloc(sizeof(*he->branch_info));
if (he->branch_info == NULL) {
map__zput(he->ms.map);
free(he->stat_acc);
free(he);
return NULL;
Expand All @@ -332,17 +332,13 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template,
memcpy(he->branch_info, template->branch_info,
sizeof(*he->branch_info));

if (he->branch_info->from.map)
he->branch_info->from.map->referenced = true;
if (he->branch_info->to.map)
he->branch_info->to.map->referenced = true;
map__get(he->branch_info->from.map);
map__get(he->branch_info->to.map);
}

if (he->mem_info) {
if (he->mem_info->iaddr.map)
he->mem_info->iaddr.map->referenced = true;
if (he->mem_info->daddr.map)
he->mem_info->daddr.map->referenced = true;
map__get(he->mem_info->iaddr.map);
map__get(he->mem_info->daddr.map);
}

if (symbol_conf.use_callchain)
Expand Down Expand Up @@ -407,9 +403,8 @@ static struct hist_entry *hists__findnew_entry(struct hists *hists,
* the history counter to increment.
*/
if (he->ms.map != entry->ms.map) {
he->ms.map = entry->ms.map;
if (he->ms.map)
he->ms.map->referenced = true;
map__put(he->ms.map);
he->ms.map = map__get(entry->ms.map);
}
goto out;
}
Expand Down Expand Up @@ -933,8 +928,20 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
void hist_entry__delete(struct hist_entry *he)
{
thread__zput(he->thread);
zfree(&he->branch_info);
zfree(&he->mem_info);
map__zput(he->ms.map);

if (he->branch_info) {
map__zput(he->branch_info->from.map);
map__zput(he->branch_info->to.map);
zfree(&he->branch_info);
}

if (he->mem_info) {
map__zput(he->mem_info->iaddr.map);
map__zput(he->mem_info->daddr.map);
zfree(&he->mem_info);
}

zfree(&he->stat_acc);
free_srcline(he->srcline);
free_callchain(he->callchain);
Expand Down
Loading

0 comments on commit 7992892

Please sign in to comment.