2013-08-14 18:27:53

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [GIT PULL 00/21] perf/core improvements and fixes

From: Arnaldo Carvalho de Melo <[email protected]>

Hi Ingo,

Please consider pulling,

Flushing it out now before processing another batch.

- Arnaldo

The following changes since commit 0a3d23a2568ed5e73bd4fb532dc672fa9f03b1f1:

Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core (2013-08-12 10:14:47 +0200)

are available in the git repository at:


git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux tags/perf-core-for-mingo

for you to fetch changes up to 2ae3a312c0ccd8ff615372f00aab1700aac27474:

perf trace: Allow specifying which syscalls to trace (2013-08-14 11:44:21 -0300)

----------------------------------------------------------------
perf/core improvements and fixes:

. Allow specifying syscalls in 'perf trace', a la strace.

. Simplify symbol filtering by doing it at machine class level,
from Adrian Hunter.

. Add option to 'perf kvm' to print only events that exceed a specified time
duration, from David Ahern.

. 'perf sched' improvements, including removing some tracepoints that provide
the same information as the PERF_RECORD_{FORK,EXIT} events.

. Improve stack trace printing, from David Ahern.

. Update documentation with live command, from David Ahern

. Fix 'perf test' compile failure on do_sort_something, from David Ahern.

. Improve robustness of topology parsing code, from Stephane Eranian.

Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>

----------------------------------------------------------------
Adrian Hunter (8):
perf machine: Add symbol filter to struct machine
perf top: Set the machines symbol filter
perf report: Set the machines symbol filter
perf mem: Remove unused symbol filter member
perf annotate: Set the machines symbol filter
perf tools: Remove filter parameter of perf_event__preprocess_sample()
perf tools: Remove filter parameter of thread__find_addr_location()
perf tools: Remove filter parameter of thread__find_addr_map()

Arnaldo Carvalho de Melo (1):
perf trace: Allow specifying which syscalls to trace

David Ahern (11):
perf kvm: Option to print events that exceed a duration
perf kvm: Update documentation with live command
perf sched: Simplify arguments to read_events
perf sched: Remove thread lookup in sample handler
perf sched: Remove sched_process_exit tracepoint
perf sched: Remove sched_process_fork tracepoint
perf tool: Simplify options to perf_evsel__print_ip
perf evsel: Add option to print stack trace on single line
perf evsel: Add option to limit stack depth in callchain dumps
perf session: Change perf_session__has_traces to actually check for tracepoints
perf tests: Fix compile failure on do_sort_something

Stephane Eranian (1):
perf tools: Improve robustness of topology parsing code

tools/perf/Documentation/perf-kvm.txt | 46 +++++++++++++++-
tools/perf/Documentation/perf-trace.txt | 4 ++
tools/perf/builtin-annotate.c | 5 +-
tools/perf/builtin-diff.c | 2 +-
tools/perf/builtin-inject.c | 2 +-
tools/perf/builtin-kvm.c | 25 +++++++--
tools/perf/builtin-mem.c | 4 +-
tools/perf/builtin-report.c | 7 ++-
tools/perf/builtin-sched.c | 94 ++++++++++++++-------------------
tools/perf/builtin-script.c | 35 +++++++++---
tools/perf/builtin-top.c | 5 +-
tools/perf/builtin-trace.c | 52 +++++++++++++++---
tools/perf/perf.h | 3 ++
tools/perf/tests/code-reading.c | 13 +++--
tools/perf/tests/hists_link.c | 4 +-
tools/perf/util/build-id.c | 2 +-
tools/perf/util/event.c | 20 +++----
tools/perf/util/event.h | 3 +-
tools/perf/util/header.c | 11 ++--
tools/perf/util/machine.c | 28 ++++++++--
tools/perf/util/machine.h | 5 ++
tools/perf/util/session.c | 40 +++++++++-----
tools/perf/util/session.h | 8 ++-
tools/perf/util/thread.h | 5 +-
tools/perf/util/unwind.c | 6 +--
25 files changed, 294 insertions(+), 135 deletions(-)


2013-08-14 18:25:30

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 08/21] perf evsel: Add option to print stack trace on single line

From: David Ahern <[email protected]>

Option is used by upcoming timehist command.

Signed-off-by: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Stephane Eranian <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/session.c | 8 ++++++--
tools/perf/util/session.h | 1 +
2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index e5fd658..0d895e7 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1497,6 +1497,8 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event,
int print_sym = print_opts & PRINT_IP_OPT_SYM;
int print_dso = print_opts & PRINT_IP_OPT_DSO;
int print_symoffset = print_opts & PRINT_IP_OPT_SYMOFFSET;
+ int print_oneline = print_opts & PRINT_IP_OPT_ONELINE;
+ char s = print_oneline ? ' ' : '\t';

if (perf_event__preprocess_sample(event, machine, &al, sample,
NULL) < 0) {
@@ -1521,7 +1523,7 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event,
break;

if (print_ip)
- printf("%16" PRIx64, node->ip);
+ printf("%c%16" PRIx64, s, node->ip);

if (print_sym) {
printf(" ");
@@ -1537,7 +1539,9 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event,
map__fprintf_dsoname(node->map, stdout);
printf(")");
}
- printf("\n");
+
+ if (!print_oneline)
+ printf("\n");

callchain_cursor_advance(&callchain_cursor);
}
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 69e554a..7c00ccb 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -45,6 +45,7 @@ struct perf_session {
#define PRINT_IP_OPT_SYM (1<<1)
#define PRINT_IP_OPT_DSO (1<<2)
#define PRINT_IP_OPT_SYMOFFSET (1<<3)
+#define PRINT_IP_OPT_ONELINE (1<<4)

struct perf_tool;

--
1.8.1.4

2013-08-14 18:25:42

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 18/21] perf tools: Remove filter parameter of thread__find_addr_map()

From: Adrian Hunter <[email protected]>

Now that the symbol filter is recorded on the machine there is no need
to pass it to thread__find_addr_map(). So remove it.

Signed-off-by: Adrian Hunter <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Stephane Eranian <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-inject.c | 2 +-
tools/perf/builtin-script.c | 4 ++--
tools/perf/tests/code-reading.c | 2 +-
tools/perf/util/build-id.c | 2 +-
tools/perf/util/event.c | 9 ++++-----
tools/perf/util/thread.h | 2 +-
tools/perf/util/unwind.c | 4 ++--
7 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index f012a98..1d8de2e 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -206,7 +206,7 @@ static int perf_event__inject_buildid(struct perf_tool *tool,
}

thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION,
- event->ip.ip, &al, NULL);
+ event->ip.ip, &al);

if (al.map != NULL) {
if (!al.map->dso->hit) {
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index a7d623f..2ad9d5b 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -361,10 +361,10 @@ static void print_sample_addr(union perf_event *event,
return;

thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION,
- sample->addr, &al, NULL);
+ sample->addr, &al);
if (!al.map)
thread__find_addr_map(thread, machine, cpumode, MAP__VARIABLE,
- sample->addr, &al, NULL);
+ sample->addr, &al);

al.cpu = sample->cpu;
al.sym = NULL;
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 8e0943b..eec1421 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -147,7 +147,7 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode,
pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr);

thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, addr,
- &al, NULL);
+ &al);
if (!al.map || !al.map->dso) {
pr_debug("thread__find_addr_map failed\n");
return -1;
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index 3a0f508..5295625 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -33,7 +33,7 @@ int build_id__mark_dso_hit(struct perf_tool *tool __maybe_unused,
}

thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION,
- event->ip.ip, &al, NULL);
+ event->ip.ip, &al);

