From: Arnaldo Carvalho de Melo <[email protected]>
Hi Ingo,
Please consider pulling,
- Arnaldo
The following changes since commit aa30a2e03a453aad9fd96c3f2d4a82c3497674e5:
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core (2013-10-23 09:45:50 +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 c1fb5651bb40f9efaf32d280f39e06df7e352673:
perf tools: Show progress on histogram collapsing (2013-10-23 15:48:24 -0300)
----------------------------------------------------------------
perf/core improvements and fixes:
. Show progress on histogram collapsing, that can take a long time, from
Namhyung Kim.
. Support "$vars" meta argument syntax for local variables, allowing
asking for all possible variables at a given probe point to be
collected when it hits, from Masami Hiramatsu.
. Address the root cause of that 'perf sched' stack initialization build
slowdown, by programmatically setting a big array after moving the
global variable back to the stack. Fix from Adrian Hunter.
. Do not repipe attributes to a perf.data file in 'perf inject',
fix from Adrian Hunter
. Change the procps visible command-name of invididual benchmark tests
plus cleanups, from Ingo Molnar.
. Do not accept parse_tag_value() overflow, fix from Adrian Hunter.
. Validate that mmap_pages is not too big. From Adrian Hunter.
. Fix non-debug build, from Adrian Hunter
. Clarify the "sample parsing" test entry.
. Consider PERF_SAMPLE_TRANSACTION in the "sample parsing" test.
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
----------------------------------------------------------------
Adrian Hunter (7):
perf sched: Make struct perf_sched sched a local variable
perf sched: Optimize build time
perf script: Make perf_script a local variable
perf inject: Do not repipe attributes to a perf.data file
perf tools: Do not accept parse_tag_value() overflow
perf evlist: Validate that mmap_pages is not too big
perf tools: Fix non-debug build
Arnaldo Carvalho de Melo (5):
perf test: Clarify the "sample parsing" test entry
perf test: Consider PERF_SAMPLE_TRANSACTION in the "sample parsing" test
perf tools: Stop using 'self' in some more places
perf ui: Rename ui_progress to ui_progress_ops
perf ui progress: Per progress bar state
Ingo Molnar (1):
perf bench: Change the procps visible command-name of invididual benchmark tests plus cleanups
Masami Hiramatsu (2):
perf probe: Support "$vars" meta argument syntax for local variables
perf probe: Find fentry mcount fuzzed parameter location
Namhyung Kim (1):
perf tools: Show progress on histogram collapsing
tools/perf/Makefile.perf | 1 +
tools/perf/builtin-annotate.c | 6 +-
tools/perf/builtin-bench.c | 239 +++++++++++++++++++-------------------
tools/perf/builtin-diff.c | 7 +-
tools/perf/builtin-inject.c | 27 +++--
tools/perf/builtin-report.c | 24 ++--
tools/perf/builtin-sched.c | 44 +++----
tools/perf/builtin-script.c | 40 ++++---
tools/perf/builtin-top.c | 4 +-
tools/perf/config/Makefile | 4 +
tools/perf/tests/hists_link.c | 2 +-
tools/perf/tests/sample-parsing.c | 4 +-
tools/perf/ui/gtk/gtk.h | 2 +-
tools/perf/ui/gtk/progress.c | 20 ++--
tools/perf/ui/gtk/setup.c | 2 +-
tools/perf/ui/progress.c | 32 +++--
tools/perf/ui/progress.h | 19 +--
tools/perf/ui/tui/progress.c | 15 +--
tools/perf/ui/tui/setup.c | 3 +-
tools/perf/ui/tui/tui.h | 6 +
tools/perf/util/build-id.c | 6 +-
tools/perf/util/evlist.c | 14 ++-
tools/perf/util/hist.c | 23 ++--
tools/perf/util/hist.h | 3 +-
tools/perf/util/probe-event.c | 1 -
tools/perf/util/probe-finder.c | 133 ++++++++++++++++++---
tools/perf/util/probe-finder.h | 1 +
tools/perf/util/session.c | 24 ++--
tools/perf/util/sort.c | 124 ++++++++++----------
tools/perf/util/strfilter.c | 46 ++++----
tools/perf/util/thread.c | 72 ++++++------
tools/perf/util/util.c | 2 +
32 files changed, 560 insertions(+), 390 deletions(-)
create mode 100644 tools/perf/ui/tui/tui.h
From: Adrian Hunter <[email protected]>
Change perf_script from being global to being local.
Signed-off-by: Adrian Hunter <[email protected]>
Acked-by: David Ahern <[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]
[ Made the minor consistency changes suggested by David Ahern ]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-script.c | 40 ++++++++++++++++++++++++----------------
1 file changed, 24 insertions(+), 16 deletions(-)
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 27de6068049d..0ae88c2538a1 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -542,18 +542,9 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
return 0;
}
-static struct perf_tool perf_script = {
- .sample = process_sample_event,
- .mmap = perf_event__process_mmap,
- .mmap2 = perf_event__process_mmap2,
- .comm = perf_event__process_comm,
- .exit = perf_event__process_exit,
- .fork = perf_event__process_fork,
- .attr = perf_event__process_attr,
- .tracing_data = perf_event__process_tracing_data,
- .build_id = perf_event__process_build_id,
- .ordered_samples = true,
- .ordering_requires_timestamps = true,
+struct perf_script {
+ struct perf_tool tool;
+ struct perf_session *session;
};
static void sig_handler(int sig __maybe_unused)
@@ -561,13 +552,13 @@ static void sig_handler(int sig __maybe_unused)
session_done = 1;
}
-static int __cmd_script(struct perf_session *session)
+static int __cmd_script(struct perf_script *script)
{
int ret;
signal(SIGINT, sig_handler);
- ret = perf_session__process_events(session, &perf_script);
+ ret = perf_session__process_events(script->session, &script->tool);
if (debug_mode)
pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
@@ -1273,6 +1264,21 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
char *script_path = NULL;
const char **__argv;
int i, j, err;
+ struct perf_script script = {
+ .tool = {
+ .sample = process_sample_event,
+ .mmap = perf_event__process_mmap,
+ .mmap2 = perf_event__process_mmap2,
+ .comm = perf_event__process_comm,
+ .exit = perf_event__process_exit,
+ .fork = perf_event__process_fork,
+ .attr = perf_event__process_attr,
+ .tracing_data = perf_event__process_tracing_data,
+ .build_id = perf_event__process_build_id,
+ .ordered_samples = true,
+ .ordering_requires_timestamps = true,
+ },
+ };
const struct option options[] = {
OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
"dump raw trace in ASCII"),
@@ -1498,10 +1504,12 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
if (!script_name)
setup_pager();
- session = perf_session__new(&file, false, &perf_script);
+ session = perf_session__new(&file, false, &script.tool);
if (session == NULL)
return -ENOMEM;
+ script.session = session;
+
if (cpu_list) {
if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap))
return -1;
@@ -1565,7 +1573,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
if (err < 0)
goto out;
- err = __cmd_script(session);
+ err = __cmd_script(&script);
perf_session__delete(session);
cleanup_scripting();
--
1.8.1.4
From: Adrian Hunter <[email protected]>
perf.data files contain the attributes separately, do not put them in
the event stream as well.
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 | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index eb1a5941912b..409ceaf3b9b9 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -72,12 +72,17 @@ static int perf_event__repipe_attr(struct perf_tool *tool,
union perf_event *event,
struct perf_evlist **pevlist)
{
+ struct perf_inject *inject = container_of(tool, struct perf_inject,
+ tool);
int ret;
ret = perf_event__process_attr(tool, event, pevlist);
if (ret)
return ret;
+ if (!inject->pipe_output)
+ return 0;
+
return perf_event__repipe_synth(tool, event);
}
--
1.8.1.4
From: Arnaldo Carvalho de Melo <[email protected]>
[root@sandy ~]# perf test -v 22
22: Test sample parsing :
--- start ---
sample format has changed, some new PERF_SAMPLE_ bit was introduced - test needs updating
---- end ----
Test sample parsing: FAILED!
[root@sandy ~]#
Cc: Adrian Hunter <[email protected]>
Cc: Andi Kleen <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Jiri Olsa <[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/tests/sample-parsing.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c
index 17d000c6c8ff..61c9da2eb3a9 100644
--- a/tools/perf/tests/sample-parsing.c
+++ b/tools/perf/tests/sample-parsing.c
@@ -275,7 +275,7 @@ int test__sample_parsing(void)
* Fail the test if it has not been updated when new sample format bits
* were added.
*/
- if (PERF_SAMPLE_MAX > PERF_SAMPLE_IDENTIFIER << 1) {
+ if (PERF_SAMPLE_MAX > PERF_SAMPLE_TRANSACTION << 1) {
pr_debug("sample format has changed, some new PERF_SAMPLE_ bit was introduced - test needs updating\n");
return -1;
}
--
1.8.1.4
From: Adrian Hunter <[email protected]>
Amend perf_evlist__parse_mmap_pages() to check that the mmap_pages
entered via the --mmap_pages/-m option is not too big.
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/evlist.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 85c4c80bcac8..2ce92eceb424 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -698,7 +698,8 @@ static size_t perf_evlist__mmap_size(unsigned long pages)
int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str,
int unset __maybe_unused)
{
- unsigned int pages, val, *mmap_pages = opt->value;
+ unsigned int *mmap_pages = opt->value;
+ unsigned long pages, val;
size_t size;
static struct parse_tag tags[] = {
{ .tag = 'B', .mult = 1 },
@@ -709,12 +710,12 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str,
};
val = parse_tag_value(str, tags);
- if (val != (unsigned int) -1) {
+ if (val != (unsigned long) -1) {
/* we got file size value */
pages = PERF_ALIGN(val, page_size) / page_size;
- if (!is_power_of_2(pages)) {
+ if (pages < (1UL << 31) && !is_power_of_2(pages)) {
pages = next_pow2(pages);
- pr_info("rounding mmap pages size to %u (%u pages)\n",
+ pr_info("rounding mmap pages size to %lu (%lu pages)\n",
pages * page_size, pages);
}
} else {
@@ -727,6 +728,11 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str,
}
}
+ if (pages > UINT_MAX || pages > SIZE_MAX / page_size) {
+ pr_err("--mmap_pages/-m value too big\n");
+ return -1;
+ }
+
size = perf_evlist__mmap_size(pages);
if (!size) {
pr_err("--mmap_pages/-m value must be a power of two.");
--
1.8.1.4
From: Adrian Hunter <[email protected]>
In the absence of s DEBUG variable definition on the command line perf
tools was building without optimization. Fix by assigning DEBUG if it
is not defined.
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/config/Makefile | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index c516d6ba6716..543aa953bab1 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -66,6 +66,10 @@ ifneq ($(WERROR),0)
CFLAGS += -Werror
endif
+ifndef DEBUG
+ DEBUG := 0
+endif
+
ifeq ($(DEBUG),0)
CFLAGS += -O6
endif
--
1.8.1.4
From: Arnaldo Carvalho de Melo <[email protected]>
As suggested by tglx, 'self' should be replaced by something that is
more useful.
Cc: Adrian Hunter <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Jiri Olsa <[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/builtin-annotate.c | 4 +-
tools/perf/builtin-diff.c | 5 +-
tools/perf/builtin-inject.c | 22 ++++----
tools/perf/builtin-report.c | 14 ++---
tools/perf/util/build-id.c | 6 +-
tools/perf/util/hist.c | 18 +++---
tools/perf/util/sort.c | 124 +++++++++++++++++++++---------------------
tools/perf/util/strfilter.c | 46 ++++++++--------
tools/perf/util/thread.c | 72 ++++++++++++------------
9 files changed, 155 insertions(+), 156 deletions(-)
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 03cfa592071f..17c6b494e8cc 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -118,11 +118,11 @@ static int hist_entry__tty_annotate(struct hist_entry *he,
ann->print_line, ann->full_paths, 0, 0);
}
-static void hists__find_annotations(struct hists *self,
+static void hists__find_annotations(struct hists *hists,
struct perf_evsel *evsel,
struct perf_annotate *ann)
{
- struct rb_node *nd = rb_first(&self->entries), *next;
+ struct rb_node *nd = rb_first(&hists->entries), *next;
int key = K_RIGHT;
while (nd) {
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 419d27dd708b..9c828881714c 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -303,12 +303,11 @@ static int formula_fprintf(struct hist_entry *he, struct hist_entry *pair,
return -1;
}
-static int hists__add_entry(struct hists *self,
+static int hists__add_entry(struct hists *hists,
struct addr_location *al, u64 period,
u64 weight, u64 transaction)
{
- if (__hists__add_entry(self, al, NULL, period, weight, transaction)
- != NULL)
+ if (__hists__add_entry(hists, al, NULL, period, weight, transaction) != NULL)
return 0;
return -ENOMEM;
}
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 4aa6d7850bcc..eb1a5941912b 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -162,38 +162,38 @@ static int perf_event__repipe_tracing_data(struct perf_tool *tool,
return err;
}
-static int dso__read_build_id(struct dso *self)
+static int dso__read_build_id(struct dso *dso)
{
- if (self->has_build_id)
+ if (dso->has_build_id)
return 0;
- if (filename__read_build_id(self->long_name, self->build_id,
- sizeof(self->build_id)) > 0) {
- self->has_build_id = true;
+ if (filename__read_build_id(dso->long_name, dso->build_id,
+ sizeof(dso->build_id)) > 0) {
+ dso->has_build_id = true;
return 0;
}
return -1;
}
-static int dso__inject_build_id(struct dso *self, struct perf_tool *tool,
+static int dso__inject_build_id(struct dso *dso, struct perf_tool *tool,
struct machine *machine)
{
u16 misc = PERF_RECORD_MISC_USER;
int err;
- if (dso__read_build_id(self) < 0) {
- pr_debug("no build_id found for %s\n", self->long_name);
+ if (dso__read_build_id(dso) < 0) {
+ pr_debug("no build_id found for %s\n", dso->long_name);
return -1;
}
- if (self->kernel)
+ if (dso->kernel)
misc = PERF_RECORD_MISC_KERNEL;
- err = perf_event__synthesize_build_id(tool, self, misc, perf_event__repipe,
+ err = perf_event__synthesize_build_id(tool, dso, misc, perf_event__repipe,
machine);
if (err) {
- pr_err("Can't synthesize build_id event for %s\n", self->long_name);
+ pr_err("Can't synthesize build_id event for %s\n", dso->long_name);
return -1;
}
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 81addcabb356..e3598a456017 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -373,9 +373,9 @@ static int process_read_event(struct perf_tool *tool,
/* For pipe mode, sample_type is not currently set */
static int perf_report__setup_sample_type(struct perf_report *rep)
{
- struct perf_session *self = rep->session;
- u64 sample_type = perf_evlist__combined_sample_type(self->evlist);
- bool is_pipe = perf_data_file__is_pipe(self->file);
+ struct perf_session *session = rep->session;
+ u64 sample_type = perf_evlist__combined_sample_type(session->evlist);
+ bool is_pipe = perf_data_file__is_pipe(session->file);
if (!is_pipe && !(sample_type & PERF_SAMPLE_CALLCHAIN)) {
if (sort__has_parent) {
@@ -417,14 +417,14 @@ static void sig_handler(int sig __maybe_unused)
}
static size_t hists__fprintf_nr_sample_events(struct perf_report *rep,
- struct hists *self,
+ struct hists *hists,
const char *evname, FILE *fp)
{
size_t ret;
char unit;
- unsigned long nr_samples = self->stats.nr_events[PERF_RECORD_SAMPLE];
- u64 nr_events = self->stats.total_period;
- struct perf_evsel *evsel = hists_to_evsel(self);
+ unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];
+ u64 nr_events = hists->stats.total_period;
+ struct perf_evsel *evsel = hists_to_evsel(hists);
char buf[512];
size_t size = sizeof(buf);
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index 7ded71d19d75..a92770c98cc7 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -89,14 +89,14 @@ int build_id__sprintf(const u8 *build_id, int len, char *bf)
return raw - build_id;
}
-char *dso__build_id_filename(struct dso *self, char *bf, size_t size)
+char *dso__build_id_filename(struct dso *dso, char *bf, size_t size)
{
char build_id_hex[BUILD_ID_SIZE * 2 + 1];
- if (!self->has_build_id)
+ if (!dso->has_build_id)
return NULL;
- build_id__sprintf(self->build_id, sizeof(self->build_id), build_id_hex);
+ build_id__sprintf(dso->build_id, sizeof(dso->build_id), build_id_hex);
if (bf == NULL) {
if (asprintf(&bf, "%s/.build-id/%.2s/%s", buildid_dir,
build_id_hex, build_id_hex + 2) < 0)
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index cca03831f41a..f0b863ef4896 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -406,7 +406,7 @@ out:
return he;
}
-struct hist_entry *__hists__add_mem_entry(struct hists *self,
+struct hist_entry *__hists__add_mem_entry(struct hists *hists,
struct addr_location *al,
struct symbol *sym_parent,
struct mem_info *mi,
@@ -429,14 +429,14 @@ struct hist_entry *__hists__add_mem_entry(struct hists *self,
.level = al->level,
.parent = sym_parent,
.filtered = symbol__parent_filter(sym_parent),
- .hists = self,
+ .hists = hists,
.mem_info = mi,
.branch_info = NULL,
};
- return add_hist_entry(self, &entry, al, period, weight);
+ return add_hist_entry(hists, &entry, al, period, weight);
}
-struct hist_entry *__hists__add_branch_entry(struct hists *self,
+struct hist_entry *__hists__add_branch_entry(struct hists *hists,
struct addr_location *al,
struct symbol *sym_parent,
struct branch_info *bi,
@@ -460,14 +460,14 @@ struct hist_entry *__hists__add_branch_entry(struct hists *self,
.parent = sym_parent,
.filtered = symbol__parent_filter(sym_parent),
.branch_info = bi,
- .hists = self,
+ .hists = hists,
.mem_info = NULL,
};
- return add_hist_entry(self, &entry, al, period, weight);
+ return add_hist_entry(hists, &entry, al, period, weight);
}
-struct hist_entry *__hists__add_entry(struct hists *self,
+struct hist_entry *__hists__add_entry(struct hists *hists,
struct addr_location *al,
struct symbol *sym_parent, u64 period,
u64 weight, u64 transaction)
@@ -488,13 +488,13 @@ struct hist_entry *__hists__add_entry(struct hists *self,
},
.parent = sym_parent,
.filtered = symbol__parent_filter(sym_parent),
- .hists = self,
+ .hists = hists,
.branch_info = NULL,
.mem_info = NULL,
.transaction = transaction,
};
- return add_hist_entry(self, &entry, al, period, weight);
+ return add_hist_entry(hists, &entry, al, period, weight);
}
int64_t
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 1f9821db9e77..19b4aa279d1e 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -60,11 +60,11 @@ sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
return right->thread->tid - left->thread->tid;
}
-static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__thread_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
return repsep_snprintf(bf, size, "%*s:%5d", width - 6,
- self->thread->comm ?: "", self->thread->tid);
+ he->thread->comm ?: "", he->thread->tid);
}
struct sort_entry sort_thread = {
@@ -94,10 +94,10 @@ sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
return strcmp(comm_l, comm_r);
}
-static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__comm_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
- return repsep_snprintf(bf, size, "%*s", width, self->thread->comm);
+ return repsep_snprintf(bf, size, "%*s", width, he->thread->comm);
}
struct sort_entry sort_comm = {
@@ -148,10 +148,10 @@ static int _hist_entry__dso_snprintf(struct map *map, char *bf,
return repsep_snprintf(bf, size, "%-*s", width, "[unknown]");
}
-static int hist_entry__dso_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__dso_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
- return _hist_entry__dso_snprintf(self->ms.map, bf, size, width);
+ return _hist_entry__dso_snprintf(he->ms.map, bf, size, width);
}
struct sort_entry sort_dso = {
@@ -234,11 +234,11 @@ static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym,
return ret;
}
-static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__sym_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
- return _hist_entry__sym_snprintf(self->ms.map, self->ms.sym, self->ip,
- self->level, bf, size, width);
+ return _hist_entry__sym_snprintf(he->ms.map, he->ms.sym, he->ip,
+ he->level, bf, size, width);
}
struct sort_entry sort_sym = {
@@ -274,11 +274,11 @@ sort__srcline_cmp(struct hist_entry *left, struct hist_entry *right)
return strcmp(left->srcline, right->srcline);
}
-static int hist_entry__srcline_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__srcline_snprintf(struct hist_entry *he, char *bf,
size_t size,
unsigned int width __maybe_unused)
{
- return repsep_snprintf(bf, size, "%s", self->srcline);
+ return repsep_snprintf(bf, size, "%s", he->srcline);
}
struct sort_entry sort_srcline = {
@@ -302,11 +302,11 @@ sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)
return strcmp(sym_l->name, sym_r->name);
}
-static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__parent_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
return repsep_snprintf(bf, size, "%-*s", width,
- self->parent ? self->parent->name : "[other]");
+ he->parent ? he->parent->name : "[other]");
}
struct sort_entry sort_parent = {
@@ -324,10 +324,10 @@ sort__cpu_cmp(struct hist_entry *left, struct hist_entry *right)
return right->cpu - left->cpu;
}
-static int hist_entry__cpu_snprintf(struct hist_entry *self, char *bf,
- size_t size, unsigned int width)
+static int hist_entry__cpu_snprintf(struct hist_entry *he, char *bf,
+ size_t size, unsigned int width)
{
- return repsep_snprintf(bf, size, "%*d", width, self->cpu);
+ return repsep_snprintf(bf, size, "%*d", width, he->cpu);
}
struct sort_entry sort_cpu = {
@@ -346,10 +346,10 @@ sort__dso_from_cmp(struct hist_entry *left, struct hist_entry *right)
right->branch_info->from.map);
}
-static int hist_entry__dso_from_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__dso_from_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
- return _hist_entry__dso_snprintf(self->branch_info->from.map,
+ return _hist_entry__dso_snprintf(he->branch_info->from.map,
bf, size, width);
}
@@ -360,10 +360,10 @@ sort__dso_to_cmp(struct hist_entry *left, struct hist_entry *right)
right->branch_info->to.map);
}
-static int hist_entry__dso_to_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__dso_to_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
- return _hist_entry__dso_snprintf(self->branch_info->to.map,
+ return _hist_entry__dso_snprintf(he->branch_info->to.map,
bf, size, width);
}
@@ -391,21 +391,21 @@ sort__sym_to_cmp(struct hist_entry *left, struct hist_entry *right)
return _sort__sym_cmp(to_l->sym, to_r->sym);
}
-static int hist_entry__sym_from_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__sym_from_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
- struct addr_map_symbol *from = &self->branch_info->from;
+ struct addr_map_symbol *from = &he->branch_info->from;
return _hist_entry__sym_snprintf(from->map, from->sym, from->addr,
- self->level, bf, size, width);
+ he->level, bf, size, width);
}
-static int hist_entry__sym_to_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__sym_to_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
- struct addr_map_symbol *to = &self->branch_info->to;
+ struct addr_map_symbol *to = &he->branch_info->to;
return _hist_entry__sym_snprintf(to->map, to->sym, to->addr,
- self->level, bf, size, width);
+ he->level, bf, size, width);
}
@@ -448,13 +448,13 @@ sort__mispredict_cmp(struct hist_entry *left, struct hist_entry *right)
return mp || p;
}
-static int hist_entry__mispredict_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__mispredict_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width){
static const char *out = "N/A";
- if (self->branch_info->flags.predicted)
+ if (he->branch_info->flags.predicted)
out = "N";
- else if (self->branch_info->flags.mispred)
+ else if (he->branch_info->flags.mispred)
out = "Y";
return repsep_snprintf(bf, size, "%-*s", width, out);
@@ -474,19 +474,19 @@ sort__daddr_cmp(struct hist_entry *left, struct hist_entry *right)
return (int64_t)(r - l);
}
-static int hist_entry__daddr_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__daddr_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
uint64_t addr = 0;
struct map *map = NULL;
struct symbol *sym = NULL;
- if (self->mem_info) {
- addr = self->mem_info->daddr.addr;
- map = self->mem_info->daddr.map;
- sym = self->mem_info->daddr.sym;
+ if (he->mem_info) {
+ addr = he->mem_info->daddr.addr;
+ map = he->mem_info->daddr.map;
+ sym = he->mem_info->daddr.sym;
}
- return _hist_entry__sym_snprintf(map, sym, addr, self->level, bf, size,
+ return _hist_entry__sym_snprintf(map, sym, addr, he->level, bf, size,
width);
}
@@ -504,13 +504,13 @@ sort__dso_daddr_cmp(struct hist_entry *left, struct hist_entry *right)
return _sort__dso_cmp(map_l, map_r);
}
-static int hist_entry__dso_daddr_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__dso_daddr_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
struct map *map = NULL;
- if (self->mem_info)
- map = self->mem_info->daddr.map;
+ if (he->mem_info)
+ map = he->mem_info->daddr.map;
return _hist_entry__dso_snprintf(map, bf, size, width);
}
@@ -534,14 +534,14 @@ sort__locked_cmp(struct hist_entry *left, struct hist_entry *right)
return (int64_t)(data_src_r.mem_lock - data_src_l.mem_lock);
}
-static int hist_entry__locked_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__locked_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
const char *out;
u64 mask = PERF_MEM_LOCK_NA;
- if (self->mem_info)
- mask = self->mem_info->data_src.mem_lock;
+ if (he->mem_info)
+ mask = he->mem_info->data_src.mem_lock;
if (mask & PERF_MEM_LOCK_NA)
out = "N/A";
@@ -583,7 +583,7 @@ static const char * const tlb_access[] = {
};
#define NUM_TLB_ACCESS (sizeof(tlb_access)/sizeof(const char *))
-static int hist_entry__tlb_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__tlb_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
char out[64];
@@ -594,8 +594,8 @@ static int hist_entry__tlb_snprintf(struct hist_entry *self, char *bf,
out[0] = '\0';
- if (self->mem_info)
- m = self->mem_info->data_src.mem_dtlb;
+ if (he->mem_info)
+ m = he->mem_info->data_src.mem_dtlb;
hit = m & PERF_MEM_TLB_HIT;
miss = m & PERF_MEM_TLB_MISS;
@@ -660,7 +660,7 @@ static const char * const mem_lvl[] = {
};
#define NUM_MEM_LVL (sizeof(mem_lvl)/sizeof(const char *))
-static int hist_entry__lvl_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__lvl_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
char out[64];
@@ -669,8 +669,8 @@ static int hist_entry__lvl_snprintf(struct hist_entry *self, char *bf,
u64 m = PERF_MEM_LVL_NA;
u64 hit, miss;
- if (self->mem_info)
- m = self->mem_info->data_src.mem_lvl;
+ if (he->mem_info)
+ m = he->mem_info->data_src.mem_lvl;
out[0] = '\0';
@@ -728,7 +728,7 @@ static const char * const snoop_access[] = {
};
#define NUM_SNOOP_ACCESS (sizeof(snoop_access)/sizeof(const char *))
-static int hist_entry__snoop_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__snoop_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
char out[64];
@@ -738,8 +738,8 @@ static int hist_entry__snoop_snprintf(struct hist_entry *self, char *bf,
out[0] = '\0';
- if (self->mem_info)
- m = self->mem_info->data_src.mem_snoop;
+ if (he->mem_info)
+ m = he->mem_info->data_src.mem_snoop;
for (i = 0; m && i < NUM_SNOOP_ACCESS; i++, m >>= 1) {
if (!(m & 0x1))
@@ -776,10 +776,10 @@ sort__local_weight_cmp(struct hist_entry *left, struct hist_entry *right)
return he_weight(left) - he_weight(right);
}
-static int hist_entry__local_weight_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__local_weight_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
- return repsep_snprintf(bf, size, "%-*llu", width, he_weight(self));
+ return repsep_snprintf(bf, size, "%-*llu", width, he_weight(he));
}
struct sort_entry sort_local_weight = {
@@ -795,10 +795,10 @@ sort__global_weight_cmp(struct hist_entry *left, struct hist_entry *right)
return left->stat.weight - right->stat.weight;
}
-static int hist_entry__global_weight_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__global_weight_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
- return repsep_snprintf(bf, size, "%-*llu", width, self->stat.weight);
+ return repsep_snprintf(bf, size, "%-*llu", width, he->stat.weight);
}
struct sort_entry sort_global_weight = {
@@ -857,12 +857,12 @@ sort__abort_cmp(struct hist_entry *left, struct hist_entry *right)
right->branch_info->flags.abort;
}
-static int hist_entry__abort_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__abort_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
static const char *out = ".";
- if (self->branch_info->flags.abort)
+ if (he->branch_info->flags.abort)
out = "A";
return repsep_snprintf(bf, size, "%-*s", width, out);
}
@@ -881,12 +881,12 @@ sort__in_tx_cmp(struct hist_entry *left, struct hist_entry *right)
right->branch_info->flags.in_tx;
}
-static int hist_entry__in_tx_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__in_tx_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
static const char *out = ".";
- if (self->branch_info->flags.in_tx)
+ if (he->branch_info->flags.in_tx)
out = "T";
return repsep_snprintf(bf, size, "%-*s", width, out);
@@ -940,10 +940,10 @@ int hist_entry__transaction_len(void)
return len;
}
-static int hist_entry__transaction_snprintf(struct hist_entry *self, char *bf,
+static int hist_entry__transaction_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
- u64 t = self->transaction;
+ u64 t = he->transaction;
char buf[128];
char *p = buf;
int i;
@@ -1125,7 +1125,7 @@ int setup_sorting(void)
return ret;
}
-static void sort_entry__setup_elide(struct sort_entry *self,
+static void sort_entry__setup_elide(struct sort_entry *se,
struct strlist *list,
const char *list_name, FILE *fp)
{
@@ -1133,7 +1133,7 @@ static void sort_entry__setup_elide(struct sort_entry *self,
if (fp != NULL)
fprintf(fp, "# %s: %s\n", list_name,
strlist__entry(list, 0)->s);
- self->elide = true;
+ se->elide = true;
}
}
diff --git a/tools/perf/util/strfilter.c b/tools/perf/util/strfilter.c
index 834c8ebfe38e..67e4a0082822 100644
--- a/tools/perf/util/strfilter.c
+++ b/tools/perf/util/strfilter.c
@@ -10,22 +10,22 @@ static const char *OP_not = "!"; /* Logical NOT */
#define is_operator(c) ((c) == '|' || (c) == '&' || (c) == '!')
#define is_separator(c) (is_operator(c) || (c) == '(' || (c) == ')')
-static void strfilter_node__delete(struct strfilter_node *self)
+static void strfilter_node__delete(struct strfilter_node *node)
{
- if (self) {
- if (self->p && !is_operator(*self->p))
- free((char *)self->p);
- strfilter_node__delete(self->l);
- strfilter_node__delete(self->r);
- free(self);
+ if (node) {
+ if (node->p && !is_operator(*node->p))
+ free((char *)node->p);
+ strfilter_node__delete(node->l);
+ strfilter_node__delete(node->r);
+ free(node);
}
}
-void strfilter__delete(struct strfilter *self)
+void strfilter__delete(struct strfilter *filter)
{
- if (self) {
- strfilter_node__delete(self->root);
- free(self);
+ if (filter) {
+ strfilter_node__delete(filter->root);
+ free(filter);
}
}
@@ -170,30 +170,30 @@ struct strfilter *strfilter__new(const char *rules, const char **err)
return ret;
}
-static bool strfilter_node__compare(struct strfilter_node *self,
+static bool strfilter_node__compare(struct strfilter_node *node,
const char *str)
{
- if (!self || !self->p)
+ if (!node || !node->p)
return false;
- switch (*self->p) {
+ switch (*node->p) {
case '|': /* OR */
- return strfilter_node__compare(self->l, str) ||
- strfilter_node__compare(self->r, str);
+ return strfilter_node__compare(node->l, str) ||
+ strfilter_node__compare(node->r, str);
case '&': /* AND */
- return strfilter_node__compare(self->l, str) &&
- strfilter_node__compare(self->r, str);
+ return strfilter_node__compare(node->l, str) &&
+ strfilter_node__compare(node->r, str);
case '!': /* NOT */
- return !strfilter_node__compare(self->r, str);
+ return !strfilter_node__compare(node->r, str);
default:
- return strglobmatch(str, self->p);
+ return strglobmatch(str, node->p);
}
}
/* Return true if STR matches the filter rules */
-bool strfilter__compare(struct strfilter *self, const char *str)
+bool strfilter__compare(struct strfilter *node, const char *str)
{
- if (!self)
+ if (!node)
return false;
- return strfilter_node__compare(self->root, str);
+ return strfilter_node__compare(node->root, str);
}
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index e3d4a550a703..80d19a086072 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -9,51 +9,51 @@
struct thread *thread__new(pid_t pid, pid_t tid)
{
- struct thread *self = zalloc(sizeof(*self));
+ struct thread *thread = zalloc(sizeof(*thread));
- if (self != NULL) {
- map_groups__init(&self->mg);
- self->pid_ = pid;
- self->tid = tid;
- self->ppid = -1;
- self->comm = malloc(32);
- if (self->comm)
- snprintf(self->comm, 32, ":%d", self->tid);
+ if (thread != NULL) {
+ map_groups__init(&thread->mg);
+ thread->pid_ = pid;
+ thread->tid = tid;
+ thread->ppid = -1;
+ thread->comm = malloc(32);
+ if (thread->comm)
+ snprintf(thread->comm, 32, ":%d", thread->tid);
}
- return self;
+ return thread;
}
-void thread__delete(struct thread *self)
+void thread__delete(struct thread *thread)
{
- map_groups__exit(&self->mg);
- free(self->comm);
- free(self);
+ map_groups__exit(&thread->mg);
+ free(thread->comm);
+ free(thread);
}
-int thread__set_comm(struct thread *self, const char *comm)
+int thread__set_comm(struct thread *thread, const char *comm)
{
int err;
- if (self->comm)
- free(self->comm);
- self->comm = strdup(comm);
- err = self->comm == NULL ? -ENOMEM : 0;
+ if (thread->comm)
+ free(thread->comm);
+ thread->comm = strdup(comm);
+ err = thread->comm == NULL ? -ENOMEM : 0;
if (!err) {
- self->comm_set = true;
+ thread->comm_set = true;
}
return err;
}
-int thread__comm_len(struct thread *self)
+int thread__comm_len(struct thread *thread)
{
- if (!self->comm_len) {
- if (!self->comm)
+ if (!thread->comm_len) {
+ if (!thread->comm)
return 0;
- self->comm_len = strlen(self->comm);
+ thread->comm_len = strlen(thread->comm);
}
- return self->comm_len;
+ return thread->comm_len;
}
size_t thread__fprintf(struct thread *thread, FILE *fp)
@@ -62,30 +62,30 @@ size_t thread__fprintf(struct thread *thread, FILE *fp)
map_groups__fprintf(&thread->mg, verbose, fp);
}
-void thread__insert_map(struct thread *self, struct map *map)
+void thread__insert_map(struct thread *thread, struct map *map)
{
- map_groups__fixup_overlappings(&self->mg, map, verbose, stderr);
- map_groups__insert(&self->mg, map);
+ map_groups__fixup_overlappings(&thread->mg, map, verbose, stderr);
+ map_groups__insert(&thread->mg, map);
}
-int thread__fork(struct thread *self, struct thread *parent)
+int thread__fork(struct thread *thread, struct thread *parent)
{
int i;
if (parent->comm_set) {
- if (self->comm)
- free(self->comm);
- self->comm = strdup(parent->comm);
- if (!self->comm)
+ if (thread->comm)
+ free(thread->comm);
+ thread->comm = strdup(parent->comm);
+ if (!thread->comm)
return -ENOMEM;
- self->comm_set = true;
+ thread->comm_set = true;
}
for (i = 0; i < MAP__NR_TYPES; ++i)
- if (map_groups__clone(&self->mg, &parent->mg, i) < 0)
+ if (map_groups__clone(&thread->mg, &parent->mg, i) < 0)
return -ENOMEM;
- self->ppid = parent->tid;
+ thread->ppid = parent->tid;
return 0;
}
--
1.8.1.4
From: Adrian Hunter <[email protected]>
Change "struct perf_sched sched" from being global to being local.
The build slowdown cured by f36f83f947ed is dealt with in the following
patch, by programatically setting perf_sched.curr_pid.
Signed-off-by: Adrian Hunter <[email protected]>
Acked-by: David Ahern <[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-sched.c | 41 ++++++++++++++++++++---------------------
1 file changed, 20 insertions(+), 21 deletions(-)
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 5a46b102eb08..5a338566195e 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1655,29 +1655,28 @@ static int __cmd_record(int argc, const char **argv)
return cmd_record(i, rec_argv, NULL);
}
-static const char default_sort_order[] = "avg, max, switch, runtime";
-static struct perf_sched sched = {
- .tool = {
- .sample = perf_sched__process_tracepoint_sample,
- .comm = perf_event__process_comm,
- .lost = perf_event__process_lost,
- .fork = perf_sched__process_fork_event,
- .ordered_samples = true,
- },
- .cmp_pid = LIST_HEAD_INIT(sched.cmp_pid),
- .sort_list = LIST_HEAD_INIT(sched.sort_list),
- .start_work_mutex = PTHREAD_MUTEX_INITIALIZER,
- .work_done_wait_mutex = PTHREAD_MUTEX_INITIALIZER,
- .curr_pid = { [0 ... MAX_CPUS - 1] = -1 },
- .sort_order = default_sort_order,
- .replay_repeat = 10,
- .profile_cpu = -1,
- .next_shortname1 = 'A',
- .next_shortname2 = '0',
-};
-
int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
{
+ const char default_sort_order[] = "avg, max, switch, runtime";
+ struct perf_sched sched = {
+ .tool = {
+ .sample = perf_sched__process_tracepoint_sample,
+ .comm = perf_event__process_comm,
+ .lost = perf_event__process_lost,
+ .fork = perf_sched__process_fork_event,
+ .ordered_samples = true,
+ },
+ .cmp_pid = LIST_HEAD_INIT(sched.cmp_pid),
+ .sort_list = LIST_HEAD_INIT(sched.sort_list),
+ .start_work_mutex = PTHREAD_MUTEX_INITIALIZER,
+ .work_done_wait_mutex = PTHREAD_MUTEX_INITIALIZER,
+ .curr_pid = { [0 ... MAX_CPUS - 1] = -1 },
+ .sort_order = default_sort_order,
+ .replay_repeat = 10,
+ .profile_cpu = -1,
+ .next_shortname1 = 'A',
+ .next_shortname2 = '0',
+ };
const struct option latency_options[] = {
OPT_STRING('s', "sort", &sched.sort_order, "key[,key2...]",
"sort by key(s): runtime, switch, avg, max"),
--
1.8.1.4
From: Masami Hiramatsu <[email protected]>
Support "$vars" meta argument syntax for tracing all local variables at
probe point.
Now you can trace all available local variables (including function
parameters) at the probe point by passing $vars.
# perf probe --add foo $vars
This automatically finds all local variables at foo() and adds it as
probe arguments.
Signed-off-by: Masami Hiramatsu <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/probe-event.c | 1 -
tools/perf/util/probe-finder.c | 96 ++++++++++++++++++++++++++++++++++++++----
tools/perf/util/probe-finder.h | 1 +
3 files changed, 89 insertions(+), 9 deletions(-)
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 779b2dacd43f..9c6989ca2bea 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -47,7 +47,6 @@
#include "session.h"
#define MAX_CMDLEN 256
-#define MAX_PROBE_ARGS 128
#define PERFPROBE_GROUP "probe"
bool probe_event_dry_run; /* Dry run flag */
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index c09e0a9fdf4c..5a46be968c0b 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -1136,12 +1136,78 @@ found:
return ret;
}
+struct local_vars_finder {
+ struct probe_finder *pf;
+ struct perf_probe_arg *args;
+ int max_args;
+ int nargs;
+ int ret;
+};
+
+/* Collect available variables in this scope */
+static int copy_variables_cb(Dwarf_Die *die_mem, void *data)
+{
+ struct local_vars_finder *vf = data;
+ int tag;
+
+ tag = dwarf_tag(die_mem);
+ if (tag == DW_TAG_formal_parameter ||
+ tag == DW_TAG_variable) {
+ if (convert_variable_location(die_mem, vf->pf->addr,
+ vf->pf->fb_ops, NULL) == 0) {
+ vf->args[vf->nargs].var = (char *)dwarf_diename(die_mem);
+ if (vf->args[vf->nargs].var == NULL) {
+ vf->ret = -ENOMEM;
+ return DIE_FIND_CB_END;
+ }
+ pr_debug(" %s", vf->args[vf->nargs].var);
+ vf->nargs++;
+ }
+ }
+
+ if (dwarf_haspc(die_mem, vf->pf->addr))
+ return DIE_FIND_CB_CONTINUE;
+ else
+ return DIE_FIND_CB_SIBLING;
+}
+
+static int expand_probe_args(Dwarf_Die *sc_die, struct probe_finder *pf,
+ struct perf_probe_arg *args)
+{
+ Dwarf_Die die_mem;
+ int i;
+ int n = 0;
+ struct local_vars_finder vf = {.pf = pf, .args = args,
+ .max_args = MAX_PROBE_ARGS, .ret = 0};
+
+ for (i = 0; i < pf->pev->nargs; i++) {
+ /* var never be NULL */
+ if (strcmp(pf->pev->args[i].var, "$vars") == 0) {
+ pr_debug("Expanding $vars into:");
+ vf.nargs = n;
+ /* Special local variables */
+ die_find_child(sc_die, copy_variables_cb, (void *)&vf,
+ &die_mem);
+ pr_debug(" (%d)\n", vf.nargs - n);
+ if (vf.ret < 0)
+ return vf.ret;
+ n = vf.nargs;
+ } else {
+ /* Copy normal argument */
+ args[n] = pf->pev->args[i];
+ n++;
+ }
+ }
+ return n;
+}
+
/* Add a found probe point into trace event list */
static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
{
struct trace_event_finder *tf =
container_of(pf, struct trace_event_finder, pf);
struct probe_trace_event *tev;
+ struct perf_probe_arg *args;
int ret, i;
/* Check number of tevs */
@@ -1161,21 +1227,35 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
pr_debug("Probe point found: %s+%lu\n", tev->point.symbol,
tev->point.offset);
- /* Find each argument */
- tev->nargs = pf->pev->nargs;
- tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
- if (tev->args == NULL)
+ /* Expand special probe argument if exist */
+ args = zalloc(sizeof(struct perf_probe_arg) * MAX_PROBE_ARGS);
+ if (args == NULL)
return -ENOMEM;
- for (i = 0; i < pf->pev->nargs; i++) {
- pf->pvar = &pf->pev->args[i];
+
+ ret = expand_probe_args(sc_die, pf, args);
+ if (ret < 0)
+ goto end;
+
+ tev->nargs = ret;
+ tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
+ if (tev->args == NULL) {
+ ret = -ENOMEM;
+ goto end;
+ }
+
+ /* Find each argument */
+ for (i = 0; i < tev->nargs; i++) {
+ pf->pvar = &args[i];
pf->tvar = &tev->args[i];
/* Variable should be found from scope DIE */
ret = find_variable(sc_die, pf);
if (ret != 0)
- return ret;
+ break;
}
- return 0;
+end:
+ free(args);
+ return ret;
}
/* Find probe_trace_events specified by perf_probe_event from debuginfo */
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index 3f0c29dd6ac5..d6dab0e0a937 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -7,6 +7,7 @@
#define MAX_PROBE_BUFFER 1024
#define MAX_PROBES 128
+#define MAX_PROBE_ARGS 128
static inline int is_c_varname(const char *name)
{
--
1.8.1.4
From: Arnaldo Carvalho de Melo <[email protected]>
Before:
[root@sandy ~]# perf test -v 22
22: Test sample parsing :
--- start ---
sample format has changed - test needs updating
---- end ----
Test sample parsing: FAILED!
[root@sandy ~]#
After:
[root@sandy ~]# perf test -v 22
22: Test sample parsing :
--- start ---
sample format has changed, some new PERF_SAMPLE_ bit was introduced - test needs updating
---- end ----
Test sample parsing: FAILED!
[root@sandy ~]#
Cc: Adrian Hunter <[email protected]>
Cc: Andi Kleen <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Jiri Olsa <[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/tests/sample-parsing.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c
index 77f598dbd97a..17d000c6c8ff 100644
--- a/tools/perf/tests/sample-parsing.c
+++ b/tools/perf/tests/sample-parsing.c
@@ -276,7 +276,7 @@ int test__sample_parsing(void)
* were added.
*/
if (PERF_SAMPLE_MAX > PERF_SAMPLE_IDENTIFIER << 1) {
- pr_debug("sample format has changed - test needs updating\n");
+ pr_debug("sample format has changed, some new PERF_SAMPLE_ bit was introduced - test needs updating\n");
return -1;
}
--
1.8.1.4
From: Arnaldo Carvalho de Melo <[email protected]>
Reserving 'struct ui_progress' to the per progress instances, not to the
particular set of operations used to implmenet a progress bar in the
current UI (GTK, TUI, etc).
Cc: Adrian Hunter <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Jiri Olsa <[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/Makefile.perf | 1 +
tools/perf/ui/gtk/gtk.h | 2 +-
tools/perf/ui/gtk/progress.c | 14 +++++++-------
tools/perf/ui/gtk/setup.c | 2 +-
tools/perf/ui/progress.c | 18 +++++++++---------
tools/perf/ui/progress.h | 6 ++----
tools/perf/ui/tui/progress.c | 7 ++++---
tools/perf/ui/tui/setup.c | 3 ++-
tools/perf/ui/tui/tui.h | 6 ++++++
9 files changed, 33 insertions(+), 26 deletions(-)
create mode 100644 tools/perf/ui/tui/tui.h
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 326a26e5fc1c..8a9ca3836043 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -487,6 +487,7 @@ ifndef NO_SLANG
LIB_OBJS += $(OUTPUT)ui/tui/util.o
LIB_OBJS += $(OUTPUT)ui/tui/helpline.o
LIB_OBJS += $(OUTPUT)ui/tui/progress.o
+ LIB_H += ui/tui/tui.h
LIB_H += ui/browser.h
LIB_H += ui/browsers/map.h
LIB_H += ui/keysyms.h
diff --git a/tools/perf/ui/gtk/gtk.h b/tools/perf/ui/gtk/gtk.h
index 8576cf194872..0a9173ff9a61 100644
--- a/tools/perf/ui/gtk/gtk.h
+++ b/tools/perf/ui/gtk/gtk.h
@@ -34,7 +34,7 @@ struct perf_gtk_context *perf_gtk__activate_context(GtkWidget *window);
int perf_gtk__deactivate_context(struct perf_gtk_context **ctx);
void perf_gtk__init_helpline(void);
-void perf_gtk__init_progress(void);
+void gtk_ui_progress__init(void);
void perf_gtk__init_hpp(void);
void perf_gtk__signal(int sig);
diff --git a/tools/perf/ui/gtk/progress.c b/tools/perf/ui/gtk/progress.c
index 482bcf3df9b7..195c7f94f98e 100644
--- a/tools/perf/ui/gtk/progress.c
+++ b/tools/perf/ui/gtk/progress.c
@@ -7,7 +7,7 @@
static GtkWidget *dialog;
static GtkWidget *progress;
-static void gtk_progress_update(u64 curr, u64 total, const char *title)
+static void gtk_ui_progress__update(u64 curr, u64 total, const char *title)
{
double fraction = total ? 1.0 * curr / total : 0.0;
char buf[1024];
@@ -40,7 +40,7 @@ static void gtk_progress_update(u64 curr, u64 total, const char *title)
gtk_main_iteration();
}
-static void gtk_progress_finish(void)
+static void gtk_ui_progress__finish(void)
{
/* this will also destroy all of its children */
gtk_widget_destroy(dialog);
@@ -48,12 +48,12 @@ static void gtk_progress_finish(void)
dialog = NULL;
}
-static struct ui_progress gtk_progress_fns = {
- .update = gtk_progress_update,
- .finish = gtk_progress_finish,
+static struct ui_progress_ops gtk_ui_progress__ops = {
+ .update = gtk_ui_progress__update,
+ .finish = gtk_ui_progress__finish,
};
-void perf_gtk__init_progress(void)
+void gtk_ui_progress__init(void)
{
- progress_fns = >k_progress_fns;
+ ui_progress__ops = >k_ui_progress__ops;
}
diff --git a/tools/perf/ui/gtk/setup.c b/tools/perf/ui/gtk/setup.c
index 6c2dd2e423f3..1d57676f8212 100644
--- a/tools/perf/ui/gtk/setup.c
+++ b/tools/perf/ui/gtk/setup.c
@@ -8,7 +8,7 @@ int perf_gtk__init(void)
{
perf_error__register(&perf_gtk_eops);
perf_gtk__init_helpline();
- perf_gtk__init_progress();
+ gtk_ui_progress__init();
perf_gtk__init_hpp();
return gtk_init_check(NULL, NULL) ? 0 : -1;
diff --git a/tools/perf/ui/progress.c b/tools/perf/ui/progress.c
index 3ec695607a4d..d753821b6e0b 100644
--- a/tools/perf/ui/progress.c
+++ b/tools/perf/ui/progress.c
@@ -1,26 +1,26 @@
#include "../cache.h"
#include "progress.h"
-static void nop_progress_update(u64 curr __maybe_unused,
- u64 total __maybe_unused,
- const char *title __maybe_unused)
+static void null_progress__update(u64 curr __maybe_unused,
+ u64 total __maybe_unused,
+ const char *title __maybe_unused)
{
}
-static struct ui_progress default_progress_fns =
+static struct ui_progress_ops null_progress__ops =
{
- .update = nop_progress_update,
+ .update = null_progress__update,
};
-struct ui_progress *progress_fns = &default_progress_fns;
+struct ui_progress_ops *ui_progress__ops = &null_progress__ops;
void ui_progress__update(u64 curr, u64 total, const char *title)
{
- return progress_fns->update(curr, total, title);
+ return ui_progress__ops->update(curr, total, title);
}
void ui_progress__finish(void)
{
- if (progress_fns->finish)
- progress_fns->finish();
+ if (ui_progress__ops->finish)
+ ui_progress__ops->finish();
}
diff --git a/tools/perf/ui/progress.h b/tools/perf/ui/progress.h
index 257cc224f9cf..d41bde5908a6 100644
--- a/tools/perf/ui/progress.h
+++ b/tools/perf/ui/progress.h
@@ -3,14 +3,12 @@
#include <../types.h>
-struct ui_progress {
+struct ui_progress_ops {
void (*update)(u64, u64, const char *);
void (*finish)(void);
};
-extern struct ui_progress *progress_fns;
-
-void ui_progress__init(void);
+extern struct ui_progress_ops *ui_progress__ops;
void ui_progress__update(u64 curr, u64 total, const char *title);
void ui_progress__finish(void);
diff --git a/tools/perf/ui/tui/progress.c b/tools/perf/ui/tui/progress.c
index 6c2184d53cbf..0fcc5a1f525a 100644
--- a/tools/perf/ui/tui/progress.c
+++ b/tools/perf/ui/tui/progress.c
@@ -2,6 +2,7 @@
#include "../progress.h"
#include "../libslang.h"
#include "../ui.h"
+#include "tui.h"
#include "../browser.h"
static void tui_progress__update(u64 curr, u64 total, const char *title)
@@ -31,12 +32,12 @@ static void tui_progress__update(u64 curr, u64 total, const char *title)
pthread_mutex_unlock(&ui__lock);
}
-static struct ui_progress tui_progress_fns =
+static struct ui_progress_ops tui_progress__ops =
{
.update = tui_progress__update,
};
-void ui_progress__init(void)
+void tui_progress__init(void)
{
- progress_fns = &tui_progress_fns;
+ ui_progress__ops = &tui_progress__ops;
}
diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c
index b9401482d110..2f612562978c 100644
--- a/tools/perf/ui/tui/setup.c
+++ b/tools/perf/ui/tui/setup.c
@@ -9,6 +9,7 @@
#include "../util.h"
#include "../libslang.h"
#include "../keysyms.h"
+#include "tui.h"
static volatile int ui__need_resize;
@@ -119,7 +120,7 @@ int ui__init(void)
ui_helpline__init();
ui_browser__init();
- ui_progress__init();
+ tui_progress__init();
signal(SIGSEGV, ui__signal);
signal(SIGFPE, ui__signal);
diff --git a/tools/perf/ui/tui/tui.h b/tools/perf/ui/tui/tui.h
new file mode 100644
index 000000000000..18961c7b6ec5
--- /dev/null
+++ b/tools/perf/ui/tui/tui.h
@@ -0,0 +1,6 @@
+#ifndef _PERF_TUI_H_
+#define _PERF_TUI_H_ 1
+
+void tui_progress__init(void);
+
+#endif /* _PERF_TUI_H_ */
--
1.8.1.4
From: Arnaldo Carvalho de Melo <[email protected]>
That will ease using a progress bar across multiple functions, like in
the upcoming patches that will present a progress bar when collapsing
histograms.
Based on a previous patch by Namhyung Kim.
Cc: Adrian Hunter <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Jiri Olsa <[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/ui/gtk/progress.c | 8 ++++----
tools/perf/ui/progress.c | 22 +++++++++++++++++-----
tools/perf/ui/progress.h | 15 +++++++++++----
tools/perf/ui/tui/progress.c | 8 ++++----
tools/perf/util/session.c | 24 +++++++++++-------------
5 files changed, 47 insertions(+), 30 deletions(-)
diff --git a/tools/perf/ui/gtk/progress.c b/tools/perf/ui/gtk/progress.c
index 195c7f94f98e..b656655fbc39 100644
--- a/tools/perf/ui/gtk/progress.c
+++ b/tools/perf/ui/gtk/progress.c
@@ -7,14 +7,14 @@
static GtkWidget *dialog;
static GtkWidget *progress;
-static void gtk_ui_progress__update(u64 curr, u64 total, const char *title)
+static void gtk_ui_progress__update(struct ui_progress *p)
{
- double fraction = total ? 1.0 * curr / total : 0.0;
+ double fraction = p->total ? 1.0 * p->curr / p->total : 0.0;
char buf[1024];
if (dialog == NULL) {
GtkWidget *vbox = gtk_vbox_new(TRUE, 5);
- GtkWidget *label = gtk_label_new(title);
+ GtkWidget *label = gtk_label_new(p->title);
dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
progress = gtk_progress_bar_new();
@@ -32,7 +32,7 @@ static void gtk_ui_progress__update(u64 curr, u64 total, const char *title)
}
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), fraction);
- snprintf(buf, sizeof(buf), "%"PRIu64" / %"PRIu64, curr, total);
+ snprintf(buf, sizeof(buf), "%"PRIu64" / %"PRIu64, p->curr, p->total);
gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress), buf);
/* we didn't call gtk_main yet, so do it manually */
diff --git a/tools/perf/ui/progress.c b/tools/perf/ui/progress.c
index d753821b6e0b..a0f24c7115c5 100644
--- a/tools/perf/ui/progress.c
+++ b/tools/perf/ui/progress.c
@@ -1,9 +1,7 @@
#include "../cache.h"
#include "progress.h"
-static void null_progress__update(u64 curr __maybe_unused,
- u64 total __maybe_unused,
- const char *title __maybe_unused)
+static void null_progress__update(struct ui_progress *p __maybe_unused)
{
}
@@ -14,9 +12,23 @@ static struct ui_progress_ops null_progress__ops =
struct ui_progress_ops *ui_progress__ops = &null_progress__ops;
-void ui_progress__update(u64 curr, u64 total, const char *title)
+void ui_progress__update(struct ui_progress *p, u64 adv)
{
- return ui_progress__ops->update(curr, total, title);
+ p->curr += adv;
+
+ if (p->curr >= p->next) {
+ p->next += p->step;
+ ui_progress__ops->update(p);
+ }
+}
+
+void ui_progress__init(struct ui_progress *p, u64 total, const char *title)
+{
+ p->curr = 0;
+ p->next = p->step = total / 16;
+ p->total = total;
+ p->title = title;
+
}
void ui_progress__finish(void)
diff --git a/tools/perf/ui/progress.h b/tools/perf/ui/progress.h
index d41bde5908a6..29ec8efffefb 100644
--- a/tools/perf/ui/progress.h
+++ b/tools/perf/ui/progress.h
@@ -3,14 +3,21 @@
#include <../types.h>
+void ui_progress__finish(void);
+
+struct ui_progress {
+ const char *title;
+ u64 curr, next, step, total;
+};
+
+void ui_progress__init(struct ui_progress *p, u64 total, const char *title);
+void ui_progress__update(struct ui_progress *p, u64 adv);
+
struct ui_progress_ops {
- void (*update)(u64, u64, const char *);
+ void (*update)(struct ui_progress *p);
void (*finish)(void);
};
extern struct ui_progress_ops *ui_progress__ops;
-void ui_progress__update(u64 curr, u64 total, const char *title);
-void ui_progress__finish(void);
-
#endif
diff --git a/tools/perf/ui/tui/progress.c b/tools/perf/ui/tui/progress.c
index 0fcc5a1f525a..3e2d936d7443 100644
--- a/tools/perf/ui/tui/progress.c
+++ b/tools/perf/ui/tui/progress.c
@@ -5,7 +5,7 @@
#include "tui.h"
#include "../browser.h"
-static void tui_progress__update(u64 curr, u64 total, const char *title)
+static void tui_progress__update(struct ui_progress *p)
{
int bar, y;
/*
@@ -15,7 +15,7 @@ static void tui_progress__update(u64 curr, u64 total, const char *title)
if (use_browser <= 0)
return;
- if (total == 0)
+ if (p->total == 0)
return;
ui__refresh_dimensions(true);
@@ -24,9 +24,9 @@ static void tui_progress__update(u64 curr, u64 total, const char *title)
SLsmg_set_color(0);
SLsmg_draw_box(y, 0, 3, SLtt_Screen_Cols);
SLsmg_gotorc(y++, 1);
- SLsmg_write_string((char *)title);
+ SLsmg_write_string((char *)p->title);
SLsmg_set_color(HE_COLORSET_SELECTED);
- bar = ((SLtt_Screen_Cols - 2) * curr) / total;
+ bar = ((SLtt_Screen_Cols - 2) * p->curr) / p->total;
SLsmg_fill_region(y, 1, 1, bar, ' ');
SLsmg_refresh();
pthread_mutex_unlock(&ui__lock);
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 854c5aa4db0d..4ba7b548e055 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -503,13 +503,16 @@ static int flush_sample_queue(struct perf_session *s,
struct perf_sample sample;
u64 limit = os->next_flush;
u64 last_ts = os->last_sample ? os->last_sample->timestamp : 0ULL;
- unsigned idx = 0, progress_next = os->nr_samples / 16;
bool show_progress = limit == ULLONG_MAX;
+ struct ui_progress prog;
int ret;
if (!tool->ordered_samples || !limit)
return 0;
+ if (show_progress)
+ ui_progress__init(&prog, os->nr_samples, "Processing time ordered events...");
+
list_for_each_entry_safe(iter, tmp, head, list) {
if (session_done())
return 0;
@@ -530,11 +533,9 @@ static int flush_sample_queue(struct perf_session *s,
os->last_flush = iter->timestamp;
list_del(&iter->list);
list_add(&iter->list, &os->sample_cache);
- if (show_progress && (++idx >= progress_next)) {
- progress_next += os->nr_samples / 16;
- ui_progress__update(idx, os->nr_samples,
- "Processing time ordered events...");
- }
+
+ if (show_progress)
+ ui_progress__update(&prog, 1);
}
if (list_empty(head)) {
@@ -1285,12 +1286,13 @@ int __perf_session__process_events(struct perf_session *session,
u64 file_size, struct perf_tool *tool)
{
int fd = perf_data_file__fd(session->file);
- u64 head, page_offset, file_offset, file_pos, progress_next;
+ u64 head, page_offset, file_offset, file_pos;
int err, mmap_prot, mmap_flags, map_idx = 0;
size_t mmap_size;
char *buf, *mmaps[NUM_MMAPS];
union perf_event *event;
uint32_t size;
+ struct ui_progress prog;
perf_tool__fill_defaults(tool);
@@ -1301,7 +1303,7 @@ int __perf_session__process_events(struct perf_session *session,
if (data_size && (data_offset + data_size < file_size))
file_size = data_offset + data_size;
- progress_next = file_size / 16;
+ ui_progress__init(&prog, file_size, "Processing events...");
mmap_size = MMAP_SIZE;
if (mmap_size > file_size)
@@ -1356,11 +1358,7 @@ more:
head += size;
file_pos += size;
- if (file_pos >= progress_next) {
- progress_next += file_size / 16;
- ui_progress__update(file_pos, file_size,
- "Processing events...");
- }
+ ui_progress__update(&prog, size);
if (session_done())
goto out;
--
1.8.1.4
From: Adrian Hunter <[email protected]>
parse_tag_value() accepts an "unsigned long" and multiplies it according
to a tag character. Do not accept the value if the multiplication
overflows.
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/util.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index c25e57b3acb2..28a0a89c1f73 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -386,6 +386,8 @@ unsigned long parse_tag_value(const char *str, struct parse_tag *tags)
if (s != endptr)
break;
+ if (value > ULONG_MAX / i->mult)
+ break;
value *= i->mult;
return value;
}
--
1.8.1.4
From: Masami Hiramatsu <[email protected]>
At this point, --fentry (mcount function entry) option for gcc fuzzes
the debuginfo variable locations by skipping the mcount instruction
offset (on x86, this is a 5 byte call instruction).
This makes variable searching fail at the entry of functions which
are mcount'ed.
e.g.)
Available variables at vfs_read
@<vfs_read+0>
(No matched variables)
This patch adds additional location search at the function entry point
to solve this issue, which tries to find the earliest address for the
variable location.
Note that this only works with function parameters (formal parameters)
because any local variables should not exist on the function entry
address (those are not initialized yet).
With this patch, perf probe shows correct parameters if possible;
# perf probe --vars vfs_read
Available variables at vfs_read
@<vfs_read+0>
char* buf
loff_t* pos
size_t count
struct file* file
Signed-off-by: Masami Hiramatsu <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/probe-finder.c | 39 +++++++++++++++++++++++++++++++--------
1 file changed, 31 insertions(+), 8 deletions(-)
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 5a46be968c0b..c04405296e5b 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -273,12 +273,15 @@ static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs)
/*
* Convert a location into trace_arg.
* If tvar == NULL, this just checks variable can be converted.
+ * If fentry == true and vr_die is a parameter, do huristic search
+ * for the location fuzzed by function entry mcount.
*/
static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
- Dwarf_Op *fb_ops,
+ Dwarf_Op *fb_ops, Dwarf_Die *sp_die,
struct probe_trace_arg *tvar)
{
Dwarf_Attribute attr;
+ Dwarf_Addr tmp = 0;
Dwarf_Op *op;
size_t nops;
unsigned int regn;
@@ -291,12 +294,29 @@ static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
goto static_var;
/* TODO: handle more than 1 exprs */
- if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL ||
- dwarf_getlocation_addr(&attr, addr, &op, &nops, 1) <= 0 ||
- nops == 0) {
- /* TODO: Support const_value */
+ if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL)
+ return -EINVAL; /* Broken DIE ? */
+ if (dwarf_getlocation_addr(&attr, addr, &op, &nops, 1) <= 0) {
+ ret = dwarf_entrypc(sp_die, &tmp);
+ if (ret || addr != tmp ||
+ dwarf_tag(vr_die) != DW_TAG_formal_parameter ||
+ dwarf_highpc(sp_die, &tmp))
+ return -ENOENT;
+ /*
+ * This is fuzzed by fentry mcount. We try to find the
+ * parameter location at the earliest address.
+ */
+ for (addr += 1; addr <= tmp; addr++) {
+ if (dwarf_getlocation_addr(&attr, addr, &op,
+ &nops, 1) > 0)
+ goto found;
+ }
return -ENOENT;
}
+found:
+ if (nops == 0)
+ /* TODO: Support const_value */
+ return -ENOENT;
if (op->atom == DW_OP_addr) {
static_var:
@@ -600,7 +620,7 @@ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
dwarf_diename(vr_die));
ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops,
- pf->tvar);
+ &pf->sp_die, pf->tvar);
if (ret == -ENOENT)
pr_err("Failed to find the location of %s at this address.\n"
" Perhaps, it has been optimized out.\n", pf->pvar->var);
@@ -1148,13 +1168,15 @@ struct local_vars_finder {
static int copy_variables_cb(Dwarf_Die *die_mem, void *data)
{
struct local_vars_finder *vf = data;
+ struct probe_finder *pf = vf->pf;
int tag;
tag = dwarf_tag(die_mem);
if (tag == DW_TAG_formal_parameter ||
tag == DW_TAG_variable) {
if (convert_variable_location(die_mem, vf->pf->addr,
- vf->pf->fb_ops, NULL) == 0) {
+ vf->pf->fb_ops, &pf->sp_die,
+ NULL) == 0) {
vf->args[vf->nargs].var = (char *)dwarf_diename(die_mem);
if (vf->args[vf->nargs].var == NULL) {
vf->ret = -ENOMEM;
@@ -1302,7 +1324,8 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
if (tag == DW_TAG_formal_parameter ||
tag == DW_TAG_variable) {
ret = convert_variable_location(die_mem, af->pf.addr,
- af->pf.fb_ops, NULL);
+ af->pf.fb_ops, &af->pf.sp_die,
+ NULL);
if (ret == 0) {
ret = die_get_varname(die_mem, buf, MAX_VAR_LEN);
pr_debug2("Add new var: %s\n", buf);
--
1.8.1.4
From: Adrian Hunter <[email protected]>
builtin-sched.c took a log time to build with -O6 optimization. This
turned out to be caused by:
.curr_pid = { [0 ... MAX_CPUS - 1] = -1 },
Fix by initializing curr_pid programmatically.
This addresses the problem cured in f36f83f947ed using a smaller hammer.
Signed-off-by: Adrian Hunter <[email protected]>
Acked-by: David Ahern <[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-sched.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 5a338566195e..ddb5dc15be17 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1670,7 +1670,6 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
.sort_list = LIST_HEAD_INIT(sched.sort_list),
.start_work_mutex = PTHREAD_MUTEX_INITIALIZER,
.work_done_wait_mutex = PTHREAD_MUTEX_INITIALIZER,
- .curr_pid = { [0 ... MAX_CPUS - 1] = -1 },
.sort_order = default_sort_order,
.replay_repeat = 10,
.profile_cpu = -1,
@@ -1732,6 +1731,10 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
.switch_event = replay_switch_event,
.fork_event = replay_fork_event,
};
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(sched.curr_pid); i++)
+ sched.curr_pid[i] = -1;
argc = parse_options(argc, argv, sched_options, sched_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
--
1.8.1.4
From: Namhyung Kim <[email protected]>
It can take quite amount of time so add progress bar UI to inform user.
Signed-off-by: Namhyung Kim <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
[ perf_progress -> ui_progress ]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-annotate.c | 2 +-
tools/perf/builtin-diff.c | 2 +-
tools/perf/builtin-report.c | 10 +++++++++-
tools/perf/builtin-top.c | 4 ++--
tools/perf/tests/hists_link.c | 2 +-
tools/perf/util/hist.c | 5 ++++-
tools/perf/util/hist.h | 3 ++-
7 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 17c6b494e8cc..6c5ae57831f6 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -247,7 +247,7 @@ static int __cmd_annotate(struct perf_annotate *ann)
if (nr_samples > 0) {
total_nr_samples += nr_samples;
- hists__collapse_resort(hists);
+ hists__collapse_resort(hists, NULL);
hists__output_resort(hists);
if (symbol_conf.event_group &&
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 9c828881714c..b605009e803f 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -369,7 +369,7 @@ static void perf_evlist__collapse_resort(struct perf_evlist *evlist)
list_for_each_entry(evsel, &evlist->entries, node) {
struct hists *hists = &evsel->hists;
- hists__collapse_resort(hists);
+ hists__collapse_resort(hists, NULL);
}
}
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index e3598a456017..98d3891392e2 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -496,6 +496,7 @@ static int __cmd_report(struct perf_report *rep)
struct map *kernel_map;
struct kmap *kernel_kmap;
const char *help = "For a higher level overview, try: perf report --sort comm,dso";
+ struct ui_progress prog;
struct perf_data_file *file = session->file;
signal(SIGINT, sig_handler);
@@ -558,13 +559,19 @@ static int __cmd_report(struct perf_report *rep)
}
nr_samples = 0;
+ list_for_each_entry(pos, &session->evlist->entries, node)
+ nr_samples += pos->hists.nr_entries;
+
+ ui_progress__init(&prog, nr_samples, "Merging related events...");
+
+ nr_samples = 0;
list_for_each_entry(pos, &session->evlist->entries, node) {
struct hists *hists = &pos->hists;
if (pos->idx == 0)
hists->symbol_filter_str = rep->symbol_filter_str;
- hists__collapse_resort(hists);
+ hists__collapse_resort(hists, &prog);
nr_samples += hists->stats.nr_events[PERF_RECORD_SAMPLE];
/* Non-group events are considered as leader */
@@ -576,6 +583,7 @@ static int __cmd_report(struct perf_report *rep)
hists__link(leader_hists, hists);
}
}
+ ui_progress__finish();
if (session_done())
return 0;
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 386d83324a8d..76c9264ed070 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -286,7 +286,7 @@ static void perf_top__print_sym_table(struct perf_top *top)
return;
}
- hists__collapse_resort(&top->sym_evsel->hists);
+ hists__collapse_resort(&top->sym_evsel->hists, NULL);
hists__output_resort(&top->sym_evsel->hists);
hists__decay_entries(&top->sym_evsel->hists,
top->hide_user_symbols,
@@ -552,7 +552,7 @@ static void perf_top__sort_new_samples(void *arg)
if (t->evlist->selected != NULL)
t->sym_evsel = t->evlist->selected;
- hists__collapse_resort(&t->sym_evsel->hists);
+ hists__collapse_resort(&t->sym_evsel->hists, NULL);
hists__output_resort(&t->sym_evsel->hists);
hists__decay_entries(&t->sym_evsel->hists,
t->hide_user_symbols,
diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c
index 025503a22ff7..b51abcb2c243 100644
--- a/tools/perf/tests/hists_link.c
+++ b/tools/perf/tests/hists_link.c
@@ -467,7 +467,7 @@ int test__hists_link(void)
goto out;
list_for_each_entry(evsel, &evlist->entries, node) {
- hists__collapse_resort(&evsel->hists);
+ hists__collapse_resort(&evsel->hists, NULL);
if (verbose > 2)
print_hists(&evsel->hists);
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index f0b863ef4896..7e80253074b0 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -399,6 +399,7 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
if (!he)
return NULL;
+ hists->nr_entries++;
rb_link_node(&he->rb_node_in, parent, p);
rb_insert_color(&he->rb_node_in, hists->entries_in);
out:
@@ -604,7 +605,7 @@ static void hists__apply_filters(struct hists *hists, struct hist_entry *he)
hists__filter_entry_by_symbol(hists, he);
}
-void hists__collapse_resort(struct hists *hists)
+void hists__collapse_resort(struct hists *hists, struct ui_progress *prog)
{
struct rb_root *root;
struct rb_node *next;
@@ -631,6 +632,8 @@ void hists__collapse_resort(struct hists *hists)
*/
hists__apply_filters(hists, n);
}
+ if (prog)
+ ui_progress__update(prog, 1);
}
}
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 20b175808cd3..0c7ce8bb8eba 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -5,6 +5,7 @@
#include <pthread.h>
#include "callchain.h"
#include "header.h"
+#include "ui/progress.h"
extern struct callchain_param callchain_param;
@@ -108,7 +109,7 @@ struct hist_entry *__hists__add_mem_entry(struct hists *self,
u64 weight);
void hists__output_resort(struct hists *self);
-void hists__collapse_resort(struct hists *self);
+void hists__collapse_resort(struct hists *self, struct ui_progress *prog);
void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel);
void hists__output_recalc_col_len(struct hists *hists, int max_rows);
--
1.8.1.4
From: Ingo Molnar <[email protected]>
Before this patch, looking at 'perf bench sched pipe' behavior over
'top' only told us that something related to perf is running:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
19934 mingo 20 0 54836 1296 952 R 18.6 0.0 0:00.56 perf
19935 mingo 20 0 54836 384 36 S 18.6 0.0 0:00.56 perf
After the patch it's clearly visible what's going on:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
19744 mingo 20 0 125m 3536 2644 R 68.2 0.0 0:01.12 sched-pipe
19745 mingo 20 0 125m 1172 276 R 68.2 0.0 0:01.12 sched-pipe
The benchmark-subsystem name is concatenated with the individual
testcase name.
Unfortunately 'perf top' does not show the reconfigured name, possibly
because it caches ->comm[] values and does not recognize changes to
them?
Also clean up a few bits in builtin-bench.c while at it and reorganize
the code and the output strings to be consistent.
Use iterators to access the various arrays. Rename 'suites' concept to
'benchmark collection' and the 'bench_suite' to 'benchmark/bench'. The
many repetitions of 'suite' made the code harder to read and understand.
The new output is:
comet:~/tip/tools/perf> ./perf bench
Usage:
perf bench [<common options>] <collection> <benchmark> [<options>]
# List of all available benchmark collections:
sched: Scheduler and IPC benchmarks
mem: Memory access benchmarks
numa: NUMA scheduling and MM benchmarks
all: All benchmarks
comet:~/tip/tools/perf> ./perf bench sched
# List of available benchmarks for collection 'sched':
messaging: Benchmark for scheduling and IPC
pipe: Benchmark for pipe() between two processes
all: Test all scheduler benchmarks
comet:~/tip/tools/perf> ./perf bench mem
# List of available benchmarks for collection 'mem':
memcpy: Benchmark for memcpy()
memset: Benchmark for memset() tests
all: Test all memory benchmarks
comet:~/tip/tools/perf> ./perf bench numa
# List of available benchmarks for collection 'numa':
mem: Benchmark for NUMA workloads
all: Test all NUMA benchmarks
Individual benchmark modules were not touched.
Signed-off-by: Ingo Molnar <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Hitoshi Mitake <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-bench.c | 239 +++++++++++++++++++++++----------------------
1 file changed, 122 insertions(+), 117 deletions(-)
diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c
index 33af80fa49cf..e47f90cc7b98 100644
--- a/tools/perf/builtin-bench.c
+++ b/tools/perf/builtin-bench.c
@@ -1,21 +1,18 @@
/*
- *
* builtin-bench.c
*
- * General benchmarking subsystem provided by perf
+ * General benchmarking collections provided by perf
*
* Copyright (C) 2009, Hitoshi Mitake <[email protected]>
- *
*/
/*
+ * Available benchmark collection list:
*
- * Available subsystem list:
- * sched ... scheduler and IPC mechanism
+ * sched ... scheduler and IPC performance
* mem ... memory access performance
- *
+ * numa ... NUMA scheduling and MM performance
*/
-
#include "perf.h"
#include "util/util.h"
#include "util/parse-options.h"
@@ -25,112 +22,92 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/prctl.h>
-struct bench_suite {
- const char *name;
- const char *summary;
- int (*fn)(int, const char **, const char *);
+typedef int (*bench_fn_t)(int argc, const char **argv, const char *prefix);
+
+struct bench {
+ const char *name;
+ const char *summary;
+ bench_fn_t fn;
};
- \
-/* sentinel: easy for help */
-#define suite_all { "all", "Test all benchmark suites", NULL }
#ifdef HAVE_LIBNUMA_SUPPORT
-static struct bench_suite numa_suites[] = {
- { "mem",
- "Benchmark for NUMA workloads",
- bench_numa },
- suite_all,
- { NULL,
- NULL,
- NULL }
+static struct bench numa_benchmarks[] = {
+ { "mem", "Benchmark for NUMA workloads", bench_numa },
+ { "all", "Test all NUMA benchmarks", NULL },
+ { NULL, NULL, NULL }
};
#endif
-static struct bench_suite sched_suites[] = {
- { "messaging",
- "Benchmark for scheduler and IPC mechanisms",
- bench_sched_messaging },
- { "pipe",
- "Flood of communication over pipe() between two processes",
- bench_sched_pipe },
- suite_all,
- { NULL,
- NULL,
- NULL }
+static struct bench sched_benchmarks[] = {
+ { "messaging", "Benchmark for scheduling and IPC", bench_sched_messaging },
+ { "pipe", "Benchmark for pipe() between two processes", bench_sched_pipe },
+ { "all", "Test all scheduler benchmarks", NULL },
+ { NULL, NULL, NULL }
};
-static struct bench_suite mem_suites[] = {
- { "memcpy",
- "Simple memory copy in various ways",
- bench_mem_memcpy },
- { "memset",
- "Simple memory set in various ways",
- bench_mem_memset },
- suite_all,
- { NULL,
- NULL,
- NULL }
+static struct bench mem_benchmarks[] = {
+ { "memcpy", "Benchmark for memcpy()", bench_mem_memcpy },
+ { "memset", "Benchmark for memset() tests", bench_mem_memset },
+ { "all", "Test all memory benchmarks", NULL },
+ { NULL, NULL, NULL }
};
-struct bench_subsys {
- const char *name;
- const char *summary;
- struct bench_suite *suites;
+struct collection {
+ const char *name;
+ const char *summary;
+ struct bench *benchmarks;
};
-static struct bench_subsys subsystems[] = {
+static struct collection collections[] = {
+ { "sched", "Scheduler and IPC benchmarks", sched_benchmarks },
+ { "mem", "Memory access benchmarks", mem_benchmarks },
#ifdef HAVE_LIBNUMA_SUPPORT
- { "numa",
- "NUMA scheduling and MM behavior",
- numa_suites },
+ { "numa", "NUMA scheduling and MM benchmarks", numa_benchmarks },
#endif
- { "sched",
- "scheduler and IPC mechanism",
- sched_suites },
- { "mem",
- "memory access performance",
- mem_suites },
- { "all", /* sentinel: easy for help */
- "all benchmark subsystem",
- NULL },
- { NULL,
- NULL,
- NULL }
+ { "all", "All benchmarks", NULL },
+ { NULL, NULL, NULL }
};
-static void dump_suites(int subsys_index)
+/* Iterate over all benchmark collections: */
+#define for_each_collection(coll) \
+ for (coll = collections; coll->name; coll++)
+
+/* Iterate over all benchmarks within a collection: */
+#define for_each_bench(coll, bench) \
+ for (bench = coll->benchmarks; bench->name; bench++)
+
+static void dump_benchmarks(struct collection *coll)
{
- int i;
+ struct bench *bench;
- printf("# List of available suites for %s...\n\n",
- subsystems[subsys_index].name);
+ printf("\n # List of available benchmarks for collection '%s':\n\n", coll->name);
- for (i = 0; subsystems[subsys_index].suites[i].name; i++)
- printf("%14s: %s\n",
- subsystems[subsys_index].suites[i].name,
- subsystems[subsys_index].suites[i].summary);
+ for_each_bench(coll, bench)
+ printf("%14s: %s\n", bench->name, bench->summary);
printf("\n");
- return;
}
static const char *bench_format_str;
+
+/* Output/formatting style, exported to benchmark modules: */
int bench_format = BENCH_FORMAT_DEFAULT;
static const struct option bench_options[] = {
- OPT_STRING('f', "format", &bench_format_str, "default",
- "Specify format style"),
+ OPT_STRING('f', "format", &bench_format_str, "default", "Specify format style"),
OPT_END()
};
static const char * const bench_usage[] = {
- "perf bench [<common options>] <subsystem> <suite> [<options>]",
+ "perf bench [<common options>] <collection> <benchmark> [<options>]",
NULL
};
static void print_usage(void)
{
+ struct collection *coll;
int i;
printf("Usage: \n");
@@ -138,11 +115,10 @@ static void print_usage(void)
printf("\t%s\n", bench_usage[i]);
printf("\n");
- printf("# List of available subsystems...\n\n");
+ printf(" # List of all available benchmark collections:\n\n");
- for (i = 0; subsystems[i].name; i++)
- printf("%14s: %s\n",
- subsystems[i].name, subsystems[i].summary);
+ for_each_collection(coll)
+ printf("%14s: %s\n", coll->name, coll->summary);
printf("\n");
}
@@ -159,44 +135,74 @@ static int bench_str2int(const char *str)
return BENCH_FORMAT_UNKNOWN;
}
-static void all_suite(struct bench_subsys *subsys) /* FROM HERE */
+/*
+ * Run a specific benchmark but first rename the running task's ->comm[]
+ * to something meaningful:
+ */
+static int run_bench(const char *coll_name, const char *bench_name, bench_fn_t fn,
+ int argc, const char **argv, const char *prefix)
{
- int i;
+ int size;
+ char *name;
+ int ret;
+
+ size = strlen(coll_name) + 1 + strlen(bench_name) + 1;
+
+ name = zalloc(size);
+ BUG_ON(!name);
+
+ scnprintf(name, size, "%s-%s", coll_name, bench_name);
+
+ prctl(PR_SET_NAME, name);
+ argv[0] = name;
+
+ ret = fn(argc, argv, prefix);
+
+ free(name);
+
+ return ret;
+}
+
+static void run_collection(struct collection *coll)
+{
+ struct bench *bench;
const char *argv[2];
- struct bench_suite *suites = subsys->suites;
argv[1] = NULL;
/*
* TODO:
- * preparing preset parameters for
+ *
+ * Preparing preset parameters for
* embedded, ordinary PC, HPC, etc...
- * will be helpful
+ * would be helpful.
*/
- for (i = 0; suites[i].fn; i++) {
- printf("# Running %s/%s benchmark...\n",
- subsys->name,
- suites[i].name);
+ for_each_bench(coll, bench) {
+ if (!bench->fn)
+ break;
+ printf("# Running %s/%s benchmark...\n", coll->name, bench->name);
fflush(stdout);
- argv[1] = suites[i].name;
- suites[i].fn(1, argv, NULL);
+ argv[1] = bench->name;
+ run_bench(coll->name, bench->name, bench->fn, 1, argv, NULL);
printf("\n");
}
}
-static void all_subsystem(void)
+static void run_all_collections(void)
{
- int i;
- for (i = 0; subsystems[i].suites; i++)
- all_suite(&subsystems[i]);
+ struct collection *coll;
+
+ for_each_collection(coll)
+ run_collection(coll);
}
int cmd_bench(int argc, const char **argv, const char *prefix __maybe_unused)
{
- int i, j, status = 0;
+ struct collection *coll;
+ int ret = 0;
if (argc < 2) {
- /* No subsystem specified. */
+ /* No collection specified. */
print_usage();
goto end;
}
@@ -206,7 +212,7 @@ int cmd_bench(int argc, const char **argv, const char *prefix __maybe_unused)
bench_format = bench_str2int(bench_format_str);
if (bench_format == BENCH_FORMAT_UNKNOWN) {
- printf("Unknown format descriptor:%s\n", bench_format_str);
+ printf("Unknown format descriptor: '%s'\n", bench_format_str);
goto end;
}
@@ -216,52 +222,51 @@ int cmd_bench(int argc, const char **argv, const char *prefix __maybe_unused)
}
if (!strcmp(argv[0], "all")) {
- all_subsystem();
+ run_all_collections();
goto end;
}
- for (i = 0; subsystems[i].name; i++) {
- if (strcmp(subsystems[i].name, argv[0]))
+ for_each_collection(coll) {
+ struct bench *bench;
+
+ if (strcmp(coll->name, argv[0]))
continue;
if (argc < 2) {
- /* No suite specified. */
- dump_suites(i);
+ /* No bench specified. */
+ dump_benchmarks(coll);
goto end;
}
if (!strcmp(argv[1], "all")) {
- all_suite(&subsystems[i]);
+ run_collection(coll);
goto end;
}
- for (j = 0; subsystems[i].suites[j].name; j++) {
- if (strcmp(subsystems[i].suites[j].name, argv[1]))
+ for_each_bench(coll, bench) {
+ if (strcmp(bench->name, argv[1]))
continue;
if (bench_format == BENCH_FORMAT_DEFAULT)
- printf("# Running %s/%s benchmark...\n",
- subsystems[i].name,
- subsystems[i].suites[j].name);
+ printf("# Running '%s/%s' benchmark:\n", coll->name, bench->name);
fflush(stdout);
- status = subsystems[i].suites[j].fn(argc - 1,
- argv + 1, prefix);
+ ret = run_bench(coll->name, bench->name, bench->fn, argc-1, argv+1, prefix);
goto end;
}
if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
- dump_suites(i);
+ dump_benchmarks(coll);
goto end;
}
- printf("Unknown suite:%s for %s\n", argv[1], argv[0]);
- status = 1;
+ printf("Unknown benchmark: '%s' for collection '%s'\n", argv[1], argv[0]);
+ ret = 1;
goto end;
}
- printf("Unknown subsystem:%s\n", argv[0]);
- status = 1;
+ printf("Unknown collection: '%s'\n", argv[0]);
+ ret = 1;
end:
- return status;
+ return ret;
}
--
1.8.1.4
* Arnaldo Carvalho de Melo <[email protected]> wrote:
> From: Arnaldo Carvalho de Melo <[email protected]>
>
> Hi Ingo,
>
> Please consider pulling,
>
> - Arnaldo
>
> The following changes since commit aa30a2e03a453aad9fd96c3f2d4a82c3497674e5:
>
> Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core (2013-10-23 09:45:50 +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 c1fb5651bb40f9efaf32d280f39e06df7e352673:
>
> perf tools: Show progress on histogram collapsing (2013-10-23 15:48:24 -0300)
>
> ----------------------------------------------------------------
> perf/core improvements and fixes:
>
> . Show progress on histogram collapsing, that can take a long time, from
> Namhyung Kim.
>
> . Support "$vars" meta argument syntax for local variables, allowing
> asking for all possible variables at a given probe point to be
> collected when it hits, from Masami Hiramatsu.
>
> . Address the root cause of that 'perf sched' stack initialization build
> slowdown, by programmatically setting a big array after moving the
> global variable back to the stack. Fix from Adrian Hunter.
>
> . Do not repipe attributes to a perf.data file in 'perf inject',
> fix from Adrian Hunter
>
> . Change the procps visible command-name of invididual benchmark tests
> plus cleanups, from Ingo Molnar.
>
> . Do not accept parse_tag_value() overflow, fix from Adrian Hunter.
>
> . Validate that mmap_pages is not too big. From Adrian Hunter.
>
> . Fix non-debug build, from Adrian Hunter
>
> . Clarify the "sample parsing" test entry.
>
> . Consider PERF_SAMPLE_TRANSACTION in the "sample parsing" test.
>
> Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
>
> ----------------------------------------------------------------
> Adrian Hunter (7):
> perf sched: Make struct perf_sched sched a local variable
> perf sched: Optimize build time
> perf script: Make perf_script a local variable
> perf inject: Do not repipe attributes to a perf.data file
> perf tools: Do not accept parse_tag_value() overflow
> perf evlist: Validate that mmap_pages is not too big
> perf tools: Fix non-debug build
>
> Arnaldo Carvalho de Melo (5):
> perf test: Clarify the "sample parsing" test entry
> perf test: Consider PERF_SAMPLE_TRANSACTION in the "sample parsing" test
> perf tools: Stop using 'self' in some more places
> perf ui: Rename ui_progress to ui_progress_ops
> perf ui progress: Per progress bar state
>
> Ingo Molnar (1):
> perf bench: Change the procps visible command-name of invididual benchmark tests plus cleanups
>
> Masami Hiramatsu (2):
> perf probe: Support "$vars" meta argument syntax for local variables
> perf probe: Find fentry mcount fuzzed parameter location
>
> Namhyung Kim (1):
> perf tools: Show progress on histogram collapsing
>
> tools/perf/Makefile.perf | 1 +
> tools/perf/builtin-annotate.c | 6 +-
> tools/perf/builtin-bench.c | 239 +++++++++++++++++++-------------------
> tools/perf/builtin-diff.c | 7 +-
> tools/perf/builtin-inject.c | 27 +++--
> tools/perf/builtin-report.c | 24 ++--
> tools/perf/builtin-sched.c | 44 +++----
> tools/perf/builtin-script.c | 40 ++++---
> tools/perf/builtin-top.c | 4 +-
> tools/perf/config/Makefile | 4 +
> tools/perf/tests/hists_link.c | 2 +-
> tools/perf/tests/sample-parsing.c | 4 +-
> tools/perf/ui/gtk/gtk.h | 2 +-
> tools/perf/ui/gtk/progress.c | 20 ++--
> tools/perf/ui/gtk/setup.c | 2 +-
> tools/perf/ui/progress.c | 32 +++--
> tools/perf/ui/progress.h | 19 +--
> tools/perf/ui/tui/progress.c | 15 +--
> tools/perf/ui/tui/setup.c | 3 +-
> tools/perf/ui/tui/tui.h | 6 +
> tools/perf/util/build-id.c | 6 +-
> tools/perf/util/evlist.c | 14 ++-
> tools/perf/util/hist.c | 23 ++--
> tools/perf/util/hist.h | 3 +-
> tools/perf/util/probe-event.c | 1 -
> tools/perf/util/probe-finder.c | 133 ++++++++++++++++++---
> tools/perf/util/probe-finder.h | 1 +
> tools/perf/util/session.c | 24 ++--
> tools/perf/util/sort.c | 124 ++++++++++----------
> tools/perf/util/strfilter.c | 46 ++++----
> tools/perf/util/thread.c | 72 ++++++------
> tools/perf/util/util.c | 2 +
> 32 files changed, 560 insertions(+), 390 deletions(-)
> create mode 100644 tools/perf/ui/tui/tui.h
Pulled, thanks Arnaldo!
Ingo