Skip to content

Commit

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

Pull perf/core fixes and some late updates from Arnaldo Carvalho de Melo:

 * Make clean brace expansion fix for some shells, from Palmer Cox

 * Warn user just once per guest kernel when not finding kernel info,
   from David Ahern

 * perf test fix from Jiri Olsa

 * Fix error handling on event creation in perf top, from David Ahern

 * Fix check on perf_target__strnerror, from Namhyung Kim

 * Save the whole cmdline, from David Ahern

 * Prep work for the DWARF CFI post unwinder, so that it doesn't
   uses perf_session in lots of places, just evlist/evsel is enough.

Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
  • Loading branch information
Ingo Molnar committed Aug 5, 2012
2 parents e7882d6 + 7f309ed commit 8a06bf1
Show file tree
Hide file tree
Showing 24 changed files with 498 additions and 187 deletions.
7 changes: 6 additions & 1 deletion tools/perf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,8 @@ LIB_H += $(ARCH_INCLUDE)
LIB_H += util/cgroup.h
LIB_H += $(TRACE_EVENT_DIR)event-parse.h
LIB_H += util/target.h
LIB_H += util/rblist.h
LIB_H += util/intlist.h

LIB_OBJS += $(OUTPUT)util/abspath.o
LIB_OBJS += $(OUTPUT)util/alias.o
Expand Down Expand Up @@ -383,6 +385,8 @@ LIB_OBJS += $(OUTPUT)util/xyarray.o
LIB_OBJS += $(OUTPUT)util/cpumap.o
LIB_OBJS += $(OUTPUT)util/cgroup.o
LIB_OBJS += $(OUTPUT)util/target.o
LIB_OBJS += $(OUTPUT)util/rblist.o
LIB_OBJS += $(OUTPUT)util/intlist.o

BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o