if (al.map != NULL)
al.map->dso->hit = 1;
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 9d301c9..49713ae 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -592,7 +592,7 @@ int perf_event__process(struct perf_tool *tool __maybe_unused,
void thread__find_addr_map(struct thread *self,
struct machine *machine, u8 cpumode,
enum map_type type, u64 addr,
- struct addr_location *al, symbol_filter_t filter)
+ struct addr_location *al)
{
struct map_groups *mg = &self->mg;
bool load_map = false;
@@ -663,7 +663,7 @@ try_again:
* must be done prior to using kernel maps.
*/
if (load_map)
- map__load(al->map, filter);
+ map__load(al->map, machine->symbol_filter);
al->addr = al->map->map_ip(al->map, al->addr);
}
}
@@ -672,8 +672,7 @@ void thread__find_addr_location(struct thread *thread, struct machine *machine,
u8 cpumode, enum map_type type, u64 addr,
struct addr_location *al)
{
- thread__find_addr_map(thread, machine, cpumode, type, addr, al,
- machine->symbol_filter);
+ thread__find_addr_map(thread, machine, cpumode, type, addr, al);
if (al->map != NULL)
al->sym = map__find_symbol(al->map, al->addr,
machine->symbol_filter);
@@ -709,7 +708,7 @@ int perf_event__preprocess_sample(const union perf_event *event,
machine__create_kernel_maps(machine);

thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION,
- event->ip.ip, al, machine->symbol_filter);
+ event->ip.ip, al);
dump_printf(" ...... dso: %s\n",
al->map ? al->map->dso->long_name :
al->level == 'H' ? "[hypervisor]" : "<not found>");
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 0ab47d8..13c62c9 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -41,7 +41,7 @@ static inline struct map *thread__find_map(struct thread *self,

void thread__find_addr_map(struct thread *thread, struct machine *machine,
u8 cpumode, enum map_type type, u64 addr,
- struct addr_location *al, symbol_filter_t filter);
+ struct addr_location *al);

void thread__find_addr_location(struct thread *thread, struct machine *machine,
u8 cpumode, enum map_type type, u64 addr,
diff --git a/tools/perf/util/unwind.c b/tools/perf/util/unwind.c
index abac3f9..2f891f7 100644
--- a/tools/perf/util/unwind.c
+++ b/tools/perf/util/unwind.c
@@ -272,7 +272,7 @@ static struct map *find_map(unw_word_t ip, struct unwind_info *ui)
struct addr_location al;

thread__find_addr_map(ui->thread, ui->machine, PERF_RECORD_MISC_USER,
- MAP__FUNCTION, ip, &al, NULL);
+ MAP__FUNCTION, ip, &al);
return al.map;
}

@@ -349,7 +349,7 @@ static int access_dso_mem(struct unwind_info *ui, unw_word_t addr,
ssize_t size;

thread__find_addr_map(ui->thread, ui->machine, PERF_RECORD_MISC_USER,
- MAP__FUNCTION, addr, &al, NULL);
+ MAP__FUNCTION, addr, &al);
if (!al.map) {
pr_debug("unwind: no map for %lx\n", (unsigned long)addr);
return -1;
--
1.8.1.4

2013-08-14 18:25:48

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 16/21] perf tools: Remove filter parameter of perf_event__preprocess_sample()

From: Adrian Hunter <[email protected]>

Now that the symbol filter is recorded on the machine there is no need
to pass it to perf_event__preprocess_sample(). So remove it.

Signed-off-by: Adrian Hunter <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Stephane Eranian <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-annotate.c | 3 +--
tools/perf/builtin-diff.c | 2 +-
tools/perf/builtin-mem.c | 3 +--
tools/perf/builtin-report.c | 3 +--
tools/perf/builtin-script.c | 2 +-
tools/perf/builtin-top.c | 3 +--
tools/perf/tests/hists_link.c | 4 ++--
tools/perf/util/event.c | 8 ++++----
tools/perf/util/event.h | 3 +--
tools/perf/util/session.c | 3 +--
10 files changed, 14 insertions(+), 20 deletions(-)

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 9754cb1..f988d38 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -90,8 +90,7 @@ static int process_sample_event(struct perf_tool *tool,
struct perf_annotate *ann = container_of(tool, struct perf_annotate, tool);
struct addr_location al;

- if (perf_event__preprocess_sample(event, machine, &al, sample,
- machine->symbol_filter) < 0) {
+ if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
pr_warning("problem processing %d event, skipping it.\n",
event->header.type);
return -1;
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 93de3ac..f28799e 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -319,7 +319,7 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused,
{
struct addr_location al;

- if (perf_event__preprocess_sample(event, machine, &al, sample, NULL) < 0) {
+ if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
pr_warning("problem processing %d event, skipping it.\n",
event->header.type);
return -1;
diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c
index f96168c..706a1fa 100644
--- a/tools/perf/builtin-mem.c
+++ b/tools/perf/builtin-mem.c
@@ -68,8 +68,7 @@ dump_raw_samples(struct perf_tool *tool,
struct addr_location al;
const char *fmt;

- if (perf_event__preprocess_sample(event, machine, &al, sample,
- NULL) < 0) {
+ if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
fprintf(stderr, "problem processing %d event, skipping it.\n",
event->header.type);
return -1;
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index f06a5a2..958a56a 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -304,8 +304,7 @@ static int process_sample_event(struct perf_tool *tool,
struct addr_location al;
int ret;

- if (perf_event__preprocess_sample(event, machine, &al, sample,
- machine->symbol_filter) < 0) {
+ if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
fprintf(stderr, "problem processing %d event, skipping it.\n",
event->header.type);
return -1;
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 33b2d83..a7d623f 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -520,7 +520,7 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
return 0;
}

- if (perf_event__preprocess_sample(event, machine, &al, sample, 0) < 0) {
+ if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
pr_err("problem processing %d event, skipping it.\n",
event->header.type);
return -1;
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index a63ade2..e37521f 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -716,8 +716,7 @@ static void perf_event__process_sample(struct perf_tool *tool,
if (event->header.misc & PERF_RECORD_MISC_EXACT_IP)
top->exact_samples++;

- if (perf_event__preprocess_sample(event, machine, &al, sample,
- machine->symbol_filter) < 0 ||
+ if (perf_event__preprocess_sample(event, machine, &al, sample) < 0 ||
al.filtered)
return;

diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c
index 89085a9..50bfb01 100644
--- a/tools/perf/tests/hists_link.c
+++ b/tools/perf/tests/hists_link.c
@@ -220,7 +220,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
};

if (perf_event__preprocess_sample(&event, machine, &al,
- &sample, 0) < 0)
+ &sample) < 0)
goto out;

he = __hists__add_entry(&evsel->hists, &al, NULL, 1, 1);
@@ -244,7 +244,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
};

if (perf_event__preprocess_sample(&event, machine, &al,
- &sample, 0) < 0)
+ &sample) < 0)
goto out;

he = __hists__add_entry(&evsel->hists, &al, NULL, 1, 1);
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index cc7c0c9..f3cf771 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -683,8 +683,7 @@ void thread__find_addr_location(struct thread *thread, struct machine *machine,
int perf_event__preprocess_sample(const union perf_event *event,
struct machine *machine,
struct addr_location *al,
- struct perf_sample *sample,
- symbol_filter_t filter)
+ struct perf_sample *sample)
{
u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
struct thread *thread = machine__findnew_thread(machine, event->ip.pid);
@@ -709,7 +708,7 @@ int perf_event__preprocess_sample(const union perf_event *event,
machine__create_kernel_maps(machine);

thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION,
- event->ip.ip, al, filter);
+ event->ip.ip, al, machine->symbol_filter);
dump_printf(" ...... dso: %s\n",
al->map ? al->map->dso->long_name :
al->level == 'H' ? "[hypervisor]" : "<not found>");
@@ -727,7 +726,8 @@ int perf_event__preprocess_sample(const union perf_event *event,
dso->long_name)))))
goto out_filtered;

- al->sym = map__find_symbol(al->map, al->addr, filter);
+ al->sym = map__find_symbol(al->map, al->addr,
+ machine->symbol_filter);
}

if (symbol_conf.sym_list &&
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 6119a64..15db071 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -234,8 +234,7 @@ struct addr_location;
int perf_event__preprocess_sample(const union perf_event *self,
struct machine *machine,
struct addr_location *al,
- struct perf_sample *sample,
- symbol_filter_t filter);
+ struct perf_sample *sample);

