From 30f31c0a492d0c1cd64af631476697f38d6a79d4 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 1 Aug 2012 14:48:58 +0200 Subject: perf test: Fix parse events automated tests Parse events tests got broken after following commit: perf tools: Fix trace events storms due to weight demux commit 0983cc0dbca45250cbb5984bec7c303ac265b8e5 Author: Frederic Weisbecker that added PERF_SAMPLE_PERIOD sample type for tracepoints. Updating related tests. Signed-off-by: Jiri Olsa Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1343825338-10618-1-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/parse-events-test.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/parse-events-test.c b/tools/perf/util/parse-events-test.c index 1b997d2b89c..127d648cc54 100644 --- a/tools/perf/util/parse-events-test.c +++ b/tools/perf/util/parse-events-test.c @@ -13,6 +13,9 @@ do { \ } \ } while (0) +#define PERF_TP_SAMPLE_TYPE (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | \ + PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD) + static int test__checkevent_tracepoint(struct perf_evlist *evlist) { struct perf_evsel *evsel = list_entry(evlist->entries.next, @@ -21,8 +24,7 @@ static int test__checkevent_tracepoint(struct perf_evlist *evlist) TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); TEST_ASSERT_VAL("wrong sample_type", - (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) == - evsel->attr.sample_type); + PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type); TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); return 0; } @@ -37,8 +39,7 @@ static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist) TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); TEST_ASSERT_VAL("wrong sample_type", - (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) - == evsel->attr.sample_type); + PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type); TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); } @@ -428,8 +429,7 @@ static int test__checkevent_list(struct perf_evlist *evlist) evsel = list_entry(evsel->node.next, struct perf_evsel, node); TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); TEST_ASSERT_VAL("wrong sample_type", - (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) == - evsel->attr.sample_type); + PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type); TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); -- cgit v1.2.3 From 028df76726c5637c6f70a064d94452808ec74f9e Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 1 Aug 2012 14:47:57 +0200 Subject: perf symbols: Fix array sizes for binary types arrays Following commit introduced wrong array boundaries, that could lead to SIGSEGV. perf symbols: Factor DSO symtab types to generic binary types commit 44f24cb3156a1e7d2b6bb501b7f6153aed08994c Author: Jiri Olsa Fixing to use proper array size. Reported-by: Markus Trippelsdorf Signed-off-by: Jiri Olsa Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Markus Trippelsdorf Link: http://lkml.kernel.org/r/1343825277-10517-1-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index fdad4eeeb42..fe86612afad 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -64,7 +64,7 @@ static enum dso_binary_type binary_type_symtab[] = { DSO_BINARY_TYPE__NOT_FOUND, }; -#define DSO_BINARY_TYPE__SYMTAB_CNT sizeof(binary_type_symtab) +#define DSO_BINARY_TYPE__SYMTAB_CNT ARRAY_SIZE(binary_type_symtab) static enum dso_binary_type binary_type_data[] = { DSO_BINARY_TYPE__BUILD_ID_CACHE, @@ -72,7 +72,7 @@ static enum dso_binary_type binary_type_data[] = { DSO_BINARY_TYPE__NOT_FOUND, }; -#define DSO_BINARY_TYPE__DATA_CNT sizeof(binary_type_data) +#define DSO_BINARY_TYPE__DATA_CNT ARRAY_SIZE(binary_type_data) int dso__name_len(const struct dso *dso) { -- cgit v1.2.3 From 0ecf4f0c02b7802de5d1251e03e6eab360f158e1 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 26 Jul 2012 10:50:10 +0900 Subject: perf target: Fix check on buffer size It was a mistake just replace assert to BUG_ON since its condition should be negated. Fix it. Signed-off-by: Namhyung Kim Cc: "Kirill A. Shutemov" Cc: Ingo Molnar Cc: Kirill A. Shutemov Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Ulrich Drepper Link: http://lkml.kernel.org/r/1343267410-7758-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/target.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/target.c b/tools/perf/util/target.c index 3f59c496e64..051eaa68095 100644 --- a/tools/perf/util/target.c +++ b/tools/perf/util/target.c @@ -110,7 +110,7 @@ int perf_target__strerror(struct perf_target *target, int errnum, int idx; const char *msg; - BUG_ON(buflen > 0); + BUG_ON(buflen == 0); if (errnum >= 0) { const char *err = strerror_r(errnum, buf, buflen); -- cgit v1.2.3 From bde09467b56c5a3cfe2a29d58edc5f7172c15184 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 1 Aug 2012 18:53:11 -0300 Subject: perf evsel: Precalculate the sample size So that we don't have to store it in the perf_session instance, because in the future perf_session instances may have multiple evlists, each with different sample_type/sizes. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-ptod86fxkpgq3h62m9refkv4@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-test.c | 9 ++++----- tools/perf/util/evsel.c | 3 ++- tools/perf/util/evsel.h | 8 +------- tools/perf/util/python.c | 2 +- tools/perf/util/session.c | 14 +++++++++++++- tools/perf/util/session.h | 13 +++---------- 6 files changed, 24 insertions(+), 25 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index d909eb74a0e..2ea5fe4cc94 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c @@ -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]; @@ -563,7 +562,8 @@ static int test__basic_mmap(void) goto out_munmap; } - err = perf_event__parse_sample(event, attr.sample_type, sample_size, + err = perf_event__parse_sample(event, attr.sample_type, + evsels[0]->sample_size, false, &sample, false); if (err) { pr_err("Can't parse sample, err = %d\n", err); @@ -666,7 +666,7 @@ static int test__PERF_RECORD(void) 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, }; @@ -761,7 +761,6 @@ static int test__PERF_RECORD(void) * 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 @@ -789,7 +788,7 @@ static int test__PERF_RECORD(void) nr_events[type]++; err = perf_event__parse_sample(event, sample_type, - sample_size, true, + evsel->sample_size, true, &sample, false); if (err < 0) { if (verbose) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index e8177136486..8feec401135 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -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; @@ -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) diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 67cc5033d19..894bd77d90c 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -65,6 +65,7 @@ struct perf_evsel { void *func; void *data; } handler; + unsigned int sample_size; bool supported; }; @@ -177,13 +178,6 @@ 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); #endif /* __PERF_EVSEL_H */ diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index e03b58a4842..b0d6f85e30f 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -806,7 +806,7 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist, first = list_entry(evlist->entries.next, struct perf_evsel, node); err = perf_event__parse_sample(event, first->attr.sample_type, - perf_evsel__sample_size(first), + first->sample_size, sample_id_all, &pevent->sample, false); if (err) return PyErr_Format(PyExc_OSError, diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 8e4f0755d2a..b8da60d1ecb 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -16,6 +16,19 @@ #include "cpumap.h" #include "event-parse.h" +int perf_session__parse_sample(struct perf_session *session, + const union perf_event *event, + struct perf_sample *sample) +{ + struct perf_evsel *first; + first = list_entry(session->evlist->entries.next, struct perf_evsel, node); + + return perf_event__parse_sample(event, session->sample_type, + first->sample_size, + session->sample_id_all, sample, + session->header.needs_swap); +} + static int perf_session__open(struct perf_session *self, bool force) { struct stat input_stat; @@ -83,7 +96,6 @@ out_close: void perf_session__update_sample_type(struct perf_session *self) { self->sample_type = perf_evlist__sample_type(self->evlist); - self->sample_size = __perf_evsel__sample_size(self->sample_type); self->sample_id_all = perf_evlist__sample_id_all(self->evlist); self->id_hdr_size = perf_evlist__id_hdr_size(self->evlist); self->host_machine.id_hdr_size = self->id_hdr_size; diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 7c435bde6eb..4d549e28248 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -42,7 +42,6 @@ struct perf_session { */ struct hists hists; u64 sample_type; - int sample_size; int fd; bool fd_pipe; bool repipe; @@ -130,15 +129,9 @@ size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp); -static inline int perf_session__parse_sample(struct perf_session *session, - const union perf_event *event, - struct perf_sample *sample) -{ - return perf_event__parse_sample(event, session->sample_type, - session->sample_size, - session->sample_id_all, sample, - session->header.needs_swap); -} +int perf_session__parse_sample(struct perf_session *session, + const union perf_event *event, + struct perf_sample *sample); static inline int perf_session__synthesize_sample(struct perf_session *session, union perf_event *event, -- cgit v1.2.3 From 7f3be652c1a8866251bfba9ea8b02067328f5db9 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 1 Aug 2012 19:15:52 -0300 Subject: perf session: Use perf_evlist__sample_type more extensively Removing perf_session->sample_type, as it can be obtained from the evsel/evlist. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-mnt1zwlik7sp7z6ljc9kyefg@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-report.c | 5 +++-- tools/perf/builtin-test.c | 10 ++-------- tools/perf/util/session.c | 31 ++++++++++++++++++++++--------- tools/perf/util/session.h | 11 +++-------- 4 files changed, 30 insertions(+), 27 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 69b1c118515..7c88a243b5d 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -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 " @@ -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; diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index 2ea5fe4cc94..e5032ed2f25 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c @@ -661,7 +661,7 @@ 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, @@ -756,12 +756,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); - /* * Now that all is properly set up, enable the events, they will * count just on workload.pid, which will start... @@ -787,7 +781,7 @@ static int test__PERF_RECORD(void) if (type < PERF_RECORD_MAX) nr_events[type]++; - err = perf_event__parse_sample(event, sample_type, + err = perf_event__parse_sample(event, evsel->attr.sample_type, evsel->sample_size, true, &sample, false); if (err < 0) { diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index b8da60d1ecb..00e180e116e 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -23,12 +23,20 @@ int perf_session__parse_sample(struct perf_session *session, struct perf_evsel *first; first = list_entry(session->evlist->entries.next, struct perf_evsel, node); - return perf_event__parse_sample(event, session->sample_type, + return perf_event__parse_sample(event, first->attr.sample_type, first->sample_size, session->sample_id_all, sample, session->header.needs_swap); } +int perf_session__synthesize_sample(struct perf_session *session, + union perf_event *event, + const struct perf_sample *sample) +{ + return perf_event__synthesize_sample(event, perf_evlist__sample_type(session->evlist), + sample, session->header.needs_swap); +} + static int perf_session__open(struct perf_session *self, bool force) { struct stat input_stat; @@ -95,7 +103,6 @@ out_close: void perf_session__update_sample_type(struct perf_session *self) { - self->sample_type = perf_evlist__sample_type(self->evlist); self->sample_id_all = perf_evlist__sample_id_all(self->evlist); self->id_hdr_size = perf_evlist__id_hdr_size(self->evlist); self->host_machine.id_hdr_size = self->id_hdr_size; @@ -877,16 +884,18 @@ static void perf_session__print_tstamp(struct perf_session *session, union perf_event *event, struct perf_sample *sample) { + u64 sample_type = perf_evlist__sample_type(session->evlist); + if (event->header.type != PERF_RECORD_SAMPLE && !session->sample_id_all) { fputs("-1 -1 ", stdout); return; } - if ((session->sample_type & PERF_SAMPLE_CPU)) + if ((sample_type & PERF_SAMPLE_CPU)) printf("%u ", sample->cpu); - if (session->sample_type & PERF_SAMPLE_TIME) + if (sample_type & PERF_SAMPLE_TIME) printf("%" PRIu64 " ", sample->time); } @@ -911,6 +920,8 @@ static void dump_event(struct perf_session *session, union perf_event *event, static void dump_sample(struct perf_session *session, union perf_event *event, struct perf_sample *sample) { + u64 sample_type; + if (!dump_trace) return; @@ -918,10 +929,12 @@ static void dump_sample(struct perf_session *session, union perf_event *event, event->header.misc, sample->pid, sample->tid, sample->ip, sample->period, sample->addr); - if (session->sample_type & PERF_SAMPLE_CALLCHAIN) + sample_type = perf_evlist__sample_type(session->evlist); + + if (sample_type & PERF_SAMPLE_CALLCHAIN) callchain__printf(sample); - if (session->sample_type & PERF_SAMPLE_BRANCH_STACK) + if (sample_type & PERF_SAMPLE_BRANCH_STACK) branch_stack__printf(sample); } @@ -1018,7 +1031,7 @@ static int perf_session__preprocess_sample(struct perf_session *session, union perf_event *event, struct perf_sample *sample) { if (event->header.type != PERF_RECORD_SAMPLE || - !(session->sample_type & PERF_SAMPLE_CALLCHAIN)) + !(perf_evlist__sample_type(session->evlist) & PERF_SAMPLE_CALLCHAIN)) return 0; if (!ip_callchain__valid(sample->callchain, event)) { @@ -1401,9 +1414,9 @@ int perf_session__process_events(struct perf_session *self, return err; } -bool perf_session__has_traces(struct perf_session *self, const char *msg) +bool perf_session__has_traces(struct perf_session *session, const char *msg) { - if (!(self->sample_type & PERF_SAMPLE_RAW)) { + if (!(perf_evlist__sample_type(session->evlist) & PERF_SAMPLE_RAW)) { pr_err("No trace sample to read. Did you call 'perf %s'?\n", msg); return false; } diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 4d549e28248..c45ce4348b8 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -41,7 +41,6 @@ struct perf_session { * perf.data file. */ struct hists hists; - u64 sample_type; int fd; bool fd_pipe; bool repipe; @@ -133,13 +132,9 @@ int perf_session__parse_sample(struct perf_session *session, const union perf_event *event, struct perf_sample *sample); -static inline int perf_session__synthesize_sample(struct perf_session *session, - union perf_event *event, - const struct perf_sample *sample) -{ - return perf_event__synthesize_sample(event, session->sample_type, - sample, session->header.needs_swap); -} +int perf_session__synthesize_sample(struct perf_session *session, + union perf_event *event, + const struct perf_sample *sample); struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, unsigned int type); -- cgit v1.2.3 From 5e5624745d7e4a2c956c072ef2542872955b59c4 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 1 Aug 2012 19:25:26 -0300 Subject: perf session: Use perf_evlist__sample_id_all more extensively Removing perf_session->sample_id_all, as it can be obtained from the evsel/evlist. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-ok58u1mlc5ci9b6p36r52uh1@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/session.c | 9 ++++----- tools/perf/util/session.h | 1 - 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 00e180e116e..348cc11385b 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -25,7 +25,7 @@ int perf_session__parse_sample(struct perf_session *session, return perf_event__parse_sample(event, first->attr.sample_type, first->sample_size, - session->sample_id_all, sample, + first->attr.sample_id_all, sample, session->header.needs_swap); } @@ -103,7 +103,6 @@ out_close: void perf_session__update_sample_type(struct perf_session *self) { - self->sample_id_all = perf_evlist__sample_id_all(self->evlist); self->id_hdr_size = perf_evlist__id_hdr_size(self->evlist); self->host_machine.id_hdr_size = self->id_hdr_size; machines__set_id_hdr_size(&self->machines, self->id_hdr_size); @@ -177,7 +176,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, } if (tool && tool->ordering_requires_timestamps && - tool->ordered_samples && !self->sample_id_all) { + tool->ordered_samples && !perf_evlist__sample_id_all(self->evlist)) { dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n"); tool->ordered_samples = false; } @@ -887,7 +886,7 @@ static void perf_session__print_tstamp(struct perf_session *session, u64 sample_type = perf_evlist__sample_type(session->evlist); if (event->header.type != PERF_RECORD_SAMPLE && - !session->sample_id_all) { + !perf_evlist__sample_id_all(session->evlist)) { fputs("-1 -1 ", stdout); return; } @@ -1090,7 +1089,7 @@ static int perf_session__process_event(struct perf_session *session, int ret; if (session->header.needs_swap) - event_swap(event, session->sample_id_all); + event_swap(event, perf_evlist__sample_id_all(session->evlist)); if (event->header.type >= PERF_RECORD_HEADER_MAX) return -EINVAL; diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index c45ce4348b8..a2c3ce9e716 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -44,7 +44,6 @@ struct perf_session { int fd; bool fd_pipe; bool repipe; - bool sample_id_all; u16 id_hdr_size; int cwdlen; char *cwd; -- cgit v1.2.3 From 7b56cce27123ccbf2cb82febbbc88443d719f1f8 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 1 Aug 2012 19:31:00 -0300 Subject: perf session: Use perf_evlist__id_hdr_size more extensively Removing perf_session->id_hdr_size, as it can be obtained from the evsel/evlist. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-1nwc2kslu7gsfblu98xbqbll@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 2 +- tools/perf/builtin-top.c | 2 +- tools/perf/util/session.c | 13 +++++++------ tools/perf/util/session.h | 3 +-- 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index f5a6452931e..dc2b62565aa 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -313,7 +313,7 @@ try_again: } } - perf_session__update_sample_type(session); + perf_session__set_id_hdr_size(session); } static int process_buildids(struct perf_record *rec) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 35e86c6df71..520e4256fc6 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1032,7 +1032,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); diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 348cc11385b..5b8601df239 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -101,11 +101,12 @@ out_close: return -1; } -void perf_session__update_sample_type(struct perf_session *self) +void perf_session__set_id_hdr_size(struct perf_session *session) { - self->id_hdr_size = perf_evlist__id_hdr_size(self->evlist); - self->host_machine.id_hdr_size = self->id_hdr_size; - machines__set_id_hdr_size(&self->machines, self->id_hdr_size); + u16 id_hdr_size = perf_evlist__id_hdr_size(session->evlist); + + session->host_machine.id_hdr_size = id_hdr_size; + machines__set_id_hdr_size(&session->machines, id_hdr_size); } int perf_session__create_kernel_maps(struct perf_session *self) @@ -165,7 +166,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, if (mode == O_RDONLY) { if (perf_session__open(self, force) < 0) goto out_delete; - perf_session__update_sample_type(self); + perf_session__set_id_hdr_size(self); } else if (mode == O_WRONLY) { /* * In O_RDONLY mode this will be performed when reading the @@ -1054,7 +1055,7 @@ static int perf_session__process_user_event(struct perf_session *session, union case PERF_RECORD_HEADER_ATTR: err = tool->attr(event, &session->evlist); if (err == 0) - perf_session__update_sample_type(session); + perf_session__set_id_hdr_size(session); return err; case PERF_RECORD_HEADER_EVENT_TYPE: return tool->event_type(tool, event); diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index a2c3ce9e716..e2a1a4b7b23 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -44,7 +44,6 @@ struct perf_session { int fd; bool fd_pipe; bool repipe; - u16 id_hdr_size; int cwdlen; char *cwd; struct ordered_samples ordered_samples; @@ -83,7 +82,7 @@ void perf_event__attr_swap(struct perf_event_attr *attr); int perf_session__create_kernel_maps(struct perf_session *self); -void perf_session__update_sample_type(struct perf_session *self); +void perf_session__set_id_hdr_size(struct perf_session *session); void perf_session__remove_thread(struct perf_session *self, struct thread *th); static inline -- cgit v1.2.3 From cb0b29e0861659c9eef9664772cd7e845ba1104a Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 2 Aug 2012 11:42:57 -0300 Subject: perf evlist: Introduce perf_evlist__parse_sample That is a more compact form of perf_session__parse_sample and to support multiple evlists per perf_session is the way to go anyway. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-vkxx3j5qktoj11bvcwmfjj13@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-test.c | 8 ++------ tools/perf/builtin-top.c | 2 +- tools/perf/util/evlist.c | 9 +++++++++ tools/perf/util/evlist.h | 4 ++++ tools/perf/util/python.c | 6 +----- tools/perf/util/session.c | 19 ++++--------------- tools/perf/util/session.h | 4 ---- 7 files changed, 21 insertions(+), 31 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index e5032ed2f25..1d592f5cbea 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c @@ -562,9 +562,7 @@ static int test__basic_mmap(void) goto out_munmap; } - err = perf_event__parse_sample(event, attr.sample_type, - evsels[0]->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; @@ -781,9 +779,7 @@ static int test__PERF_RECORD(void) if (type < PERF_RECORD_MAX) nr_events[type]++; - err = perf_event__parse_sample(event, evsel->attr.sample_type, - evsel->sample_size, true, - &sample, false); + err = perf_evlist__parse_sample(evlist, event, &sample, false); if (err < 0) { if (verbose) perf_event__fprintf(event, stderr); diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 520e4256fc6..40264eaa9f0 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -811,7 +811,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; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 3edfd348381..1a560e0904a 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -881,3 +881,12 @@ int perf_evlist__start_workload(struct perf_evlist *evlist) return 0; } + +int perf_evlist__parse_sample(struct perf_evlist *evlist, + const 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_event__parse_sample(event, e->attr.sample_type, e->sample_size, + e->attr.sample_id_all, sample, swapped); +} diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 40d4d3cdced..a5a49118a91 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -122,6 +122,10 @@ 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, + const 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); diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index b0d6f85e30f..0688bfb6d28 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -797,17 +797,13 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist, event = perf_evlist__mmap_read(evlist, cpu); if (event != NULL) { - struct perf_evsel *first; PyObject *pyevent = pyrf_event__new(event); struct pyrf_event *pevent = (struct pyrf_event *)pyevent; if (pyevent == NULL) return PyErr_NoMemory(); - first = list_entry(evlist->entries.next, struct perf_evsel, node); - err = perf_event__parse_sample(event, first->attr.sample_type, - first->sample_size, - sample_id_all, &pevent->sample, false); + err = perf_evlist__parse_sample(evlist, event, &pevent->sample, false); if (err) return PyErr_Format(PyExc_OSError, "perf: can't parse sample, err=%d", err); diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 5b8601df239..7d07324db41 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -16,19 +16,6 @@ #include "cpumap.h" #include "event-parse.h" -int perf_session__parse_sample(struct perf_session *session, - const union perf_event *event, - struct perf_sample *sample) -{ - struct perf_evsel *first; - first = list_entry(session->evlist->entries.next, struct perf_evsel, node); - - return perf_event__parse_sample(event, first->attr.sample_type, - first->sample_size, - first->attr.sample_id_all, sample, - session->header.needs_swap); -} - int perf_session__synthesize_sample(struct perf_session *session, union perf_event *event, const struct perf_sample *sample) @@ -692,7 +679,8 @@ static void flush_sample_queue(struct perf_session *s, if (iter->timestamp > limit) break; - ret = perf_session__parse_sample(s, iter->event, &sample); + ret = perf_evlist__parse_sample(s->evlist, iter->event, &sample, + s->header.needs_swap); if (ret) pr_err("Can't parse sample, err = %d\n", ret); else @@ -1103,7 +1091,8 @@ static int perf_session__process_event(struct perf_session *session, /* * For all kernel events we get the sample data */ - ret = perf_session__parse_sample(session, event, &sample); + ret = perf_evlist__parse_sample(session->evlist, event, &sample, + session->header.needs_swap); if (ret) return ret; diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index e2a1a4b7b23..7389fb1f010 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -126,10 +126,6 @@ size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp); -int perf_session__parse_sample(struct perf_session *session, - const union perf_event *event, - struct perf_sample *sample); - int perf_session__synthesize_sample(struct perf_session *session, union perf_event *event, const struct perf_sample *sample); -- cgit v1.2.3 From a3f698fe3082ff80a7f3b27c9b64b4b748c81f9d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 2 Aug 2012 12:23:46 -0300 Subject: perf evsel: Adopt parse_sample method from perf_event Since we need evsel->{attr.{sample_{id_all,type}},sample_size}, reducing the number of parameters tools have to pass. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-wdtmgak0ihgsmw1brb54a8h4@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/event.h | 3 --- tools/perf/util/evlist.c | 6 ++---- tools/perf/util/evlist.h | 3 +-- tools/perf/util/evsel.c | 12 ++++++------ tools/perf/util/evsel.h | 2 ++ 5 files changed, 11 insertions(+), 15 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 1b197280c62..d84870b0642 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -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); diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 1a560e0904a..9b38681add9 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -882,11 +882,9 @@ int perf_evlist__start_workload(struct perf_evlist *evlist) return 0; } -int perf_evlist__parse_sample(struct perf_evlist *evlist, - const union perf_event *event, +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_event__parse_sample(event, e->attr.sample_type, e->sample_size, - e->attr.sample_id_all, sample, swapped); + return perf_evsel__parse_sample(e, event, sample, swapped); } diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index a5a49118a91..528c1acd929 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -122,8 +122,7 @@ 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, - const union perf_event *event, +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); diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 8feec401135..2eaae140def 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -729,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; /* @@ -747,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) { @@ -896,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]); @@ -931,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); diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 894bd77d90c..b559929983b 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -180,4 +180,6 @@ static inline int perf_evsel__read_scaled(struct perf_evsel *evsel, 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 */ -- cgit v1.2.3 From 7405ed10f6adcdd556d59c360b5b216fccada3d9 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 2 Aug 2012 21:01:17 -0300 Subject: perf session: Remove no longer used synthesize_sample method Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-jd8tqbx8o8bs4t4g50vyhoc2@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/session.c | 8 -------- tools/perf/util/session.h | 4 ---- 2 files changed, 12 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 7d07324db41..2437fb0b463 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -16,14 +16,6 @@ #include "cpumap.h" #include "event-parse.h" -int perf_session__synthesize_sample(struct perf_session *session, - union perf_event *event, - const struct perf_sample *sample) -{ - return perf_event__synthesize_sample(event, perf_evlist__sample_type(session->evlist), - sample, session->header.needs_swap); -} - static int perf_session__open(struct perf_session *self, bool force) { struct stat input_stat; diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 7389fb1f010..1f7ec87db7d 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -126,10 +126,6 @@ size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp); -int perf_session__synthesize_sample(struct perf_session *session, - union perf_event *event, - const struct perf_sample *sample); - struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, unsigned int type); -- cgit v1.2.3 From 1a31fc904f1c897e4aaf7c3176e6aafa49f5d395 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Sun, 29 Jul 2012 20:53:03 -0600 Subject: perf top: Error handling for counter creation should parallel perf-record 5a7ed29 fixed up perf-record but not perf-top. Similar argument holds for it -- fallback to PMU only if it does not exist and handle invalid attributes separately. Signed-off-by: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Robert Richter Link: http://lkml.kernel.org/r/1343616783-6360-1-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 40264eaa9f0..34096275a7b 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -943,8 +943,10 @@ try_again: * 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"); -- cgit v1.2.3 From 56e6f602aa4432f7fe90a0d9ba379b2735b07b6b Mon Sep 17 00:00:00 2001 From: David Ahern Date: Sun, 29 Jul 2012 20:53:51 -0600 Subject: perf tool: Save cmdline from user in file header vs what is passed to record A number of builtin commands process some user args and then pass the rest to cmd_record. cmd_record then saves argc/argv that it receives into the header of the perf data file. But this loses the arguments handled by the first command -- ie., the real command line from the user. This patch saves the command line as typed by the user rather than what was passed to cmd_record. As an example consider the command: $ perf kvm --guest --host --guestmount=/tmp/guest-mount record -fo /tmp/perf.data -ag -- sleep 10 Currently the command saved to the header is: cmdline : /tmp/p3.5/perf record -o perf.data.kvm -fo /tmp/perf.data -ag -- sleep 1 (ignore the duplicated -o -- the first would be yet another bug with perf-kvm). With this patch the command line saved to the header is: cmdline : /tmp/p3.5/perf kvm --guest --host --guestmount=/tmp/guest-mount record -fo /tmp/perf.data -ag -- sleep 1 v2: simplified to saving the command in parse_options per Stephane's suggestion Signed-off-by: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1343616831-6408-1-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 2 -- tools/perf/util/header.c | 9 +++++++++ tools/perf/util/parse-options.c | 3 +++ 3 files changed, 12 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index dc2b62565aa..4db6e1ba54e 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -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; diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 3a6d2044333..74ea3c2f813 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -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 */ diff --git a/tools/perf/util/parse-options.c b/tools/perf/util/parse-options.c index 99d02aa57db..594f8fad5ec 100644 --- a/tools/perf/util/parse-options.c +++ b/tools/perf/util/parse-options.c @@ -1,6 +1,7 @@ #include "util.h" #include "parse-options.h" #include "cache.h" +#include "header.h" #define OPT_SHORT 1 #define OPT_UNSET 2 @@ -413,6 +414,8 @@ int parse_options(int argc, const char **argv, const struct option *options, { struct parse_opt_ctx_t ctx; + perf_header__set_cmdline(argc, argv); + parse_options_start(&ctx, argc, argv, flags); switch (parse_options_step(&ctx, options, usagestr)) { case PARSE_OPT_HELP: -- cgit v1.2.3 From 347ed9903a10179d1cf733d5d77072b283d89da3 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Sun, 29 Jul 2012 20:54:35 -0600 Subject: perf kvm: Use strtol for walking guestmount directory Only want to process directories under the guestmnount directory that have a pid as a name (ie, all digits). Other entries in the guestmount directory should be ignored. There is already a check that requires the first character of each entry to be a digit, but atoi is used to convert the directory name to a pid. For example if guestmount contains a directory with the name 1foo, atoi converts it to a pid of 1 and a machine is created with a pid of 1. This is wrong; this directory really should be ignored. Use strtol to do that. Signed-off-by: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1343616875-6455-1-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index fe86612afad..8b63b678e12 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -2875,6 +2875,7 @@ int machines__create_guest_kernel_maps(struct rb_root *machines) int i, items = 0; char path[PATH_MAX]; pid_t pid; + char *endp; if (symbol_conf.default_guest_vmlinux_name || symbol_conf.default_guest_modules || @@ -2891,7 +2892,14 @@ int machines__create_guest_kernel_maps(struct rb_root *machines) /* Filter out . and .. */ continue; } - pid = atoi(namelist[i]->d_name); + pid = (pid_t)strtol(namelist[i]->d_name, &endp, 10); + if ((*endp != '\0') || + (endp == namelist[i]->d_name) || + (errno == ERANGE)) { + pr_debug("invalid directory (%s). Skipping.\n", + namelist[i]->d_name); + continue; + } sprintf(path, "%s/%s/proc/kallsyms", symbol_conf.guestmount, namelist[i]->d_name); -- cgit v1.2.3 From 37bbd3fff1480a1f5d57abb9e9e56f468954c1b1 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Mon, 30 Jul 2012 22:31:32 -0600 Subject: perf tools: Introducing rblist rblist is the rbtree based code from strlist. It will be the common code for strlist and the to-be-introduced intlist. Signed-off-by: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1343709095-7089-2-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 2 + tools/perf/util/rblist.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/rblist.h | 47 +++++++++++++++++++++ 3 files changed, 156 insertions(+) create mode 100644 tools/perf/util/rblist.c create mode 100644 tools/perf/util/rblist.h (limited to 'tools') diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 77f124fe57a..285f700a783 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -319,6 +319,7 @@ 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_OBJS += $(OUTPUT)util/abspath.o LIB_OBJS += $(OUTPUT)util/alias.o @@ -383,6 +384,7 @@ 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 BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o diff --git a/tools/perf/util/rblist.c b/tools/perf/util/rblist.c new file mode 100644 index 00000000000..0171fb61100 --- /dev/null +++ b/tools/perf/util/rblist.c @@ -0,0 +1,107 @@ +/* + * Based on strlist.c by: + * (c) 2009 Arnaldo Carvalho de Melo + * + * Licensed under the GPLv2. + */ + +#include +#include +#include + +#include "rblist.h" + +int rblist__add_node(struct rblist *rblist, const void *new_entry) +{ + struct rb_node **p = &rblist->entries.rb_node; + struct rb_node *parent = NULL, *new_node; + + while (*p != NULL) { + int rc; + + parent = *p; + + rc = rblist->node_cmp(parent, new_entry); + if (rc > 0) + p = &(*p)->rb_left; + else if (rc < 0) + p = &(*p)->rb_right; + else + return -EEXIST; + } + + new_node = rblist->node_new(rblist, new_entry); + if (new_node == NULL) + return -ENOMEM; + + rb_link_node(new_node, parent, p); + rb_insert_color(new_node, &rblist->entries); + ++rblist->nr_entries; + + return 0; +} + +void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node) +{ + rb_erase(rb_node, &rblist->entries); + rblist->node_delete(rblist, rb_node); +} + +struct rb_node *rblist__find(struct rblist *rblist, const void *entry) +{ + struct rb_node **p = &rblist->entries.rb_node; + struct rb_node *parent = NULL; + + while (*p != NULL) { + int rc; + + parent = *p; + + rc = rblist->node_cmp(parent, entry); + if (rc > 0) + p = &(*p)->rb_left; + else if (rc < 0) + p = &(*p)->rb_right; + else + return parent; + } + + return NULL; +} + +void rblist__init(struct rblist *rblist) +{ + if (rblist != NULL) { + rblist->entries = RB_ROOT; + rblist->nr_entries = 0; + } + + return; +} + +void rblist__delete(struct rblist *rblist) +{ + if (rblist != NULL) { + struct rb_node *pos, *next = rb_first(&rblist->entries); + + while (next) { + pos = next; + next = rb_next(pos); + rb_erase(pos, &rblist->entries); + rblist->node_delete(rblist, pos); + } + free(rblist); + } +} + +struct rb_node *rblist__entry(const struct rblist *rblist, unsigned int idx) +{ + struct rb_node *node; + + for (node = rb_first(&rblist->entries); node; node = rb_next(node)) { + if (!idx--) + return node; + } + + return NULL; +} diff --git a/tools/perf/util/rblist.h b/tools/perf/util/rblist.h new file mode 100644 index 00000000000..6d0cae5ae83 --- /dev/null +++ b/tools/perf/util/rblist.h @@ -0,0 +1,47 @@ +#ifndef __PERF_RBLIST_H +#define __PERF_RBLIST_H + +#include +#include + +/* + * create node structs of the form: + * struct my_node { + * struct rb_node rb_node; + * ... my data ... + * }; + * + * create list structs of the form: + * struct mylist { + * struct rblist rblist; + * ... my data ... + * }; + */ + +struct rblist { + struct rb_root entries; + unsigned int nr_entries; + + int (*node_cmp)(struct rb_node *rbn, const void *entry); + struct rb_node *(*node_new)(struct rblist *rlist, const void *new_entry); + void (*node_delete)(struct rblist *rblist, struct rb_node *rb_node); +}; + +void rblist__init(struct rblist *rblist); +void rblist__delete(struct rblist *rblist); +int rblist__add_node(struct rblist *rblist, const void *new_entry); +void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node); +struct rb_node *rblist__find(struct rblist *rblist, const void *entry); +struct rb_node *rblist__entry(const struct rblist *rblist, unsigned int idx); + +static inline bool rblist__empty(const struct rblist *rblist) +{ + return rblist->nr_entries == 0; +} + +static inline unsigned int rblist__nr_entries(const struct rblist *rblist) +{ + return rblist->nr_entries; +} + +#endif /* __PERF_RBLIST_H */ -- cgit v1.2.3 From ee8dd3ca43f151d9fbe1edeef68fb8a77eb9f047 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Mon, 30 Jul 2012 22:31:33 -0600 Subject: perf tools: Change strlist to use the new rblist Replaces the direct use of rbtree code with the rblist API. In the end the patch is a no-op on strlist functionality; the API for strlist is not changed, only its implementaton. Signed-off-by: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1343709095-7089-3-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/strlist.c | 130 ++++++++++++++++++---------------------------- tools/perf/util/strlist.h | 11 ++-- 2 files changed, 57 insertions(+), 84 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/strlist.c b/tools/perf/util/strlist.c index 6783a204355..95856ff3dda 100644 --- a/tools/perf/util/strlist.c +++ b/tools/perf/util/strlist.c @@ -10,23 +10,28 @@ #include #include -static struct str_node *str_node__new(const char *s, bool dupstr) +static +struct rb_node *strlist__node_new(struct rblist *rblist, const void *entry) { - struct str_node *self = malloc(sizeof(*self)); + const char *s = entry; + struct rb_node *rc = NULL; + struct strlist *strlist = container_of(rblist, struct strlist, rblist); + struct str_node *snode = malloc(sizeof(*snode)); - if (self != NULL) { - if (dupstr) { + if (snode != NULL) { + if (strlist->dupstr) { s = strdup(s); if (s == NULL) goto out_delete; } - self->s = s; + snode->s = s; + rc = &snode->rb_node; } - return self; + return rc; out_delete: - free(self); + free(snode); return NULL; } @@ -37,36 +42,26 @@ static void str_node__delete(struct str_node *self, bool dupstr) free(self); } -int strlist__add(struct strlist *self, const char *new_entry) +static +void strlist__node_delete(struct rblist *rblist, struct rb_node *rb_node) { - struct rb_node **p = &self->entries.rb_node; - struct rb_node *parent = NULL; - struct str_node *sn; - - while (*p != NULL) { - int rc; - - parent = *p; - sn = rb_entry(parent, struct str_node, rb_node); - rc = strcmp(sn->s, new_entry); - - if (rc > 0) - p = &(*p)->rb_left; - else if (rc < 0) - p = &(*p)->rb_right; - else - return -EEXIST; - } + struct strlist *slist = container_of(rblist, struct strlist, rblist); + struct str_node *snode = container_of(rb_node, struct str_node, rb_node); - sn = str_node__new(new_entry, self->dupstr); - if (sn == NULL) - return -ENOMEM; + str_node__delete(snode, slist->dupstr); +} - rb_link_node(&sn->rb_node, parent, p); - rb_insert_color(&sn->rb_node, &self->entries); - ++self->nr_entries; +static int strlist__node_cmp(struct rb_node *rb_node, const void *entry) +{ + const char *str = entry; + struct str_node *snode = container_of(rb_node, struct str_node, rb_node); + + return strcmp(snode->s, str); +} - return 0; +int strlist__add(struct strlist *self, const char *new_entry) +{ + return rblist__add_node(&self->rblist, new_entry); } int strlist__load(struct strlist *self, const char *filename) @@ -96,34 +91,20 @@ out: return err; } -void strlist__remove(struct strlist *self, struct str_node *sn) +void strlist__remove(struct strlist *slist, struct str_node *snode) { - rb_erase(&sn->rb_node, &self->entries); - str_node__delete(sn, self->dupstr); + str_node__delete(snode, slist->dupstr); } -struct str_node *strlist__find(struct strlist *self, const char *entry) +struct str_node *strlist__find(struct strlist *slist, const char *entry) { - struct rb_node **p = &self->entries.rb_node; - struct rb_node *parent = NULL; - - while (*p != NULL) { - struct str_node *sn; - int rc; - - parent = *p; - sn = rb_entry(parent, struct str_node, rb_node); - rc = strcmp(sn->s, entry); - - if (rc > 0) - p = &(*p)->rb_left; - else if (rc < 0) - p = &(*p)->rb_right; - else - return sn; - } + struct str_node *snode = NULL; + struct rb_node *rb_node = rblist__find(&slist->rblist, entry); - return NULL; + if (rb_node) + snode = container_of(rb_node, struct str_node, rb_node); + + return snode; } static int strlist__parse_list_entry(struct strlist *self, const char *s) @@ -156,9 +137,12 @@ struct strlist *strlist__new(bool dupstr, const char *slist) struct strlist *self = malloc(sizeof(*self)); if (self != NULL) { - self->entries = RB_ROOT; + rblist__init(&self->rblist); + self->rblist.node_cmp = strlist__node_cmp; + self->rblist.node_new = strlist__node_new; + self->rblist.node_delete = strlist__node_delete; + self->dupstr = dupstr; - self->nr_entries = 0; if (slist && strlist__parse_list(self, slist) != 0) goto out_error; } @@ -171,30 +155,18 @@ out_error: void strlist__delete(struct strlist *self) { - if (self != NULL) { - struct str_node *pos; - struct rb_node *next = rb_first(&self->entries); - - while (next) { - pos = rb_entry(next, struct str_node, rb_node); - next = rb_next(&pos->rb_node); - strlist__remove(self, pos); - } - self->entries = RB_ROOT; - free(self); - } + if (self != NULL) + rblist__delete(&self->rblist); } -struct str_node *strlist__entry(const struct strlist *self, unsigned int idx) +struct str_node *strlist__entry(const struct strlist *slist, unsigned int idx) { - struct rb_node *nd; + struct str_node *snode = NULL; + struct rb_node *rb_node; - for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { - struct str_node *pos = rb_entry(nd, struct str_node, rb_node); + rb_node = rblist__entry(&slist->rblist, idx); + if (rb_node) + snode = container_of(rb_node, struct str_node, rb_node); - if (!idx--) - return pos; - } - - return NULL; + return snode; } diff --git a/tools/perf/util/strlist.h b/tools/perf/util/strlist.h index 3ba839007d2..dd9f922ec67 100644 --- a/tools/perf/util/strlist.h +++ b/tools/perf/util/strlist.h @@ -4,14 +4,15 @@ #include #include +#include "rblist.h" + struct str_node { struct rb_node rb_node; const char *s; }; struct strlist { - struct rb_root entries; - unsigned int nr_entries; + struct rblist rblist; bool dupstr; }; @@ -32,18 +33,18 @@ static inline bool strlist__has_entry(struct strlist *self, const char *entry) static inline bool strlist__empty(const struct strlist *self) { - return self->nr_entries == 0; + return rblist__empty(&self->rblist); } static inline unsigned int strlist__nr_entries(const struct strlist *self) { - return self->nr_entries; + return rblist__nr_entries(&self->rblist); } /* For strlist iteration */ static inline struct str_node *strlist__first(struct strlist *self) { - struct rb_node *rn = rb_first(&self->entries); + struct rb_node *rn = rb_first(&self->rblist.entries); return rn ? rb_entry(rn, struct str_node, rb_node) : NULL; } static inline struct str_node *strlist__next(struct str_node *sn) -- cgit v1.2.3 From 70b40c4a43ddfcf7a06dad4be32ff1dd2b62be09 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Mon, 30 Jul 2012 22:31:34 -0600 Subject: perf tools: Introduce intlist Built on rblist - like strlist. Used in the next patch. Signed-off-by: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1343709095-7089-4-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 2 + tools/perf/util/intlist.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/intlist.h | 75 ++++++++++++++++++++++++++++++++++ 3 files changed, 178 insertions(+) create mode 100644 tools/perf/util/intlist.c create mode 100644 tools/perf/util/intlist.h (limited to 'tools') diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 285f700a783..32912af430f 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -320,6 +320,7 @@ 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 @@ -385,6 +386,7 @@ 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 diff --git a/tools/perf/util/intlist.c b/tools/perf/util/intlist.c new file mode 100644 index 00000000000..fd530dced9c --- /dev/null +++ b/tools/perf/util/intlist.c @@ -0,0 +1,101 @@ +/* + * Based on intlist.c by: + * (c) 2009 Arnaldo Carvalho de Melo + * + * Licensed under the GPLv2. + */ + +#include +#include +#include + +#include "intlist.h" + +static struct rb_node *intlist__node_new(struct rblist *rblist __used, + const void *entry) +{ + int i = (int)((long)entry); + struct rb_node *rc = NULL; + struct int_node *node = malloc(sizeof(*node)); + + if (node != NULL) { + node->i = i; + rc = &node->rb_node; + } + + return rc; +} + +static void int_node__delete(struct int_node *ilist) +{ + free(ilist); +} + +static void intlist__node_delete(struct rblist *rblist __used, + struct rb_node *rb_node) +{ + struct int_node *node = container_of(rb_node, struct int_node, rb_node); + + int_node__delete(node); +} + +static int intlist__node_cmp(struct rb_node *rb_node, const void *entry) +{ + int i = (int)((long)entry); + struct int_node *node = container_of(rb_node, struct int_node, rb_node); + + return node->i - i; +} + +int intlist__add(struct intlist *ilist, int i) +{ + return rblist__add_node(&ilist->rblist, (void *)((long)i)); +} + +void intlist__remove(struct intlist *ilist __used, struct int_node *node) +{ + int_node__delete(node); +} + +struct int_node *intlist__find(struct intlist *ilist, int i) +{ + struct int_node *node = NULL; + struct rb_node *rb_node = rblist__find(&ilist->rblist, (void *)((long)i)); + + if (rb_node) + node = container_of(rb_node, struct int_node, rb_node); + + return node; +} + +struct intlist *intlist__new(void) +{ + struct intlist *ilist = malloc(sizeof(*ilist)); + + if (ilist != NULL) { + rblist__init(&ilist->rblist); + ilist->rblist.node_cmp = intlist__node_cmp; + ilist->rblist.node_new = intlist__node_new; + ilist->rblist.node_delete = intlist__node_delete; + } + + return ilist; +} + +void intlist__delete(struct intlist *ilist) +{ + if (ilist != NULL) + rblist__delete(&ilist->rblist); +} + +struct int_node *intlist__entry(const struct intlist *ilist, unsigned int idx) +{ + struct int_node *node = NULL; + struct rb_node *rb_node; + + rb_node = rblist__entry(&ilist->rblist, idx); + if (rb_node) + node = container_of(rb_node, struct int_node, rb_node); + + return node; +} diff --git a/tools/perf/util/intlist.h b/tools/perf/util/intlist.h new file mode 100644 index 00000000000..6d63ab90db5 --- /dev/null +++ b/tools/perf/util/intlist.h @@ -0,0 +1,75 @@ +#ifndef __PERF_INTLIST_H +#define __PERF_INTLIST_H + +#include +#include + +#include "rblist.h" + +struct int_node { + struct rb_node rb_node; + int i; +}; + +struct intlist { + struct rblist rblist; +}; + +struct intlist *intlist__new(void); +void intlist__delete(struct intlist *ilist); + +void intlist__remove(struct intlist *ilist, struct int_node *in); +int intlist__add(struct intlist *ilist, int i); + +struct int_node *intlist__entry(const struct intlist *ilist, unsigned int idx); +struct int_node *intlist__find(struct intlist *ilist, int i); + +static inline bool intlist__has_entry(struct intlist *ilist, int i) +{ + return intlist__find(ilist, i) != NULL; +} + +static inline bool intlist__empty(const struct intlist *ilist) +{ + return rblist__empty(&ilist->rblist); +} + +static inline unsigned int intlist__nr_entries(const struct intlist *ilist) +{ + return rblist__nr_entries(&ilist->rblist); +} + +/* For intlist iteration */ +static inline struct int_node *intlist__first(struct intlist *ilist) +{ + struct rb_node *rn = rb_first(&ilist->rblist.entries); + return rn ? rb_entry(rn, struct int_node, rb_node) : NULL; +} +static inline struct int_node *intlist__next(struct int_node *in) +{ + struct rb_node *rn; + if (!in) + return NULL; + rn = rb_next(&in->rb_node); + return rn ? rb_entry(rn, struct int_node, rb_node) : NULL; +} + +/** + * intlist_for_each - iterate over a intlist + * @pos: the &struct int_node to use as a loop cursor. + * @ilist: the &struct intlist for loop. + */ +#define intlist__for_each(pos, ilist) \ + for (pos = intlist__first(ilist); pos; pos = intlist__next(pos)) + +/** + * intlist_for_each_safe - iterate over a intlist safe against removal of + * int_node + * @pos: the &struct int_node to use as a loop cursor. + * @n: another &struct int_node to use as temporary storage. + * @ilist: the &struct intlist for loop. + */ +#define intlist__for_each_safe(pos, n, ilist) \ + for (pos = intlist__first(ilist), n = intlist__next(pos); pos;\ + pos = n, n = intlist__next(n)) +#endif /* __PERF_INTLIST_H */ -- cgit v1.2.3 From 6b118e92cc78ccef7b54a296158d4738fd377bcc Mon Sep 17 00:00:00 2001 From: David Ahern Date: Mon, 30 Jul 2012 22:31:35 -0600 Subject: perf kvm top: Limit guest kernel info message to once 'perf kvm top' shows a continual flurry of: Can't find guest [5201]'s kernel information if it can't find the guest info and with a lot of VMs running a user has no chance of reading them all. Limit message to once per guest. Signed-off-by: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1343709095-7089-5-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 34096275a7b..68cd61ef6ac 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -38,6 +38,7 @@ #include "util/cpumap.h" #include "util/xyarray.h" #include "util/sort.h" +#include "util/intlist.h" #include "util/debug.h" @@ -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; } -- cgit v1.2.3 From 7f309ed6453926a81e2a97d274f67f1e48f0d74c Mon Sep 17 00:00:00 2001 From: Palmer Cox Date: Sun, 29 Jul 2012 17:54:43 -0400 Subject: perf tools: Remove brace expansion from clean target The clean target uses brace expansion to remove some generated files. However, the default shells on many systems do not support this feature resulting in some generated files not being removed by clean. Signed-off-by: Palmer Cox Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1343598883-17907-1-git-send-email-p@lmercox.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 32912af430f..35655c3a7b7 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -987,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) -- cgit v1.2.3