Expand Down Expand Up @@ -983,7 +987,8 @@ clean:
$(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope*
$(MAKE) -C Documentation/ clean
$(RM) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS
$(RM) $(OUTPUT)util/*-{bison,flex}*
$(RM) $(OUTPUT)util/*-bison*
$(RM) $(OUTPUT)util/*-flex*
$(python-clean)

.PHONY: all install clean strip $(LIBTRACEEVENT)
Expand Down
4 changes: 1 addition & 3 deletions tools/perf/builtin-record.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ static void perf_record__open(struct perf_record *rec)
}
}

perf_session__update_sample_type(session);
perf_session__set_id_hdr_size(session);
}

static int process_buildids(struct perf_record *rec)
Expand Down Expand Up @@ -844,8 +844,6 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
struct perf_record *rec = &record;
char errbuf[BUFSIZ];

perf_header__set_cmdline(argc, argv);

evsel_list = perf_evlist__new(NULL, NULL);
if (evsel_list == NULL)
return -ENOMEM;
Expand Down
5 changes: 3 additions & 2 deletions tools/perf/builtin-report.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,9 @@ static int process_read_event(struct perf_tool *tool,
static int perf_report__setup_sample_type(struct perf_report *rep)
{
struct perf_session *self = rep->session;
u64 sample_type = perf_evlist__sample_type(self->evlist);

if (!self->fd_pipe && !(self->sample_type & PERF_SAMPLE_CALLCHAIN)) {
if (!self->fd_pipe && !(sample_type & PERF_SAMPLE_CALLCHAIN)) {
if (sort__has_parent) {
ui__error("Selected --sort parent, but no "
"callchain data. Did you call "
Expand All @@ -274,7 +275,7 @@ static int perf_report__setup_sample_type(struct perf_report *rep)

if (sort__branch_mode == 1) {
if (!self->fd_pipe &&
!(self->sample_type & PERF_SAMPLE_BRANCH_STACK)) {
!(sample_type & PERF_SAMPLE_BRANCH_STACK)) {
ui__error("Selected -b but no branch data. "
"Did you call perf record without -b?\n");
return -1;
Expand Down
19 changes: 4 additions & 15 deletions tools/perf/builtin-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,6 @@ static int test__basic_mmap(void)
unsigned int nr_events[nsyscalls],
expected_nr_events[nsyscalls], i, j;
struct perf_evsel *evsels[nsyscalls], *evsel;
int sample_size = __perf_evsel__sample_size(attr.sample_type);

for (i = 0; i < nsyscalls; ++i) {
char name[64];
Expand Down Expand Up @@ -563,8 +562,7 @@ static int test__basic_mmap(void)
goto out_munmap;
}

err = perf_event__parse_sample(event, attr.sample_type, sample_size,
false, &sample, false);
err = perf_evlist__parse_sample(evlist, event, &sample, false);
if (err) {
pr_err("Can't parse sample, err = %d\n", err);
goto out_munmap;
Expand Down Expand Up @@ -661,12 +659,12 @@ static int test__PERF_RECORD(void)
const char *cmd = "sleep";
const char *argv[] = { cmd, "1", NULL, };
char *bname;
u64 sample_type, prev_time = 0;
u64 prev_time = 0;
bool found_cmd_mmap = false,
found_libc_mmap = false,
found_vdso_mmap = false,
found_ld_mmap = false;
int err = -1, errs = 0, i, wakeups = 0, sample_size;
int err = -1, errs = 0, i, wakeups = 0;
u32 cpu;
int total_events = 0, nr_events[PERF_RECORD_MAX] = { 0, };

Expand Down Expand Up @@ -756,13 +754,6 @@ static int test__PERF_RECORD(void)
goto out_delete_evlist;
}

/*
* We'll need these two to parse the PERF_SAMPLE_* fields in each
* event.
*/
sample_type = perf_evlist__sample_type(evlist);
sample_size = __perf_evsel__sample_size(sample_type);

/*
* Now that all is properly set up, enable the events, they will
* count just on workload.pid, which will start...
Expand All @@ -788,9 +779,7 @@ static int test__PERF_RECORD(void)
if (type < PERF_RECORD_MAX)
nr_events[type]++;

err = perf_event__parse_sample(event, sample_type,
sample_size, true,
&sample, false);
err = perf_evlist__parse_sample(evlist, event, &sample, false);
if (err < 0) {
if (verbose)
perf_event__fprintf(event, stderr);
Expand Down
23 changes: 17 additions & 6 deletions tools/perf/builtin-top.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "util/cpumap.h"
#include "util/xyarray.h"
#include "util/sort.h"
#include "util/intlist.h"

#include "util/debug.h"

Expand Down Expand Up @@ -706,8 +707,16 @@ static void perf_event__process_sample(struct perf_tool *tool,
int err;

if (!machine && perf_guest) {
pr_err("Can't find guest [%d]'s kernel information\n",
event->ip.pid);
static struct intlist *seen;

if (!seen)
seen = intlist__new();

if (!intlist__has_entry(seen, event->ip.pid)) {
pr_err("Can't find guest [%d]'s kernel information\n",
event->ip.pid);
intlist__add(seen, event->ip.pid);
}
return;
}

Expand Down Expand Up @@ -811,7 +820,7 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx)
int ret;

while ((event = perf_evlist__mmap_read(top->evlist, idx)) != NULL) {
ret = perf_session__parse_sample(session, event, &sample);
ret = perf_evlist__parse_sample(top->evlist, event, &sample, false);
if (ret) {
pr_err("Can't parse sample, err = %d\n", ret);
continue;
Expand Down Expand Up @@ -943,8 +952,10 @@ static void perf_top__start_counters(struct perf_top *top)
* based cpu-clock-tick sw counter, which
* is always available even if no PMU support:
*/
if (attr->type == PERF_TYPE_HARDWARE &&
attr->config == PERF_COUNT_HW_CPU_CYCLES) {
if ((err == ENOENT || err == ENXIO) &&
(attr->type == PERF_TYPE_HARDWARE) &&
(attr->config == PERF_COUNT_HW_CPU_CYCLES)) {

if (verbose)
ui__warning("Cycles event not supported,\n"
"trying to fall back to cpu-clock-ticks\n");
Expand Down Expand Up @@ -1032,7 +1043,7 @@ static int __cmd_top(struct perf_top *top)
&top->session->host_machine);
perf_top__start_counters(top);
top->session->evlist = top->evlist;
perf_session__update_sample_type(top->session);
perf_session__set_id_hdr_size(top->session);

/* Wait for a minimal set of events before starting the snapshot */
poll(top->evlist->pollfd, top->evlist->nr_fds, 100);
Expand Down
3 changes: 0 additions & 3 deletions tools/perf/util/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,6 @@ int perf_event__preprocess_sample(const union perf_event *self,

const char *perf_event__name(unsigned int id);

int perf_event__parse_sample(const union perf_event *event, u64 type,
int sample_size, bool sample_id_all,
struct perf_sample *sample, bool swapped);
int perf_event__synthesize_sample(union perf_event *event, u64 type,
const struct perf_sample *sample,
bool swapped);
Expand Down
7 changes: 7 additions & 0 deletions tools/perf/util/evlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -881,3 +881,10 @@ int perf_evlist__start_workload(struct perf_evlist *evlist)

return 0;
}

int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *event,
struct perf_sample *sample, bool swapped)
{
struct perf_evsel *e = list_entry(evlist->entries.next, struct perf_evsel, node);
return perf_evsel__parse_sample(e, event, sample, swapped);
}
3 changes: 3 additions & 0 deletions tools/perf/util/evlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ u64 perf_evlist__sample_type(const struct perf_evlist *evlist);
bool perf_evlist__sample_id_all(const const struct perf_evlist *evlist);
u16 perf_evlist__id_hdr_size(const struct perf_evlist *evlist);

int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *event,
struct perf_sample *sample, bool swapped);

bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist);
bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist);

Expand Down
15 changes: 8 additions & 7 deletions tools/perf/util/evsel.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
#define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0))

int __perf_evsel__sample_size(u64 sample_type)
static int __perf_evsel__sample_size(u64 sample_type)
{
u64 mask = sample_type & PERF_SAMPLE_MASK;
int size = 0;
Expand Down Expand Up @@ -53,6 +53,7 @@ void perf_evsel__init(struct perf_evsel *evsel,
evsel->attr = *attr;
INIT_LIST_HEAD(&evsel->node);
hists__init(&evsel->hists);
evsel->sample_size = __perf_evsel__sample_size(attr->sample_type);
}

struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx)
Expand Down Expand Up @@ -728,10 +729,10 @@ static bool sample_overlap(const union perf_event *event,
return false;
}

int perf_event__parse_sample(const union perf_event *event, u64 type,
int sample_size, bool sample_id_all,
int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
struct perf_sample *data, bool swapped)
{
u64 type = evsel->attr.sample_type;
const u64 *array;

/*
Expand All @@ -746,14 +747,14 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,
data->period = 1;

if (event->header.type != PERF_RECORD_SAMPLE) {
if (!sample_id_all)
if (!evsel->attr.sample_id_all)
return 0;
return perf_event__parse_id_sample(event, type, data, swapped);
}

array = event->sample.array;

if (sample_size + sizeof(event->header) > event->header.size)
if (evsel->sample_size + sizeof(event->header) > event->header.size)
return -EFAULT;

if (type & PERF_SAMPLE_IP) {
Expand Down Expand Up @@ -895,7 +896,7 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type,
u.val32[1] = sample->tid;
if (swapped) {
/*
* Inverse of what is done in perf_event__parse_sample
* Inverse of what is done in perf_evsel__parse_sample
*/
u.val32[0] = bswap_32(u.val32[0]);
u.val32[1] = bswap_32(u.val32[1]);
Expand Down Expand Up @@ -930,7 +931,7 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type,
u.val32[0] = sample->cpu;
if (swapped) {
/*
* Inverse of what is done in perf_event__parse_sample
* Inverse of what is done in perf_evsel__parse_sample
*/
u.val32[0] = bswap_32(u.val32[0]);
u.val64 = bswap_64(u.val64);
Expand Down
10 changes: 3 additions & 7 deletions tools/perf/util/evsel.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ struct perf_evsel {
void *func;
void *data;
} handler;
unsigned int sample_size;
bool supported;
};

Expand Down Expand Up @@ -177,13 +178,8 @@ static inline int perf_evsel__read_scaled(struct perf_evsel *evsel,
return __perf_evsel__read(evsel, ncpus, nthreads, true);
}

int __perf_evsel__sample_size(u64 sample_type);

static inline int perf_evsel__sample_size(struct perf_evsel *evsel)
{
return __perf_evsel__sample_size(evsel->attr.sample_type);
}

void hists__init(struct hists *hists);

int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
struct perf_sample *sample, bool swapped);
#endif /* __PERF_EVSEL_H */
9 changes: 9 additions & 0 deletions tools/perf/util/header.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,15 @@ perf_header__set_cmdline(int argc, const char **argv)
{
int i;

/*
* If header_argv has already been set, do not override it.
* This allows a command to set the cmdline, parse args and
* then call another builtin function that implements a
* command -- e.g, cmd_kvm calling cmd_record.
*/
if (header_argv)
return 0;

header_argc = (u32)argc;

/* do not include NULL termination */
Expand Down
Loading

0 comments on commit 8a06bf1

Please sign in to comment.