const char *perf_event__name(unsigned int id);

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 4d9028e..de16a77 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1503,8 +1503,7 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event,
int print_oneline = print_opts & PRINT_IP_OPT_ONELINE;
char s = print_oneline ? ' ' : '\t';

- if (perf_event__preprocess_sample(event, machine, &al, sample,
- NULL) < 0) {
+ if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
error("problem processing %d event, skipping it.\n",
event->header.type);
return;
--
1.8.1.4

2013-08-14 18:25:40

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 21/21] perf trace: Allow specifying which syscalls to trace

From: Arnaldo Carvalho de Melo <[email protected]>

Similar to -e in strace, i.e. a comma separated list of syscall names
to trace.

Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Stephane Eranian <[email protected]>
Link: http://lkml.kernel.org/n/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/Documentation/perf-trace.txt | 4 +++
tools/perf/builtin-trace.c | 52 +++++++++++++++++++++++++++++----
2 files changed, 50 insertions(+), 6 deletions(-)

diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt
index 68718cc..3b3552a 100644
--- a/tools/perf/Documentation/perf-trace.txt
+++ b/tools/perf/Documentation/perf-trace.txt
@@ -26,6 +26,10 @@ OPTIONS
--all-cpus::
System-wide collection from all CPUs.

+-e::
+--expr::
+ List of events to show, currently only syscall names.
+
-p::
--pid=::
Record events on existing process ID (comma separated list).
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index da7ae01..120fdfb 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -5,6 +5,7 @@
#include "util/machine.h"
#include "util/thread.h"
#include "util/parse-options.h"
+#include "util/strlist.h"
#include "util/thread_map.h"

#include <libaudit.h>
@@ -47,6 +48,7 @@ static struct syscall_fmt *syscall_fmt__find(const char *name)
struct syscall {
struct event_format *tp_format;
const char *name;
+ bool filtered;
struct syscall_fmt *fmt;
};

@@ -110,6 +112,7 @@ struct trace {
struct perf_record_opts opts;
struct machine host;
u64 base_time;
+ struct strlist *ev_qualifier;
unsigned long nr_events;
bool sched;
bool multiple_threads;
@@ -226,6 +229,16 @@ static int trace__read_syscall_info(struct trace *trace, int id)

sc = trace->syscalls.table + id;
sc->name = name;
+
+ if (trace->ev_qualifier && !strlist__find(trace->ev_qualifier, name)) {
+ sc->filtered = true;
+ /*
+ * No need to do read tracepoint information since this will be
+ * filtered out.
+ */
+ return 0;
+ }
+
sc->fmt = syscall_fmt__find(sc->name);

snprintf(tp_name, sizeof(tp_name), "sys_enter_%s", sc->name);
@@ -302,11 +315,19 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
char *msg;
void *args;
size_t printed = 0;
- struct thread *thread = machine__findnew_thread(&trace->host, sample->tid);
+ struct thread *thread;
struct syscall *sc = trace__syscall_info(trace, evsel, sample);
- struct thread_trace *ttrace = thread__trace(thread);
+ struct thread_trace *ttrace;
+
+ if (sc == NULL)
+ return -1;

- if (ttrace == NULL || sc == NULL)
+ if (sc->filtered)
+ return 0;
+
+ thread = machine__findnew_thread(&trace->host, sample->tid);
+ ttrace = thread__trace(thread);
+ if (ttrace == NULL)
return -1;

args = perf_evsel__rawptr(evsel, sample, "args");
@@ -345,11 +366,19 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
{
int ret;
u64 duration = 0;
- struct thread *thread = machine__findnew_thread(&trace->host, sample->tid);
- struct thread_trace *ttrace = thread__trace(thread);
+ struct thread *thread;
struct syscall *sc = trace__syscall_info(trace, evsel, sample);
+ struct thread_trace *ttrace;
+
+ if (sc == NULL)
+ return -1;

- if (ttrace == NULL || sc == NULL)
+ if (sc->filtered)
+ return 0;
+
+ thread = machine__findnew_thread(&trace->host, sample->tid);
+ ttrace = thread__trace(thread);
+ if (ttrace == NULL)
return -1;

ret = perf_evsel__intval(evsel, sample, "ret");
@@ -634,7 +663,10 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
.mmap_pages = 1024,
},
};
+ const char *ev_qualifier_str = NULL;
const struct option trace_options[] = {
+ OPT_STRING('e', "expr", &ev_qualifier_str, "expr",
+ "list of events to trace"),
OPT_STRING('p', "pid", &trace.opts.target.pid, "pid",
"trace events on existing process id"),
OPT_STRING(0, "tid", &trace.opts.target.tid, "tid",
@@ -660,6 +692,14 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)

argc = parse_options(argc, argv, trace_options, trace_usage, 0);

+ if (ev_qualifier_str != NULL) {
+ trace.ev_qualifier = strlist__new(true, ev_qualifier_str);
+ if (trace.ev_qualifier == NULL) {
+ puts("Not enough memory to parse event qualifier");
+ return -ENOMEM;
+ }
+ }
+
err = perf_target__validate(&trace.opts.target);
if (err) {
perf_target__strerror(&trace.opts.target, err, bf, sizeof(bf));
--
1.8.1.4

2013-08-14 18:25:38

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 12/21] perf top: Set the machines symbol filter

From: Adrian Hunter <[email protected]>

Take into use the machines symbol filter member.

Signed-off-by: Adrian Hunter <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Stephane Eranian <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-top.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 440c3b3..a63ade2 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -717,7 +717,7 @@ static void perf_event__process_sample(struct perf_tool *tool,
top->exact_samples++;

if (perf_event__preprocess_sample(event, machine, &al, sample,
- symbol_filter) < 0 ||
+ machine->symbol_filter) < 0 ||
al.filtered)
return;

@@ -938,6 +938,8 @@ static int __cmd_top(struct perf_top *top)
if (top->session == NULL)
return -ENOMEM;

+ machines__set_symbol_filter(&top->session->machines, symbol_filter);
+
if (!objdump_path) {
ret = perf_session_env__lookup_objdump(&top->session->header.env);
if (ret)
--
1.8.1.4

2013-08-14 18:26:49

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 17/21] perf tools: Remove filter parameter of thread__find_addr_location()

From: Adrian Hunter <[email protected]>

Now that the symbol filter is recorded on the machine there is no need
to pass it to thread__find_addr_location(). So remove it.

Signed-off-by: Adrian Hunter <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Stephane Eranian <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/event.c | 9 +++++----
tools/perf/util/machine.c | 8 ++++----
tools/perf/util/thread.h | 3 +--
tools/perf/util/unwind.c | 2 +-
4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index f3cf771..9d301c9 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -670,12 +670,13 @@ try_again:

void thread__find_addr_location(struct thread *thread, struct machine *machine,
u8 cpumode, enum map_type type, u64 addr,
- struct addr_location *al,
- symbol_filter_t filter)
+ struct addr_location *al)
{
- thread__find_addr_map(thread, machine, cpumode, type, addr, al, filter);
+ thread__find_addr_map(thread, machine, cpumode, type, addr, al,
+ machine->symbol_filter);
if (al->map != NULL)
- al->sym = map__find_symbol(al->map, al->addr, filter);
+ al->sym = map__find_symbol(al->map, al->addr,
+ machine->symbol_filter);
else
al->sym = NULL;
}
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 4c7e0a28..4514e7e 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1130,7 +1130,7 @@ static void ip__resolve_ams(struct machine *machine, struct thread *thread,
* or else, the symbol is unknown
*/
thread__find_addr_location(thread, machine, m, MAP__FUNCTION,
- ip, &al, NULL);
+ ip, &al);
if (al.sym)
goto found;
}
@@ -1148,8 +1148,8 @@ static void ip__resolve_data(struct machine *machine, struct thread *thread,

memset(&al, 0, sizeof(al));

- thread__find_addr_location(thread, machine, m, MAP__VARIABLE, addr, &al,
- NULL);
+ thread__find_addr_location(thread, machine, m, MAP__VARIABLE, addr,
+ &al);
ams->addr = addr;
ams->al_addr = al.addr;
ams->sym = al.sym;
@@ -1244,7 +1244,7 @@ static int machine__resolve_callchain_sample(struct machine *machine,

al.filtered = false;
thread__find_addr_location(thread, machine, cpumode,
- MAP__FUNCTION, ip, &al, NULL);
+ MAP__FUNCTION, ip, &al);
if (al.sym != NULL) {
if (sort__has_parent && !*parent &&
symbol__match_regex(al.sym, &parent_regex))
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index f98d1d9..0ab47d8 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -45,8 +45,7 @@ void thread__find_addr_map(struct thread *thread, struct machine *machine,

void thread__find_addr_location(struct thread *thread, struct machine *machine,
u8 cpumode, enum map_type type, u64 addr,
- struct addr_location *al,
- symbol_filter_t filter);
+ struct addr_location *al);

static inline void *thread__priv(struct thread *thread)
{
diff --git a/tools/perf/util/unwind.c b/tools/perf/util/unwind.c
index 5bbd494..abac3f9 100644
--- a/tools/perf/util/unwind.c
+++ b/tools/perf/util/unwind.c
@@ -473,7 +473,7 @@ static int entry(u64 ip, struct thread *thread, struct machine *machine,

thread__find_addr_location(thread, machine,
PERF_RECORD_MISC_USER,
- MAP__FUNCTION, ip, &al, NULL);
+ MAP__FUNCTION, ip, &al);

e.ip = ip;
e.map = al.map;
--
1.8.1.4

2013-08-14 18:25:36

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 13/21] perf report: Set the machines symbol filter

From: Adrian Hunter <[email protected]>

Take into use the machines' symbol filter member.

Signed-off-by: Adrian Hunter <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Stephane Eranian <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-report.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index d785d89..f06a5a2 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -49,7 +49,6 @@ struct perf_report {
bool mem_mode;
struct perf_read_values show_threads_values;
const char *pretty_printing_style;
- symbol_filter_t annotate_init;
const char *cpu_list;
const char *symbol_filter_str;
float min_percent;
@@ -306,7 +305,7 @@ static int process_sample_event(struct perf_tool *tool,
int ret;

if (perf_event__preprocess_sample(event, machine, &al, sample,
- rep->annotate_init) < 0) {
+ machine->symbol_filter) < 0) {
fprintf(stderr, "problem processing %d event, skipping it.\n",
event->header.type);
return -1;
@@ -924,7 +923,8 @@ repeat:
*/
if (use_browser == 1 && sort__has_sym) {
symbol_conf.priv_size = sizeof(struct annotation);
- report.annotate_init = symbol__annotate_init;
+ machines__set_symbol_filter(&session->machines,
+ symbol__annotate_init);
/*
* For searching by name on the "Browse map details".
* providing it only in verbose mode not to bloat too
--
1.8.1.4

2013-08-14 18:27:16

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 14/21] perf mem: Remove unused symbol filter member

From: Adrian Hunter <[email protected]>

Member 'annotate_init' of struct perf_mem is unused. Remove it.

Signed-off-by: Adrian Hunter <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Stephane Eranian <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-mem.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c
index a8ff6d2..f96168c 100644
--- a/tools/perf/builtin-mem.c
+++ b/tools/perf/builtin-mem.c
@@ -14,7 +14,6 @@ static const char *mem_operation = MEM_OPERATION_LOAD;
struct perf_mem {
struct perf_tool tool;
char const *input_name;
- symbol_filter_t annotate_init;
bool hide_unresolved;
bool dump_raw;
const char *cpu_list;
@@ -70,7 +69,7 @@ dump_raw_samples(struct perf_tool *tool,
const char *fmt;

if (perf_event__preprocess_sample(event, machine, &al, sample,
- mem->annotate_init) < 0) {
+ NULL) < 0) {
fprintf(stderr, "problem processing %d event, skipping it.\n",
event->header.type);
return -1;
--
1.8.1.4

2013-08-14 18:27:35

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 15/21] perf annotate: Set the machines symbol filter

From: Adrian Hunter <[email protected]>

Take into use the machines symbol filter member.

Signed-off-by: Adrian Hunter <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Stephane Eranian <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-annotate.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index db491e9..9754cb1 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -91,7 +91,7 @@ static int process_sample_event(struct perf_tool *tool,
struct addr_location al;

if (perf_event__preprocess_sample(event, machine, &al, sample,
- symbol__annotate_init) < 0) {
+ machine->symbol_filter) < 0) {
pr_warning("problem processing %d event, skipping it.\n",
event->header.type);
return -1;
@@ -195,6 +195,8 @@ static int __cmd_annotate(struct perf_annotate *ann)
if (session == NULL)
return -ENOMEM;

+ machines__set_symbol_filter(&session->machines, symbol__annotate_init);
+
if (ann->cpu_list) {
ret = perf_session__cpu_bitmap(session, ann->cpu_list,
ann->cpu_bitmap);
--
1.8.1.4

2013-08-14 18:27:54

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 11/21] perf machine: Add symbol filter to struct machine

From: Adrian Hunter <[email protected]>

The symbol filter needs to be applied machine-wide, so add it to struct
machine.

Currently tools pass the symbol filter as a parameter to various
map-related functions. However a need to load a map can occur anywhere
in the code, at which point the filter is needed.

Signed-off-by: Adrian Hunter <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Stephane Eranian <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/machine.c | 20 ++++++++++++++++++++
tools/perf/util/machine.h | 5 +++++
2 files changed, 25 insertions(+)

diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 6fcc358..4c7e0a28 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -25,6 +25,8 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
machine->kmaps.machine = machine;
machine->pid = pid;

+ machine->symbol_filter = NULL;
+
machine->root_dir = strdup(root_dir);
if (machine->root_dir == NULL)
return -ENOMEM;
@@ -95,6 +97,7 @@ void machines__init(struct machines *machines)
{
machine__init(&machines->host, "", HOST_KERNEL_ID);
machines->guests = RB_ROOT;
+ machines->symbol_filter = NULL;
}

void machines__exit(struct machines *machines)
@@ -118,6 +121,8 @@ struct machine *machines__add(struct machines *machines, pid_t pid,
return NULL;
}

+ machine->symbol_filter = machines->symbol_filter;
+
while (*p != NULL) {
parent = *p;
pos = rb_entry(parent, struct machine, rb_node);
@@ -133,6 +138,21 @@ struct machine *machines__add(struct machines *machines, pid_t pid,
return machine;
}

+void machines__set_symbol_filter(struct machines *machines,
+ symbol_filter_t symbol_filter)
+{
+ struct rb_node *nd;
+
+ machines->symbol_filter = symbol_filter;
+ machines->host.symbol_filter = symbol_filter;
+
+ for (nd = rb_first(&machines->guests); nd; nd = rb_next(nd)) {
+ struct machine *machine = rb_entry(nd, struct machine, rb_node);
+
+ machine->symbol_filter = symbol_filter;
+ }
+}
+
struct machine *machines__find(struct machines *machines, pid_t pid)
{
struct rb_node **p = &machines->guests.rb_node;
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index 5bb6244..603ffba 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -29,6 +29,7 @@ struct machine {
struct list_head kernel_dsos;
struct map_groups kmaps;
struct map *vmlinux_maps[MAP__NR_TYPES];
+ symbol_filter_t symbol_filter;
};

static inline
@@ -51,6 +52,7 @@ typedef void (*machine__process_t)(struct machine *machine, void *data);
struct machines {
struct machine host;
struct rb_root guests;
+ symbol_filter_t symbol_filter;
};

void machines__init(struct machines *machines);
@@ -68,6 +70,9 @@ struct machine *machines__findnew(struct machines *machines, pid_t pid);
void machines__set_id_hdr_size(struct machines *machines, u16 id_hdr_size);
char *machine__mmap_name(struct machine *machine, char *bf, size_t size);

+void machines__set_symbol_filter(struct machines *machines,
+ symbol_filter_t symbol_filter);
+
int machine__init(struct machine *machine, const char *root_dir, pid_t pid);
void machine__exit(struct machine *machine);
void machine__delete_dead_threads(struct machine *machine);
--
1.8.1.4

2013-08-14 18:27:51

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 20/21] perf tools: Improve robustness of topology parsing code

From: Stephane Eranian <[email protected]>

This patch improves the robustness of the build_cpu_topo() routine by
allowing either the CPU parsing or the thread parsing to fail and yet
get perf to produce some topology data which could be useful for the
analysis.

Without this patch, if the cpu parsing fails, the thread parsing is not
attempted vice-versa.

Signed-off-by: Stephane Eranian <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/20130814100426.GA3444@quad
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/header.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index f558f83..a33197a 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -716,18 +716,19 @@ static int build_cpu_topo(struct cpu_topo *tp, int cpu)
char filename[MAXPATHLEN];
char *buf = NULL, *p;
size_t len = 0;
+ ssize_t sret;
u32 i = 0;
int ret = -1;

sprintf(filename, CORE_SIB_FMT, cpu);
fp = fopen(filename, "r");
if (!fp)
- return -1;
-
- if (getline(&buf, &len, fp) <= 0)
- goto done;
+ goto try_threads;

+ sret = getline(&buf, &len, fp);
fclose(fp);
+ if (sret <= 0)
+ goto try_threads;

p = strchr(buf, '\n');
if (p)
@@ -743,7 +744,9 @@ static int build_cpu_topo(struct cpu_topo *tp, int cpu)
buf = NULL;
len = 0;
}
+ ret = 0;

+try_threads:
sprintf(filename, THRD_SIB_FMT, cpu);
fp = fopen(filename, "r");
if (!fp)
--
1.8.1.4

2013-08-14 18:28:53

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 19/21] perf tests: Fix compile failure on do_sort_something

From: David Ahern <[email protected]>

Commit b55ae0a9 added code-reading.c which fails to compile on Fedora 16
with compiler version:
$ gcc --version
gcc (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2)

Failure message is:

tests/code-reading.c: In function ‘do_sort_something’:
tests/code-reading.c:305:13: error: stack protector not protecting local variables: variable length buffer [-Werror=stack-protector]
cc1: all warnings being treated as errors
make: *** [/tmp/junk/tests/code-reading.o] Error 1
make: *** Waiting for unfinished jobs....

v2: as Adrian noticed changed sizeof to ARRAY_SIZE

Signed-off-by: David Ahern <[email protected]>
Acked-by: Adrian Hunter <[email protected]>
Cc: Adrian Hunter <[email protected]>
Cc: Jiri Olsa <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/tests/code-reading.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index eec1421..df9afd9 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -304,15 +304,14 @@ static int comp(const void *a, const void *b)

static void do_sort_something(void)
{
- size_t sz = 40960;
- int buf[sz], i;
+ int buf[40960], i;

- for (i = 0; i < (int)sz; i++)
- buf[i] = sz - i - 1;
+ for (i = 0; i < (int)ARRAY_SIZE(buf); i++)
+ buf[i] = ARRAY_SIZE(buf) - i - 1;

- qsort(buf, sz, sizeof(int), comp);
+ qsort(buf, ARRAY_SIZE(buf), sizeof(int), comp);

- for (i = 0; i < (int)sz; i++) {
+ for (i = 0; i < (int)ARRAY_SIZE(buf); i++) {
if (buf[i] != i) {
pr_debug("qsort failed\n");
break;
--
1.8.1.4

2013-08-14 18:25:29

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 04/21] perf sched: Remove thread lookup in sample handler

From: David Ahern <[email protected]>

Not used in the function, so no sense in doing the lookup here. Thread
look up will be done in the timehist command, and no sense in doing it
twice.

Signed-off-by: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Stephane Eranian <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-sched.c | 7 -------
1 file changed, 7 deletions(-)

diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 34ce57d..5285024 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1425,15 +1425,8 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool __maybe_
struct perf_evsel *evsel,
struct machine *machine)
{
- struct thread *thread = machine__findnew_thread(machine, sample->tid);
int err = 0;

- if (thread == NULL) {
- pr_debug("problem processing %s event, skipping it.\n",
- perf_evsel__name(evsel));
- return -1;
- }
-
evsel->hists.stats.total_period += sample->period;
hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);

--
1.8.1.4

2013-08-14 18:25:27

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 03/21] perf sched: Simplify arguments to read_events

From: David Ahern <[email protected]>

Destroy argument is not necessary. If session is not returned to caller,
then clean it up.

Signed-off-by: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Stephane Eranian <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-sched.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 948183a..34ce57d 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1445,7 +1445,7 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool __maybe_
return err;
}

-static int perf_sched__read_events(struct perf_sched *sched, bool destroy,
+static int perf_sched__read_events(struct perf_sched *sched,
struct perf_session **psession)
{
const struct perf_evsel_str_handler handlers[] = {
@@ -1480,11 +1480,10 @@ static int perf_sched__read_events(struct perf_sched *sched, bool destroy,
sched->nr_lost_chunks = session->stats.nr_events[PERF_RECORD_LOST];
}

- if (destroy)
- perf_session__delete(session);
-
if (psession)
*psession = session;
+ else
+ perf_session__delete(session);

return 0;

@@ -1529,8 +1528,11 @@ static int perf_sched__lat(struct perf_sched *sched)
struct perf_session *session;

setup_pager();
- if (perf_sched__read_events(sched, false, &session))
+
+ /* save session -- references to threads are held in work_list */
+ if (perf_sched__read_events(sched, &session))
return -1;
+
perf_sched__sort_lat(sched);

printf("\n ---------------------------------------------------------------------------------------------------------------\n");
@@ -1565,7 +1567,7 @@ static int perf_sched__map(struct perf_sched *sched)
sched->max_cpu = sysconf(_SC_NPROCESSORS_CONF);

setup_pager();
- if (perf_sched__read_events(sched, true, NULL))
+ if (perf_sched__read_events(sched, NULL))
return -1;
print_bad_events(sched);
return 0;
@@ -1580,7 +1582,7 @@ static int perf_sched__replay(struct perf_sched *sched)

test_calibrations(sched);

- if (perf_sched__read_events(sched, true, NULL))
+ if (perf_sched__read_events(sched, NULL))
return -1;

printf("nr_run_events: %ld\n", sched->nr_run_events);
--
1.8.1.4

2013-08-14 18:25:25

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 01/21] perf kvm: Option to print events that exceed a duration

From: David Ahern <[email protected]>

This is useful to spot high latency blips. It is normal for HLT reasons
to have long exit times, so strip those from the duration check.

v2: changed threshold to duration per acme's request

Signed-off-by: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Runzhen Wang <[email protected]>
Cc: Xiao Guangrong <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-kvm.c | 25 +++++++++++++++++++++----
tools/perf/perf.h | 3 +++
2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 2ceec81..fa2f3d7 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -106,6 +106,7 @@ struct perf_kvm_stat {
u64 total_time;
u64 total_count;
u64 lost_events;
+ u64 duration;

const char *pid_str;
struct intlist *pid_list;
@@ -473,7 +474,7 @@ static bool update_kvm_event(struct kvm_event *event, int vcpu_id,
static bool handle_end_event(struct perf_kvm_stat *kvm,
struct vcpu_event_record *vcpu_record,
struct event_key *key,
- u64 timestamp)
+ struct perf_sample *sample)
{
struct kvm_event *event;
u64 time_begin, time_diff;
@@ -510,12 +511,24 @@ static bool handle_end_event(struct perf_kvm_stat *kvm,
vcpu_record->start_time = 0;

/* seems to happen once in a while during live mode */
- if (timestamp < time_begin) {
+ if (sample->time < time_begin) {
pr_debug("End time before begin time; skipping event.\n");
return true;
}

- time_diff = timestamp - time_begin;
+ time_diff = sample->time - time_begin;
+
+ if (kvm->duration && time_diff > kvm->duration) {
+ char decode[32];
+
+ kvm->events_ops->decode_key(kvm, &event->key, decode);
+ if (strcmp(decode, "HLT")) {
+ pr_info("%" PRIu64 " VM %d, vcpu %d: %s event took %" PRIu64 "usec\n",
+ sample->time, sample->pid, vcpu_record->vcpu_id,
+ decode, time_diff/1000);
+ }
+ }
+
return update_kvm_event(event, vcpu, time_diff);
}

@@ -562,7 +575,7 @@ static bool handle_kvm_event(struct perf_kvm_stat *kvm,
return handle_begin_event(kvm, vcpu_record, &key, sample->time);

if (kvm->events_ops->is_end_event(evsel, sample, &key))
- return handle_end_event(kvm, vcpu_record, &key, sample->time);
+ return handle_end_event(kvm, vcpu_record, &key, sample);

return true;
}
@@ -1429,6 +1442,8 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
OPT_STRING('k', "key", &kvm->sort_key, "sort-key",
"key for sorting: sample(sort by samples number)"
" time (sort by avg time)"),
+ OPT_U64(0, "duration", &kvm->duration,
+ "show events other than HALT that take longer than duration usecs"),
OPT_END()
};
const char * const live_usage[] = {
@@ -1467,6 +1482,8 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
usage_with_options(live_usage, live_options);
}

+ kvm->duration *= NSEC_PER_USEC; /* convert usec to nsec */
+
/*
* target related setups
*/
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index 32bd102..cf20187 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -125,6 +125,9 @@
#ifndef NSEC_PER_SEC
# define NSEC_PER_SEC 1000000000ULL
#endif
+#ifndef NSEC_PER_USEC
+# define NSEC_PER_USEC 1000ULL
+#endif

static inline unsigned long long rdclock(void)
{
--
1.8.1.4

2013-08-14 18:29:57

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 06/21] perf sched: Remove sched_process_fork tracepoint

From: David Ahern <[email protected]>

The PERF_RECORD_FORK event is already collected as part of the use of
cmd_record and those events are analyzed as part of the libperf
machinery. Using the fork tracepoint as well just duplicates the event
load.

Signed-off-by: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Stephane Eranian <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-sched.c | 60 ++++++++++++++++++++++++----------------------
1 file changed, 31 insertions(+), 29 deletions(-)

diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 42f4587..f809cc7 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -109,8 +109,9 @@ struct trace_sched_handler {
int (*wakeup_event)(struct perf_sched *sched, struct perf_evsel *evsel,
struct perf_sample *sample, struct machine *machine);

- int (*fork_event)(struct perf_sched *sched, struct perf_evsel *evsel,
- struct perf_sample *sample);
+ /* PERF_RECORD_FORK event, not sched_process_fork tracepoint */
+ int (*fork_event)(struct perf_sched *sched, union perf_event *event,
+ struct machine *machine);

int (*migrate_task_event)(struct perf_sched *sched,
struct perf_evsel *evsel,
@@ -717,22 +718,29 @@ static int replay_switch_event(struct perf_sched *sched,
return 0;
}

-static int replay_fork_event(struct perf_sched *sched, struct perf_evsel *evsel,
- struct perf_sample *sample)
+static int replay_fork_event(struct perf_sched *sched,
+ union perf_event *event,
+ struct machine *machine)
{
- const char *parent_comm = perf_evsel__strval(evsel, sample, "parent_comm"),
- *child_comm = perf_evsel__strval(evsel, sample, "child_comm");
- const u32 parent_pid = perf_evsel__intval(evsel, sample, "parent_pid"),
- child_pid = perf_evsel__intval(evsel, sample, "child_pid");
+ struct thread *child, *parent;
+
+ child = machine__findnew_thread(machine, event->fork.tid);
+ parent = machine__findnew_thread(machine, event->fork.ptid);
+
+ if (child == NULL || parent == NULL) {
+ pr_debug("thread does not exist on fork event: child %p, parent %p\n",
+ child, parent);
+ return 0;
+ }

if (verbose) {
- printf("sched_fork event %p\n", evsel);
- printf("... parent: %s/%d\n", parent_comm, parent_pid);
- printf("... child: %s/%d\n", child_comm, child_pid);
+ printf("fork event\n");
+ printf("... parent: %s/%d\n", parent->comm, parent->tid);
+ printf("... child: %s/%d\n", child->comm, child->tid);
}

- register_pid(sched, parent_pid, parent_comm);
- register_pid(sched, child_pid, child_comm);
+ register_pid(sched, parent->tid, parent->comm);
+ register_pid(sched, child->tid, child->comm);
return 0;
}

@@ -824,14 +832,6 @@ static int thread_atoms_insert(struct perf_sched *sched, struct thread *thread)
return 0;
}

-static int latency_fork_event(struct perf_sched *sched __maybe_unused,
- struct perf_evsel *evsel __maybe_unused,
- struct perf_sample *sample __maybe_unused)
-{
- /* should insert the newcomer */
- return 0;
-}
-
static char sched_out_state(u64 prev_state)
{
const char *str = TASK_STATE_TO_CHAR_STR;
@@ -1379,15 +1379,19 @@ static int process_sched_runtime_event(struct perf_tool *tool,
return 0;
}

-static int process_sched_fork_event(struct perf_tool *tool,
- struct perf_evsel *evsel,
- struct perf_sample *sample,
- struct machine *machine __maybe_unused)
+static int perf_sched__process_fork_event(struct perf_tool *tool,
+ union perf_event *event,
+ struct perf_sample *sample,
+ struct machine *machine)
{
struct perf_sched *sched = container_of(tool, struct perf_sched, tool);

+ /* run the fork event through the perf machineruy */
+ perf_event__process_fork(tool, event, sample, machine);
+
+ /* and then run additional processing needed for this command */
if (sched->tp_handler->fork_event)
- return sched->tp_handler->fork_event(sched, evsel, sample);
+ return sched->tp_handler->fork_event(sched, event, machine);

return 0;
}
@@ -1437,7 +1441,6 @@ static int perf_sched__read_events(struct perf_sched *sched,
{ "sched:sched_stat_runtime", process_sched_runtime_event, },
{ "sched:sched_wakeup", process_sched_wakeup_event, },
{ "sched:sched_wakeup_new", process_sched_wakeup_event, },
- { "sched:sched_process_fork", process_sched_fork_event, },
{ "sched:sched_migrate_task", process_sched_migrate_task_event, },
};
struct perf_session *session;
@@ -1652,7 +1655,7 @@ static struct perf_sched sched = {
.sample = perf_sched__process_tracepoint_sample,
.comm = perf_event__process_comm,
.lost = perf_event__process_lost,
- .fork = perf_event__process_fork,
+ .fork = perf_sched__process_fork_event,
.ordered_samples = true,
},
.cmp_pid = LIST_HEAD_INIT(sched.cmp_pid),
@@ -1714,7 +1717,6 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
.wakeup_event = latency_wakeup_event,
.switch_event = latency_switch_event,
.runtime_event = latency_runtime_event,
- .fork_event = latency_fork_event,
.migrate_task_event = latency_migrate_task_event,
};
struct trace_sched_handler map_ops = {
--
1.8.1.4

2013-08-14 18:30:07

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 07/21] perf tool: Simplify options to perf_evsel__print_ip

From: David Ahern <[email protected]>

Make print options based on flags. Simplifies addition of more print
options which is the subject of upcoming patches.

Signed-off-by: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Stephane Eranian <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-script.c | 27 +++++++++++++++++++++++----
tools/perf/util/session.c | 14 +++++++++++---
tools/perf/util/session.h | 7 ++++++-
3 files changed, 40 insertions(+), 8 deletions(-)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index cd616ff..ee5d6f8 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -66,6 +66,7 @@ struct output_option {
static struct {
bool user_set;
bool wildcard_set;
+ unsigned int print_ip_opts;
u64 fields;
u64 invalid_fields;
} output[PERF_TYPE_MAX] = {
@@ -235,6 +236,7 @@ static int perf_session__check_output_opt(struct perf_session *session)
{
int j;
struct perf_evsel *evsel;
+ struct perf_event_attr *attr;

for (j = 0; j < PERF_TYPE_MAX; ++j) {
evsel = perf_session__find_first_evtype(session, j);
@@ -253,6 +255,24 @@ static int perf_session__check_output_opt(struct perf_session *session)
if (evsel && output[j].fields &&
perf_evsel__check_attr(evsel, session))
return -1;
+
+ if (evsel == NULL)
+ continue;
+
+ attr = &evsel->attr;
+
+ output[j].print_ip_opts = 0;
+ if (PRINT_FIELD(IP))
+ output[j].print_ip_opts |= PRINT_IP_OPT_IP;
+
+ if (PRINT_FIELD(SYM))
+ output[j].print_ip_opts |= PRINT_IP_OPT_SYM;
+
+ if (PRINT_FIELD(DSO))
+ output[j].print_ip_opts |= PRINT_IP_OPT_DSO;
+
+ if (PRINT_FIELD(SYMOFFSET))
+ output[j].print_ip_opts |= PRINT_IP_OPT_SYMOFFSET;
}

return 0;
@@ -382,8 +402,7 @@ static void print_sample_bts(union perf_event *event,
else
printf("\n");
perf_evsel__print_ip(evsel, event, sample, machine,
- PRINT_FIELD(SYM), PRINT_FIELD(DSO),
- PRINT_FIELD(SYMOFFSET));
+ output[attr->type].print_ip_opts);
}

printf(" => ");
@@ -423,9 +442,9 @@ static void process_event(union perf_event *event, struct perf_sample *sample,
printf(" ");
else
printf("\n");
+
perf_evsel__print_ip(evsel, event, sample, machine,
- PRINT_FIELD(SYM), PRINT_FIELD(DSO),
- PRINT_FIELD(SYMOFFSET));
+ output[attr->type].print_ip_opts);
}

printf("\n");
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index dedaeb2..e5fd658 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1489,10 +1489,14 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,

void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event,
struct perf_sample *sample, struct machine *machine,
- int print_sym, int print_dso, int print_symoffset)
+ unsigned int print_opts)
{
struct addr_location al;
struct callchain_cursor_node *node;
+ int print_ip = print_opts & PRINT_IP_OPT_IP;
+ int print_sym = print_opts & PRINT_IP_OPT_SYM;
+ int print_dso = print_opts & PRINT_IP_OPT_DSO;
+ int print_symoffset = print_opts & PRINT_IP_OPT_SYMOFFSET;

if (perf_event__preprocess_sample(event, machine, &al, sample,
NULL) < 0) {
@@ -1516,7 +1520,9 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event,
if (!node)
break;

- printf("\t%16" PRIx64, node->ip);
+ if (print_ip)
+ printf("%16" PRIx64, node->ip);
+
if (print_sym) {
printf(" ");
if (print_symoffset) {
@@ -1537,7 +1543,9 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event,
}

} else {
- printf("%16" PRIx64, sample->ip);
+ if (print_ip)
+ printf("%16" PRIx64, sample->ip);
+
if (print_sym) {
printf(" ");
if (print_symoffset)
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 8bed17e..69e554a 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -41,6 +41,11 @@ struct perf_session {
char filename[1];
};

+#define PRINT_IP_OPT_IP (1<<0)
+#define PRINT_IP_OPT_SYM (1<<1)
+#define PRINT_IP_OPT_DSO (1<<2)
+#define PRINT_IP_OPT_SYMOFFSET (1<<3)
+
struct perf_tool;

struct perf_session *perf_session__new(const char *filename, int mode,
@@ -103,7 +108,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,

void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event,
struct perf_sample *sample, struct machine *machine,
- int print_sym, int print_dso, int print_symoffset);
+ unsigned int print_opts);

int perf_session__cpu_bitmap(struct perf_session *session,
const char *cpu_list, unsigned long *cpu_bitmap);
--
1.8.1.4

2013-08-14 18:30:04

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 05/21] perf sched: Remove sched_process_exit tracepoint

From: David Ahern <[email protected]>

Event is not needed nor analyzed. Since perf-sched leverages perf-record
to capture the sched data, we already capture task events like EXIT.

Signed-off-by: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Stephane Eranian <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-sched.c | 11 -----------
1 file changed, 11 deletions(-)

diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 5285024..42f4587 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1392,15 +1392,6 @@ static int process_sched_fork_event(struct perf_tool *tool,
return 0;
}

-static int process_sched_exit_event(struct perf_tool *tool __maybe_unused,
- struct perf_evsel *evsel,
- struct perf_sample *sample __maybe_unused,
- struct machine *machine __maybe_unused)
-{
- pr_debug("sched_exit event %p\n", evsel);
- return 0;
-}
-
static int process_sched_migrate_task_event(struct perf_tool *tool,
struct perf_evsel *evsel,
struct perf_sample *sample,
@@ -1447,7 +1438,6 @@ static int perf_sched__read_events(struct perf_sched *sched,
{ "sched:sched_wakeup", process_sched_wakeup_event, },
{ "sched:sched_wakeup_new", process_sched_wakeup_event, },
{ "sched:sched_process_fork", process_sched_fork_event, },
- { "sched:sched_process_exit", process_sched_exit_event, },
{ "sched:sched_migrate_task", process_sched_migrate_task_event, },
};
struct perf_session *session;
@@ -1634,7 +1624,6 @@ static int __cmd_record(int argc, const char **argv)
"-e", "sched:sched_stat_sleep",
"-e", "sched:sched_stat_iowait",
"-e", "sched:sched_stat_runtime",
- "-e", "sched:sched_process_exit",
"-e", "sched:sched_process_fork",
"-e", "sched:sched_wakeup",
"-e", "sched:sched_migrate_task",
--
1.8.1.4

2013-08-14 18:30:01

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 10/21] perf session: Change perf_session__has_traces to actually check for tracepoints

From: David Ahern <[email protected]>

Any event can have RAW data attribute set. The intent of the function is
to determine if the session has tracepoints, so check for the type of
each event explicitly.

Signed-off-by: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Stephane Eranian <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/session.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 5a89964..4d9028e 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1401,12 +1401,15 @@ int perf_session__process_events(struct perf_session *self,

bool perf_session__has_traces(struct perf_session *session, const char *msg)
{
- 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;
+ struct perf_evsel *evsel;
+
+ list_for_each_entry(evsel, &session->evlist->entries, node) {
+ if (evsel->attr.type == PERF_TYPE_TRACEPOINT)
+ return true;
}

- return true;
+ pr_err("No trace sample to read. Did you call 'perf %s'?\n", msg);
+ return false;
}

int maps__set_kallsyms_ref_reloc_sym(struct map **maps,
--
1.8.1.4

2013-08-14 18:29:59

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 09/21] perf evsel: Add option to limit stack depth in callchain dumps

From: David Ahern <[email protected]>

Option is used by upcoming timehist command.

Signed-off-by: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Stephane Eranian <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-script.c | 6 ++++--
tools/perf/util/session.c | 6 ++++--
tools/perf/util/session.h | 2 +-
3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index ee5d6f8..33b2d83 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -402,7 +402,8 @@ static void print_sample_bts(union perf_event *event,
else
printf("\n");
perf_evsel__print_ip(evsel, event, sample, machine,
- output[attr->type].print_ip_opts);
+ output[attr->type].print_ip_opts,
+ PERF_MAX_STACK_DEPTH);
}

printf(" => ");
@@ -444,7 +445,8 @@ static void process_event(union perf_event *event, struct perf_sample *sample,
printf("\n");

perf_evsel__print_ip(evsel, event, sample, machine,
- output[attr->type].print_ip_opts);
+ output[attr->type].print_ip_opts,
+ PERF_MAX_STACK_DEPTH);
}

printf("\n");
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 0d895e7..5a89964 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1489,7 +1489,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,

void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event,
struct perf_sample *sample, struct machine *machine,
- unsigned int print_opts)
+ unsigned int print_opts, unsigned int stack_depth)
{
struct addr_location al;
struct callchain_cursor_node *node;
@@ -1517,7 +1517,7 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event,
}
callchain_cursor_commit(&callchain_cursor);

- while (1) {
+ while (stack_depth) {
node = callchain_cursor_current(&callchain_cursor);
if (!node)
break;
@@ -1544,6 +1544,8 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event,
printf("\n");

callchain_cursor_advance(&callchain_cursor);
+
+ stack_depth--;
}

} else {
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 7c00ccb..3aa75fb 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -109,7 +109,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,

void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event,
struct perf_sample *sample, struct machine *machine,
- unsigned int print_opts);
+ unsigned int print_opts, unsigned int stack_depth);

int perf_session__cpu_bitmap(struct perf_session *session,
const char *cpu_list, unsigned long *cpu_bitmap);
--
1.8.1.4

2013-08-14 18:29:55

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 02/21] perf kvm: Update documentation with live command

From: David Ahern <[email protected]>

Update perf-kvm documentation with new live subcommand. Add -p/--pid
option for perf-kvm-stat-report as well.

Signed-off-by: David Ahern <[email protected]>
Requested-by: Xiao Guangrong <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Runzhen Wang <[email protected]>
Cc: Xiao Guangrong <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/Documentation/perf-kvm.txt | 46 +++++++++++++++++++++++++++++++++--
1 file changed, 44 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Documentation/perf-kvm.txt b/tools/perf/Documentation/perf-kvm.txt
index 326f2cb..ac84db2 100644
--- a/tools/perf/Documentation/perf-kvm.txt
+++ b/tools/perf/Documentation/perf-kvm.txt
@@ -13,6 +13,7 @@ SYNOPSIS
{top|record|report|diff|buildid-list}
'perf kvm' [--host] [--guest] [--guestkallsyms=<path> --guestmodules=<path>
| --guestvmlinux=<path>] {top|record|report|diff|buildid-list|stat}
+'perf kvm stat [record|report|live] [<options>]

DESCRIPTION
-----------
@@ -50,6 +51,10 @@ There are a couple of variants of perf kvm:
'perf kvm stat report' reports statistical data which includes events
handled time, samples, and so on.

+ 'perf kvm stat live' reports statistical data in a live mode (similar to
+ record + report but with statistical data updated live at a given display
+ rate).
+
OPTIONS
-------
-i::
@@ -85,13 +90,50 @@ STAT REPORT OPTIONS
--vcpu=<value>::
analyze events which occures on this vcpu. (default: all vcpus)

---events=<value>::
- events to be analyzed. Possible values: vmexit, mmio, ioport.
+--event=<value>::
+ event to be analyzed. Possible values: vmexit, mmio, ioport.
(default: vmexit)
-k::
--key=<value>::
Sorting key. Possible values: sample (default, sort by samples
number), time (sort by average time).
+-p::
+--pid=::
+ Analyze events only for given process ID(s) (comma separated list).
+
+STAT LIVE OPTIONS
+-----------------
+-d::
+--display::
+ Time in seconds between display updates
+
+-m::
+--mmap-pages=::
+ Number of mmap data pages. Must be a power of two.
+
+-a::
+--all-cpus::
+ System-wide collection from all CPUs.
+
+-p::
+--pid=::
+ Analyze events only for given process ID(s) (comma separated list).
+
+--vcpu=<value>::
+ analyze events which occures on this vcpu. (default: all vcpus)
+
+
+--event=<value>::
+ event to be analyzed. Possible values: vmexit, mmio, ioport.
+ (default: vmexit)
+
+-k::
+--key=<value>::
+ Sorting key. Possible values: sample (default, sort by samples
+ number), time (sort by average time).
+
+--duration=<value>::
+ Show events other than HLT that take longer than duration usecs.

SEE ALSO
--------
--
1.8.1.4

2013-08-15 07:52:21

by Ingo Molnar

[permalink] [raw]
Subject: Re: [GIT PULL 00/21] perf/core improvements and fixes


* Arnaldo Carvalho de Melo <[email protected]> wrote:

> From: Arnaldo Carvalho de Melo <[email protected]>
>
> Hi Ingo,
>
> Please consider pulling,
>
> Flushing it out now before processing another batch.
>
> - Arnaldo
>
> The following changes since commit 0a3d23a2568ed5e73bd4fb532dc672fa9f03b1f1:
>
> Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core (2013-08-12 10:14:47 +0200)
>
> are available in the git repository at:
>
>
> git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux tags/perf-core-for-mingo
>
> for you to fetch changes up to 2ae3a312c0ccd8ff615372f00aab1700aac27474:
>
> perf trace: Allow specifying which syscalls to trace (2013-08-14 11:44:21 -0300)
>
> ----------------------------------------------------------------
> perf/core improvements and fixes:
>
> . Allow specifying syscalls in 'perf trace', a la strace.
>
> . Simplify symbol filtering by doing it at machine class level,
> from Adrian Hunter.
>
> . Add option to 'perf kvm' to print only events that exceed a specified time
> duration, from David Ahern.
>
> . 'perf sched' improvements, including removing some tracepoints that provide
> the same information as the PERF_RECORD_{FORK,EXIT} events.
>
> . Improve stack trace printing, from David Ahern.
>
> . Update documentation with live command, from David Ahern
>
> . Fix 'perf test' compile failure on do_sort_something, from David Ahern.
>
> . Improve robustness of topology parsing code, from Stephane Eranian.
>
> Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
>
> ----------------------------------------------------------------
> Adrian Hunter (8):
> perf machine: Add symbol filter to struct machine
> perf top: Set the machines symbol filter
> perf report: Set the machines symbol filter
> perf mem: Remove unused symbol filter member
> perf annotate: Set the machines symbol filter
> perf tools: Remove filter parameter of perf_event__preprocess_sample()
> perf tools: Remove filter parameter of thread__find_addr_location()
> perf tools: Remove filter parameter of thread__find_addr_map()
>
> Arnaldo Carvalho de Melo (1):
> perf trace: Allow specifying which syscalls to trace
>
> David Ahern (11):
> perf kvm: Option to print events that exceed a duration
> perf kvm: Update documentation with live command
> perf sched: Simplify arguments to read_events
> perf sched: Remove thread lookup in sample handler
> perf sched: Remove sched_process_exit tracepoint
> perf sched: Remove sched_process_fork tracepoint
> perf tool: Simplify options to perf_evsel__print_ip
> perf evsel: Add option to print stack trace on single line
> perf evsel: Add option to limit stack depth in callchain dumps
> perf session: Change perf_session__has_traces to actually check for tracepoints
> perf tests: Fix compile failure on do_sort_something
>
> Stephane Eranian (1):
> perf tools: Improve robustness of topology parsing code
>
> tools/perf/Documentation/perf-kvm.txt | 46 +++++++++++++++-
> tools/perf/Documentation/perf-trace.txt | 4 ++
> tools/perf/builtin-annotate.c | 5 +-
> tools/perf/builtin-diff.c | 2 +-
> tools/perf/builtin-inject.c | 2 +-
> tools/perf/builtin-kvm.c | 25 +++++++--
> tools/perf/builtin-mem.c | 4 +-
> tools/perf/builtin-report.c | 7 ++-
> tools/perf/builtin-sched.c | 94 ++++++++++++++-------------------
> tools/perf/builtin-script.c | 35 +++++++++---
> tools/perf/builtin-top.c | 5 +-
> tools/perf/builtin-trace.c | 52 +++++++++++++++---
> tools/perf/perf.h | 3 ++
> tools/perf/tests/code-reading.c | 13 +++--
> tools/perf/tests/hists_link.c | 4 +-
> tools/perf/util/build-id.c | 2 +-
> tools/perf/util/event.c | 20 +++----
> tools/perf/util/event.h | 3 +-
> tools/perf/util/header.c | 11 ++--
> tools/perf/util/machine.c | 28 ++++++++--
> tools/perf/util/machine.h | 5 ++
> tools/perf/util/session.c | 40 +++++++++-----
> tools/perf/util/session.h | 8 ++-
> tools/perf/util/thread.h | 5 +-
> tools/perf/util/unwind.c | 6 +--
> 25 files changed, 294 insertions(+), 135 deletions(-)

Pulled, thanks Arnaldo!

Ingo