Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[PATCH 07/29] perf tools: Get current comm instead of last one

7 views
Skip to first unread message

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:00:01 PM11/4/13
to
From: Namhyung Kim <namhyu...@lge.com>

At insert time, a hist entry should reference comm at the time otherwise
it'll get the last comm anyway.

Signed-off-by: Namhyung Kim <namh...@kernel.org>
Acked-by: Frederic Weisbecker <fwei...@gmail.com>
Tested-by: Jiri Olsa <jo...@redhat.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Link: http://lkml.kernel.org/n/tip-n6pykiiymt...@git.kernel.org
[ Fixed up const pointer issues ]
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/comm.c | 15 +++++++++++++++
tools/perf/util/comm.h | 1 +
tools/perf/util/hist.c | 3 +++
tools/perf/util/sort.c | 14 +++++---------
tools/perf/util/sort.h | 1 +
tools/perf/util/thread.c | 6 +++---
tools/perf/util/thread.h | 2 ++
7 files changed, 30 insertions(+), 12 deletions(-)

diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c
index 8b3ac9f0207f..ee0df0e24cdb 100644
--- a/tools/perf/util/comm.c
+++ b/tools/perf/util/comm.c
@@ -94,6 +94,21 @@ struct comm *comm__new(const char *str, u64 timestamp)
return comm;
}

+void comm__override(struct comm *comm, const char *str, u64 timestamp)
+{
+ struct comm_str *old = comm->comm_str;
+
+ comm->comm_str = comm_str__findnew(str, &comm_str_root);
+ if (!comm->comm_str) {
+ comm->comm_str = old;
+ return;
+ }
+
+ comm->start = timestamp;
+ comm_str__get(comm->comm_str);
+ comm_str__put(old);
+}
+
void comm__free(struct comm *comm)
{
comm_str__put(comm->comm_str);
diff --git a/tools/perf/util/comm.h b/tools/perf/util/comm.h
index f62d215bede2..7a86e5656710 100644
--- a/tools/perf/util/comm.h
+++ b/tools/perf/util/comm.h
@@ -16,5 +16,6 @@ struct comm {
void comm__free(struct comm *comm);
struct comm *comm__new(const char *str, u64 timestamp);
const char *comm__str(const struct comm *comm);
+void comm__override(struct comm *comm, const char *str, u64 timestamp);

#endif /* __PERF_COMM_H */
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 7e80253074b0..30793f98c8bb 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -416,6 +416,7 @@ struct hist_entry *__hists__add_mem_entry(struct hists *hists,
{
struct hist_entry entry = {
.thread = al->thread,
+ .comm = thread__comm(al->thread),
.ms = {
.map = al->map,
.sym = al->sym,
@@ -446,6 +447,7 @@ struct hist_entry *__hists__add_branch_entry(struct hists *hists,
{
struct hist_entry entry = {
.thread = al->thread,
+ .comm = thread__comm(al->thread),
.ms = {
.map = bi->to.map,
.sym = bi->to.sym,
@@ -475,6 +477,7 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
{
struct hist_entry entry = {
.thread = al->thread,
+ .comm = thread__comm(al->thread),
.ms = {
.map = al->map,
.sym = al->sym,
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index bf91d0e5c16e..3c1b75c8b9a6 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -1,5 +1,6 @@
#include "sort.h"
#include "hist.h"
+#include "comm.h"
#include "symbol.h"

regex_t parent_regex;
@@ -81,25 +82,20 @@ static int64_t
sort__comm_cmp(struct hist_entry *left, struct hist_entry *right)
{
/* Compare the addr that should be unique among comm */
- return thread__comm_str(right->thread) - thread__comm_str(left->thread);
+ return comm__str(right->comm) - comm__str(left->comm);
}

static int64_t
sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
{
- const char *comm_l = thread__comm_str(left->thread);
- const char *comm_r = thread__comm_str(right->thread);
-
- if (!comm_l || !comm_r)
- return cmp_null(comm_l, comm_r);
-
- return strcmp(comm_l, comm_r);
+ /* Compare the addr that should be unique among comm */
+ return comm__str(right->comm) - comm__str(left->comm);
}

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, thread__comm_str(he->thread));
+ return repsep_snprintf(bf, size, "%*s", width, comm__str(he->comm));
}

struct sort_entry sort_comm = {
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index bf4333694d3a..f4e16f359d64 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -84,6 +84,7 @@ struct hist_entry {
struct he_stat stat;
struct map_symbol ms;
struct thread *thread;
+ struct comm *comm;
u64 ip;
u64 transaction;
s32 cpu;
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 15c53c2e109e..cd8e2f592719 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -54,7 +54,7 @@ void thread__delete(struct thread *thread)
free(thread);
}

-static struct comm *thread__comm(const struct thread *thread)
+struct comm *thread__comm(const struct thread *thread)
{
if (list_empty(&thread->comm_list))
return NULL;
@@ -69,8 +69,8 @@ int thread__set_comm(struct thread *thread, const char *str, u64 timestamp)

/* Override latest entry if it had no specific time coverage */
if (!curr->start) {
- list_del(&curr->list);
- comm__free(curr);
+ comm__override(curr, str, timestamp);
+ return 0;
}

new = comm__new(str, timestamp);
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 8702c6b4163a..373c055989ed 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -26,6 +26,7 @@ struct thread {
};

struct machine;
+struct comm;

struct thread *thread__new(pid_t pid, pid_t tid);
void thread__delete(struct thread *self);
@@ -36,6 +37,7 @@ static inline void thread__exited(struct thread *thread)

int thread__set_comm(struct thread *thread, const char *comm, u64 timestamp);
int thread__comm_len(struct thread *self);
+struct comm *thread__comm(const struct thread *thread);
const char *thread__comm_str(const struct thread *thread);
void thread__insert_map(struct thread *self, struct map *map);
int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp);
--
1.8.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majo...@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:00:02 PM11/4/13
to
From: "Steven Rostedt (Red Hat)" <ros...@goodmis.org>

Currently when using the raw format for fields, when looking at a
character array, to determine if it is a string or not, we make sure all
characters are "isprint()". If not, then we consider it a numeric array,
and print the hex numbers of the characters instead.

But it seems that '\n' fails the isprint() check! Add isspace() to the
check as well, such that if all characters pass isprint() or isspace()
it will assume the character array is a string.

Reported-by: Xenia Ragiadakou <burza...@gmail.com>
Signed-off-by: Steven Rostedt <ros...@goodmis.org>
Cc: Andrew Morton <ak...@linux-foundation.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Namhyung Kim <namh...@kernel.org>
Cc: Xenia Ragiadakou <burza...@gmail.com>
Link: http://lkml.kernel.org/r/201311012155...@goodmis.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/lib/traceevent/event-parse.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index e1c743c52834..85cbbddb6880 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -3981,7 +3981,7 @@ static int is_printable_array(char *p, unsigned int len)
unsigned int i;

for (i = 0; i < len && p[i]; i++)
- if (!isprint(p[i]))
+ if (!isprint(p[i]) && !isspace(p[i]))
return 0;
return 1;

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:01 PM11/4/13
to
From: Howard Cochran <hcoc...@lexmark.com>

The kernel has a few events with a format similar to this excerpt:
field:unsigned int len; offset:12; size:4; signed:0;
field:__data_loc unsigned char[] data_array; offset:16; size:4; signed:0;
print fmt: "%s", __print_hex(__get_dynamic_array(data_array), REC->len)

trace-cmd could already parse that arg correctly, but print_str_arg()
was unable to handle the first parameter being a dynamic array. (It
just printed a "field not found" warning).

Teach print_str_arg's PRINT_HEX case to handle the nested
PRINT_DYNAMIC_ARRAY correctly. The output now matches the kernel's own
formatting for this case.

Signed-off-by: Howard Cochran <hcoc...@lexmark.com>
Cc: Andrew Morton <ak...@linux-foundation.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Namhyung Kim <namh...@kernel.org>
Link: http://lkml.kernel.org/r/1381503349-12271-1-gi...@lexmark.com
[ Removed "polish compare", we don't do that here ]
Signed-off-by: Steven Rostedt <ros...@goodmis.org>
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/lib/traceevent/event-parse.c | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 013c8d3db806..0a1ffe07de3f 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -3588,15 +3588,23 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
}
break;
case PRINT_HEX:
- field = arg->hex.field->field.field;
- if (!field) {
- str = arg->hex.field->field.name;
- field = pevent_find_any_field(event, str);
- if (!field)
- goto out_warning_field;
- arg->hex.field->field.field = field;
+ if (arg->hex.field->type == PRINT_DYNAMIC_ARRAY) {
+ unsigned long offset;
+ offset = pevent_read_number(pevent,
+ data + arg->hex.field->dynarray.field->offset,
+ arg->hex.field->dynarray.field->size);
+ hex = data + (offset & 0xffff);
+ } else {
+ field = arg->hex.field->field.field;
+ if (!field) {
+ str = arg->hex.field->field.name;
+ field = pevent_find_any_field(event, str);
+ if (!field)
+ goto out_warning_field;
+ arg->hex.field->field.field = field;
+ }
+ hex = data + field->offset;
}
- hex = data + field->offset;
len = eval_num_arg(data, size, event, arg->hex.size);
for (i = 0; i < len; i++) {
if (i)

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:01 PM11/4/13
to
From: "Steven Rostedt (Red Hat)" <ros...@goodmis.org>

If the format string of TP_printk() contains a %s, and the argument is
not a string, check if the argument is a pointer that might match the
printk_formats that were stored.

Signed-off-by: Steven Rostedt <ros...@goodmis.org>
Cc: Andrew Morton <ak...@linux-foundation.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Namhyung Kim <namh...@kernel.org>
Link: http://lkml.kernel.org/r/201311012155...@goodmis.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/lib/traceevent/event-parse.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 856b79105abc..013c8d3db806 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -3505,6 +3505,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
struct pevent *pevent = event->pevent;
struct print_flag_sym *flag;
struct format_field *field;
+ struct printk_map *printk;
unsigned long long val, fval;
unsigned long addr;
char *str;
@@ -3540,7 +3541,12 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
if (!(field->flags & FIELD_IS_ARRAY) &&
field->size == pevent->long_size) {
addr = *(unsigned long *)(data + field->offset);
- trace_seq_printf(s, "%lx", addr);
+ /* Check if it matches a print format */
+ printk = find_printk(pevent, addr);
+ if (printk)
+ trace_seq_puts(s, printk->printk);
+ else
+ trace_seq_printf(s, "%lx", addr);
break;
}
str = malloc(len + 1);

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:01 PM11/4/13
to
From: Adrian Hunter <adrian...@intel.com>

Setting EXTRA_CFLAGS=-m32 did not work because it was not passed around.

Signed-off-by: Adrian Hunter <adrian...@intel.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@redhat.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: Namhyung Kim <namh...@gmail.com>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/r/1383313899-15987-4-git-...@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/Makefile.perf | 2 +-
tools/perf/config/Makefile | 4 ++--
tools/perf/config/feature-checks/Makefile | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index cb52bdb755c7..5b8639025aae 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -711,7 +711,7 @@ $(LIB_FILE): $(LIB_OBJS)
TE_SOURCES = $(wildcard $(TRACE_EVENT_DIR)*.[ch])

$(LIBTRACEEVENT): $(TE_SOURCES)
- $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) libtraceevent.a
+ $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) CFLAGS="-g -Wall $(EXTRA_CFLAGS)" libtraceevent.a

$(LIBTRACEEVENT)-clean:
$(call QUIET_CLEAN, libtraceevent)
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 543aa953bab1..2f1d7d78f744 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -96,7 +96,7 @@ endif

feature_check = $(eval $(feature_check_code))
define feature_check_code
- feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) LDFLAGS=$(LDFLAGS) -C config/feature-checks test-$1 >/dev/null 2>/dev/null && echo 1 || echo 0)
+ feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS=$(LDFLAGS) -C config/feature-checks test-$1 >/dev/null 2>/dev/null && echo 1 || echo 0)
endef

feature_set = $(eval $(feature_set_code))
@@ -173,7 +173,7 @@ ifeq ($(feature-all), 1)
#
$(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_set,$(feat)))
else
- $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) LDFLAGS=$(LDFLAGS) -i -j -C config/feature-checks $(CORE_FEATURE_TESTS) >/dev/null 2>&1)
+ $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS=$(LDFLAGS) -i -j -C config/feature-checks $(CORE_FEATURE_TESTS) >/dev/null 2>&1)
$(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_check,$(feat)))
endif

diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile
index 452b67cc4d7b..353c00cde4d6 100644
--- a/tools/perf/config/feature-checks/Makefile
+++ b/tools/perf/config/feature-checks/Makefile
@@ -31,7 +31,7 @@ CC := $(CC) -MD

all: $(FILES)

-BUILD = $(CC) $(LDFLAGS) -o $(OUTPUT)$@ $@.c
+BUILD = $(CC) $(CFLAGS) $(LDFLAGS) -o $(OUTPUT)$@ $@.c

###############################

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:02 PM11/4/13
to
From: Adrian Hunter <adrian...@intel.com>

Add missing PERF_SAMPLE_TRANSACTION to perf_event__synthesize_sample()
and perf_event__sample_event_size().

This makes the "sample parsing" test pass.

Signed-off-by: Adrian Hunter <adrian...@intel.com>
Cc: Andi Kleen <an...@firstfloor.org>
Cc: David Ahern <dsa...@gmail.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@redhat.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: Namhyung Kim <namh...@gmail.com>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/r/1383313899-15987-11-git-...@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/evsel.c | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index b121717ce42a..5280820ed389 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1578,6 +1578,9 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type,
if (type & PERF_SAMPLE_DATA_SRC)
result += sizeof(u64);

+ if (type & PERF_SAMPLE_TRANSACTION)
+ result += sizeof(u64);
+
return result;
}

@@ -1751,6 +1754,11 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type,
array++;
}

+ if (type & PERF_SAMPLE_TRANSACTION) {
+ *array = sample->transaction;
+ array++;
+ }
+
return 0;

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:02 PM11/4/13
to
From: Arnaldo Carvalho de Melo <ac...@ghostprotocols.net>

Hi Ingo,

Please consider pulling,

- Arnaldo

The following changes since commit 46d525eae2a076adfde92dca1db12d9a3b8ad8bb:

perf test: Update command line callchain attribute tests (2013-11-01 10:42:57 -0300)

are available in the git repository at:

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

for you to fetch changes up to 46d525eae2a076adfde92dca1db12d9a3b8ad8bb:

perf test: Update command line callchain attribute tests (2013-11-01 10:42:57 -0300)

----------------------------------------------------------------
perf/urgent fixes:

. Fix command line callchain attribute tests to handle the new
-g/--call-chain semantics.

. Remove cast of non-variadic function to variadic, fixing perf output
on armhf arch. Fix from Michael Hudson-Doyle.

. Fix 32-bit building of 'perf bench', from Wei Yang.

Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>

----------------------------------------------------------------

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:02 PM11/4/13
to
From: Steven Rostedt <sros...@redhat.com>

Add the pevent_print_func_field() that will look up a field that is
expected to be a function pointer, and it will print the function name
and offset of the address given by the field.

Signed-off-by: Steven Rostedt <ros...@goodmis.org>
Cc: Andrew Morton <ak...@linux-foundation.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/lib/traceevent/event-parse.c | 42 ++++++++++++++++++++++++++++++++++++++
tools/lib/traceevent/event-parse.h | 4 ++++
2 files changed, 46 insertions(+)

diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index fc6f35f591f6..8f450adaa9c2 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -5367,6 +5367,48 @@ int pevent_print_num_field(struct trace_seq *s, const char *fmt,
return -1;
}

+/**
+ * pevent_print_func_field - print a field and a format for function pointers
+ * @s: The seq to print to
+ * @fmt: The printf format to print the field with.
+ * @event: the event that the field is for
+ * @name: The name of the field
+ * @record: The record with the field name.
+ * @err: print default error if failed.
+ *
+ * Returns: 0 on success, -1 field not found, or 1 if buffer is full.
+ */
+int pevent_print_func_field(struct trace_seq *s, const char *fmt,
+ struct event_format *event, const char *name,
+ struct pevent_record *record, int err)
+{
+ struct format_field *field = pevent_find_field(event, name);
+ struct pevent *pevent = event->pevent;
+ unsigned long long val;
+ struct func_map *func;
+ char tmp[128];
+
+ if (!field)
+ goto failed;
+
+ if (pevent_read_number_field(field, record->data, &val))
+ goto failed;
+
+ func = find_func(pevent, val);
+
+ if (func)
+ snprintf(tmp, 128, "%s/0x%llx", func->func, func->addr - val);
+ else
+ sprintf(tmp, "0x%08llx", val);
+
+ return trace_seq_printf(s, fmt, tmp);
+
+ failed:
+ if (err)
+ trace_seq_printf(s, "CAN'T FIND FIELD \"%s\"", name);
+ return -1;
+}
+
static void free_func_handle(struct pevent_function_handler *func)
{
struct pevent_func_params *params;
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index dc8539ee9485..8d73d2594f65 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -569,6 +569,10 @@ int pevent_print_num_field(struct trace_seq *s, const char *fmt,
struct event_format *event, const char *name,
struct pevent_record *record, int err);

+int pevent_print_func_field(struct trace_seq *s, const char *fmt,
+ struct event_format *event, const char *name,
+ struct pevent_record *record, int err);
+
int pevent_register_event_handler(struct pevent *pevent, int id,
const char *sys_name, const char *event_name,
pevent_event_handler_func func, void *context);
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:02 PM11/4/13
to
From: Namhyung Kim <namhyu...@lge.com>

The -s (--sort) option was processed after normal option parsing so that
it cannot call the parse_options_usage() automatically. Currently it
calls usage_with_options() which shows entire help messages for event
option. Fix it by showing just -s options.

$ perf top -s help
Error: Unknown --sort key: `help'

usage: perf top [<options>]

-s, --sort <key[,key2...]>
sort by key(s): pid, comm, dso, symbol, ...

Signed-off-by: Namhyung Kim <namh...@kernel.org>
Acked-by: Ingo Molnar <mi...@kernel.org>
Reviewed-by: Ingo Molnar <mi...@kernel.org>
Enthusiastically-Supported-by: Ingo Molnar <mi...@kernel.org>
Cc: David Ahern <dsa...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Link: http://lkml.kernel.org/r/1383291195-24386-5-gi...@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-top.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 21db76d71ddf..ca5ca37980fb 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -1040,7 +1040,7 @@ parse_percent_limit(const struct option *opt, const char *arg,

int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
{
- int status;
+ int status = -1;
char errbuf[BUFSIZ];
struct perf_top top = {
.count_filter = 5,
@@ -1159,8 +1159,10 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
if (sort_order == default_sort_order)
sort_order = "dso,symbol";

- if (setup_sorting() < 0)
- usage_with_options(top_usage, options);
+ if (setup_sorting() < 0) {
+ parse_options_usage(top_usage, options, "s", 1);
+ goto out_delete_evlist;
+ }

/* display thread wants entries to be collapsed in a different tree */
sort__need_collapse = 1;
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:02 PM11/4/13
to
From: Adrian Hunter <adrian...@intel.com>

In fact the "sample parsing" test does not automatically check new
sample type bits - they must be added to the comparison logic.

Doing that shows that the test fails because the functions
perf_event__synthesize_sample() and perf_event__sample_event_size() have
not been updated with PERF_SAMPLE_TRANSACTION either.

Signed-off-by: Adrian Hunter <adrian...@intel.com>
Cc: Andi Kleen <an...@firstfloor.org>
Cc: David Ahern <dsa...@gmail.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@redhat.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: Namhyung Kim <namh...@gmail.com>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/r/1383313899-15987-10-git-...@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/tests/sample-parsing.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c
index 61c9da2eb3a9..1b677202638d 100644
--- a/tools/perf/tests/sample-parsing.c
+++ b/tools/perf/tests/sample-parsing.c
@@ -121,6 +121,9 @@ static bool samples_same(const struct perf_sample *s1,
if (type & PERF_SAMPLE_DATA_SRC)
COMP(data_src);

+ if (type & PERF_SAMPLE_TRANSACTION)
+ COMP(transaction);
+
return true;
}

@@ -165,6 +168,7 @@ static int do_test(u64 sample_type, u64 sample_regs_user, u64 read_format)
.cpu = 110,
.raw_size = sizeof(raw_data),
.data_src = 111,
+ .transaction = 112,
.raw_data = (void *)raw_data,
.callchain = &callchain.callchain,
.branch_stack = &branch_stack.branch_stack,
@@ -273,7 +277,8 @@ int test__sample_parsing(void)

/*
* Fail the test if it has not been updated when new sample format bits
- * were added.
+ * were added. Please actually update the test rather than just change
+ * the condition below.
*/
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");
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:02 PM11/4/13
to
From: Steven Rostedt <sros...@redhat.com>

Add the flags EVENT_FL_NOHANDLE and EVENT_FL_PRINTRAW to the event flags
to have the event either ignore the register handler or to ignore the
handler and also print the raw format respectively.

This allows a tool to force a raw format or non handle for an event.

Signed-off-by: Steven Rostedt <ros...@goodmis.org>
Cc: Andrew Morton <ak...@linux-foundation.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/lib/traceevent/event-parse.c | 4 ++--
tools/lib/traceevent/event-parse.h | 2 ++
2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 85cbbddb6880..fc6f35f591f6 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -4446,11 +4446,11 @@ void pevent_event_info(struct trace_seq *s, struct event_format *event,
{
int print_pretty = 1;

- if (event->pevent->print_raw)
+ if (event->pevent->print_raw || (event->flags & EVENT_FL_PRINTRAW))
print_event_fields(s, record->data, record->size, event);
else {

- if (event->handler)
+ if (event->handler && !(event->flags & EVENT_FL_NOHANDLE))
print_pretty = event->handler(s, record, event,
event->context);

diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index 9ab6367f2fe9..dc8539ee9485 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -308,6 +308,8 @@ enum {
EVENT_FL_ISBPRINT = 0x04,
EVENT_FL_ISFUNCENT = 0x10,
EVENT_FL_ISFUNCRET = 0x20,
+ EVENT_FL_NOHANDLE = 0x40,
+ EVENT_FL_PRINTRAW = 0x80,

EVENT_FL_FAILED = 0x80000000
};
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:02 PM11/4/13
to
From: Adrian Hunter <adrian...@intel.com>

Add a debug print if mmap of the perf event ring buffer fails.

Signed-off-by: Adrian Hunter <adrian...@intel.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@redhat.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: Namhyung Kim <namh...@gmail.com>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/r/1383313899-15987-6-git-...@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/evlist.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 0582f67fbefc..1c173ccb0ef2 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -607,6 +607,8 @@ static int __perf_evlist__mmap(struct perf_evlist *evlist,
evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, prot,
MAP_SHARED, fd, 0);
if (evlist->mmap[idx].base == MAP_FAILED) {
+ pr_debug2("failed to mmap perf event ring buffer, error %d\n",
+ errno);
evlist->mmap[idx].base = NULL;
return -1;
}
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:03 PM11/4/13
to
From: Yoshihiro YUNOMAE <yoshihiro....@hitachi.com>

If trace-cmd extracts trace_clock, trace-cmd reads trace_clock data from
the trace.dat and switches outputting format of timestamp for each
trace_clock.

Signed-off-by: Yoshihiro YUNOMAE <yoshihiro....@hitachi.com>
Cc: Andrew Morton <ak...@linux-foundation.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Namhyung Kim <namh...@kernel.org>
Link: http://lkml.kernel.org/r/20130424231305.14877.86147.stgit@yunodevel
Signed-off-by: Steven Rostedt <ros...@goodmis.org>
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/lib/traceevent/event-parse.c | 50 +++++++++++++++++++++++++++++---------
tools/lib/traceevent/event-parse.h | 6 ++++-
2 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index d1c2a6a4cd32..deedff9d06af 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -305,6 +305,11 @@ int pevent_register_comm(struct pevent *pevent, const char *comm, int pid)
return 0;
}

+void pevent_register_trace_clock(struct pevent *pevent, char *trace_clock)
+{
+ pevent->trace_clock = trace_clock;
+}
+
struct func_map {
unsigned long long addr;
char *func;
@@ -4443,8 +4448,21 @@ void pevent_event_info(struct trace_seq *s, struct event_format *event,
trace_seq_terminate(s);
}

+static bool is_timestamp_in_us(char *trace_clock, bool use_trace_clock)
+{
+ if (!use_trace_clock)
+ return true;
+
+ if (!strcmp(trace_clock, "local") || !strcmp(trace_clock, "global")
+ || !strcmp(trace_clock, "uptime") || !strcmp(trace_clock, "perf"))
+ return true;
+
+ /* trace_clock is setting in tsc or counter mode */
+ return false;
+}
+
void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
- struct pevent_record *record)
+ struct pevent_record *record, bool use_trace_clock)
{
static const char *spaces = " "; /* 20 spaces */
struct event_format *event;
@@ -4457,9 +4475,14 @@ void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
int pid;
int len;
int p;
+ bool use_usec_format;

- secs = record->ts / NSECS_PER_SEC;
- nsecs = record->ts - secs * NSECS_PER_SEC;
+ use_usec_format = is_timestamp_in_us(pevent->trace_clock,
+ use_trace_clock);
+ if (use_usec_format) {
+ secs = record->ts / NSECS_PER_SEC;
+ nsecs = record->ts - secs * NSECS_PER_SEC;
+ }

if (record->size < 0) {
do_warning("ug! negative record size %d", record->size);
@@ -4484,15 +4507,20 @@ void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
} else
trace_seq_printf(s, "%16s-%-5d [%03d]", comm, pid, record->cpu);

- if (pevent->flags & PEVENT_NSEC_OUTPUT) {
- usecs = nsecs;
- p = 9;
- } else {
- usecs = (nsecs + 500) / NSECS_PER_USEC;
- p = 6;
- }
+ if (use_usec_format) {
+ if (pevent->flags & PEVENT_NSEC_OUTPUT) {
+ usecs = nsecs;
+ p = 9;
+ } else {
+ usecs = (nsecs + 500) / NSECS_PER_USEC;
+ p = 6;
+ }

- trace_seq_printf(s, " %5lu.%0*lu: %s: ", secs, p, usecs, event->name);
+ trace_seq_printf(s, " %5lu.%0*lu: %s: ",
+ secs, p, usecs, event->name);
+ } else
+ trace_seq_printf(s, " %12llu: %s: ",
+ record->ts, event->name);

/* Space out the event names evenly. */
len = strlen(event->name);
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index c37b2026d04a..7503edf5ac6a 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -20,6 +20,7 @@
#ifndef _PARSE_EVENTS_H
#define _PARSE_EVENTS_H

+#include <stdbool.h>
#include <stdarg.h>
#include <regex.h>

@@ -450,6 +451,8 @@ struct pevent {

/* cache */
struct event_format *last_event;
+
+ char *trace_clock;
};

static inline void pevent_set_flag(struct pevent *pevent, int flag)
@@ -527,6 +530,7 @@ enum trace_flag_type {
};

int pevent_register_comm(struct pevent *pevent, const char *comm, int pid);
+void pevent_register_trace_clock(struct pevent *pevent, char *trace_clock);
int pevent_register_function(struct pevent *pevent, char *name,
unsigned long long addr, char *mod);
int pevent_register_print_string(struct pevent *pevent, char *fmt,
@@ -534,7 +538,7 @@ int pevent_register_print_string(struct pevent *pevent, char *fmt,
int pevent_pid_is_registered(struct pevent *pevent, int pid);

void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
- struct pevent_record *record);
+ struct pevent_record *record, bool use_trace_clock);

int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size,
int long_size);
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:03 PM11/4/13
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

s/tyep/type/g.

Cc: Adrian Hunter <adrian...@intel.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Masami Hiramatsu <masami.hi...@hitachi.com>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/n/tip-cznw5tnruo...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/probe-finder.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index e41b0941e18f..2200dad4c3f4 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -583,7 +583,7 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
}

if (die_find_member(&type, field->name, die_mem) == NULL) {
- pr_warning("%s(tyep:%s) has no member %s.\n", varname,
+ pr_warning("%s(type:%s) has no member %s.\n", varname,
dwarf_diename(&type), field->name);
return -EINVAL;
}
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:03 PM11/4/13
to
From: Adrian Hunter <adrian...@intel.com>

Add missing overflow check for PERF_SAMPLE_TRANSACTION in
perf_evsel__parse_sample().

Signed-off-by: Adrian Hunter <adrian...@intel.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@redhat.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: Namhyung Kim <namh...@gmail.com>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/r/1383313899-15987-9-git-...@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/evsel.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 47bbf03aa7ef..b121717ce42a 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1481,6 +1481,7 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,

data->transaction = 0;
if (type & PERF_SAMPLE_TRANSACTION) {
+ OVERFLOW_CHECK_u64(array);
data->transaction = *array;
array++;
}
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:03 PM11/4/13
to
From: Adrian Hunter <adrian...@intel.com>

Use -lunwind-x86 instead of -lunwind-x86_64 for 32-bit build.

Signed-off-by: Adrian Hunter <adrian...@intel.com>
Acked-by: Jiri Olsa <jo...@redhat.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@redhat.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: Namhyung Kim <namh...@gmail.com>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/r/1383313899-15987-5-git-...@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/config/Makefile | 6 ++++--
tools/perf/config/feature-checks/Makefile | 4 ++--
2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 2f1d7d78f744..ffb5f55c8fba 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -25,9 +25,11 @@ ifeq ($(ARCH),x86_64)
RAW_ARCH := x86_64
CFLAGS += -DHAVE_ARCH_X86_64_SUPPORT
ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S
+ LIBUNWIND_LIBS = -lunwind -lunwind-x86_64
+ else
+ LIBUNWIND_LIBS = -lunwind -lunwind-x86
endif
NO_PERF_REGS := 0
- LIBUNWIND_LIBS = -lunwind -lunwind-x86_64
endif

ifeq ($(NO_PERF_REGS),0)
@@ -96,7 +98,7 @@ endif

feature_check = $(eval $(feature_check_code))
define feature_check_code
- feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS=$(LDFLAGS) -C config/feature-checks test-$1 >/dev/null 2>/dev/null && echo 1 || echo 0)
+ feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS=$(LDFLAGS) LIBUNWIND_LIBS="$(LIBUNWIND_LIBS)" -C config/feature-checks test-$1 >/dev/null 2>/dev/null && echo 1 || echo 0)
endef

feature_set = $(eval $(feature_set_code))
diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile
index 353c00cde4d6..d37d58d273fe 100644
--- a/tools/perf/config/feature-checks/Makefile
+++ b/tools/perf/config/feature-checks/Makefile
@@ -36,7 +36,7 @@ BUILD = $(CC) $(CFLAGS) $(LDFLAGS) -o $(OUTPUT)$@ $@.c
###############################

test-all:
- $(BUILD) -Werror -fstack-protector -fstack-protector-all -O2 -Werror -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lunwind -lunwind-x86_64 -lelf -laudit -I/usr/include/slang -lslang $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -DPACKAGE='"perf"' -lbfd -ldl
+ $(BUILD) -Werror -fstack-protector -fstack-protector-all -O2 -Werror -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma $(LIBUNWIND_LIBS) -lelf -laudit -I/usr/include/slang -lslang $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -DPACKAGE='"perf"' -lbfd -ldl

test-hello:
$(BUILD)
@@ -72,7 +72,7 @@ test-libnuma:
$(BUILD) -lnuma

test-libunwind:
- $(BUILD) -lunwind -lunwind-x86_64 -lelf
+ $(BUILD) $(LIBUNWIND_LIBS) -lelf

test-libaudit:
$(BUILD) -laudit
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:03 PM11/4/13
to
From: Namhyung Kim <namhyu...@lge.com>

Current option parser outputs whole option help string when it failed to
parse an option. However this is not good for user if the command has
many option, she might feel hard which one is related easily.

Fix it by just showing the help message of the given option only.

Signed-off-by: Namhyung Kim <namh...@kernel.org>
Requested-by: Ingo Molnar <mi...@kernel.org>
Acked-by: Ingo Molnar <mi...@kernel.org>
Reviewed-by: Ingo Molnar <mi...@kernel.org>
Enthusiastically-Supported-by: Ingo Molnar <mi...@kernel.org>
Cc: David Ahern <dsa...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Link: http://lkml.kernel.org/r/1383291195-24386-2-gi...@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/parse-options.c | 217 ++++++++++++++++++++++++----------------
tools/perf/util/parse-options.h | 4 +-
2 files changed, 132 insertions(+), 89 deletions(-)

diff --git a/tools/perf/util/parse-options.c b/tools/perf/util/parse-options.c
index 2bc9e70df7e2..1caf7b9a01ee 100644
--- a/tools/perf/util/parse-options.c
+++ b/tools/perf/util/parse-options.c
@@ -339,10 +339,10 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
if (arg[1] != '-') {
ctx->opt = arg + 1;
if (internal_help && *ctx->opt == 'h')
- return parse_options_usage(usagestr, options);
+ return usage_with_options_internal(usagestr, options, 0);
switch (parse_short_opt(ctx, options)) {
case -1:
- return parse_options_usage(usagestr, options);
+ return parse_options_usage(usagestr, options, arg + 1, 1);
case -2:
goto unknown;
default:
@@ -352,10 +352,11 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
check_typos(arg + 1, options);
while (ctx->opt) {
if (internal_help && *ctx->opt == 'h')
- return parse_options_usage(usagestr, options);
+ return usage_with_options_internal(usagestr, options, 0);
+ arg = ctx->opt;
switch (parse_short_opt(ctx, options)) {
case -1:
- return parse_options_usage(usagestr, options);
+ return parse_options_usage(usagestr, options, arg, 1);
case -2:
/* fake a short option thing to hide the fact that we may have
* started to parse aggregated stuff
@@ -383,12 +384,12 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
if (internal_help && !strcmp(arg + 2, "help-all"))
return usage_with_options_internal(usagestr, options, 1);
if (internal_help && !strcmp(arg + 2, "help"))
- return parse_options_usage(usagestr, options);
+ return usage_with_options_internal(usagestr, options, 0);
if (!strcmp(arg + 2, "list-opts"))
return PARSE_OPT_LIST;
switch (parse_long_opt(ctx, arg + 2, options)) {
case -1:
- return parse_options_usage(usagestr, options);
+ return parse_options_usage(usagestr, options, arg + 2, 0);
case -2:
goto unknown;
default:
@@ -445,6 +446,89 @@ int parse_options(int argc, const char **argv, const struct option *options,
#define USAGE_OPTS_WIDTH 24
#define USAGE_GAP 2

+static void print_option_help(const struct option *opts, int full)
+{
+ size_t pos;
+ int pad;
+
+ if (opts->type == OPTION_GROUP) {
+ fputc('\n', stderr);
+ if (*opts->help)
+ fprintf(stderr, "%s\n", opts->help);
+ return;
+ }
+ if (!full && (opts->flags & PARSE_OPT_HIDDEN))
+ return;
+
+ pos = fprintf(stderr, " ");
+ if (opts->short_name)
+ pos += fprintf(stderr, "-%c", opts->short_name);
+ else
+ pos += fprintf(stderr, " ");
+
+ if (opts->long_name && opts->short_name)
+ pos += fprintf(stderr, ", ");
+ if (opts->long_name)
+ pos += fprintf(stderr, "--%s", opts->long_name);
+
+ switch (opts->type) {
+ case OPTION_ARGUMENT:
+ break;
+ case OPTION_LONG:
+ case OPTION_U64:
+ case OPTION_INTEGER:
+ case OPTION_UINTEGER:
+ if (opts->flags & PARSE_OPT_OPTARG)
+ if (opts->long_name)
+ pos += fprintf(stderr, "[=<n>]");
+ else
+ pos += fprintf(stderr, "[<n>]");
+ else
+ pos += fprintf(stderr, " <n>");
+ break;
+ case OPTION_CALLBACK:
+ if (opts->flags & PARSE_OPT_NOARG)
+ break;
+ /* FALLTHROUGH */
+ case OPTION_STRING:
+ if (opts->argh) {
+ if (opts->flags & PARSE_OPT_OPTARG)
+ if (opts->long_name)
+ pos += fprintf(stderr, "[=<%s>]", opts->argh);
+ else
+ pos += fprintf(stderr, "[<%s>]", opts->argh);
+ else
+ pos += fprintf(stderr, " <%s>", opts->argh);
+ } else {
+ if (opts->flags & PARSE_OPT_OPTARG)
+ if (opts->long_name)
+ pos += fprintf(stderr, "[=...]");
+ else
+ pos += fprintf(stderr, "[...]");
+ else
+ pos += fprintf(stderr, " ...");
+ }
+ break;
+ default: /* OPTION_{BIT,BOOLEAN,SET_UINT,SET_PTR} */
+ case OPTION_END:
+ case OPTION_GROUP:
+ case OPTION_BIT:
+ case OPTION_BOOLEAN:
+ case OPTION_INCR:
+ case OPTION_SET_UINT:
+ case OPTION_SET_PTR:
+ break;
+ }
+
+ if (pos <= USAGE_OPTS_WIDTH)
+ pad = USAGE_OPTS_WIDTH - pos;
+ else {
+ fputc('\n', stderr);
+ pad = USAGE_OPTS_WIDTH;
+ }
+ fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help);
+}
+
int usage_with_options_internal(const char * const *usagestr,
const struct option *opts, int full)
{
@@ -464,87 +548,9 @@ int usage_with_options_internal(const char * const *usagestr,
if (opts->type != OPTION_GROUP)
fputc('\n', stderr);

- for (; opts->type != OPTION_END; opts++) {
- size_t pos;
- int pad;
-
- if (opts->type == OPTION_GROUP) {
- fputc('\n', stderr);
- if (*opts->help)
- fprintf(stderr, "%s\n", opts->help);
- continue;
- }
- if (!full && (opts->flags & PARSE_OPT_HIDDEN))
- continue;
-
- pos = fprintf(stderr, " ");
- if (opts->short_name)
- pos += fprintf(stderr, "-%c", opts->short_name);
- else
- pos += fprintf(stderr, " ");
-
- if (opts->long_name && opts->short_name)
- pos += fprintf(stderr, ", ");
- if (opts->long_name)
- pos += fprintf(stderr, "--%s", opts->long_name);
+ for ( ; opts->type != OPTION_END; opts++)
+ print_option_help(opts, full);

- switch (opts->type) {
- case OPTION_ARGUMENT:
- break;
- case OPTION_LONG:
- case OPTION_U64:
- case OPTION_INTEGER:
- case OPTION_UINTEGER:
- if (opts->flags & PARSE_OPT_OPTARG)
- if (opts->long_name)
- pos += fprintf(stderr, "[=<n>]");
- else
- pos += fprintf(stderr, "[<n>]");
- else
- pos += fprintf(stderr, " <n>");
- break;
- case OPTION_CALLBACK:
- if (opts->flags & PARSE_OPT_NOARG)
- break;
- /* FALLTHROUGH */
- case OPTION_STRING:
- if (opts->argh) {
- if (opts->flags & PARSE_OPT_OPTARG)
- if (opts->long_name)
- pos += fprintf(stderr, "[=<%s>]", opts->argh);
- else
- pos += fprintf(stderr, "[<%s>]", opts->argh);
- else
- pos += fprintf(stderr, " <%s>", opts->argh);
- } else {
- if (opts->flags & PARSE_OPT_OPTARG)
- if (opts->long_name)
- pos += fprintf(stderr, "[=...]");
- else
- pos += fprintf(stderr, "[...]");
- else
- pos += fprintf(stderr, " ...");
- }
- break;
- default: /* OPTION_{BIT,BOOLEAN,SET_UINT,SET_PTR} */
- case OPTION_END:
- case OPTION_GROUP:
- case OPTION_BIT:
- case OPTION_BOOLEAN:
- case OPTION_INCR:
- case OPTION_SET_UINT:
- case OPTION_SET_PTR:
- break;
- }
-
- if (pos <= USAGE_OPTS_WIDTH)
- pad = USAGE_OPTS_WIDTH - pos;
- else {
- fputc('\n', stderr);
- pad = USAGE_OPTS_WIDTH;
- }
- fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help);
- }
fputc('\n', stderr);

return PARSE_OPT_HELP;
@@ -559,9 +565,44 @@ void usage_with_options(const char * const *usagestr,
}

int parse_options_usage(const char * const *usagestr,
- const struct option *opts)
+ const struct option *opts,
+ const char *optstr, bool short_opt)
{
- return usage_with_options_internal(usagestr, opts, 0);
+ if (!usagestr)
+ return PARSE_OPT_HELP;
+
+ fprintf(stderr, "\n usage: %s\n", *usagestr++);
+ while (*usagestr && **usagestr)
+ fprintf(stderr, " or: %s\n", *usagestr++);
+ while (*usagestr) {
+ fprintf(stderr, "%s%s\n",
+ **usagestr ? " " : "",
+ *usagestr);
+ usagestr++;
+ }
+ fputc('\n', stderr);
+
+ for ( ; opts->type != OPTION_END; opts++) {
+ if (short_opt) {
+ if (opts->short_name == *optstr)
+ break;
+ continue;
+ }
+
+ if (opts->long_name == NULL)
+ continue;
+
+ if (!prefixcmp(optstr, opts->long_name))
+ break;
+ if (!prefixcmp(optstr, "no-") &&
+ !prefixcmp(optstr + 3, opts->long_name))
+ break;
+ }
+
+ if (opts->type != OPTION_END)
+ print_option_help(opts, 0);
+
+ return PARSE_OPT_HELP;
}


diff --git a/tools/perf/util/parse-options.h b/tools/perf/util/parse-options.h
index 7bb5999940ca..b0241e28eaf7 100644
--- a/tools/perf/util/parse-options.h
+++ b/tools/perf/util/parse-options.h
@@ -158,7 +158,9 @@ struct parse_opt_ctx_t {
};

extern int parse_options_usage(const char * const *usagestr,
- const struct option *opts);
+ const struct option *opts,
+ const char *optstr,
+ bool short_opt);

extern void parse_options_start(struct parse_opt_ctx_t *ctx,
int argc, const char **argv, int flags);
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:03 PM11/4/13
to
From: Frederic Weisbecker <fwei...@gmail.com>

Now that comm strings are allocated only once and refcounted to be shared
among threads, these can now be safely compared by addresses. This
should remove most hists collapses on post processing.

Signed-off-by: Frederic Weisbecker <fwei...@gmail.com>
Tested-by: Jiri Olsa <jo...@redhat.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Ingo Molnar <mi...@elte.hu>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Arnaldo Carvalho de Melo <ac...@redhat.com>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/r/1381468543-25334-8-gi...@kernel.org
Signed-off-by: Namhyung Kim <namh...@kernel.org>
---
tools/perf/util/sort.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 835e8bdd869f..bf91d0e5c16e 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -80,7 +80,8 @@ struct sort_entry sort_thread = {
static int64_t
sort__comm_cmp(struct hist_entry *left, struct hist_entry *right)
{
- return right->thread->tid - left->thread->tid;
+ /* Compare the addr that should be unique among comm */
+ return thread__comm_str(right->thread) - thread__comm_str(left->thread);
}

static int64_t
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:03 PM11/4/13
to
From: Adrian Hunter <adrian...@intel.com>

Always use perf_evsel__set_sample_bit() rather than just setting the
bit.

Signed-off-by: Adrian Hunter <adrian...@intel.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@redhat.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: Namhyung Kim <namh...@gmail.com>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/r/1383313899-15987-8-git-...@intel.com
[ Cope with 3090ffb "perf: Disable PERF_RECORD_MMAP2 support" ]
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/evsel.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index f0e65dec66a5..47bbf03aa7ef 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -663,7 +663,7 @@ void perf_evsel__config(struct perf_evsel *evsel,
}

if (opts->sample_address)
- attr->sample_type |= PERF_SAMPLE_DATA_SRC;
+ perf_evsel__set_sample_bit(evsel, DATA_SRC);

if (opts->no_delay) {
attr->watermark = 0;
@@ -675,13 +675,13 @@ void perf_evsel__config(struct perf_evsel *evsel,
}

if (opts->sample_weight)
- attr->sample_type |= PERF_SAMPLE_WEIGHT;
+ perf_evsel__set_sample_bit(evsel, WEIGHT);

attr->mmap = track;
attr->comm = track;

if (opts->sample_transaction)
- attr->sample_type |= PERF_SAMPLE_TRANSACTION;
+ perf_evsel__set_sample_bit(evsel, TRANSACTION);

/*
* XXX see the function comment above
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:03 PM11/4/13
to
From: "Steven Rostedt (Red Hat)" <ros...@goodmis.org>

The trace_bprintk() in the kernel looks like:

ring_buffer_producer_thread: Missed: 0
ring_buffer_producer_thread: Hit: 62174350
ring_buffer_producer_thread: Entries per millisec: 6296
ring_buffer_producer_thread: 158 ns per entry
ring_buffer_producer_thread: Sleeping for 10 secs
ring_buffer_producer_thread: Starting ring buffer hammer
ring_buffer_producer_thread: End ring buffer hammer

But the current output looks like this:

ring_buffer_producer_thread : Time: 9407018 (usecs)
ring_buffer_producer_thread : Overruns: 43285485
ring_buffer_producer_thread : Read: 4405365 (by events)
ring_buffer_producer_thread : Entries: 0
ring_buffer_producer_thread : Total: 47690850
ring_buffer_producer_thread : Missed: 0
ring_buffer_producer_thread : Hit: 47690850

Remove the space between the function and the colon.

Signed-off-by: Steven Rostedt <ros...@goodmis.org>
Cc: Andrew Morton <ak...@linux-foundation.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Namhyung Kim <namh...@kernel.org>
Link: http://lkml.kernel.org/r/201311012155...@goodmis.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/lib/traceevent/event-parse.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 0a1ffe07de3f..e1c743c52834 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -3802,8 +3802,8 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
if (asprintf(&arg->atom.atom, "%lld", ip) < 0)
goto out_free;

- /* skip the first "%pf : " */
- for (ptr = fmt + 6, bptr = data + field->offset;
+ /* skip the first "%pf: " */
+ for (ptr = fmt + 5, bptr = data + field->offset;
bptr < data + size && *ptr; ptr++) {
int ls = 0;

@@ -3929,12 +3929,12 @@ get_bprint_format(void *data, int size __maybe_unused,

printk = find_printk(pevent, addr);
if (!printk) {
- if (asprintf(&format, "%%pf : (NO FORMAT FOUND at %llx)\n", addr) < 0)
+ if (asprintf(&format, "%%pf: (NO FORMAT FOUND at %llx)\n", addr) < 0)
return NULL;
return format;
}

- if (asprintf(&format, "%s : %s", "%pf", printk->printk) < 0)
+ if (asprintf(&format, "%s: %s", "%pf", printk->printk) < 0)
return NULL;

return format;
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:03 PM11/4/13
to
From: Namhyung Kim <namhyu...@lge.com>

Print related option help messages only when it failed to process
options. While at it, modify parse_options_usage() to skip usage part
so that it can be used for showing multiple option help messages
naturally like below:

$ perf stat -Bx, ls
-B option not supported with -x

usage: perf stat [<options>] [<command>]

-B, --big-num print large numbers with thousands' separators
-x, --field-separator <separator>
print counts with custom separator

Signed-off-by: Namhyung Kim <namh...@kernel.org>
Acked-by: Ingo Molnar <mi...@kernel.org>
Reviewed-by: Ingo Molnar <mi...@kernel.org>
Enthusiastically-Supported-by: Ingo Molnar <mi...@kernel.org>
Cc: David Ahern <dsa...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Link: http://lkml.kernel.org/r/1383291195-24386-6-gi...@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-stat.c | 42 ++++++++++++++++++++++++++---------------
tools/perf/util/parse-options.c | 3 ++-
2 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 1a9c95d270aa..0fc1c941a73c 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1596,7 +1596,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
"perf stat [<options>] [<command>]",
NULL
};
- int status = -ENOMEM, run_idx;
+ int status = -EINVAL, run_idx;
const char *mode;

setlocale(LC_ALL, "");
@@ -1614,12 +1614,15 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)

if (output_name && output_fd) {
fprintf(stderr, "cannot use both --output and --log-fd\n");
- usage_with_options(stat_usage, options);
+ parse_options_usage(stat_usage, options, "o", 1);
+ parse_options_usage(NULL, options, "log-fd", 0);
+ goto out;
}

if (output_fd < 0) {
fprintf(stderr, "argument to --log-fd must be a > 0\n");
- usage_with_options(stat_usage, options);
+ parse_options_usage(stat_usage, options, "log-fd", 0);
+ goto out;
}

if (!output) {
@@ -1656,7 +1659,9 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
/* User explicitly passed -B? */
if (big_num_opt == 1) {
fprintf(stderr, "-B option not supported with -x\n");
- usage_with_options(stat_usage, options);
+ parse_options_usage(stat_usage, options, "B", 1);
+ parse_options_usage(NULL, options, "x", 1);
+ goto out;
} else /* Nope, so disable big number formatting */
big_num = false;
} else if (big_num_opt == 0) /* User passed --no-big-num */
@@ -1666,7 +1671,9 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
usage_with_options(stat_usage, options);

if (run_count < 0) {
- usage_with_options(stat_usage, options);
+ pr_err("Run count must be a positive number\n");
+ parse_options_usage(stat_usage, options, "r", 1);
+ goto out;
} else if (run_count == 0) {
forever = true;
run_count = 1;
@@ -1678,8 +1685,10 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
fprintf(stderr, "both cgroup and no-aggregation "
"modes only available in system-wide mode\n");

- usage_with_options(stat_usage, options);
- return -1;
+ parse_options_usage(stat_usage, options, "G", 1);
+ parse_options_usage(NULL, options, "A", 1);
+ parse_options_usage(NULL, options, "a", 1);
+ goto out;
}

if (add_default_attributes())
@@ -1688,25 +1697,28 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
perf_target__validate(&target);

if (perf_evlist__create_maps(evsel_list, &target) < 0) {
- if (perf_target__has_task(&target))
+ if (perf_target__has_task(&target)) {
pr_err("Problems finding threads of monitor\n");
- if (perf_target__has_cpu(&target))
+ parse_options_usage(stat_usage, options, "p", 1);
+ parse_options_usage(NULL, options, "t", 1);
+ } else if (perf_target__has_cpu(&target)) {
perror("failed to parse CPUs map");
-
- usage_with_options(stat_usage, options);
- return -1;
+ parse_options_usage(stat_usage, options, "C", 1);
+ parse_options_usage(NULL, options, "a", 1);
+ }
+ goto out;
}
if (interval && interval < 100) {
pr_err("print interval must be >= 100ms\n");
- usage_with_options(stat_usage, options);
- return -1;
+ parse_options_usage(stat_usage, options, "I", 1);
+ goto out_free_maps;
}

if (perf_evlist__alloc_stats(evsel_list, interval))
goto out_free_maps;

if (perf_stat_init_aggr_mode())
- goto out;
+ goto out_free_maps;

/*
* We dont want to block the signals - that would cause
diff --git a/tools/perf/util/parse-options.c b/tools/perf/util/parse-options.c
index 1caf7b9a01ee..31f404a032a9 100644
--- a/tools/perf/util/parse-options.c
+++ b/tools/perf/util/parse-options.c
@@ -569,7 +569,7 @@ int parse_options_usage(const char * const *usagestr,
const char *optstr, bool short_opt)
{
if (!usagestr)
- return PARSE_OPT_HELP;
+ goto opt;

fprintf(stderr, "\n usage: %s\n", *usagestr++);
while (*usagestr && **usagestr)
@@ -582,6 +582,7 @@ int parse_options_usage(const char * const *usagestr,
}
fputc('\n', stderr);

+opt:
for ( ; opts->type != OPTION_END; opts++) {
if (short_opt) {
if (opts->short_name == *optstr)
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:04 PM11/4/13
to
From: Adrian Hunter <adrian...@intel.com>

There is a debug print (at verbose level 2) for each call to
perf_event_open. Add another debug print if the call fails, and print
the error number.

Signed-off-by: Adrian Hunter <adrian...@intel.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@redhat.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: Namhyung Kim <namh...@gmail.com>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/r/1383313899-15987-2-git-...@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/evsel.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 3a334f001997..f0e65dec66a5 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1051,6 +1051,8 @@ retry_open:
group_fd, flags);
if (FD(evsel, cpu, thread) < 0) {
err = -errno;
+ pr_debug2("perf_event_open failed, error %d\n",
+ err);
goto try_fallback;
}
set_rlimit = NO_CHANGE;
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:04 PM11/4/13
to
From: Namhyung Kim <namhyu...@lge.com>

If setup_browser() called earlier than option parsing, the actual error
message can be discarded during the terminal reset. So move it after
setup_sorting() checks whether the sort keys are valid.

Signed-off-by: Namhyung Kim <namh...@kernel.org>
Acked-by: Ingo Molnar <mi...@kernel.org>
Reviewed-by: Ingo Molnar <mi...@kernel.org>
Enthusiastically-Supported-by: Ingo Molnar <mi...@kernel.org>
Cc: David Ahern <dsa...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Link: http://lkml.kernel.org/r/1383291195-24386-3-gi...@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-report.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 98d3891392e2..4df3161c7df2 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -905,13 +905,6 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
input_name = "perf.data";
}

- if (strcmp(input_name, "-") != 0)
- setup_browser(true);
- else {
- use_browser = 0;
- perf_hpp__init();
- }
-
file.path = input_name;
file.force = report.force;

@@ -957,6 +950,18 @@ repeat:
if (setup_sorting() < 0)
usage_with_options(report_usage, options);

+ if (parent_pattern != default_parent_pattern) {
+ if (sort_dimension__add("parent") < 0)
+ goto error;
+ }
+
+ if (strcmp(input_name, "-") != 0)
+ setup_browser(true);
+ else {
+ use_browser = 0;
+ perf_hpp__init();
+ }
+
/*
* Only in the TUI browser we are doing integrated annotation,
* so don't allocate extra space that won't be used in the stdio
@@ -986,11 +991,6 @@ repeat:
if (symbol__init() < 0)
goto error;

- if (parent_pattern != default_parent_pattern) {
- if (sort_dimension__add("parent") < 0)
- goto error;
- }
-
if (argc) {
/*
* Special case: if there's an argument left then assume that
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:04 PM11/4/13
to
From: Frederic Weisbecker <fwei...@gmail.com>

This way we can later delimit a lifecycle for the COMM and map a hist to
a precise COMM:timeslice couple.

PERF_RECORD_COMM and PERF_RECORD_FORK events that don't have
PERF_SAMPLE_TIME samples can only send 0 value as a timestamp and thus
should overwrite any previous COMM on a given thread because there is no
sensible way to keep track of all the comms lifecycles in a thread
without time informations.

Signed-off-by: Frederic Weisbecker <fwei...@gmail.com>
Tested-by: Jiri Olsa <jo...@redhat.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Ingo Molnar <mi...@elte.hu>
Cc: Namhyung Kim <namh...@kernel.org>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/n/tip-6tyow99vgm...@git.kernel.org
[ Made it cope with PERF_RECORD_MMAP2 ]
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-top.c | 2 +-
tools/perf/builtin-trace.c | 12 ++++++------
tools/perf/tests/code-reading.c | 2 +-
tools/perf/tests/hists_link.c | 4 ++--
tools/perf/util/event.c | 28 ++++++++++++++--------------
tools/perf/util/machine.c | 39 ++++++++++++++++++++++-----------------
tools/perf/util/machine.h | 21 ++++++++++++++-------
tools/perf/util/session.c | 2 +-
tools/perf/util/thread.c | 6 ++++--
tools/perf/util/thread.h | 4 ++--
10 files changed, 67 insertions(+), 53 deletions(-)

diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index a6ea956a533e..21db76d71ddf 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -856,7 +856,7 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx)
&sample, machine);
} else if (event->header.type < PERF_RECORD_MAX) {
hists__inc_nr_events(&evsel->hists, event->header.type);
- machine__process_event(machine, event);
+ machine__process_event(machine, event, &sample);
} else
++session->stats.nr_unknown_events;
next_event:
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index dc3da654ff12..95d639212d98 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1122,7 +1122,7 @@ static size_t trace__fprintf_entry_head(struct trace *trace, struct thread *thre
}

static int trace__process_event(struct trace *trace, struct machine *machine,
- union perf_event *event)
+ union perf_event *event, struct perf_sample *sample)
{
int ret = 0;

@@ -1130,9 +1130,9 @@ static int trace__process_event(struct trace *trace, struct machine *machine,
case PERF_RECORD_LOST:
color_fprintf(trace->output, PERF_COLOR_RED,
"LOST %" PRIu64 " events!\n", event->lost.lost);
- ret = machine__process_lost_event(machine, event);
+ ret = machine__process_lost_event(machine, event, sample);
default:
- ret = machine__process_event(machine, event);
+ ret = machine__process_event(machine, event, sample);
break;
}

@@ -1141,11 +1141,11 @@ static int trace__process_event(struct trace *trace, struct machine *machine,

static int trace__tool_process(struct perf_tool *tool,
union perf_event *event,
- struct perf_sample *sample __maybe_unused,
+ struct perf_sample *sample,
struct machine *machine)
{
struct trace *trace = container_of(tool, struct trace, tool);
- return trace__process_event(trace, machine, event);
+ return trace__process_event(trace, machine, event, sample);
}

static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist)
@@ -1751,7 +1751,7 @@ again:
trace->base_time = sample.time;

if (type != PERF_RECORD_SAMPLE) {
- trace__process_event(trace, trace->host, event);
+ trace__process_event(trace, trace->host, event, &sample);
continue;
}

diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index e3fedfa2906e..49ccc3b2995e 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -276,7 +276,7 @@ static int process_event(struct machine *machine, struct perf_evlist *evlist,
return process_sample_event(machine, evlist, event, state);

if (event->header.type < PERF_RECORD_MAX)
- return machine__process_event(machine, event);
+ return machine__process_event(machine, event, NULL);

return 0;
}
diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c
index 4475b0ff76e5..6c337e653540 100644
--- a/tools/perf/tests/hists_link.c
+++ b/tools/perf/tests/hists_link.c
@@ -93,7 +93,7 @@ static struct machine *setup_fake_machine(struct machines *machines)
if (thread == NULL)
goto out;

- thread__set_comm(thread, fake_threads[i].comm);
+ thread__set_comm(thread, fake_threads[i].comm, 0);
}

for (i = 0; i < ARRAY_SIZE(fake_mmap_info); i++) {
@@ -110,7 +110,7 @@ static struct machine *setup_fake_machine(struct machines *machines)
strcpy(fake_mmap_event.mmap.filename,
fake_mmap_info[i].filename);

- machine__process_mmap_event(machine, &fake_mmap_event);
+ machine__process_mmap_event(machine, &fake_mmap_event, NULL);
}

for (i = 0; i < ARRAY_SIZE(fake_symbols); i++) {
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 7a2842ed53f3..c26b3539187b 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -512,18 +512,18 @@ size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp)

int perf_event__process_comm(struct perf_tool *tool __maybe_unused,
union perf_event *event,
- struct perf_sample *sample __maybe_unused,
+ struct perf_sample *sample,
struct machine *machine)
{
- return machine__process_comm_event(machine, event);
+ return machine__process_comm_event(machine, event, sample);
}

int perf_event__process_lost(struct perf_tool *tool __maybe_unused,
union perf_event *event,
- struct perf_sample *sample __maybe_unused,
+ struct perf_sample *sample,
struct machine *machine)
{
- return machine__process_lost_event(machine, event);
+ return machine__process_lost_event(machine, event, sample);
}

size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp)
@@ -546,18 +546,18 @@ size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp)

int perf_event__process_mmap(struct perf_tool *tool __maybe_unused,
union perf_event *event,
- struct perf_sample *sample __maybe_unused,
+ struct perf_sample *sample,
struct machine *machine)
{
- return machine__process_mmap_event(machine, event);
+ return machine__process_mmap_event(machine, event, sample);
}

int perf_event__process_mmap2(struct perf_tool *tool __maybe_unused,
union perf_event *event,
- struct perf_sample *sample __maybe_unused,
+ struct perf_sample *sample,
struct machine *machine)
{
- return machine__process_mmap2_event(machine, event);
+ return machine__process_mmap2_event(machine, event, sample);
}

size_t perf_event__fprintf_task(union perf_event *event, FILE *fp)
@@ -569,18 +569,18 @@ size_t perf_event__fprintf_task(union perf_event *event, FILE *fp)

int perf_event__process_fork(struct perf_tool *tool __maybe_unused,
union perf_event *event,
- struct perf_sample *sample __maybe_unused,
+ struct perf_sample *sample,
struct machine *machine)
{
- return machine__process_fork_event(machine, event);
+ return machine__process_fork_event(machine, event, sample);
}

int perf_event__process_exit(struct perf_tool *tool __maybe_unused,
union perf_event *event,
- struct perf_sample *sample __maybe_unused,
+ struct perf_sample *sample,
struct machine *machine)
{
- return machine__process_exit_event(machine, event);
+ return machine__process_exit_event(machine, event, sample);
}

size_t perf_event__fprintf(union perf_event *event, FILE *fp)
@@ -611,10 +611,10 @@ size_t perf_event__fprintf(union perf_event *event, FILE *fp)

int perf_event__process(struct perf_tool *tool __maybe_unused,
union perf_event *event,
- struct perf_sample *sample __maybe_unused,
+ struct perf_sample *sample,
struct machine *machine)
{
- return machine__process_event(machine, event);
+ return machine__process_event(machine, event, sample);
}

void thread__find_addr_map(struct thread *self,
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index ea93425cce95..ce034c183a7e 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -40,7 +40,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
return -ENOMEM;

snprintf(comm, sizeof(comm), "[guest/%d]", pid);
- thread__set_comm(thread, comm);
+ thread__set_comm(thread, comm, 0);
}

return 0;
@@ -331,7 +331,8 @@ struct thread *machine__find_thread(struct machine *machine, pid_t tid)
return __machine__findnew_thread(machine, 0, tid, false);
}

-int machine__process_comm_event(struct machine *machine, union perf_event *event)
+int machine__process_comm_event(struct machine *machine, union perf_event *event,
+ struct perf_sample *sample)
{
struct thread *thread = machine__findnew_thread(machine,
event->comm.pid,
@@ -340,7 +341,7 @@ int machine__process_comm_event(struct machine *machine, union perf_event *event
if (dump_trace)
perf_event__fprintf_comm(event, stdout);

- if (thread == NULL || thread__set_comm(thread, event->comm.comm)) {
+ if (thread == NULL || thread__set_comm(thread, event->comm.comm, sample->time)) {
dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
return -1;
}
@@ -349,7 +350,7 @@ int machine__process_comm_event(struct machine *machine, union perf_event *event
}

int machine__process_lost_event(struct machine *machine __maybe_unused,
- union perf_event *event)
+ union perf_event *event, struct perf_sample *sample __maybe_unused)
{
dump_printf(": id:%" PRIu64 ": lost:%" PRIu64 "\n",
event->lost.id, event->lost.lost);
@@ -984,7 +985,8 @@ out_problem:
}

int machine__process_mmap2_event(struct machine *machine,
- union perf_event *event)
+ union perf_event *event,
+ struct perf_sample *sample __maybe_unused)
{
u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
struct thread *thread;
@@ -1031,7 +1033,8 @@ out_problem:
return 0;
}

-int machine__process_mmap_event(struct machine *machine, union perf_event *event)
+int machine__process_mmap_event(struct machine *machine, union perf_event *event,
+ struct perf_sample *sample __maybe_unused)
{
u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
struct thread *thread;
@@ -1088,7 +1091,8 @@ static void machine__remove_thread(struct machine *machine, struct thread *th)
list_add_tail(&th->node, &machine->dead_threads);
}

-int machine__process_fork_event(struct machine *machine, union perf_event *event)
+int machine__process_fork_event(struct machine *machine, union perf_event *event,
+ struct perf_sample *sample)
{
struct thread *thread = machine__find_thread(machine, event->fork.tid);
struct thread *parent = machine__findnew_thread(machine,
@@ -1105,7 +1109,7 @@ int machine__process_fork_event(struct machine *machine, union perf_event *event
perf_event__fprintf_task(event, stdout);

if (thread == NULL || parent == NULL ||
- thread__fork(thread, parent) < 0) {
+ thread__fork(thread, parent, sample->time) < 0) {
dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n");
return -1;
}
@@ -1113,8 +1117,8 @@ int machine__process_fork_event(struct machine *machine, union perf_event *event
return 0;
}

-int machine__process_exit_event(struct machine *machine __maybe_unused,
- union perf_event *event)
+int machine__process_exit_event(struct machine *machine, union perf_event *event,
+ struct perf_sample *sample __maybe_unused)
{
struct thread *thread = machine__find_thread(machine, event->fork.tid);

@@ -1127,23 +1131,24 @@ int machine__process_exit_event(struct machine *machine __maybe_unused,
return 0;
}

-int machine__process_event(struct machine *machine, union perf_event *event)
+int machine__process_event(struct machine *machine, union perf_event *event,
+ struct perf_sample *sample)
{
int ret;

switch (event->header.type) {
case PERF_RECORD_COMM:
- ret = machine__process_comm_event(machine, event); break;
+ ret = machine__process_comm_event(machine, event, sample); break;
case PERF_RECORD_MMAP:
- ret = machine__process_mmap_event(machine, event); break;
+ ret = machine__process_mmap_event(machine, event, sample); break;
case PERF_RECORD_MMAP2:
- ret = machine__process_mmap2_event(machine, event); break;
+ ret = machine__process_mmap2_event(machine, event, sample); break;
case PERF_RECORD_FORK:
- ret = machine__process_fork_event(machine, event); break;
+ ret = machine__process_fork_event(machine, event, sample); break;
case PERF_RECORD_EXIT:
- ret = machine__process_exit_event(machine, event); break;
+ ret = machine__process_exit_event(machine, event, sample); break;
case PERF_RECORD_LOST:
- ret = machine__process_lost_event(machine, event); break;
+ ret = machine__process_lost_event(machine, event, sample); break;
default:
ret = -1;
break;
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index 4c1f5d567f54..2389ba81fafe 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -40,13 +40,20 @@ struct map *machine__kernel_map(struct machine *machine, enum map_type type)

struct thread *machine__find_thread(struct machine *machine, pid_t tid);

-int machine__process_comm_event(struct machine *machine, union perf_event *event);
-int machine__process_exit_event(struct machine *machine, union perf_event *event);
-int machine__process_fork_event(struct machine *machine, union perf_event *event);
-int machine__process_lost_event(struct machine *machine, union perf_event *event);
-int machine__process_mmap_event(struct machine *machine, union perf_event *event);
-int machine__process_mmap2_event(struct machine *machine, union perf_event *event);
-int machine__process_event(struct machine *machine, union perf_event *event);
+int machine__process_comm_event(struct machine *machine, union perf_event *event,
+ struct perf_sample *sample);
+int machine__process_exit_event(struct machine *machine, union perf_event *event,
+ struct perf_sample *sample);
+int machine__process_fork_event(struct machine *machine, union perf_event *event,
+ struct perf_sample *sample);
+int machine__process_lost_event(struct machine *machine, union perf_event *event,
+ struct perf_sample *sample);
+int machine__process_mmap_event(struct machine *machine, union perf_event *event,
+ struct perf_sample *sample);
+int machine__process_mmap2_event(struct machine *machine, union perf_event *event,
+ struct perf_sample *sample);
+int machine__process_event(struct machine *machine, union perf_event *event,
+ struct perf_sample *sample);

typedef void (*machine__process_t)(struct machine *machine, void *data);

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 4ba7b548e055..3c1b30103d54 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1100,7 +1100,7 @@ static struct thread *perf_session__register_idle_thread(struct perf_session *se
{
struct thread *thread = perf_session__findnew(self, 0);

- if (thread == NULL || thread__set_comm(thread, "swapper")) {
+ if (thread == NULL || thread__set_comm(thread, "swapper", 0)) {
pr_err("problem inserting idle task.\n");
thread = NULL;
}
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 56760079565b..0ea73fe383f5 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -31,7 +31,8 @@ void thread__delete(struct thread *thread)
free(thread);
}

-int thread__set_comm(struct thread *thread, const char *comm)
+int thread__set_comm(struct thread *thread, const char *comm,
+ u64 timestamp __maybe_unused)
{
int err;

@@ -73,7 +74,8 @@ void thread__insert_map(struct thread *thread, struct map *map)
map_groups__insert(&thread->mg, map);
}

-int thread__fork(struct thread *thread, struct thread *parent)
+int thread__fork(struct thread *thread, struct thread *parent,
+ u64 timestamp __maybe_unused)
{
int i;

diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 6561ad21d9a7..4e9724270a64 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -33,11 +33,11 @@ static inline void thread__exited(struct thread *thread)
thread->dead = true;
}

-int thread__set_comm(struct thread *self, const char *comm);
+int thread__set_comm(struct thread *thread, const char *comm, u64 timestamp);
int thread__comm_len(struct thread *self);
const char *thread__comm_str(const struct thread *thread);
void thread__insert_map(struct thread *self, struct map *map);
-int thread__fork(struct thread *self, struct thread *parent);
+int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp);
size_t thread__fprintf(struct thread *thread, FILE *fp);

static inline struct map *thread__find_map(struct thread *self,
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:04 PM11/4/13
to
From: Namhyung Kim <namhyu...@lge.com>

The -s (--sort) option was processed after normal option parsing so that
it cannot call the parse_options_usage() automatically. Currently it
calls usage_with_options() which shows entire help messages for event
option. Fix it by showing just -s options.

$ perf report -s help
Error: Unknown --sort key: `help'

usage: perf report [<options>]

-s, --sort <key[,key2...]>
sort by key(s): pid, comm, dso, symbol, ...

Signed-off-by: Namhyung Kim <namh...@kernel.org>
Acked-by: Ingo Molnar <mi...@kernel.org>
Reviewed-by: Ingo Molnar <mi...@kernel.org>
Enthusiastically-Supported-by: Ingo Molnar <mi...@kernel.org>
Cc: David Ahern <dsa...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Link: http://lkml.kernel.org/r/1383291195-24386-4-gi...@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-report.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 4df3161c7df2..25f83d5d66fd 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -947,8 +947,10 @@ repeat:
sort_order = "local_weight,mem,sym,dso,symbol_daddr,dso_daddr,snoop,tlb,locked";
}

- if (setup_sorting() < 0)
- usage_with_options(report_usage, options);
+ if (setup_sorting() < 0) {
+ parse_options_usage(report_usage, options, "s", 1);
+ goto error;
+ }

if (parent_pattern != default_parent_pattern) {
if (sort_dimension__add("parent") < 0)
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:04 PM11/4/13
to
From: Frederic Weisbecker <fwei...@gmail.com>

As the thread comm is going to be implemented by way of a more
complicated data structure than just a pointer to a string from the
thread struct, convert the readers of comm to use an accessor instead of
accessing it directly.

The accessor will be later overriden to support an enhanced comm
implementation.

Signed-off-by: Frederic Weisbecker <fwei...@gmail.com>
Tested-by: Jiri Olsa <jo...@redhat.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Ingo Molnar <mi...@elte.hu>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Arnaldo Carvalho de Melo <ac...@redhat.com>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/n/tip-wr683zwy94...@git.kernel.org
[ Rename thread__comm_curr() to thread__comm_str() ]
Signed-off-by: Namhyung Kim <namh...@kernel.org>
[ Fixed up some minor const pointer issues ]
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-kmem.c | 2 +-
tools/perf/builtin-lock.c | 2 +-
tools/perf/builtin-sched.c | 16 ++++++++--------
tools/perf/builtin-script.c | 6 +++---
tools/perf/tests/hists_link.c | 2 +-
tools/perf/ui/browsers/hists.c | 10 +++++-----
tools/perf/util/event.c | 4 ++--
tools/perf/util/scripting-engines/trace-event-perl.c | 2 +-
tools/perf/util/scripting-engines/trace-event-python.c | 4 ++--
tools/perf/util/sort.c | 11 ++++++-----
tools/perf/util/thread.c | 7 ++++++-
tools/perf/util/thread.h | 1 +
12 files changed, 37 insertions(+), 30 deletions(-)

diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 1126382659a9..a28970f7ddfb 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -315,7 +315,7 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
return -1;
}

- dump_printf(" ... thread: %s:%d\n", thread->comm, thread->tid);
+ dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid);

if (evsel->handler.func != NULL) {
tracepoint_handler f = evsel->handler.func;
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
index 33c7253295b9..35f9aaa565cc 100644
--- a/tools/perf/builtin-lock.c
+++ b/tools/perf/builtin-lock.c
@@ -767,7 +767,7 @@ static void dump_threads(void)
while (node) {
st = container_of(node, struct thread_stat, rb);
t = perf_session__findnew(session, st->tid);
- pr_info("%10d: %s\n", st->tid, t->comm);
+ pr_info("%10d: %s\n", st->tid, thread__comm_str(t));
node = rb_next(node);
};
}
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index ddb5dc15be17..a81ab1828aa5 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -737,12 +737,12 @@ static int replay_fork_event(struct perf_sched *sched,

if (verbose) {
printf("fork event\n");
- printf("... parent: %s/%d\n", parent->comm, parent->tid);
- printf("... child: %s/%d\n", child->comm, child->tid);
+ printf("... parent: %s/%d\n", thread__comm_str(parent), parent->tid);
+ printf("... child: %s/%d\n", thread__comm_str(child), child->tid);
}

- register_pid(sched, parent->tid, parent->comm);
- register_pid(sched, child->tid, child->comm);
+ register_pid(sched, parent->tid, thread__comm_str(parent));
+ register_pid(sched, child->tid, thread__comm_str(child));
return 0;
}

@@ -1077,7 +1077,7 @@ static int latency_migrate_task_event(struct perf_sched *sched,
if (!atoms) {
if (thread_atoms_insert(sched, migrant))
return -1;
- register_pid(sched, migrant->tid, migrant->comm);
+ register_pid(sched, migrant->tid, thread__comm_str(migrant));
atoms = thread_atoms_search(&sched->atom_root, migrant, &sched->cmp_pid);
if (!atoms) {
pr_err("migration-event: Internal tree error");
@@ -1111,13 +1111,13 @@ static void output_lat_thread(struct perf_sched *sched, struct work_atoms *work_
/*
* Ignore idle threads:
*/
- if (!strcmp(work_list->thread->comm, "swapper"))
+ if (!strcmp(thread__comm_str(work_list->thread), "swapper"))
return;

sched->all_runtime += work_list->total_runtime;
sched->all_count += work_list->nb_atoms;

- ret = printf(" %s:%d ", work_list->thread->comm, work_list->thread->tid);
+ ret = printf(" %s:%d ", thread__comm_str(work_list->thread), work_list->thread->tid);

for (i = 0; i < 24 - ret; i++)
printf(" ");
@@ -1334,7 +1334,7 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel,
printf(" %12.6f secs ", (double)timestamp/1e9);
if (new_shortname) {
printf("%s => %s:%d\n",
- sched_in->shortname, sched_in->comm, sched_in->tid);
+ sched_in->shortname, thread__comm_str(sched_in), sched_in->tid);
} else {
printf("\n");
}
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 0ae88c2538a1..b866cc8c3878 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -291,11 +291,11 @@ static void print_sample_start(struct perf_sample *sample,

if (PRINT_FIELD(COMM)) {
if (latency_format)
- printf("%8.8s ", thread->comm);
+ printf("%8.8s ", thread__comm_str(thread));
else if (PRINT_FIELD(IP) && symbol_conf.use_callchain)
- printf("%s ", thread->comm);
+ printf("%s ", thread__comm_str(thread));
else
- printf("%16s ", thread->comm);
+ printf("%16s ", thread__comm_str(thread));
}

if (PRINT_FIELD(PID) && PRINT_FIELD(TID))
diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c
index b51abcb2c243..4475b0ff76e5 100644
--- a/tools/perf/tests/hists_link.c
+++ b/tools/perf/tests/hists_link.c
@@ -421,7 +421,7 @@ static void print_hists(struct hists *hists)
he = rb_entry(node, struct hist_entry, rb_node_in);

pr_info("%2d: entry: %-8s [%-8s] %20s: period = %"PRIu64"\n",
- i, he->thread->comm, he->ms.map->dso->short_name,
+ i, thread__comm_str(he->thread), he->ms.map->dso->short_name,
he->ms.sym->name, he->stat.period);

i++;
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 7ef36c360471..a91b6b219412 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -1255,7 +1255,7 @@ static int hists__browser_title(struct hists *hists, char *bf, size_t size,
if (thread)
printed += scnprintf(bf + printed, size - printed,
", Thread: %s(%d)",
- (thread->comm_set ? thread->comm : ""),
+ (thread->comm_set ? thread__comm_str(thread) : ""),
thread->tid);
if (dso)
printed += scnprintf(bf + printed, size - printed,
@@ -1578,7 +1578,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
if (thread != NULL &&
asprintf(&options[nr_options], "Zoom %s %s(%d) thread",
(browser->hists->thread_filter ? "out of" : "into"),
- (thread->comm_set ? thread->comm : ""),
+ (thread->comm_set ? thread__comm_str(thread) : ""),
thread->tid) > 0)
zoom_thread = nr_options++;

@@ -1598,7 +1598,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
struct symbol *sym;

if (asprintf(&options[nr_options], "Run scripts for samples of thread [%s]",
- browser->he_selection->thread->comm) > 0)
+ thread__comm_str(browser->he_selection->thread)) > 0)
scripts_comm = nr_options++;

sym = browser->he_selection->ms.sym;
@@ -1701,7 +1701,7 @@ zoom_out_thread:
sort_thread.elide = false;
} else {
ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s(%d) thread\"",
- thread->comm_set ? thread->comm : "",
+ thread->comm_set ? thread__comm_str(thread) : "",
thread->tid);
browser->hists->thread_filter = thread;
sort_thread.elide = true;
@@ -1717,7 +1717,7 @@ do_scripts:
memset(script_opt, 0, 64);

if (choice == scripts_comm)
- sprintf(script_opt, " -c %s ", browser->he_selection->thread->comm);
+ sprintf(script_opt, " -c %s ", thread__comm_str(browser->he_selection->thread));

if (choice == scripts_symbol)
sprintf(script_opt, " -S %s ", browser->he_selection->ms.sym->name);
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 49096ea58a15..7a2842ed53f3 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -721,10 +721,10 @@ int perf_event__preprocess_sample(const union perf_event *event,
return -1;

if (symbol_conf.comm_list &&
- !strlist__has_entry(symbol_conf.comm_list, thread->comm))
+ !strlist__has_entry(symbol_conf.comm_list, thread__comm_str(thread)))
goto out_filtered;

- dump_printf(" ... thread: %s:%d\n", thread->comm, thread->tid);
+ dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid);
/*
* Have we already created the kernel maps for this machine?
*
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index c0c9795c4f02..d5e5969f6fea 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -273,7 +273,7 @@ static void perl_process_tracepoint(union perf_event *perf_event __maybe_unused,
int cpu = sample->cpu;
void *data = sample->raw_data;
unsigned long long nsecs = sample->time;
- char *comm = thread->comm;
+ const char *comm = thread__comm_str(thread);

dSP;

diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 95d91a0b23af..53c20e7fd900 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -250,7 +250,7 @@ static void python_process_tracepoint(union perf_event *perf_event
int cpu = sample->cpu;
void *data = sample->raw_data;
unsigned long long nsecs = sample->time;
- char *comm = thread->comm;
+ const char *comm = thread__comm_str(thread);

t = PyTuple_New(MAX_FIELDS);
if (!t)
@@ -389,7 +389,7 @@ static void python_process_general_event(union perf_event *perf_event
pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize(
(const char *)sample->raw_data, sample->raw_size));
pydict_set_item_string_decref(dict, "comm",
- PyString_FromString(thread->comm));
+ PyString_FromString(thread__comm_str(thread)));
if (al->map) {
pydict_set_item_string_decref(dict, "dso",
PyString_FromString(al->map->dso->name));
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 19b4aa279d1e..835e8bdd869f 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -42,7 +42,7 @@ static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...)
return n;
}

-static int64_t cmp_null(void *l, void *r)
+static int64_t cmp_null(const void *l, const void *r)
{
if (!l && !r)
return 0;
@@ -63,8 +63,9 @@ sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
static int hist_entry__thread_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
+ const char *comm = thread__comm_str(he->thread);
return repsep_snprintf(bf, size, "%*s:%5d", width - 6,
- he->thread->comm ?: "", he->thread->tid);
+ comm ?: "", he->thread->tid);
}

struct sort_entry sort_thread = {
@@ -85,8 +86,8 @@ sort__comm_cmp(struct hist_entry *left, struct hist_entry *right)
static int64_t
sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
{
- char *comm_l = left->thread->comm;
- char *comm_r = right->thread->comm;
+ const char *comm_l = thread__comm_str(left->thread);
+ const char *comm_r = thread__comm_str(right->thread);

if (!comm_l || !comm_r)
return cmp_null(comm_l, comm_r);
@@ -97,7 +98,7 @@ sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
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, he->thread->comm);
+ return repsep_snprintf(bf, size, "%*s", width, thread__comm_str(he->thread));
}

struct sort_entry sort_comm = {
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 80d19a086072..56760079565b 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -45,6 +45,11 @@ int thread__set_comm(struct thread *thread, const char *comm)
return err;
}

+const char *thread__comm_str(const struct thread *thread)
+{
+ return thread->comm;
+}
+
int thread__comm_len(struct thread *thread)
{
if (!thread->comm_len) {
@@ -58,7 +63,7 @@ int thread__comm_len(struct thread *thread)

size_t thread__fprintf(struct thread *thread, FILE *fp)
{
- return fprintf(fp, "Thread %d %s\n", thread->tid, thread->comm) +
+ return fprintf(fp, "Thread %d %s\n", thread->tid, thread__comm_str(thread)) +
map_groups__fprintf(&thread->mg, verbose, fp);
}

diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 4ebbb40d46d4..6561ad21d9a7 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -35,6 +35,7 @@ static inline void thread__exited(struct thread *thread)

int thread__set_comm(struct thread *self, const char *comm);
int thread__comm_len(struct thread *self);
+const char *thread__comm_str(const struct thread *thread);
void thread__insert_map(struct thread *self, struct map *map);
int thread__fork(struct thread *self, struct thread *parent);
size_t thread__fprintf(struct thread *thread, FILE *fp);
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:04 PM11/4/13
to
From: Adrian Hunter <adrian...@intel.com>

Attributes (struct perf_event_attr) are recorded separately in the
perf.data file. perf script uses them to set up output options.
However attributes can also be in the event stream, for example when the
input is a pipe (i.e. live mode). This patch makes perf script process
in-stream attributes in the same way as on-file attributes.

Here is an example:

Before this patch:

$ perf record uname | perf script
Linux
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.015 MB (null) (~655 samples) ]
:4220 4220 [-01] 2933367.838906: cycles:

:4220 4220 [-01] 2933367.838910: cycles:

:4220 4220 [-01] 2933367.838912: cycles:

:4220 4220 [-01] 2933367.838914: cycles:

:4220 4220 [-01] 2933367.838916: cycles:

:4220 4220 [-01] 2933367.838918: cycles:

uname 4220 [-01] 2933367.838938: cycles:

uname 4220 [-01] 2933367.839207: cycles:

After this patch:

$ perf record uname | perf script
Linux
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.015 MB (null) (~655 samples) ]
:4582 4582 2933425.707724: cycles: ffffffff81043ffa native_write_msr_safe ([kernel.kallsyms])
:4582 4582 2933425.707728: cycles: ffffffff81043ffa native_write_msr_safe ([kernel.kallsyms])
:4582 4582 2933425.707730: cycles: ffffffff81043ffa native_write_msr_safe ([kernel.kallsyms])
:4582 4582 2933425.707732: cycles: ffffffff81043ffa native_write_msr_safe ([kernel.kallsyms])
:4582 4582 2933425.707734: cycles: ffffffff81043ffa native_write_msr_safe ([kernel.kallsyms])
:4582 4582 2933425.707736: cycles: ffffffff81309a24 memcpy ([kernel.kallsyms])
uname 4582 2933425.707760: cycles: ffffffff8109c1c7 enqueue_task_fair ([kernel.kallsyms])
uname 4582 2933425.707978: cycles: ffffffff81308457 clear_page_c ([kernel.kallsyms])

Signed-off-by: Adrian Hunter <adrian...@intel.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@redhat.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: Namhyung Kim <namh...@gmail.com>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/r/1383313899-15987-3-git-...@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-script.c | 64 +++++++++++++++++++++++++++++++++------------
1 file changed, 48 insertions(+), 16 deletions(-)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index b866cc8c3878..baf17989a216 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -229,6 +229,24 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
return 0;
}

+static void set_print_ip_opts(struct perf_event_attr *attr)
+{
+ unsigned int type = attr->type;
+
+ output[type].print_ip_opts = 0;
+ if (PRINT_FIELD(IP))
+ output[type].print_ip_opts |= PRINT_IP_OPT_IP;
+
+ if (PRINT_FIELD(SYM))
+ output[type].print_ip_opts |= PRINT_IP_OPT_SYM;
+
+ if (PRINT_FIELD(DSO))
+ output[type].print_ip_opts |= PRINT_IP_OPT_DSO;
+
+ if (PRINT_FIELD(SYMOFFSET))
+ output[type].print_ip_opts |= PRINT_IP_OPT_SYMOFFSET;
+}
+
/*
* verify all user requested events exist and the samples
* have the expected data
@@ -237,7 +255,6 @@ 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);
@@ -260,20 +277,7 @@ static int perf_session__check_output_opt(struct perf_session *session)
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;
+ set_print_ip_opts(&evsel->attr);
}

return 0;
@@ -547,6 +551,34 @@ struct perf_script {
struct perf_session *session;
};

+static int process_attr(struct perf_tool *tool, union perf_event *event,
+ struct perf_evlist **pevlist)
+{
+ struct perf_script *scr = container_of(tool, struct perf_script, tool);
+ struct perf_evlist *evlist;
+ struct perf_evsel *evsel, *pos;
+ int err;
+
+ err = perf_event__process_attr(tool, event, pevlist);
+ if (err)
+ return err;
+
+ evlist = *pevlist;
+ evsel = perf_evlist__last(*pevlist);
+
+ if (evsel->attr.type >= PERF_TYPE_MAX)
+ return 0;
+
+ list_for_each_entry(pos, &evlist->entries, node) {
+ if (pos->attr.type == evsel->attr.type && pos != evsel)
+ return 0;
+ }
+
+ set_print_ip_opts(&evsel->attr);
+
+ return perf_evsel__check_attr(evsel, scr->session);
+}
+
static void sig_handler(int sig __maybe_unused)
{
session_done = 1;
@@ -1272,7 +1304,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
.comm = perf_event__process_comm,
.exit = perf_event__process_exit,
.fork = perf_event__process_fork,
- .attr = perf_event__process_attr,
+ .attr = process_attr,
.tracing_data = perf_event__process_tracing_data,
.build_id = perf_event__process_build_id,
.ordered_samples = true,
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:04 PM11/4/13
to
From: Frederic Weisbecker <fwei...@gmail.com>

This new COMM infrastructure provides two features:

1) It keeps track of all comms lifecycle for a given thread. This way we
can associate a timeframe to any thread COMM, as long as
PERF_SAMPLE_TIME samples are joined to COMM and fork events.

As a result we should have more precise COMM sorted hists with seperated
entries for pre and post exec time after a fork.

2) It also makes sure that a given COMM string is not duplicated but
rather shared among the threads that refer to it. This way the threads
COMM can be compared against pointer values from the sort
infrastructure.

Signed-off-by: Frederic Weisbecker <fwei...@gmail.com>
Tested-by: Jiri Olsa <jo...@redhat.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Ingo Molnar <mi...@elte.hu>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Arnaldo Carvalho de Melo <ac...@redhat.com>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/n/tip-hwjf70b2wv...@git.kernel.org
[ Rename some accessor functions ]
Signed-off-by: Namhyung Kim <namh...@kernel.org>
[ Use __ as separator for class__method for private comm_str methods ]
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/Makefile.perf | 2 +
tools/perf/builtin-trace.c | 4 +-
tools/perf/util/comm.c | 106 +++++++++++++++++++++++++++++++++++++++++++++
tools/perf/util/comm.h | 20 +++++++++
tools/perf/util/thread.c | 92 +++++++++++++++++++++++++++++----------
tools/perf/util/thread.h | 3 +-
6 files changed, 200 insertions(+), 27 deletions(-)
create mode 100644 tools/perf/util/comm.c
create mode 100644 tools/perf/util/comm.h

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index bc7cfa18a1e3..cb52bdb755c7 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -273,6 +273,7 @@ LIB_H += util/color.h
LIB_H += util/values.h
LIB_H += util/sort.h
LIB_H += util/hist.h
+LIB_H += util/comm.h
LIB_H += util/thread.h
LIB_H += util/thread_map.h
LIB_H += util/trace-event.h
@@ -341,6 +342,7 @@ LIB_OBJS += $(OUTPUT)util/machine.o
LIB_OBJS += $(OUTPUT)util/map.o
LIB_OBJS += $(OUTPUT)util/pstack.o
LIB_OBJS += $(OUTPUT)util/session.o
+LIB_OBJS += $(OUTPUT)util/comm.o
LIB_OBJS += $(OUTPUT)util/thread.o
LIB_OBJS += $(OUTPUT)util/thread_map.o
LIB_OBJS += $(OUTPUT)util/trace-event-parse.o
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 95d639212d98..b3e57dc64546 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1114,7 +1114,7 @@ static size_t trace__fprintf_entry_head(struct trace *trace, struct thread *thre

if (trace->multiple_threads) {
if (trace->show_comm)
- printed += fprintf(fp, "%.14s/", thread->comm);
+ printed += fprintf(fp, "%.14s/", thread__comm_str(thread));
printed += fprintf(fp, "%d ", thread->tid);
}

@@ -1986,7 +1986,7 @@ static int trace__fprintf_one_thread(struct thread *thread, void *priv)
else if (ratio > 5.0)
color = PERF_COLOR_YELLOW;

- printed += color_fprintf(fp, color, "%20s", thread->comm);
+ printed += color_fprintf(fp, color, "%20s", thread__comm_str(thread));
printed += fprintf(fp, " - %-5d :%11lu [", thread->tid, ttrace->nr_events);
printed += color_fprintf(fp, color, "%5.1f%%", ratio);
printed += fprintf(fp, " ] %10.3f ms\n", ttrace->runtime_ms);
diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c
new file mode 100644
index 000000000000..8b3ac9f0207f
--- /dev/null
+++ b/tools/perf/util/comm.c
@@ -0,0 +1,106 @@
+#include "comm.h"
+#include "util.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+struct comm_str {
+ char *str;
+ struct rb_node rb_node;
+ int ref;
+};
+
+/* Should perhaps be moved to struct machine */
+static struct rb_root comm_str_root;
+
+static void comm_str__get(struct comm_str *cs)
+{
+ cs->ref++;
+}
+
+static void comm_str__put(struct comm_str *cs)
+{
+ if (!--cs->ref) {
+ rb_erase(&cs->rb_node, &comm_str_root);
+ free(cs->str);
+ free(cs);
+ }
+}
+
+static struct comm_str *comm_str__alloc(const char *str)
+{
+ struct comm_str *cs;
+
+ cs = zalloc(sizeof(*cs));
+ if (!cs)
+ return NULL;
+
+ cs->str = strdup(str);
+ if (!cs->str) {
+ free(cs);
+ return NULL;
+ }
+
+ return cs;
+}
+
+static struct comm_str *comm_str__findnew(const char *str, struct rb_root *root)
+{
+ struct rb_node **p = &root->rb_node;
+ struct rb_node *parent = NULL;
+ struct comm_str *iter, *new;
+ int cmp;
+
+ while (*p != NULL) {
+ parent = *p;
+ iter = rb_entry(parent, struct comm_str, rb_node);
+
+ cmp = strcmp(str, iter->str);
+ if (!cmp)
+ return iter;
+
+ if (cmp < 0)
+ p = &(*p)->rb_left;
+ else
+ p = &(*p)->rb_right;
+ }
+
+ new = comm_str__alloc(str);
+ if (!new)
+ return NULL;
+
+ rb_link_node(&new->rb_node, parent, p);
+ rb_insert_color(&new->rb_node, root);
+
+ return new;
+}
+
+struct comm *comm__new(const char *str, u64 timestamp)
+{
+ struct comm *comm = zalloc(sizeof(*comm));
+
+ if (!comm)
+ return NULL;
+
+ comm->start = timestamp;
+
+ comm->comm_str = comm_str__findnew(str, &comm_str_root);
+ if (!comm->comm_str) {
+ free(comm);
+ return NULL;
+ }
+
+ comm_str__get(comm->comm_str);
+
+ return comm;
+}
+
+void comm__free(struct comm *comm)
+{
+ comm_str__put(comm->comm_str);
+ free(comm);
+}
+
+const char *comm__str(const struct comm *comm)
+{
+ return comm->comm_str->str;
+}
diff --git a/tools/perf/util/comm.h b/tools/perf/util/comm.h
new file mode 100644
index 000000000000..f62d215bede2
--- /dev/null
+++ b/tools/perf/util/comm.h
@@ -0,0 +1,20 @@
+#ifndef __PERF_COMM_H
+#define __PERF_COMM_H
+
+#include "../perf.h"
+#include <linux/rbtree.h>
+#include <linux/list.h>
+
+struct comm_str;
+
+struct comm {
+ struct comm_str *comm_str;
+ u64 start;
+ struct list_head list;
+};
+
+void comm__free(struct comm *comm);
+struct comm *comm__new(const char *str, u64 timestamp);
+const char *comm__str(const struct comm *comm);
+
+#endif /* __PERF_COMM_H */
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 0ea73fe383f5..15c53c2e109e 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -6,9 +6,12 @@
#include "thread.h"
#include "util.h"
#include "debug.h"
+#include "comm.h"

struct thread *thread__new(pid_t pid, pid_t tid)
{
+ char *comm_str;
+ struct comm *comm;
struct thread *thread = zalloc(sizeof(*thread));

if (thread != NULL) {
@@ -16,47 +19,88 @@ struct thread *thread__new(pid_t pid, pid_t tid)
thread->pid_ = pid;
thread->tid = tid;
thread->ppid = -1;
- thread->comm = malloc(32);
- if (thread->comm)
- snprintf(thread->comm, 32, ":%d", thread->tid);
+ INIT_LIST_HEAD(&thread->comm_list);
+
+ comm_str = malloc(32);
+ if (!comm_str)
+ goto err_thread;
+
+ snprintf(comm_str, 32, ":%d", tid);
+ comm = comm__new(comm_str, 0);
+ free(comm_str);
+ if (!comm)
+ goto err_thread;
+
+ list_add(&comm->list, &thread->comm_list);
}

return thread;
+
+err_thread:
+ free(thread);
+ return NULL;
}

void thread__delete(struct thread *thread)
{
+ struct comm *comm, *tmp;
+
map_groups__exit(&thread->mg);
- free(thread->comm);
+ list_for_each_entry_safe(comm, tmp, &thread->comm_list, list) {
+ list_del(&comm->list);
+ comm__free(comm);
+ }
+
free(thread);
}

-int thread__set_comm(struct thread *thread, const char *comm,
- u64 timestamp __maybe_unused)
+static struct comm *thread__comm(const struct thread *thread)
{
- int err;
+ if (list_empty(&thread->comm_list))
+ return NULL;

- if (thread->comm)
- free(thread->comm);
- thread->comm = strdup(comm);
- err = thread->comm == NULL ? -ENOMEM : 0;
- if (!err) {
- thread->comm_set = true;
+ return list_first_entry(&thread->comm_list, struct comm, list);
+}
+
+/* CHECKME: time should always be 0 if event aren't ordered */
+int thread__set_comm(struct thread *thread, const char *str, u64 timestamp)
+{
+ struct comm *new, *curr = thread__comm(thread);
+
+ /* Override latest entry if it had no specific time coverage */
+ if (!curr->start) {
+ list_del(&curr->list);
+ comm__free(curr);
}
- return err;
+
+ new = comm__new(str, timestamp);
+ if (!new)
+ return -ENOMEM;
+
+ list_add(&new->list, &thread->comm_list);
+ thread->comm_set = true;
+
+ return 0;
}

const char *thread__comm_str(const struct thread *thread)
{
- return thread->comm;
+ const struct comm *comm = thread__comm(thread);
+
+ if (!comm)
+ return NULL;
+
+ return comm__str(comm);
}

+/* CHECKME: it should probably better return the max comm len from its comm list */
int thread__comm_len(struct thread *thread)
{
if (!thread->comm_len) {
- if (!thread->comm)
+ const char *comm = thread__comm_str(thread);
+ if (!comm)
return 0;
- thread->comm_len = strlen(thread->comm);
+ thread->comm_len = strlen(comm);
}

return thread->comm_len;
@@ -74,17 +118,17 @@ void thread__insert_map(struct thread *thread, struct map *map)
map_groups__insert(&thread->mg, map);
}

-int thread__fork(struct thread *thread, struct thread *parent,
- u64 timestamp __maybe_unused)
+int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp)
{
- int i;
+ int i, err;

if (parent->comm_set) {
- if (thread->comm)
- free(thread->comm);
- thread->comm = strdup(parent->comm);
- if (!thread->comm)
+ const char *comm = thread__comm_str(parent);
+ if (!comm)
return -ENOMEM;
+ err = thread__set_comm(thread, comm, timestamp);
+ if (!err)
+ return err;
thread->comm_set = true;
}

diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 4e9724270a64..8702c6b4163a 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -2,6 +2,7 @@
#define __PERF_THREAD_H

#include <linux/rbtree.h>
+#include <linux/list.h>
#include <unistd.h>
#include <sys/types.h>
#include "symbol.h"
@@ -18,7 +19,7 @@ struct thread {
char shortname[3];
bool comm_set;
bool dead; /* if set thread has exited */
- char *comm;
+ struct list_head comm_list;
int comm_len;

void *priv;
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:04 PM11/4/13
to
From: "Steven Rostedt (Red Hat)" <ros...@goodmis.org>

Instead of cropping off the '"' and '\n"' from a printk format every
time it is referenced, do it when it's added. This makes it easier to
reference a printk_map and should speed things up a little.

Signed-off-by: Steven Rostedt <ros...@goodmis.org>
Cc: Andrew Morton <ak...@linux-foundation.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/lib/traceevent/event-parse.c | 29 ++++++++++++++---------------
tools/lib/traceevent/event-parse.h | 2 +-
2 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index deedff9d06af..856b79105abc 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -604,10 +604,11 @@ find_printk(struct pevent *pevent, unsigned long long addr)
* This registers a string by the address it was stored in the kernel.
* The @fmt passed in is duplicated.
*/
-int pevent_register_print_string(struct pevent *pevent, char *fmt,
+int pevent_register_print_string(struct pevent *pevent, const char *fmt,
unsigned long long addr)
{
struct printk_list *item = malloc(sizeof(*item));
+ char *p;

if (!item)
return -1;
@@ -615,10 +616,21 @@ int pevent_register_print_string(struct pevent *pevent, char *fmt,
item->next = pevent->printklist;
item->addr = addr;

+ /* Strip off quotes and '\n' from the end */
+ if (fmt[0] == '"')
+ fmt++;
item->printk = strdup(fmt);
if (!item->printk)
goto out_free;

+ p = item->printk + strlen(item->printk) - 1;
+ if (*p == '"')
+ *p = 0;
+
+ p -= 2;
+ if (strcmp(p, "\\n") == 0)
+ *p = 0;
+
pevent->printklist = item;
pevent->printk_count++;

@@ -3887,7 +3899,6 @@ get_bprint_format(void *data, int size __maybe_unused,
struct format_field *field;
struct printk_map *printk;
char *format;
- char *p;

field = pevent->bprint_fmt_field;

@@ -3909,20 +3920,8 @@ get_bprint_format(void *data, int size __maybe_unused,
return format;
}

- p = printk->printk;
- /* Remove any quotes. */
- if (*p == '"')
- p++;
- if (asprintf(&format, "%s : %s", "%pf", p) < 0)
+ if (asprintf(&format, "%s : %s", "%pf", printk->printk) < 0)
return NULL;
- /* remove ending quotes and new line since we will add one too */
- p = format + strlen(format) - 1;
- if (*p == '"')
- *p = 0;
-
- p -= 2;
- if (strcmp(p, "\\n") == 0)
- *p = 0;

return format;
}
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index 7503edf5ac6a..9ab6367f2fe9 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -533,7 +533,7 @@ int pevent_register_comm(struct pevent *pevent, const char *comm, int pid);
void pevent_register_trace_clock(struct pevent *pevent, char *trace_clock);
int pevent_register_function(struct pevent *pevent, char *name,
unsigned long long addr, char *mod);
-int pevent_register_print_string(struct pevent *pevent, char *fmt,
+int pevent_register_print_string(struct pevent *pevent, const char *fmt,
unsigned long long addr);
int pevent_pid_is_registered(struct pevent *pevent, int pid);

--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 1:10:05 PM11/4/13
to
From: Jiri Olsa <jo...@redhat.com>

Adding missing data.h into LIB_H headers so the build could keep up with
its changes.

Reported-by: Adrian Hunter <adrian...@intel.com>
Cc: Adrian Hunter <adrian...@intel.com>
Cc: Andi Kleen <an...@firstfloor.org>
Cc: Corey Ashford <cjas...@linux.vnet.ibm.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@elte.hu>
Cc: Namhyung Kim <namh...@kernel.org>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Link: http://lkml.kernel.org/r/20131026185...@krava.brq.redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/Makefile.perf | 1 +
1 file changed, 1 insertion(+)

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 8a9ca3836043..bc7cfa18a1e3 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -295,6 +295,7 @@ LIB_H += ui/helpline.h
LIB_H += ui/progress.h
LIB_H += ui/util.h
LIB_H += ui/ui.h
+LIB_H += util/data.h

LIB_OBJS += $(OUTPUT)util/abspath.o
LIB_OBJS += $(OUTPUT)util/alias.o
--
1.8.1.4

Ingo Molnar

unread,
Nov 4, 2013, 3:20:01 PM11/4/13
to

* Arnaldo Carvalho de Melo <ac...@infradead.org> wrote:

> From: Arnaldo Carvalho de Melo <ac...@ghostprotocols.net>
>
> Hi Ingo,
>
> Please consider pulling,
>
> - Arnaldo
>
> The following changes since commit 46d525eae2a076adfde92dca1db12d9a3b8ad8bb:
>
> perf test: Update command line callchain attribute tests (2013-11-01 10:42:57 -0300)
>
> are available in the git repository at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux tags/perf-urgent-for-mingo

I guess this wanted to be perf-core-for-mingo?

Pulled those bits, thanks Arnaldo!

Ingo

tip-bot for Arnaldo Carvalho de Melo

unread,
Nov 4, 2013, 3:30:01 PM11/4/13
to
Commit-ID: 9ef0438a957937bf0edc26d58bce891034ff9e30
Gitweb: http://git.kernel.org/tip/9ef0438a957937bf0edc26d58bce891034ff9e30
Author: Arnaldo Carvalho de Melo <ac...@redhat.com>
AuthorDate: Thu, 24 Oct 2013 17:36:31 -0300
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Mon, 4 Nov 2013 10:48:02 -0300

perf probe: Fix typo

s/tyep/type/g.

Cc: Adrian Hunter <adrian...@intel.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Masami Hiramatsu <masami.hi...@hitachi.com>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/n/tip-cznw5tnruo...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/probe-finder.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index e41b094..2200dad 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -583,7 +583,7 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
}

if (die_find_member(&type, field->name, die_mem) == NULL) {
- pr_warning("%s(tyep:%s) has no member %s.\n", varname,
+ pr_warning("%s(type:%s) has no member %s.\n", varname,
dwarf_diename(&type), field->name);
return -EINVAL;
}

tip-bot for Frederic Weisbecker

unread,
Nov 4, 2013, 3:30:01 PM11/4/13
to
Commit-ID: 1902efe7f626fdebe1520f5ff11f1309ec506708
Gitweb: http://git.kernel.org/tip/1902efe7f626fdebe1520f5ff11f1309ec506708
Author: Frederic Weisbecker <fwei...@gmail.com>
AuthorDate: Wed, 11 Sep 2013 16:56:44 +0200
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Mon, 4 Nov 2013 12:13:53 -0300

perf tools: Add new COMM infrastructure

This new COMM infrastructure provides two features:

1) It keeps track of all comms lifecycle for a given thread. This way we
can associate a timeframe to any thread COMM, as long as
PERF_SAMPLE_TIME samples are joined to COMM and fork events.

As a result we should have more precise COMM sorted hists with seperated
entries for pre and post exec time after a fork.

2) It also makes sure that a given COMM string is not duplicated but
rather shared among the threads that refer to it. This way the threads
COMM can be compared against pointer values from the sort
infrastructure.

Signed-off-by: Frederic Weisbecker <fwei...@gmail.com>
Tested-by: Jiri Olsa <jo...@redhat.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Ingo Molnar <mi...@elte.hu>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Arnaldo Carvalho de Melo <ac...@redhat.com>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/n/tip-hwjf70b2wv...@git.kernel.org
[ Rename some accessor functions ]
Signed-off-by: Namhyung Kim <namh...@kernel.org>
[ Use __ as separator for class__method for private comm_str methods ]
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/Makefile.perf | 2 +
tools/perf/builtin-trace.c | 4 +-
tools/perf/util/comm.c | 106 +++++++++++++++++++++++++++++++++++++++++++++
tools/perf/util/comm.h | 20 +++++++++
tools/perf/util/thread.c | 92 +++++++++++++++++++++++++++++----------
tools/perf/util/thread.h | 3 +-
6 files changed, 200 insertions(+), 27 deletions(-)

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index bc7cfa1..cb52bdb 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -273,6 +273,7 @@ LIB_H += util/color.h
LIB_H += util/values.h
LIB_H += util/sort.h
LIB_H += util/hist.h
+LIB_H += util/comm.h
LIB_H += util/thread.h
LIB_H += util/thread_map.h
LIB_H += util/trace-event.h
@@ -341,6 +342,7 @@ LIB_OBJS += $(OUTPUT)util/machine.o
LIB_OBJS += $(OUTPUT)util/map.o
LIB_OBJS += $(OUTPUT)util/pstack.o
LIB_OBJS += $(OUTPUT)util/session.o
+LIB_OBJS += $(OUTPUT)util/comm.o
LIB_OBJS += $(OUTPUT)util/thread.o
LIB_OBJS += $(OUTPUT)util/thread_map.o
LIB_OBJS += $(OUTPUT)util/trace-event-parse.o
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 95d6392..b3e57dc 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1114,7 +1114,7 @@ static size_t trace__fprintf_entry_head(struct trace *trace, struct thread *thre

if (trace->multiple_threads) {
if (trace->show_comm)
- printed += fprintf(fp, "%.14s/", thread->comm);
+ printed += fprintf(fp, "%.14s/", thread__comm_str(thread));
printed += fprintf(fp, "%d ", thread->tid);
}

@@ -1986,7 +1986,7 @@ static int trace__fprintf_one_thread(struct thread *thread, void *priv)
else if (ratio > 5.0)
color = PERF_COLOR_YELLOW;

- printed += color_fprintf(fp, color, "%20s", thread->comm);
+ printed += color_fprintf(fp, color, "%20s", thread__comm_str(thread));
printed += fprintf(fp, " - %-5d :%11lu [", thread->tid, ttrace->nr_events);
printed += color_fprintf(fp, color, "%5.1f%%", ratio);
printed += fprintf(fp, " ] %10.3f ms\n", ttrace->runtime_ms);
diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c
new file mode 100644
index 0000000..8b3ac9f
index 0000000..f62d215
--- /dev/null
+++ b/tools/perf/util/comm.h
@@ -0,0 +1,20 @@
+#ifndef __PERF_COMM_H
+#define __PERF_COMM_H
+
+#include "../perf.h"
+#include <linux/rbtree.h>
+#include <linux/list.h>
+
+struct comm_str;
+
+struct comm {
+ struct comm_str *comm_str;
+ u64 start;
+ struct list_head list;
+};
+
+void comm__free(struct comm *comm);
+struct comm *comm__new(const char *str, u64 timestamp);
+const char *comm__str(const struct comm *comm);
+
+#endif /* __PERF_COMM_H */
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 0ea73fe..15c53c2 100644
index 4e97242..8702c6b 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -2,6 +2,7 @@
#define __PERF_THREAD_H

#include <linux/rbtree.h>
+#include <linux/list.h>
#include <unistd.h>
#include <sys/types.h>
#include "symbol.h"
@@ -18,7 +19,7 @@ struct thread {
char shortname[3];
bool comm_set;
bool dead; /* if set thread has exited */
- char *comm;
+ struct list_head comm_list;
int comm_len;

void *priv;

tip-bot for Frederic Weisbecker

unread,
Nov 4, 2013, 3:30:01 PM11/4/13
to
Commit-ID: b9c5143a012a543c4ee872498d6dbae5c10beb2e
Gitweb: http://git.kernel.org/tip/b9c5143a012a543c4ee872498d6dbae5c10beb2e
Author: Frederic Weisbecker <fwei...@gmail.com>
AuthorDate: Wed, 11 Sep 2013 14:46:56 +0200
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Mon, 4 Nov 2013 11:50:28 -0300

perf tools: Use an accessor to read thread comm

As the thread comm is going to be implemented by way of a more
complicated data structure than just a pointer to a string from the
thread struct, convert the readers of comm to use an accessor instead of
accessing it directly.

The accessor will be later overriden to support an enhanced comm
implementation.

Signed-off-by: Frederic Weisbecker <fwei...@gmail.com>
Tested-by: Jiri Olsa <jo...@redhat.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Ingo Molnar <mi...@elte.hu>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Arnaldo Carvalho de Melo <ac...@redhat.com>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/n/tip-wr683zwy94...@git.kernel.org
[ Rename thread__comm_curr() to thread__comm_str() ]
Signed-off-by: Namhyung Kim <namh...@kernel.org>
[ Fixed up some minor const pointer issues ]
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-kmem.c | 2 +-
tools/perf/builtin-lock.c | 2 +-
tools/perf/builtin-sched.c | 16 ++++++++--------
tools/perf/builtin-script.c | 6 +++---
tools/perf/tests/hists_link.c | 2 +-
tools/perf/ui/browsers/hists.c | 10 +++++-----
tools/perf/util/event.c | 4 ++--
tools/perf/util/scripting-engines/trace-event-perl.c | 2 +-
tools/perf/util/scripting-engines/trace-event-python.c | 4 ++--
tools/perf/util/sort.c | 11 ++++++-----
tools/perf/util/thread.c | 7 ++++++-
tools/perf/util/thread.h | 1 +
12 files changed, 37 insertions(+), 30 deletions(-)

diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 1126382..a28970f 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -315,7 +315,7 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
return -1;
}

- dump_printf(" ... thread: %s:%d\n", thread->comm, thread->tid);
+ dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid);

if (evsel->handler.func != NULL) {
tracepoint_handler f = evsel->handler.func;
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
index 33c7253..35f9aaa 100644
--- a/tools/perf/builtin-lock.c
+++ b/tools/perf/builtin-lock.c
@@ -767,7 +767,7 @@ static void dump_threads(void)
while (node) {
st = container_of(node, struct thread_stat, rb);
t = perf_session__findnew(session, st->tid);
- pr_info("%10d: %s\n", st->tid, t->comm);
+ pr_info("%10d: %s\n", st->tid, thread__comm_str(t));
node = rb_next(node);
};
}
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index ddb5dc1..a81ab18 100644
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 0ae88c2..b866cc8 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -291,11 +291,11 @@ static void print_sample_start(struct perf_sample *sample,

if (PRINT_FIELD(COMM)) {
if (latency_format)
- printf("%8.8s ", thread->comm);
+ printf("%8.8s ", thread__comm_str(thread));
else if (PRINT_FIELD(IP) && symbol_conf.use_callchain)
- printf("%s ", thread->comm);
+ printf("%s ", thread__comm_str(thread));
else
- printf("%16s ", thread->comm);
+ printf("%16s ", thread__comm_str(thread));
}

if (PRINT_FIELD(PID) && PRINT_FIELD(TID))
diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c
index b51abcb..4475b0f 100644
--- a/tools/perf/tests/hists_link.c
+++ b/tools/perf/tests/hists_link.c
@@ -421,7 +421,7 @@ static void print_hists(struct hists *hists)
he = rb_entry(node, struct hist_entry, rb_node_in);

pr_info("%2d: entry: %-8s [%-8s] %20s: period = %"PRIu64"\n",
- i, he->thread->comm, he->ms.map->dso->short_name,
+ i, thread__comm_str(he->thread), he->ms.map->dso->short_name,
he->ms.sym->name, he->stat.period);

i++;
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 7ef36c3..a91b6b2 100644
index 49096ea..7a2842e 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -721,10 +721,10 @@ int perf_event__preprocess_sample(const union perf_event *event,
return -1;

if (symbol_conf.comm_list &&
- !strlist__has_entry(symbol_conf.comm_list, thread->comm))
+ !strlist__has_entry(symbol_conf.comm_list, thread__comm_str(thread)))
goto out_filtered;

- dump_printf(" ... thread: %s:%d\n", thread->comm, thread->tid);
+ dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid);
/*
* Have we already created the kernel maps for this machine?
*
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index c0c9795..d5e5969 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -273,7 +273,7 @@ static void perl_process_tracepoint(union perf_event *perf_event __maybe_unused,
int cpu = sample->cpu;
void *data = sample->raw_data;
unsigned long long nsecs = sample->time;
- char *comm = thread->comm;
+ const char *comm = thread__comm_str(thread);

dSP;

diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 95d91a0..53c20e7 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -250,7 +250,7 @@ static void python_process_tracepoint(union perf_event *perf_event
int cpu = sample->cpu;
void *data = sample->raw_data;
unsigned long long nsecs = sample->time;
- char *comm = thread->comm;
+ const char *comm = thread__comm_str(thread);

t = PyTuple_New(MAX_FIELDS);
if (!t)
@@ -389,7 +389,7 @@ static void python_process_general_event(union perf_event *perf_event
pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize(
(const char *)sample->raw_data, sample->raw_size));
pydict_set_item_string_decref(dict, "comm",
- PyString_FromString(thread->comm));
+ PyString_FromString(thread__comm_str(thread)));
if (al->map) {
pydict_set_item_string_decref(dict, "dso",
PyString_FromString(al->map->dso->name));
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 19b4aa2..835e8bd 100644
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 80d19a0..5676007 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -45,6 +45,11 @@ int thread__set_comm(struct thread *thread, const char *comm)
return err;
}

+const char *thread__comm_str(const struct thread *thread)
+{
+ return thread->comm;
+}
+
int thread__comm_len(struct thread *thread)
{
if (!thread->comm_len) {
@@ -58,7 +63,7 @@ int thread__comm_len(struct thread *thread)

size_t thread__fprintf(struct thread *thread, FILE *fp)
{
- return fprintf(fp, "Thread %d %s\n", thread->tid, thread->comm) +
+ return fprintf(fp, "Thread %d %s\n", thread->tid, thread__comm_str(thread)) +
map_groups__fprintf(&thread->mg, verbose, fp);
}

diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 4ebbb40..6561ad2 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -35,6 +35,7 @@ static inline void thread__exited(struct thread *thread)

int thread__set_comm(struct thread *self, const char *comm);
int thread__comm_len(struct thread *self);
+const char *thread__comm_str(const struct thread *thread);
void thread__insert_map(struct thread *self, struct map *map);
int thread__fork(struct thread *self, struct thread *parent);
size_t thread__fprintf(struct thread *thread, FILE *fp);

tip-bot for Namhyung Kim

unread,
Nov 4, 2013, 3:30:02 PM11/4/13
to
Commit-ID: 4dfced359fbc719a35527416f1b4b3999647f68b
Gitweb: http://git.kernel.org/tip/4dfced359fbc719a35527416f1b4b3999647f68b
Author: Namhyung Kim <namhyu...@lge.com>
AuthorDate: Fri, 13 Sep 2013 16:28:57 +0900
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Mon, 4 Nov 2013 12:16:39 -0300

perf tools: Get current comm instead of last one

At insert time, a hist entry should reference comm at the time otherwise
it'll get the last comm anyway.

Signed-off-by: Namhyung Kim <namh...@kernel.org>
Acked-by: Frederic Weisbecker <fwei...@gmail.com>
Tested-by: Jiri Olsa <jo...@redhat.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Link: http://lkml.kernel.org/n/tip-n6pykiiymt...@git.kernel.org
[ Fixed up const pointer issues ]
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/comm.c | 15 +++++++++++++++
tools/perf/util/comm.h | 1 +
tools/perf/util/hist.c | 3 +++
tools/perf/util/sort.c | 14 +++++---------
tools/perf/util/sort.h | 1 +
tools/perf/util/thread.c | 6 +++---
tools/perf/util/thread.h | 2 ++
7 files changed, 30 insertions(+), 12 deletions(-)

diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c
index 8b3ac9f..ee0df0e 100644
--- a/tools/perf/util/comm.c
+++ b/tools/perf/util/comm.c
@@ -94,6 +94,21 @@ struct comm *comm__new(const char *str, u64 timestamp)
return comm;
}

+void comm__override(struct comm *comm, const char *str, u64 timestamp)
+{
+ struct comm_str *old = comm->comm_str;
+
+ comm->comm_str = comm_str__findnew(str, &comm_str_root);
+ if (!comm->comm_str) {
+ comm->comm_str = old;
+ return;
+ }
+
+ comm->start = timestamp;
+ comm_str__get(comm->comm_str);
+ comm_str__put(old);
+}
+
void comm__free(struct comm *comm)
{
comm_str__put(comm->comm_str);
diff --git a/tools/perf/util/comm.h b/tools/perf/util/comm.h
index f62d215..7a86e56 100644
--- a/tools/perf/util/comm.h
+++ b/tools/perf/util/comm.h
@@ -16,5 +16,6 @@ struct comm {
void comm__free(struct comm *comm);
struct comm *comm__new(const char *str, u64 timestamp);
const char *comm__str(const struct comm *comm);
+void comm__override(struct comm *comm, const char *str, u64 timestamp);

#endif /* __PERF_COMM_H */
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 7e80253..30793f9 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -416,6 +416,7 @@ struct hist_entry *__hists__add_mem_entry(struct hists *hists,
{
struct hist_entry entry = {
.thread = al->thread,
+ .comm = thread__comm(al->thread),
.ms = {
.map = al->map,
.sym = al->sym,
@@ -446,6 +447,7 @@ struct hist_entry *__hists__add_branch_entry(struct hists *hists,
{
struct hist_entry entry = {
.thread = al->thread,
+ .comm = thread__comm(al->thread),
.ms = {
.map = bi->to.map,
.sym = bi->to.sym,
@@ -475,6 +477,7 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
{
struct hist_entry entry = {
.thread = al->thread,
+ .comm = thread__comm(al->thread),
.ms = {
.map = al->map,
.sym = al->sym,
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index bf91d0e..3c1b75c 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -1,5 +1,6 @@
#include "sort.h"
#include "hist.h"
+#include "comm.h"
#include "symbol.h"

regex_t parent_regex;
@@ -81,25 +82,20 @@ static int64_t
sort__comm_cmp(struct hist_entry *left, struct hist_entry *right)
{
/* Compare the addr that should be unique among comm */
- return thread__comm_str(right->thread) - thread__comm_str(left->thread);
+ return comm__str(right->comm) - comm__str(left->comm);
}

static int64_t
sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
{
- const char *comm_l = thread__comm_str(left->thread);
- const char *comm_r = thread__comm_str(right->thread);
-
- if (!comm_l || !comm_r)
- return cmp_null(comm_l, comm_r);
-
- return strcmp(comm_l, comm_r);
+ /* Compare the addr that should be unique among comm */
+ return comm__str(right->comm) - comm__str(left->comm);
}

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, thread__comm_str(he->thread));
+ return repsep_snprintf(bf, size, "%*s", width, comm__str(he->comm));
}

struct sort_entry sort_comm = {
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index bf43336..f4e16f3 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -84,6 +84,7 @@ struct hist_entry {
struct he_stat stat;
struct map_symbol ms;
struct thread *thread;
+ struct comm *comm;
u64 ip;
u64 transaction;
s32 cpu;
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 15c53c2..cd8e2f5 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -54,7 +54,7 @@ void thread__delete(struct thread *thread)
free(thread);
}

-static struct comm *thread__comm(const struct thread *thread)
+struct comm *thread__comm(const struct thread *thread)
{
if (list_empty(&thread->comm_list))
return NULL;
@@ -69,8 +69,8 @@ int thread__set_comm(struct thread *thread, const char *str, u64 timestamp)

/* Override latest entry if it had no specific time coverage */
if (!curr->start) {
- list_del(&curr->list);
- comm__free(curr);
+ comm__override(curr, str, timestamp);
+ return 0;
}

new = comm__new(str, timestamp);
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 8702c6b..373c055 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -26,6 +26,7 @@ struct thread {
};

struct machine;
+struct comm;

struct thread *thread__new(pid_t pid, pid_t tid);
void thread__delete(struct thread *self);
@@ -36,6 +37,7 @@ static inline void thread__exited(struct thread *thread)

int thread__set_comm(struct thread *thread, const char *comm, u64 timestamp);
int thread__comm_len(struct thread *self);
+struct comm *thread__comm(const struct thread *thread);
const char *thread__comm_str(const struct thread *thread);
void thread__insert_map(struct thread *self, struct map *map);
int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp);

tip-bot for Frederic Weisbecker

unread,
Nov 4, 2013, 3:30:03 PM11/4/13
to
Commit-ID: 162f0befda3becc2cc9f44075fccc030e55baec1
Gitweb: http://git.kernel.org/tip/162f0befda3becc2cc9f44075fccc030e55baec1
Author: Frederic Weisbecker <fwei...@gmail.com>
AuthorDate: Wed, 11 Sep 2013 16:18:24 +0200
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Mon, 4 Nov 2013 11:57:06 -0300

perf tools: Add time argument on COMM setting

This way we can later delimit a lifecycle for the COMM and map a hist to
a precise COMM:timeslice couple.

PERF_RECORD_COMM and PERF_RECORD_FORK events that don't have
PERF_SAMPLE_TIME samples can only send 0 value as a timestamp and thus
should overwrite any previous COMM on a given thread because there is no
sensible way to keep track of all the comms lifecycles in a thread
without time informations.

Signed-off-by: Frederic Weisbecker <fwei...@gmail.com>
Tested-by: Jiri Olsa <jo...@redhat.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Ingo Molnar <mi...@elte.hu>
Cc: Namhyung Kim <namh...@kernel.org>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/n/tip-6tyow99vgm...@git.kernel.org
[ Made it cope with PERF_RECORD_MMAP2 ]
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-top.c | 2 +-
tools/perf/builtin-trace.c | 12 ++++++------
tools/perf/tests/code-reading.c | 2 +-
tools/perf/tests/hists_link.c | 4 ++--
tools/perf/util/event.c | 28 ++++++++++++++--------------
tools/perf/util/machine.c | 39 ++++++++++++++++++++++-----------------
tools/perf/util/machine.h | 21 ++++++++++++++-------
tools/perf/util/session.c | 2 +-
tools/perf/util/thread.c | 6 ++++--
tools/perf/util/thread.h | 4 ++--
10 files changed, 67 insertions(+), 53 deletions(-)

diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index a6ea956..21db76d 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -856,7 +856,7 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx)
&sample, machine);
} else if (event->header.type < PERF_RECORD_MAX) {
hists__inc_nr_events(&evsel->hists, event->header.type);
- machine__process_event(machine, event);
+ machine__process_event(machine, event, &sample);
} else
++session->stats.nr_unknown_events;
next_event:
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index dc3da65..95d6392 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1122,7 +1122,7 @@ static size_t trace__fprintf_entry_head(struct trace *trace, struct thread *thre
}

static int trace__process_event(struct trace *trace, struct machine *machine,
- union perf_event *event)
+ union perf_event *event, struct perf_sample *sample)
{
int ret = 0;

@@ -1130,9 +1130,9 @@ static int trace__process_event(struct trace *trace, struct machine *machine,
case PERF_RECORD_LOST:
color_fprintf(trace->output, PERF_COLOR_RED,
"LOST %" PRIu64 " events!\n", event->lost.lost);
- ret = machine__process_lost_event(machine, event);
+ ret = machine__process_lost_event(machine, event, sample);
default:
- ret = machine__process_event(machine, event);
+ ret = machine__process_event(machine, event, sample);
break;
}

@@ -1141,11 +1141,11 @@ static int trace__process_event(struct trace *trace, struct machine *machine,

static int trace__tool_process(struct perf_tool *tool,
union perf_event *event,
- struct perf_sample *sample __maybe_unused,
+ struct perf_sample *sample,
struct machine *machine)
{
struct trace *trace = container_of(tool, struct trace, tool);
- return trace__process_event(trace, machine, event);
+ return trace__process_event(trace, machine, event, sample);
}

static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist)
@@ -1751,7 +1751,7 @@ again:
trace->base_time = sample.time;

if (type != PERF_RECORD_SAMPLE) {
- trace__process_event(trace, trace->host, event);
+ trace__process_event(trace, trace->host, event, &sample);
continue;
}

diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index e3fedfa..49ccc3b 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -276,7 +276,7 @@ static int process_event(struct machine *machine, struct perf_evlist *evlist,
return process_sample_event(machine, evlist, event, state);

if (event->header.type < PERF_RECORD_MAX)
- return machine__process_event(machine, event);
+ return machine__process_event(machine, event, NULL);

return 0;
}
diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c
index 4475b0f..6c337e6 100644
--- a/tools/perf/tests/hists_link.c
+++ b/tools/perf/tests/hists_link.c
@@ -93,7 +93,7 @@ static struct machine *setup_fake_machine(struct machines *machines)
if (thread == NULL)
goto out;

- thread__set_comm(thread, fake_threads[i].comm);
+ thread__set_comm(thread, fake_threads[i].comm, 0);
}

for (i = 0; i < ARRAY_SIZE(fake_mmap_info); i++) {
@@ -110,7 +110,7 @@ static struct machine *setup_fake_machine(struct machines *machines)
strcpy(fake_mmap_event.mmap.filename,
fake_mmap_info[i].filename);

- machine__process_mmap_event(machine, &fake_mmap_event);
+ machine__process_mmap_event(machine, &fake_mmap_event, NULL);
}

for (i = 0; i < ARRAY_SIZE(fake_symbols); i++) {
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 7a2842e..c26b353 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
index ea93425..ce034c1 100644
index 4c1f5d5..2389ba8 100644
index 4ba7b54..3c1b301 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1100,7 +1100,7 @@ static struct thread *perf_session__register_idle_thread(struct perf_session *se
{
struct thread *thread = perf_session__findnew(self, 0);

- if (thread == NULL || thread__set_comm(thread, "swapper")) {
+ if (thread == NULL || thread__set_comm(thread, "swapper", 0)) {
pr_err("problem inserting idle task.\n");
thread = NULL;
}
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 5676007..0ea73fe 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -31,7 +31,8 @@ void thread__delete(struct thread *thread)
free(thread);
}

-int thread__set_comm(struct thread *thread, const char *comm)
+int thread__set_comm(struct thread *thread, const char *comm,
+ u64 timestamp __maybe_unused)
{
int err;

@@ -73,7 +74,8 @@ void thread__insert_map(struct thread *thread, struct map *map)
map_groups__insert(&thread->mg, map);
}

-int thread__fork(struct thread *thread, struct thread *parent)
+int thread__fork(struct thread *thread, struct thread *parent,
+ u64 timestamp __maybe_unused)
{
int i;

diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 6561ad2..4e97242 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -33,11 +33,11 @@ static inline void thread__exited(struct thread *thread)
thread->dead = true;
}

-int thread__set_comm(struct thread *self, const char *comm);
+int thread__set_comm(struct thread *thread, const char *comm, u64 timestamp);
int thread__comm_len(struct thread *self);
const char *thread__comm_str(const struct thread *thread);
void thread__insert_map(struct thread *self, struct map *map);
-int thread__fork(struct thread *self, struct thread *parent);
+int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp);
size_t thread__fprintf(struct thread *thread, FILE *fp);

static inline struct map *thread__find_map(struct thread *self,

Ingo Molnar

unread,
Nov 5, 2013, 3:00:01 AM11/5/13
to

hm, probably one of these commits:

8a0c4c2843d3 perf tools: Fix libunwind build and feature detection for 32-bit build
28e962b9d79f perf tools: Fix 32-bit cross build
74af377bc25d perf tools: Fix non-debug build
9402802a416c perf tools: Fix test_on_exit for 32-bit build

broke the suppression of the auto-detection messages on repeat invocations
of 'make', if all testcases pass.

'make' used to display this on repeat invocations:

comet:~/tip/tools/perf> make
BUILD: Doing 'make -j12' parallel build
comet:~/tip/tools/perf> make
BUILD: Doing 'make -j12' parallel build
comet:~/tip/tools/perf> make
BUILD: Doing 'make -j12' parallel build

Now it displays the spammy auto-detection all the time:

comet:~/tip/tools/perf> make
BUILD: Doing 'make -j12' parallel build

Auto-detecting system features:
... backtrace: [ on ]
... dwarf: [ on ]
... fortify-source: [ on ]
... glibc: [ on ]
... gtk2: [ on ]
... gtk2-infobar: [ on ]
... libaudit: [ on ]
... libbfd: [ on ]
... libelf: [ on ]
... libelf-getphdrnum: [ on ]
... libelf-mmap: [ on ]
... libnuma: [ on ]
... libperl: [ on ]
... libpython: [ on ]
... libpython-version: [ on ]
... libslang: [ on ]
... libunwind: [ on ]
... on-exit: [ on ]
... stackprotector: [ on ]
... stackprotector-all: [ on ]

maybe a new testcase fails on my box, but is not properly displayed?

Thanks,

Ingo Molnar

unread,
Nov 5, 2013, 3:10:02 AM11/5/13
to
Hm, a 'make clean' cleaned up the condition and it now works as expected.

So what happened is that GCC got upgraded from 4.8.1 to 4.8.2 and
test-all.c failed to build:

comet:~/tip/tools/perf/config/feature-checks> make -i
make: *** No rule to make target `/usr/lib/gcc/x86_64-redhat-linux/4.8.1/include/limits.h', needed by `test-all'. Stop.

but the individual testcases got built successfully and the perf build was
fine and correct - it's just that the test-all.c .d file never got updated
due to the broken dependency.

I think Namhyung warned about this during the feature-detection
discussion, and I dismissed the concern - but Namhyung was right, it's a
real problem.

I think to fix this we should automatically clean out potentially stale .d
files automatically after testcase build failures (be it test-all.c or any
other testcase)?

That would still preserve all the good roles of these dependencies and it
would preserve the build speed and detection of system library changes.

Arnaldo Carvalho de Melo

unread,
Nov 5, 2013, 3:20:02 PM11/5/13
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

Hi Ingo,

Please consider pulling,

- Arnaldo

The following changes since commit 87968f94fbea47df334502a0db645833ce8a848b:

Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core (2013-11-04 21:14:04 +0100)

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 316c7136f8bad924609163b9b115f68d59a68c82:

perf tools: Finish the removal of 'self' arguments (2013-11-05 15:32:36 -0300)

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

. Check maximum frequency rate for record/top, emitting better error
messages, from Jiri Olsa.

. Disable live kvm command if timerfd is not supported, from David Ahern.

. Add usage to 'perf list', from David Ahern.

. Fix detection of non-core features, from David Ahern.

. Consolidate __hists__add_*entry(), cleanup from Namhyung Kim.

Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>

----------------------------------------------------------------
Arnaldo Carvalho de Melo (2):
perf fs: Rename NAME_find_mountpoint() to NAME__mountpoint()
perf tools: Finish the removal of 'self' arguments

David Ahern (4):
perf kvm: Disable live command if timerfd is not supported
tools/perf/build: Fix detection of non-core features
perf list: Remove a level of indentation
perf list: Add usage

Jiri Olsa (3):
perf tools: Factor sysfs code into generic fs object
perf fs: Add procfs support
perf tools: Check maximum frequency rate for record/top

Namhyung Kim (1):
perf hists: Consolidate __hists__add_*entry()

tools/perf/Makefile.perf | 4 +-
tools/perf/builtin-annotate.c | 2 +-
tools/perf/builtin-diff.c | 3 +-
tools/perf/builtin-kvm.c | 12 ++
tools/perf/builtin-list.c | 84 ++++++++------
tools/perf/builtin-record.c | 15 +--
tools/perf/builtin-report.c | 16 ++-
tools/perf/builtin-top.c | 20 +---
tools/perf/config/Makefile | 17 ++-
tools/perf/config/feature-checks/Makefile | 6 +-
tools/perf/config/feature-checks/test-all.c | 5 +
tools/perf/config/feature-checks/test-timerfd.c | 18 +++
.../perf/scripts/python/Perf-Trace-Util/Context.c | 6 +-
tools/perf/tests/hists_link.c | 6 +-
tools/perf/tests/parse-events.c | 6 +-
tools/perf/ui/browser.h | 32 +++---
tools/perf/ui/browsers/hists.c | 2 +-
tools/perf/ui/browsers/map.c | 40 +++----
tools/perf/ui/browsers/map.h | 2 +-
tools/perf/ui/browsers/scripts.c | 8 +-
tools/perf/ui/stdio/hist.c | 14 +--
tools/perf/util/build-id.h | 3 +-
tools/perf/util/cpumap.c | 6 +-
tools/perf/util/event.c | 6 +-
tools/perf/util/event.h | 3 +-
tools/perf/util/evlist.h | 3 +-
tools/perf/util/fs.c | 119 ++++++++++++++++++++
tools/perf/util/fs.h | 7 ++
tools/perf/util/hist.c | 75 ++-----------
tools/perf/util/hist.h | 51 +++------
tools/perf/util/include/linux/magic.h | 4 +
tools/perf/util/pmu.c | 17 +--
tools/perf/util/probe-finder.c | 113 +++++++++----------
tools/perf/util/probe-finder.h | 10 +-
tools/perf/util/pstack.h | 10 +-
tools/perf/util/python-ext-sources | 2 +-
tools/perf/util/record.c | 71 ++++++++++++
tools/perf/util/session.c | 121 ++++++++++-----------
tools/perf/util/session.h | 27 ++---
tools/perf/util/sort.h | 2 +-
tools/perf/util/strfilter.c | 32 +++---
tools/perf/util/strfilter.h | 12 +-
tools/perf/util/sysfs.c | 60 ----------
tools/perf/util/sysfs.h | 6 -
tools/perf/util/thread.h | 10 +-
45 files changed, 591 insertions(+), 497 deletions(-)
create mode 100644 tools/perf/config/feature-checks/test-timerfd.c
create mode 100644 tools/perf/util/fs.c
create mode 100644 tools/perf/util/fs.h
delete mode 100644 tools/perf/util/sysfs.c
delete mode 100644 tools/perf/util/sysfs.h

Arnaldo Carvalho de Melo

unread,
Nov 5, 2013, 3:20:02 PM11/5/13
to
From: David Ahern <dsa...@gmail.com>

feature_check needs to be invoked through call, and LDFLAGS may not be
set so quotes are needed.

Thanks to Jiri for spotting the quotes around LDFLAGS; that one was
driving me nuts with the upcoming timerfd feature detection.

Signed-off-by: David Ahern <dsa...@gmail.com>
Reviewed-by: Jiri Olsa <jo...@redhat.com>
Tested-by: Jiri Olsa <jo...@redhat.com>
Acked-by: Ingo Molnar <mi...@kernel.org>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namh...@kernel.org>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Link: http://lkml.kernel.org/r/1383064996-20933-1-g...@gmail.com
[ Fixed conflict with 8a0c4c2843d3 ("perf tools: Fix libunwind build and feature detection for 32-bit build") ]
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/config/Makefile | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index be8bb9a77287..58b2d37ae23a 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -98,7 +98,7 @@ endif

feature_check = $(eval $(feature_check_code))
define feature_check_code
- feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS=$(LDFLAGS) LIBUNWIND_LIBS="$(LIBUNWIND_LIBS)" -C config/feature-checks test-$1 >/dev/null 2>/dev/null && echo 1 || echo 0)
+ feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS="$(LDFLAGS)" LIBUNWIND_LIBS="$(LIBUNWIND_LIBS)" -C config/feature-checks test-$1 >/dev/null 2>/dev/null && echo 1 || echo 0)
endef

feature_set = $(eval $(feature_set_code))
@@ -235,7 +235,7 @@ CFLAGS += -I$(LIB_INCLUDE)
CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE

ifndef NO_BIONIC
- $(feature_check,bionic)
+ $(call feature_check,bionic)
ifeq ($(feature-bionic), 1)
BIONIC := 1
EXTLIBS := $(filter-out -lrt,$(EXTLIBS))
@@ -479,15 +479,15 @@ else
CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT
else
ifneq ($(feature-libbfd), 1)
- $(feature_check,liberty)
+ $(call feature_check,liberty)
ifeq ($(feature-liberty), 1)
EXTLIBS += -lbfd -liberty
else
- $(feature_check,liberty-z)
+ $(call feature_check,liberty-z)
ifeq ($(feature-liberty-z), 1)
EXTLIBS += -lbfd -liberty -lz
else
- $(feature_check,cplus-demangle)
+ $(call feature_check,cplus-demangle)
ifeq ($(feature-cplus-demangle), 1)
EXTLIBS += -liberty
CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 5, 2013, 3:20:03 PM11/5/13
to
From: David Ahern <dsa...@gmail.com>

If the OS does not have timerfd support (e.g., older OS'es like RHEL5)
disable perf kvm stat live.

Signed-off-by: David Ahern <dsa...@gmail.com>
Reviewed-by: Jiri Olsa <jo...@redhat.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namh...@kernel.org>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Link: http://lkml.kernel.org/r/1383064996-20933-2-g...@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-kvm.c | 12 ++++++++++++
tools/perf/config/Makefile | 7 +++++++
tools/perf/config/feature-checks/Makefile | 6 +++++-
tools/perf/config/feature-checks/test-all.c | 5 +++++
tools/perf/config/feature-checks/test-timerfd.c | 18 ++++++++++++++++++
5 files changed, 47 insertions(+), 1 deletion(-)
create mode 100644 tools/perf/config/feature-checks/test-timerfd.c

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index cb05f39d8a77..cd9f92078aba 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -20,7 +20,9 @@
#include "util/data.h"

#include <sys/prctl.h>
+#ifdef HAVE_TIMERFD_SUPPORT
#include <sys/timerfd.h>
+#endif

#include <termios.h>
#include <semaphore.h>
@@ -337,6 +339,7 @@ static void init_kvm_event_record(struct perf_kvm_stat *kvm)
INIT_LIST_HEAD(&kvm->kvm_events_cache[i]);
}

+#ifdef HAVE_TIMERFD_SUPPORT
static void clear_events_cache_stats(struct list_head *kvm_events_cache)
{
struct list_head *head;
@@ -358,6 +361,7 @@ static void clear_events_cache_stats(struct list_head *kvm_events_cache)
}
}
}
+#endif

static int kvm_events_hash_fn(u64 key)
{
@@ -783,6 +787,7 @@ static void print_result(struct perf_kvm_stat *kvm)
pr_info("\nLost events: %" PRIu64 "\n\n", kvm->lost_events);
}

+#ifdef HAVE_TIMERFD_SUPPORT
static int process_lost_event(struct perf_tool *tool,
union perf_event *event __maybe_unused,
struct perf_sample *sample __maybe_unused,
@@ -793,6 +798,7 @@ static int process_lost_event(struct perf_tool *tool,
kvm->lost_events++;
return 0;
}
+#endif

static bool skip_sample(struct perf_kvm_stat *kvm,
struct perf_sample *sample)
@@ -872,6 +878,7 @@ static bool verify_vcpu(int vcpu)
return true;
}

+#ifdef HAVE_TIMERFD_SUPPORT
/* keeping the max events to a modest level to keep
* the processing of samples per mmap smooth.
*/
@@ -1213,6 +1220,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm)
out:
return rc;
}
+#endif

static int read_events(struct perf_kvm_stat *kvm)
{
@@ -1379,6 +1387,7 @@ kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv)
return kvm_events_report_vcpu(kvm);
}

+#ifdef HAVE_TIMERFD_SUPPORT
static struct perf_evlist *kvm_live_event_list(void)
{
struct perf_evlist *evlist;
@@ -1566,6 +1575,7 @@ out:

return err;
}
+#endif

static void print_kvm_stat_usage(void)
{
@@ -1604,8 +1614,10 @@ static int kvm_cmd_stat(const char *file_name, int argc, const char **argv)
if (!strncmp(argv[1], "rep", 3))
return kvm_events_report(&kvm, argc - 1 , argv + 1);

+#ifdef HAVE_TIMERFD_SUPPORT
if (!strncmp(argv[1], "live", 4))
return kvm_events_live(&kvm, argc - 1 , argv + 1);
+#endif

perf_stat:
return cmd_stat(argc, argv, NULL);
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index ffb5f55c8fba..be8bb9a77287 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -397,6 +397,13 @@ else
endif
endif

+$(call feature_check,timerfd)
+ifeq ($(feature-timerfd), 1)
+ CFLAGS += -DHAVE_TIMERFD_SUPPORT
+else
+ msg := $(warning No timerfd support. Disables 'perf kvm stat live');
+endif
+
disable-python = $(eval $(disable-python_code))
define disable-python_code
CFLAGS += -DNO_LIBPYTHON
diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile
index d37d58d273fe..c803f17fb986 100644
--- a/tools/perf/config/feature-checks/Makefile
+++ b/tools/perf/config/feature-checks/Makefile
@@ -25,7 +25,8 @@ FILES= \
test-libunwind \
test-on-exit \
test-stackprotector-all \
- test-stackprotector
+ test-stackprotector \
+ test-timerfd

CC := $(CC) -MD

@@ -136,6 +137,9 @@ test-on-exit:
test-backtrace:
$(BUILD)

+test-timerfd:
+ $(BUILD)
+
-include *.d

###############################
diff --git a/tools/perf/config/feature-checks/test-all.c b/tools/perf/config/feature-checks/test-all.c
index 50d431892a0c..59e7a705e146 100644
--- a/tools/perf/config/feature-checks/test-all.c
+++ b/tools/perf/config/feature-checks/test-all.c
@@ -81,6 +81,10 @@
# include "test-libnuma.c"
#undef main

+#define main main_test_timerfd
+# include "test-timerfd.c"
+#undef main
+
int main(int argc, char *argv[])
{
main_test_libpython();
@@ -101,6 +105,7 @@ int main(int argc, char *argv[])
main_test_on_exit();
main_test_backtrace();
main_test_libnuma();
+ main_test_timerfd();

return 0;
}
diff --git a/tools/perf/config/feature-checks/test-timerfd.c b/tools/perf/config/feature-checks/test-timerfd.c
new file mode 100644
index 000000000000..8c5c083b4d3c
--- /dev/null
+++ b/tools/perf/config/feature-checks/test-timerfd.c
@@ -0,0 +1,18 @@
+/*
+ * test for timerfd functions used by perf-kvm-stat-live
+ */
+#include <sys/timerfd.h>
+
+int main(void)
+{
+ struct itimerspec new_value;
+
+ int fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
+ if (fd < 0)
+ return 1;
+
+ if (timerfd_settime(fd, 0, &new_value, NULL) != 0)
+ return 1;
+
+ return 0;
+}
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 5, 2013, 3:20:03 PM11/5/13
to
From: Namhyung Kim <namhyu...@lge.com>

The __hists__add_{branch,mem}_entry() does almost the same thing that
__hists__add_entry() does. Consolidate them into one.

Signed-off-by: Namhyung Kim <namh...@kernel.org>
Acked-by: Jiri Olsa <jo...@redhat.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Rodrigo Campos <rod...@sdfg.com.ar>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/r/1383202576-28141-2-gi...@kernel.org
[ Fixup clash with new COMM infrastructure ]
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-annotate.c | 2 +-
tools/perf/builtin-diff.c | 3 +-
tools/perf/builtin-report.c | 16 ++++++---
tools/perf/builtin-top.c | 5 +--
tools/perf/tests/hists_link.c | 6 ++--
tools/perf/util/hist.c | 75 ++++---------------------------------------
tools/perf/util/hist.h | 18 ++---------
7 files changed, 30 insertions(+), 95 deletions(-)

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 6c5ae57831f6..4087ab19823c 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -65,7 +65,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel,
return 0;
}

- he = __hists__add_entry(&evsel->hists, al, NULL, 1, 1, 0);
+ he = __hists__add_entry(&evsel->hists, al, NULL, NULL, NULL, 1, 1, 0);
if (he == NULL)
return -ENOMEM;

diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index b605009e803f..3b67ea2444bd 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -307,7 +307,8 @@ static int hists__add_entry(struct hists *hists,
struct addr_location *al, u64 period,
u64 weight, u64 transaction)
{
- if (__hists__add_entry(hists, al, NULL, period, weight, transaction) != NULL)
+ if (__hists__add_entry(hists, al, NULL, NULL, NULL, period, weight,
+ transaction) != NULL)
return 0;
return -ENOMEM;
}
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 25f83d5d66fd..8cf8e66ba594 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -115,7 +115,8 @@ static int perf_report__add_mem_hist_entry(struct perf_tool *tool,
* and this is indirectly achieved by passing period=weight here
* and the he_stat__add_period() function.
*/
- he = __hists__add_mem_entry(&evsel->hists, al, parent, mi, cost, cost);
+ he = __hists__add_entry(&evsel->hists, al, parent, NULL, mi,
+ cost, cost, 0);
if (!he)
return -ENOMEM;

@@ -200,12 +201,16 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,

err = -ENOMEM;

+ /* overwrite the 'al' to branch-to info */
+ al->map = bi[i].to.map;
+ al->sym = bi[i].to.sym;
+ al->addr = bi[i].to.addr;
/*
* The report shows the percentage of total branches captured
* and not events sampled. Thus we use a pseudo period of 1.
*/
- he = __hists__add_branch_entry(&evsel->hists, al, parent,
- &bi[i], 1, 1);
+ he = __hists__add_entry(&evsel->hists, al, parent, &bi[i], NULL,
+ 1, 1, 0);
if (he) {
struct annotation *notes;
bx = he->branch_info;
@@ -266,8 +271,9 @@ static int perf_evsel__add_hist_entry(struct perf_tool *tool,
return err;
}

- he = __hists__add_entry(&evsel->hists, al, parent, sample->period,
- sample->weight, sample->transaction);
+ he = __hists__add_entry(&evsel->hists, al, parent, NULL, NULL,
+ sample->period, sample->weight,
+ sample->transaction);
if (he == NULL)
return -ENOMEM;

diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index ca5ca37980fb..21897f0ffcd3 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -246,8 +246,9 @@ static struct hist_entry *perf_evsel__add_hist_entry(struct perf_evsel *evsel,
struct hist_entry *he;

pthread_mutex_lock(&evsel->hists.lock);
- he = __hists__add_entry(&evsel->hists, al, NULL, sample->period,
- sample->weight, sample->transaction);
+ he = __hists__add_entry(&evsel->hists, al, NULL, NULL, NULL,
+ sample->period, sample->weight,
+ sample->transaction);
pthread_mutex_unlock(&evsel->hists.lock);
if (he == NULL)
return NULL;
diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c
index 6c337e653540..173bf42cc03e 100644
--- a/tools/perf/tests/hists_link.c
+++ b/tools/perf/tests/hists_link.c
@@ -223,7 +223,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
goto out;

he = __hists__add_entry(&evsel->hists, &al, NULL,
- 1, 1, 0);
+ NULL, NULL, 1, 1, 0);
if (he == NULL)
goto out;

@@ -245,8 +245,8 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
&sample) < 0)
goto out;

- he = __hists__add_entry(&evsel->hists, &al, NULL, 1, 1,
- 0);
+ he = __hists__add_entry(&evsel->hists, &al, NULL,
+ NULL, NULL, 1, 1, 0);
if (he == NULL)
goto out;

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 30793f98c8bb..822903eaa201 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -407,73 +407,12 @@ out:
return he;
}

-struct hist_entry *__hists__add_mem_entry(struct hists *hists,
- struct addr_location *al,
- struct symbol *sym_parent,
- struct mem_info *mi,
- u64 period,
- u64 weight)
-{
- struct hist_entry entry = {
- .thread = al->thread,
- .comm = thread__comm(al->thread),
- .ms = {
- .map = al->map,
- .sym = al->sym,
- },
- .stat = {
- .period = period,
- .weight = weight,
- .nr_events = 1,
- },
- .cpu = al->cpu,
- .ip = al->addr,
- .level = al->level,
- .parent = sym_parent,
- .filtered = symbol__parent_filter(sym_parent),
- .hists = hists,
- .mem_info = mi,
- .branch_info = NULL,
- };
- return add_hist_entry(hists, &entry, al, period, weight);
-}
-
-struct hist_entry *__hists__add_branch_entry(struct hists *hists,
- struct addr_location *al,
- struct symbol *sym_parent,
- struct branch_info *bi,
- u64 period,
- u64 weight)
-{
- struct hist_entry entry = {
- .thread = al->thread,
- .comm = thread__comm(al->thread),
- .ms = {
- .map = bi->to.map,
- .sym = bi->to.sym,
- },
- .cpu = al->cpu,
- .ip = bi->to.addr,
- .level = al->level,
- .stat = {
- .period = period,
- .nr_events = 1,
- .weight = weight,
- },
- .parent = sym_parent,
- .filtered = symbol__parent_filter(sym_parent),
- .branch_info = bi,
- .hists = hists,
- .mem_info = NULL,
- };
-
- return add_hist_entry(hists, &entry, al, period, weight);
-}
-
struct hist_entry *__hists__add_entry(struct hists *hists,
struct addr_location *al,
- struct symbol *sym_parent, u64 period,
- u64 weight, u64 transaction)
+ struct symbol *sym_parent,
+ struct branch_info *bi,
+ struct mem_info *mi,
+ u64 period, u64 weight, u64 transaction)
{
struct hist_entry entry = {
.thread = al->thread,
@@ -486,15 +425,15 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
.ip = al->addr,
.level = al->level,
.stat = {
- .period = period,
.nr_events = 1,
+ .period = period,
.weight = weight,
},
.parent = sym_parent,
.filtered = symbol__parent_filter(sym_parent),
.hists = hists,
- .branch_info = NULL,
- .mem_info = NULL,
+ .branch_info = bi,
+ .mem_info = mi,
.transaction = transaction,
};

diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 9d2d022cdb79..307f1c742563 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -86,7 +86,9 @@ struct hists {

struct hist_entry *__hists__add_entry(struct hists *self,
struct addr_location *al,
- struct symbol *parent, u64 period,
+ struct symbol *parent,
+ struct branch_info *bi,
+ struct mem_info *mi, u64 period,
u64 weight, u64 transaction);
int64_t hist_entry__cmp(struct hist_entry *left, struct hist_entry *right);
int64_t hist_entry__collapse(struct hist_entry *left, struct hist_entry *right);
@@ -95,20 +97,6 @@ int hist_entry__sort_snprintf(struct hist_entry *self, char *bf, size_t size,
struct hists *hists);
void hist_entry__free(struct hist_entry *);

-struct hist_entry *__hists__add_branch_entry(struct hists *self,
- struct addr_location *al,
- struct symbol *sym_parent,
- struct branch_info *bi,
- u64 period,
- u64 weight);
-
-struct hist_entry *__hists__add_mem_entry(struct hists *self,
- struct addr_location *al,
- struct symbol *sym_parent,
- struct mem_info *mi,
- u64 period,
- u64 weight);
-
void hists__output_resort(struct hists *self);
void hists__collapse_resort(struct hists *self, struct ui_progress *prog);

--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 5, 2013, 3:20:03 PM11/5/13
to
From: David Ahern <dsa...@gmail.com>

Currently 'perf list' is not very helpful if you forget the syntax:

$ perf list -h

List of pre-defined events (to be used in -e):

After:
$ perf list -h

usage: perf list [hw|sw|cache|tracepoint|pmu|event_glob]

Signed-off-by: David Ahern <dsa...@gmail.com>
Acked-by: Ingo Molnar <mi...@kernel.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namh...@kernel.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/r/527133AD...@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-list.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
index 45000e7d4398..011195e38f21 100644
--- a/tools/perf/builtin-list.c
+++ b/tools/perf/builtin-list.c
@@ -14,20 +14,31 @@
#include "util/parse-events.h"
#include "util/cache.h"
#include "util/pmu.h"
+#include "util/parse-options.h"

int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
{
int i;
+ const struct option list_options[] = {
+ OPT_END()
+ };
+ const char * const list_usage[] = {
+ "perf list [hw|sw|cache|tracepoint|pmu|event_glob]",
+ NULL
+ };
+
+ argc = parse_options(argc, argv, list_options, list_usage,
+ PARSE_OPT_STOP_AT_NON_OPTION);

setup_pager();

- if (argc == 1) {
+ if (argc == 0) {
print_events(NULL, false);
return 0;
}

- for (i = 1; i < argc; ++i) {
- if (i > 2)
+ for (i = 0; i < argc; ++i) {
+ if (i)
putchar('\n');
if (strncmp(argv[i], "tracepoint", 10) == 0)
print_tracepoint_events(NULL, NULL, false);
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 5, 2013, 3:20:03 PM11/5/13
to
From: Jiri Olsa <jo...@redhat.com>

Adding procfs support into fs class.

The interface function:
const char *procfs__mountpoint(void);

provides existing mountpoint path for procfs.

Signed-off-by: Jiri Olsa <jo...@redhat.com>
Cc: Adrian Hunter <adrian...@intel.com>
Cc: Corey Ashford <cjas...@linux.vnet.ibm.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@elte.hu>
Cc: Namhyung Kim <namh...@kernel.org>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Link: http://lkml.kernel.org/r/1383660887-1734-3-g...@redhat.com
[ Fixup namespace ]
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/fs.c | 16 ++++++++++++++--
tools/perf/util/fs.h | 1 +
tools/perf/util/include/linux/magic.h | 4 ++++
3 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/fs.c b/tools/perf/util/fs.c
index 77bac4e4c115..f5be1f26e724 100644
--- a/tools/perf/util/fs.c
+++ b/tools/perf/util/fs.c
@@ -9,6 +9,11 @@ static const char * const sysfs__fs_known_mountpoints[] = {
0,
};

+static const char * const procfs__known_mountpoints[] = {
+ "/proc",
+ 0,
+};
+
struct fs {
const char *name;
const char * const *mounts;
@@ -18,7 +23,8 @@ struct fs {
};

enum {
- FS__SYSFS = 0,
+ FS__SYSFS = 0,
+ FS__PROCFS = 1,
};

static struct fs fs__entries[] = {
@@ -27,6 +33,11 @@ static struct fs fs__entries[] = {
.mounts = sysfs__fs_known_mountpoints,
.magic = SYSFS_MAGIC,
},
+ [FS__PROCFS] = {
+ .name = "proc",
+ .mounts = procfs__known_mountpoints,
+ .magic = PROC_SUPER_MAGIC,
+ },
};

static bool fs__read_mounts(struct fs *fs)
@@ -104,4 +115,5 @@ const char *name##__mountpoint(void) \
return fs__mountpoint(idx); \
}

-FS__MOUNTPOINT(sysfs, FS__SYSFS);
+FS__MOUNTPOINT(sysfs, FS__SYSFS);
+FS__MOUNTPOINT(procfs, FS__PROCFS);
diff --git a/tools/perf/util/fs.h b/tools/perf/util/fs.h
index a7561c83c33c..5e09ce1bab0e 100644
--- a/tools/perf/util/fs.h
+++ b/tools/perf/util/fs.h
@@ -2,5 +2,6 @@
#define __PERF_FS

const char *sysfs__mountpoint(void);
+const char *procfs__mountpoint(void);

#endif /* __PERF_FS */
diff --git a/tools/perf/util/include/linux/magic.h b/tools/perf/util/include/linux/magic.h
index 58b64ed4da12..07d63cf3e0f6 100644
--- a/tools/perf/util/include/linux/magic.h
+++ b/tools/perf/util/include/linux/magic.h
@@ -9,4 +9,8 @@
#define SYSFS_MAGIC 0x62656572
#endif

+#ifndef PROC_SUPER_MAGIC
+#define PROC_SUPER_MAGIC 0x9fa0
+#endif
+
#endif
--
1.8.1.4

Rodrigo Campos

unread,
Nov 5, 2013, 5:00:02 PM11/5/13
to
On Tue, Nov 05, 2013 at 05:09:52PM -0300, Arnaldo Carvalho de Melo wrote:
> @@ -486,15 +425,15 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
> .ip = al->addr,
> .level = al->level,
> .stat = {
> - .period = period,
> .nr_events = 1,
> + .period = period,
> .weight = weight,
> },

Isn't this seems unrelated and unneeded ?

The "period" field is before the "nr_events" field in the struct, so maybe is
more clear to leave it as it was ? The actual relative order (it has some more
fields) in the struct is: period, weigth, nr_events. Might be better if they
match that order here ? Although not sure since we are using the fields with
name and is clear enough.





Thanks a lot,
Rodrigo

Ingo Molnar

unread,
Nov 6, 2013, 12:40:02 AM11/6/13
to

* Arnaldo Carvalho de Melo <ac...@infradead.org> wrote:

Pulled, thanks Arnaldo!

Ingo

Namhyung Kim

unread,
Nov 6, 2013, 3:20:02 AM11/6/13
to
Hi Rodrigo,

On Tue, 5 Nov 2013 21:52:43 +0000, Rodrigo Campos wrote:
> On Tue, Nov 05, 2013 at 05:09:52PM -0300, Arnaldo Carvalho de Melo wrote:
>> @@ -486,15 +425,15 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
>> .ip = al->addr,
>> .level = al->level,
>> .stat = {
>> - .period = period,
>> .nr_events = 1,
>> + .period = period,
>> .weight = weight,
>> },
>
> Isn't this seems unrelated and unneeded ?
>
> The "period" field is before the "nr_events" field in the struct, so maybe is
> more clear to leave it as it was ? The actual relative order (it has some more
> fields) in the struct is: period, weigth, nr_events. Might be better if they
> match that order here ? Although not sure since we are using the fields with
> name and is clear enough.

Yes, it just a small unrelated cosmetic change. I don't think the order
matters much - it just makes my eyes a bit more comfortable. :)

IOW, I changed it since _add_branch_entry() and _add_mem_entry() do it
slightly different order. So I decided to clean it up and putting
nr_events at first looked reasonable to me.

Thanks,
Namhyung

Rodrigo Campos

unread,
Nov 6, 2013, 3:30:02 AM11/6/13
to
On Wed, Nov 06, 2013 at 05:16:04PM +0900, Namhyung Kim wrote:
> Hi Rodrigo,
>
> On Tue, 5 Nov 2013 21:52:43 +0000, Rodrigo Campos wrote:
> > On Tue, Nov 05, 2013 at 05:09:52PM -0300, Arnaldo Carvalho de Melo wrote:
> >> @@ -486,15 +425,15 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
> >> .ip = al->addr,
> >> .level = al->level,
> >> .stat = {
> >> - .period = period,
> >> .nr_events = 1,
> >> + .period = period,
> >> .weight = weight,
> >> },
> >
> > Isn't this seems unrelated and unneeded ?
> >
> > The "period" field is before the "nr_events" field in the struct, so maybe is
> > more clear to leave it as it was ? The actual relative order (it has some more
> > fields) in the struct is: period, weigth, nr_events. Might be better if they
> > match that order here ? Although not sure since we are using the fields with
> > name and is clear enough.
>
> Yes, it just a small unrelated cosmetic change. I don't think the order
> matters much - it just makes my eyes a bit more comfortable. :)
>
> IOW, I changed it since _add_branch_entry() and _add_mem_entry() do it
> slightly different order. So I decided to clean it up and putting
> nr_events at first looked reasonable to me.

Great, sounds reasonable to me too :)




Thangs again,
Rodrigo

Arnaldo Carvalho de Melo

unread,
Nov 6, 2013, 8:50:01 AM11/6/13
to
Em Tue, Nov 05, 2013 at 09:52:43PM +0000, Rodrigo Campos escreveu:
> On Tue, Nov 05, 2013 at 05:09:52PM -0300, Arnaldo Carvalho de Melo wrote:
> > @@ -486,15 +425,15 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
> > .stat = {
> > - .period = period,
> > .nr_events = 1,
> > + .period = period,
> > .weight = weight,
> > },

> Isn't this seems unrelated and unneeded ?

> The "period" field is before the "nr_events" field in the struct, so maybe is
> more clear to leave it as it was ? The actual relative order (it has some more
> fields) in the struct is: period, weigth, nr_events. Might be better if they
> match that order here ? Although not sure since we are using the fields with
> name and is clear enough.

Yeah, this shouldn't be there, I thought about fixing this up to reduce
the patch size, but ended up being lenient.

Namhyung, please avoid such unneeded patch churn :-)

- Arnaldo

Namhyung Kim

unread,
Nov 7, 2013, 1:50:02 AM11/7/13
to
Hi Arnaldo,

On Wed, 6 Nov 2013 10:42:10 -0300, Arnaldo Carvalho de Melo wrote:
> Em Tue, Nov 05, 2013 at 09:52:43PM +0000, Rodrigo Campos escreveu:
>> On Tue, Nov 05, 2013 at 05:09:52PM -0300, Arnaldo Carvalho de Melo wrote:
>> > @@ -486,15 +425,15 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
>> > .stat = {
>> > - .period = period,
>> > .nr_events = 1,
>> > + .period = period,
>> > .weight = weight,
>> > },
>
>> Isn't this seems unrelated and unneeded ?
>
>> The "period" field is before the "nr_events" field in the struct, so maybe is
>> more clear to leave it as it was ? The actual relative order (it has some more
>> fields) in the struct is: period, weigth, nr_events. Might be better if they
>> match that order here ? Although not sure since we are using the fields with
>> name and is clear enough.
>
> Yeah, this shouldn't be there, I thought about fixing this up to reduce
> the patch size, but ended up being lenient.
>
> Namhyung, please avoid such unneeded patch churn :-)

Okay, I'll keep it in mind.

Thanks,
Namhyung

Arnaldo Carvalho de Melo

unread,
Nov 7, 2013, 10:10:03 AM11/7/13
to
From: Arnaldo Carvalho de Melo <ac...@ghostprotocols.net>

Hi Ingo,

Please consider pulling,

- Arnaldo

The following changes since commit 8a4d0b56b031455adcbe4a9383c3b497456fcfac:

Merge branch 'uprobes/core' of git://git.kernel.org/pub/scm/linux/kernel/git/oleg/misc into perf/core (2013-11-07 08:46:13 +0100)

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 8ce000e83848578a621d64eccdc88bd34c2fc70c:

perf tools: Remove unneeded include (2013-11-07 11:51:19 -0300)

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

. Fix version when building out of tree, as when using one of these:

$ make help | grep perf
perf-tar-src-pkg - Build perf-3.12.0.tar source tarball
perf-targz-src-pkg - Build perf-3.12.0.tar.gz source tarball
perf-tarbz2-src-pkg - Build perf-3.12.0.tar.bz2 source tarball
perf-tarxz-src-pkg - Build perf-3.12.0.tar.xz source tarball
$

from David Ahern.

. Don't relookup fields by name in each sample in 'trace'.

. 'perf record' code cleanups, from David Ahern.

. Remove unneeded include in sort.h, from Rodrigo Campos.

Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>

----------------------------------------------------------------
Arnaldo Carvalho de Melo (2):
perf evsel: Ditch evsel->handler.data field
perf trace: Don't relookup fields by name in each sample

David Ahern (4):
perf tools: Fix version when building out of tree
perf record: Refactor feature handling into a separate function
perf record: Remove advance_output function
perf record: Remove post_processing_offset variable

Rodrigo Campos (1):
perf tools: Remove unneeded include

scripts/package/Makefile | 4 +-
tools/perf/builtin-inject.c | 10 +-
tools/perf/builtin-kmem.c | 4 +-
tools/perf/builtin-lock.c | 4 +-
tools/perf/builtin-record.c | 48 ++++-----
tools/perf/builtin-sched.c | 4 +-
tools/perf/builtin-timechart.c | 4 +-
tools/perf/builtin-trace.c | 205 ++++++++++++++++++++++++++++++++++++---
tools/perf/util/PERF-VERSION-GEN | 3 +
tools/perf/util/evlist.c | 2 +-
tools/perf/util/evsel.h | 5 +-
tools/perf/util/session.c | 4 +-
tools/perf/util/sort.h | 1 -
13 files changed, 239 insertions(+), 59 deletions(-)

Ingo Molnar

unread,
Nov 7, 2013, 10:30:02 AM11/7/13
to

* Arnaldo Carvalho de Melo <ac...@infradead.org> wrote:

Pulled, thanks a lot Arnaldo!

Ingo

Arnaldo Carvalho de Melo

unread,
Nov 11, 2013, 3:30:04 PM11/11/13
to
From: Arnaldo Carvalho de Melo <ac...@ghostprotocols.net>

Hi Ingo,

Please consider pulling,

- Arnaldo

The following changes since commit caea6cf52139116e43e615d87fcbf9823e197fdf:

Merge branch 'uprobes/core' of git://git.kernel.org/pub/scm/linux/kernel/git/oleg/misc into perf/core (2013-11-11 09:44:16 +0100)

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 67c1e4a53b17894e6a24f95057cc374c4be051cb:

perf tests: Use lower sample_freq in sw clock event period test (2013-11-11 16:43:34 -0300)

----------------------------------------------------------------
perf/core improvements and fixes.

. Prevent condition that all sort keys are elided, fix from Namhyung Kim.

. Synthesize non-exec MMAP records when --data used, allowing the resolution of
data addresses to symbols (global variables, etc).

. Don't force a refresh during progress update in the TUI, greatly reducing
startup costs, fix from Patrick Palka.

. Fix sw clock event period test wrt not checking if using > max_sample_freq.

. Code cleanups by David Ahern and Adrian Hunter.

Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>

----------------------------------------------------------------
Adrian Hunter (1):
perf record: Use correct return type for write()

Arnaldo Carvalho de Melo (6):
perf evsel: Remove idx parm from constructor
perf record: Synthesize non-exec MMAP records when --data used
perf machine: Introduce synthesize_threads method out of open coded equivalent
perf machine: Simplify synthesize_threads method
perf tests: Check return of perf_evlist__open sw clock event period test
perf tests: Use lower sample_freq in sw clock event period test

David Ahern (1):
perf record: Move existing write_output into helper function

Namhyung Kim (1):
perf tools: Prevent condition that all sort keys are elided

Patrick Palka (1):
perf ui tui progress: Don't force a refresh during progress update

tools/perf/builtin-kvm.c | 14 ++-------
tools/perf/builtin-record.c | 21 ++++++-------
tools/perf/builtin-top.c | 10 ++-----
tools/perf/builtin-trace.c | 24 +++++----------
tools/perf/tests/code-reading.c | 2 +-
tools/perf/tests/evsel-tp-sched.c | 4 +--
tools/perf/tests/mmap-basic.c | 2 +-
tools/perf/tests/open-syscall-all-cpus.c | 2 +-
tools/perf/tests/open-syscall-tp-fields.c | 2 +-
tools/perf/tests/open-syscall.c | 2 +-
tools/perf/tests/sw-clock.c | 13 ++++++--
tools/perf/ui/tui/progress.c | 3 +-
tools/perf/util/event.c | 50 ++++++++++++++++++-------------
tools/perf/util/event.h | 4 +--
tools/perf/util/evlist.c | 9 +++---
tools/perf/util/evsel.c | 4 +--
tools/perf/util/evsel.h | 15 ++++++++--
tools/perf/util/header.c | 4 +--
tools/perf/util/machine.c | 12 ++++++++
tools/perf/util/machine.h | 12 ++++++++
tools/perf/util/parse-events.c | 6 ++--
tools/perf/util/sort.c | 13 ++++++++
22 files changed, 133 insertions(+), 95 deletions(-)

Arnaldo Carvalho de Melo

unread,
Nov 11, 2013, 3:30:04 PM11/11/13
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

When perf_event_attr.mmap_data is set the kernel will generate
PERF_RECORD_MMAP events when non-exec (data, SysV mem) mmaps are
created, so we need to synthesize from /proc/pid/maps for existing
threads, as we do for exec mmaps.

Right now just 'perf record' does it, but any other tool that uses
perf_event__synthesize_thread(s|map) can request it.

Reported-by: Don Zickus <dzi...@redhat.com>
Tested-by: Don Zickus <dzi...@redhat.com>
Cc: Adrian Hunter <adrian...@intel.com>
Cc: Bill Gray <bg...@redhat.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Don Zickus <dzi...@redhat.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Joe Mario <jma...@redhat.com>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Richard Fowles <rfo...@redhat.com>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/n/tip-ihwzraikx2...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-kvm.c | 4 ++--
tools/perf/builtin-record.c | 6 ++---
tools/perf/builtin-top.c | 4 ++--
tools/perf/builtin-trace.c | 4 ++--
tools/perf/tests/code-reading.c | 2 +-
tools/perf/util/event.c | 50 ++++++++++++++++++++++++-----------------
tools/perf/util/event.h | 4 ++--
7 files changed, 42 insertions(+), 32 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index cd9f92078aba..f36e8209c300 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -1550,10 +1550,10 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
perf_event__synthesize_thread_map(&kvm->tool,
kvm->evlist->threads,
perf_event__process,
- &kvm->session->machines.host);
+ &kvm->session->machines.host, false);
else
perf_event__synthesize_threads(&kvm->tool, perf_event__process,
- &kvm->session->machines.host);
+ &kvm->session->machines.host, false);


err = kvm_live_open_events(kvm);
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 15280b5e5574..afb252cf6eca 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -482,11 +482,11 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)

if (perf_target__has_task(&opts->target))
err = perf_event__synthesize_thread_map(tool, evsel_list->threads,
- process_synthesized_event,
- machine);
+ process_synthesized_event,
+ machine, opts->sample_address);
else if (perf_target__has_cpu(&opts->target))
err = perf_event__synthesize_threads(tool, process_synthesized_event,
- machine);
+ machine, opts->sample_address);
else /* command specified */
err = 0;

diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 9acca8856ccb..cc96d753db96 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -953,10 +953,10 @@ static int __cmd_top(struct perf_top *top)
if (perf_target__has_task(&opts->target))
perf_event__synthesize_thread_map(&top->tool, top->evlist->threads,
perf_event__process,
- &top->session->machines.host);
+ &top->session->machines.host, false);
else
perf_event__synthesize_threads(&top->tool, perf_event__process,
- &top->session->machines.host);
+ &top->session->machines.host, false);

ret = perf_top__start_counters(top);
if (ret)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 68943cad70d4..277c2367e0cf 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1343,10 +1343,10 @@ static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist)
if (perf_target__has_task(&trace->opts.target)) {
err = perf_event__synthesize_thread_map(&trace->tool, evlist->threads,
trace__tool_process,
- trace->host);
+ trace->host, false);
} else {
err = perf_event__synthesize_threads(&trace->tool, trace__tool_process,
- trace->host);
+ trace->host, false);
}

if (err)
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 49ccc3b2995e..6d9dc198a200 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -441,7 +441,7 @@ static int do_test_code_reading(bool try_kcore)
}

ret = perf_event__synthesize_thread_map(NULL, threads,
- perf_event__process, machine);
+ perf_event__process, machine, false);
if (ret < 0) {
pr_debug("perf_event__synthesize_thread_map failed\n");
goto out_err;
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index ec9ae1114ed4..6e3a846aed0e 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -170,7 +170,8 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
union perf_event *event,
pid_t pid, pid_t tgid,
perf_event__handler_t process,
- struct machine *machine)
+ struct machine *machine,
+ bool mmap_data)
{
char filename[PATH_MAX];
FILE *fp;
@@ -188,10 +189,6 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
}

event->header.type = PERF_RECORD_MMAP;
- /*
- * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c
- */
- event->header.misc = PERF_RECORD_MISC_USER;

while (1) {
char bf[BUFSIZ];
@@ -215,9 +212,17 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,

if (n != 5)
continue;
+ /*
+ * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c
+ */
+ event->header.misc = PERF_RECORD_MISC_USER;

- if (prot[2] != 'x')
- continue;
+ if (prot[2] != 'x') {
+ if (!mmap_data || prot[0] != 'r')
+ continue;
+
+ event->header.misc |= PERF_RECORD_MISC_MMAP_DATA;
+ }

if (!strcmp(execname, ""))
strcpy(execname, anonstr);
@@ -304,20 +309,21 @@ static int __event__synthesize_thread(union perf_event *comm_event,
pid_t pid, int full,
perf_event__handler_t process,
struct perf_tool *tool,
- struct machine *machine)
+ struct machine *machine, bool mmap_data)
{
pid_t tgid = perf_event__synthesize_comm(tool, comm_event, pid, full,
process, machine);
if (tgid == -1)
return -1;
return perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid,
- process, machine);
+ process, machine, mmap_data);
}

int perf_event__synthesize_thread_map(struct perf_tool *tool,
struct thread_map *threads,
perf_event__handler_t process,
- struct machine *machine)
+ struct machine *machine,
+ bool mmap_data)
{
union perf_event *comm_event, *mmap_event;
int err = -1, thread, j;
@@ -334,7 +340,8 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool,
for (thread = 0; thread < threads->nr; ++thread) {
if (__event__synthesize_thread(comm_event, mmap_event,
threads->map[thread], 0,
- process, tool, machine)) {
+ process, tool, machine,
+ mmap_data)) {
err = -1;
break;
}
@@ -356,10 +363,10 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool,

/* if not, generate events for it */
if (need_leader &&
- __event__synthesize_thread(comm_event,
- mmap_event,
- comm_event->comm.pid, 0,
- process, tool, machine)) {
+ __event__synthesize_thread(comm_event, mmap_event,
+ comm_event->comm.pid, 0,
+ process, tool, machine,
+ mmap_data)) {
err = -1;
break;
}
@@ -374,7 +381,7 @@ out:

int perf_event__synthesize_threads(struct perf_tool *tool,
perf_event__handler_t process,
- struct machine *machine)
+ struct machine *machine, bool mmap_data)
{
DIR *proc;
struct dirent dirent, *next;
@@ -404,7 +411,7 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
* one thread couldn't be synthesized.
*/
__event__synthesize_thread(comm_event, mmap_event, pid, 1,
- process, tool, machine);
+ process, tool, machine, mmap_data);
}

err = 0;
@@ -528,19 +535,22 @@ int perf_event__process_lost(struct perf_tool *tool __maybe_unused,

size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp)
{
- return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 "]: %s\n",
+ return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 "]: %c %s\n",
event->mmap.pid, event->mmap.tid, event->mmap.start,
- event->mmap.len, event->mmap.pgoff, event->mmap.filename);
+ event->mmap.len, event->mmap.pgoff,
+ (event->header.misc & PERF_RECORD_MISC_MMAP_DATA) ? 'r' : 'x',
+ event->mmap.filename);
}

size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp)
{
return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64
- " %02x:%02x %"PRIu64" %"PRIu64"]: %s\n",
+ " %02x:%02x %"PRIu64" %"PRIu64"]: %c %s\n",
event->mmap2.pid, event->mmap2.tid, event->mmap2.start,
event->mmap2.len, event->mmap2.pgoff, event->mmap2.maj,
event->mmap2.min, event->mmap2.ino,
event->mmap2.ino_generation,
+ (event->header.misc & PERF_RECORD_MISC_MMAP_DATA) ? 'r' : 'x',
event->mmap2.filename);
}

diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index f8d70f3003ab..30fec9901e44 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -208,10 +208,10 @@ typedef int (*perf_event__handler_t)(struct perf_tool *tool,
int perf_event__synthesize_thread_map(struct perf_tool *tool,
struct thread_map *threads,
perf_event__handler_t process,
- struct machine *machine);
+ struct machine *machine, bool mmap_data);
int perf_event__synthesize_threads(struct perf_tool *tool,
perf_event__handler_t process,
- struct machine *machine);
+ struct machine *machine, bool mmap_data);
int perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
perf_event__handler_t process,
struct machine *machine,
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 11, 2013, 3:30:03 PM11/11/13
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

Further simplifications to be done on following patch, as most tools
don't use the callback, using instead just the canned
machine__process_event one.

Cc: Adrian Hunter <adrian...@intel.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/n/tip-r1m0vuuj3c...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-kvm.c | 15 +++------------
tools/perf/builtin-record.c | 12 ++----------
tools/perf/builtin-top.c | 11 +++--------
tools/perf/builtin-trace.c | 11 ++---------
tools/perf/util/machine.c | 12 ++++++++++++
tools/perf/util/machine.h | 4 ++++
6 files changed, 26 insertions(+), 39 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index f36e8209c300..f5d2c4bccbec 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -1544,18 +1544,9 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
}
kvm->session->evlist = kvm->evlist;
perf_session__set_id_hdr_size(kvm->session);
-
-
- if (perf_target__has_task(&kvm->opts.target))
- perf_event__synthesize_thread_map(&kvm->tool,
- kvm->evlist->threads,
- perf_event__process,
- &kvm->session->machines.host, false);
- else
- perf_event__synthesize_threads(&kvm->tool, perf_event__process,
- &kvm->session->machines.host, false);
-
-
+ machine__synthesize_threads(&kvm->session->machines.host, &kvm->tool,
+ &kvm->opts.target, kvm->evlist->threads,
+ perf_event__process, false);
err = kvm_live_open_events(kvm);
if (err)
goto out;
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index afb252cf6eca..41d1f37f5348 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -480,16 +480,8 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
perf_event__synthesize_guest_os, tool);
}

- if (perf_target__has_task(&opts->target))
- err = perf_event__synthesize_thread_map(tool, evsel_list->threads,
- process_synthesized_event,
- machine, opts->sample_address);
- else if (perf_target__has_cpu(&opts->target))
- err = perf_event__synthesize_threads(tool, process_synthesized_event,
- machine, opts->sample_address);
- else /* command specified */
- err = 0;
-
+ err = machine__synthesize_threads(machine, tool, &opts->target, evsel_list->threads,
+ process_synthesized_event, opts->sample_address);
if (err != 0)
goto out_delete_session;

diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index cc96d753db96..c3a936ef7688 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -950,14 +950,9 @@ static int __cmd_top(struct perf_top *top)
if (ret)
goto out_delete;

- if (perf_target__has_task(&opts->target))
- perf_event__synthesize_thread_map(&top->tool, top->evlist->threads,
- perf_event__process,
- &top->session->machines.host, false);
- else
- perf_event__synthesize_threads(&top->tool, perf_event__process,
- &top->session->machines.host, false);
-
+ machine__synthesize_threads(&top->session->machines.host, &top->tool,
+ &opts->target, top->evlist->threads,
+ perf_event__process, false);
ret = perf_top__start_counters(top);
if (ret)
goto out_delete;
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 277c2367e0cf..7690324824db 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1340,15 +1340,8 @@ static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist)
if (trace->host == NULL)
return -ENOMEM;

- if (perf_target__has_task(&trace->opts.target)) {
- err = perf_event__synthesize_thread_map(&trace->tool, evlist->threads,
- trace__tool_process,
- trace->host, false);
- } else {
- err = perf_event__synthesize_threads(&trace->tool, trace__tool_process,
- trace->host, false);
- }
-
+ err = machine__synthesize_threads(trace->host, &trace->tool, &trace->opts.target,
+ evlist->threads, trace__tool_process, false);
if (err)
symbol__exit();

diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index ce034c183a7e..9f2c61d5a9ed 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1394,3 +1394,15 @@ int machine__for_each_thread(struct machine *machine,
}
return rc;
}
+
+int machine__synthesize_threads(struct machine *machine, struct perf_tool *tool,
+ struct perf_target *target, struct thread_map *threads,
+ perf_event__handler_t process, bool data_mmap)
+{
+ if (perf_target__has_task(target))
+ return perf_event__synthesize_thread_map(tool, threads, process, machine, data_mmap);
+ else if (perf_target__has_cpu(target))
+ return perf_event__synthesize_threads(tool, process, machine, data_mmap);
+ /* command specified */
+ return 0;
+}
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index 2389ba81fafe..14a89d2aecaf 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -4,6 +4,7 @@
#include <sys/types.h>
#include <linux/rbtree.h>
#include "map.h"
+#include "event.h"

struct addr_location;
struct branch_stack;
@@ -178,4 +179,7 @@ int machine__for_each_thread(struct machine *machine,
int (*fn)(struct thread *thread, void *p),
void *priv);

+int machine__synthesize_threads(struct machine *machine, struct perf_tool *tool,
+ struct perf_target *target, struct thread_map *threads,
+ perf_event__handler_t process, bool data_mmap);
#endif /* __PERF_MACHINE_H */
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Nov 11, 2013, 3:30:04 PM11/11/13
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

We were using it at 10 kHz, which doesn't work in machines where somehow
the max freq was auto reduced by the kernel:

[root@ssdandy ~]# perf test 19
19: Test software clock events have valid period values : FAILED!
[root@ssdandy ~]# perf test -v 19
19: Test software clock events have valid period values :
--- start ---
Couldn't open evlist: Invalid argument
---- end ----
Test software clock events have valid period values: FAILED!
[root@ssdandy ~]#

[root@ssdandy ~]# cat /proc/sys/kernel/perf_event_max_sample_rate
7000

Reducing it to 500 Hz should be good enough for this test and also
shouldn't affect what it is testing.

But warn the user if it fails, informing the knob and the freq tried.

Cc: Adrian Hunter <adrian...@intel.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: Namhyung Kim <namh...@kernel.org>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/n/tip-548rhj1uo6...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/tests/sw-clock.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c
index ed777728dfe7..93a7139ff5f7 100644
--- a/tools/perf/tests/sw-clock.c
+++ b/tools/perf/tests/sw-clock.c
@@ -34,7 +34,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
.freq = 1,
};

- attr.sample_freq = 10000;
+ attr.sample_freq = 500;

evlist = perf_evlist__new();
if (evlist == NULL) {
@@ -58,8 +58,11 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
}

if (perf_evlist__open(evlist)) {
+ const char *knob = "/proc/sys/kernel/perf_event_max_sample_rate";
+
err = -errno;
- pr_debug("Couldn't open evlist: %s\n", strerror(errno));
+ pr_debug("Couldn't open evlist: %s\nHint: check %s, using %" PRIu64 " in this test.\n",
+ strerror(errno), knob, (u64)attr.sample_freq);
goto out_delete_maps;
}

--
1.8.1.4

David Ahern

unread,
Nov 11, 2013, 3:40:02 PM11/11/13
to
[Added Vince]

On 11/11/13, 1:22 PM, Arnaldo Carvalho de Melo wrote:
> When perf_event_attr.mmap_data is set the kernel will generate
> PERF_RECORD_MMAP events when non-exec (data, SysV mem) mmaps are
> created, so we need to synthesize from /proc/pid/maps for existing
> threads

Seems like that should be documented in the man pages:

[dsa@MacBook perf]$ egrep -r mmap_data Documentation/
[dsa@MacBook perf]$

Vince: where are you keeping the man page you are putting together?

David

David Ahern

unread,
Nov 11, 2013, 3:50:01 PM11/11/13
to
On 11/11/13, 1:22 PM, Arnaldo Carvalho de Melo wrote:

> @@ -58,8 +58,11 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
> }
>
> if (perf_evlist__open(evlist)) {
> + const char *knob = "/proc/sys/kernel/perf_event_max_sample_rate";
> +
> err = -errno;
> - pr_debug("Couldn't open evlist: %s\n", strerror(errno));
> + pr_debug("Couldn't open evlist: %s\nHint: check %s, using %" PRIu64 " in this test.\n",
> + strerror(errno), knob, (u64)attr.sample_freq);
> goto out_delete_maps;
> }

Jiri had a patch to drop the sample rate to max. Perhaps re-use that here?

David Ahern

unread,
Nov 11, 2013, 3:50:01 PM11/11/13
to
On 11/11/13, 1:22 PM, Arnaldo Carvalho de Melo wrote:
> + if (perf_target__has_task(target))
> + return perf_event__synthesize_thread_map(tool, threads, process, machine, data_mmap);
> + else if (perf_target__has_cpu(target))
> + return perf_event__synthesize_threads(tool, process, machine, data_mmap);


Getting kind of long on the line lengths...

Ingo Molnar

unread,
Nov 11, 2013, 4:00:01 PM11/11/13
to

* David Ahern <dsa...@gmail.com> wrote:

> On 11/11/13, 1:22 PM, Arnaldo Carvalho de Melo wrote:
> >+ if (perf_target__has_task(target))
> >+ return perf_event__synthesize_thread_map(tool, threads, process, machine, data_mmap);
> >+ else if (perf_target__has_cpu(target))
> >+ return perf_event__synthesize_threads(tool, process, machine, data_mmap);
>
>
> Getting kind of long on the line lengths...

Maybe we could start losing most of the perf_ prefixes - it's all about
perf here, so it does not really add much information, does it?

that would turn it into:

if (target__has_task(target))
return event__synthesize_thread_map(tool, threads, process, machine, data_mmap);
else if (target__has_cpu(target))
return event__synthesize_threads(tool, process, machine, data_mmap);

Another trick would be to combine (tool, machine) into a single helper
struct (struct context *ctx?), if that is mostly a constant combination
describing tool environment, which gets passed deep inside the guts of
functions.

Thanks,

Ingo

Vince Weaver

unread,
Nov 11, 2013, 4:00:02 PM11/11/13
to
On Mon, 11 Nov 2013, David Ahern wrote:

> [Added Vince]
>
> On 11/11/13, 1:22 PM, Arnaldo Carvalho de Melo wrote:
> > When perf_event_attr.mmap_data is set the kernel will generate
> > PERF_RECORD_MMAP events when non-exec (data, SysV mem) mmaps are
> > created, so we need to synthesize from /proc/pid/maps for existing
> > threads
>
> Seems like that should be documented in the man pages:
>
> [dsa@MacBook perf]$ egrep -r mmap_data Documentation/
> [dsa@MacBook perf]$
>
> Vince: where are you keeping the man page you are putting together?

It's in the official linux manpage git tree (perf_event_open.2) and
has been included in the last few manpage releases.

There is a blurb on PERF_RECORD_MMAP, though it definitely could use a
bit more elaboration.

Vince

Adrian Hunter

unread,
Nov 12, 2013, 2:10:01 AM11/12/13
to
On 11/11/13 22:22, Arnaldo Carvalho de Melo wrote:
> From: Arnaldo Carvalho de Melo <ac...@redhat.com>
>
> We were using it at 10 kHz, which doesn't work in machines where somehow
> the max freq was auto reduced by the kernel:
>
> [root@ssdandy ~]# perf test 19
> 19: Test software clock events have valid period values : FAILED!
> [root@ssdandy ~]# perf test -v 19
> 19: Test software clock events have valid period values :
> --- start ---
> Couldn't open evlist: Invalid argument
> ---- end ----
> Test software clock events have valid period values: FAILED!
> [root@ssdandy ~]#
>
> [root@ssdandy ~]# cat /proc/sys/kernel/perf_event_max_sample_rate
> 7000
>
> Reducing it to 500 Hz should be good enough for this test and also
> shouldn't affect what it is testing.
>
> But warn the user if it fails, informing the knob and the freq tried.

Doesn't work for me:

./perf test -v 19
19: Test software clock events have valid period values :
--- start ---
mmap size 528384B
mmap size 528384B
All (0) samples have period value of 1!
---- end ----
Test software clock events have valid period values: FAILED!

But this fixes it:

diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c
index 93a7139..6664a7c 100644
--- a/tools/perf/tests/sw-clock.c
+++ b/tools/perf/tests/sw-clock.c
@@ -9,7 +9,7 @@
#include "util/cpumap.h"
#include "util/thread_map.h"

-#define NR_LOOPS 1000000
+#define NR_LOOPS 10000000

/*
* This test will open software clock events (cpu-clock, task-clock)

Namhyung Kim

unread,
Nov 12, 2013, 3:50:02 AM11/12/13
to
Hi Adrian,
Or else, why not using the max_sample_rate as the freq value?

Thanks,
Namhyung

Arnaldo Carvalho de Melo

unread,
Nov 12, 2013, 6:40:02 AM11/12/13
to
Em Mon, Nov 11, 2013 at 09:50:45PM +0100, Ingo Molnar escreveu:
> * David Ahern <dsa...@gmail.com> wrote:

> > On 11/11/13, 1:22 PM, Arnaldo Carvalho de Melo wrote:
> > >+ if (perf_target__has_task(target))
> > >+ return perf_event__synthesize_thread_map(tool, threads, process, machine, data_mmap);
> > >+ else if (perf_target__has_cpu(target))
> > >+ return perf_event__synthesize_threads(tool, process, machine, data_mmap);

> > Getting kind of long on the line lengths...

> Maybe we could start losing most of the perf_ prefixes - it's all about
> perf here, so it does not really add much information, does it?

In some cases that is ok, that is why I didn't call it 'perf_machine',
just 'machine', in others, like 'perf_event', I thought 'event' would be
too general when somebody tries to use this code together with other
libraries.

In some cases, like 'perf_target', probably its ok to move to
'target', perhaps this is ok for this problem domain, i.e.
monitoring/profiling/etc.

> that would turn it into:
>
> if (target__has_task(target))
> return event__synthesize_thread_map(tool, threads, process, machine, data_mmap);
> else if (target__has_cpu(target))
> return event__synthesize_threads(tool, process, machine, data_mmap);
>
> Another trick would be to combine (tool, machine) into a single helper
> struct (struct context *ctx?), if that is mostly a constant combination
> describing tool environment, which gets passed deep inside the guts of
> functions.


Reducing the function signature is something that may help as well, and
was done in this series with machine__synthesize_threads, that avoids
passing the tool and process arguments, since they were constanty
anyway.

What you propose is used in some cases, like with symbol_conf, will try
to work in that direction as time goes by, i.e. doing some refactoring
work of this kind every once in a while, not to disrupt too much the
patch flow.

- Arnaldo

Arnaldo Carvalho de Melo

unread,
Nov 12, 2013, 7:00:02 AM11/12/13
to
Sure, that probably is better, I was just trying the lazy way, as doing
what you suggest entails reworking what Jiri did, since the routine that
reads that max_sample_rate is not exported, needs some massaging, etc.

Using a low enough max_sample_rate and warning the user that anyway
would be better knowing that the sample rate lowered so dramatically
looked quicker/lazy enough ;-)

- Arnaldo

Ingo Molnar

unread,
Nov 12, 2013, 7:50:01 AM11/12/13
to

* Arnaldo Carvalho de Melo <ac...@ghostprotocols.net> wrote:

> Em Mon, Nov 11, 2013 at 09:50:45PM +0100, Ingo Molnar escreveu:
> > * David Ahern <dsa...@gmail.com> wrote:
>
> > > On 11/11/13, 1:22 PM, Arnaldo Carvalho de Melo wrote:
> > > >+ if (perf_target__has_task(target))
> > > >+ return perf_event__synthesize_thread_map(tool, threads, process, machine, data_mmap);
> > > >+ else if (perf_target__has_cpu(target))
> > > >+ return perf_event__synthesize_threads(tool, process, machine, data_mmap);
>
> > > Getting kind of long on the line lengths...
>
> > Maybe we could start losing most of the perf_ prefixes - it's all about
> > perf here, so it does not really add much information, does it?
>
> In some cases that is ok, that is why I didn't call it 'perf_machine',
> just 'machine', in others, like 'perf_event', I thought 'event' would be
> too general when somebody tries to use this code together with other
> libraries.

I think 'event' as a variable name is generally unused by libraries,
exactly because so much random code uses it.

The only unfortunate C library land grabs I've run into are 'time' [by
glibc] and 'y0' [by libm].

What I was suggesting here was more like an event__*() namespace - there
shouldn't be any collision with public functions from libraries, public
functions are generally either well established, or prefixed with a
library name.

These are perf-internal function names, so using event__*() should be fine
- assuming there are no counter arguments.

Thanks,

Ingo

Arnaldo Carvalho de Melo

unread,
Nov 12, 2013, 9:50:02 AM11/12/13
to
Lower frequency, need to generate more noise, ugh. Adding that, but I
think this test needs to be reworked, Namhyung?

- Arnaldo

Arnaldo Carvalho de Melo

unread,
Nov 12, 2013, 3:50:02 PM11/12/13
to
From: Arnaldo Carvalho de Melo <ac...@ghostprotocols.net>

Hi Ingo,

Please consider pulling,

- Arnaldo

The following changes since commit 67c1e4a53b17894e6a24f95057cc374c4be051cb:

perf tests: Use lower sample_freq in sw clock event period test (2013-11-11 16:43:34 -0300)

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 0497a9ebaf7ae4d573497b3e053ad4c3d5c9921d:

tools lib traceevent: Add direct access to dynamic arrays (2013-11-12 17:23:44 -0300)

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

. Add summary only option to 'perf trace', suppressing the decoding of
events, from David Ahern

. 'perf trace --summary' formatting simplifications, from Pekka Emberg.

. Beautify fifth argument of mmap() as fd, in 'perf trace', from Namhyung Kim.

. Fix segfault on perf trace -i perf.data, from Namhyung Kim.

. Fix segfault with --no-mmap-pages, from David Ahern.

. Round mmap pages to power 2, from David Ahern.

. Add direct access to dynamic arrays in libtraceevent, from Steven Rostedt.

. Handle throttle events in 'object code reading' test, fix from Adrian Hunter.

Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>

----------------------------------------------------------------
Adrian Hunter (2):
perf tests: Compensate lower sample freq with longer test loop
perf tests: Handle throttle events in 'object code reading' test

Arnaldo Carvalho de Melo (1):
perf target: Shorten perf_target__ to target__

David Ahern (4):
perf trace: Add summary only option
perf record: Fix segfault with --no-mmap-pages
perf evlist: Round mmap pages to power 2 - v2
perf evlist: Refactor mmap_pages parsing

Namhyung Kim (3):
perf trace: Beautify fifth argument of mmap() as fd
perf trace: Separate tp syscall field caching into init routine to be reused
perf trace: Fix segfault on perf trace -i perf.data

Pekka Enberg (2):
perf trace: Change syscall summary duration order
perf trace: Simplify '--summary' output

Steven Rostedt (1):
tools lib traceevent: Add direct access to dynamic arrays

tools/lib/traceevent/event-parse.c | 13 ++++
tools/perf/Documentation/perf-trace.txt | 10 ++-
tools/perf/builtin-kvm.c | 6 +-
tools/perf/builtin-record.c | 14 ++--
tools/perf/builtin-stat.c | 21 +++---
tools/perf/builtin-top.c | 14 ++--
tools/perf/builtin-trace.c | 121 +++++++++++++++++++-------------
tools/perf/perf.h | 2 +-
tools/perf/tests/code-reading.c | 15 +++-
tools/perf/tests/sw-clock.c | 2 +-
tools/perf/tests/task-exit.c | 2 +-
tools/perf/util/evlist.c | 64 ++++++++++-------
tools/perf/util/evlist.h | 5 +-
tools/perf/util/evsel.c | 9 ++-
tools/perf/util/evsel.h | 3 +-
tools/perf/util/machine.c | 6 +-
tools/perf/util/machine.h | 4 +-
tools/perf/util/target.c | 54 +++++++-------
tools/perf/util/target.h | 44 ++++++------
tools/perf/util/top.c | 2 +-
20 files changed, 236 insertions(+), 175 deletions(-)

Ingo Molnar

unread,
Nov 12, 2013, 4:00:02 PM11/12/13
to
Pulled, including yesterday's bits as well - thanks a lot Arnaldo!

Ingo

tip-bot for Arnaldo Carvalho de Melo

unread,
Nov 12, 2013, 5:00:02 PM11/12/13
to
Commit-ID: 67c1e4a53b17894e6a24f95057cc374c4be051cb
Gitweb: http://git.kernel.org/tip/67c1e4a53b17894e6a24f95057cc374c4be051cb
Author: Arnaldo Carvalho de Melo <ac...@redhat.com>
AuthorDate: Mon, 11 Nov 2013 16:33:18 -0300
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Mon, 11 Nov 2013 16:43:34 -0300

perf tests: Use lower sample_freq in sw clock event period test

We were using it at 10 kHz, which doesn't work in machines where somehow
the max freq was auto reduced by the kernel:

[root@ssdandy ~]# perf test 19
19: Test software clock events have valid period values : FAILED!
[root@ssdandy ~]# perf test -v 19
19: Test software clock events have valid period values :
--- start ---
Couldn't open evlist: Invalid argument
---- end ----
Test software clock events have valid period values: FAILED!
[root@ssdandy ~]#

[root@ssdandy ~]# cat /proc/sys/kernel/perf_event_max_sample_rate
7000

Reducing it to 500 Hz should be good enough for this test and also
shouldn't affect what it is testing.

But warn the user if it fails, informing the knob and the freq tried.

Cc: Adrian Hunter <adrian...@intel.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: Namhyung Kim <namh...@kernel.org>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/n/tip-548rhj1uo6...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/tests/sw-clock.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c
index ed77772..93a7139 100644
--- a/tools/perf/tests/sw-clock.c
+++ b/tools/perf/tests/sw-clock.c
@@ -34,7 +34,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
.freq = 1,
};

- attr.sample_freq = 10000;
+ attr.sample_freq = 500;

evlist = perf_evlist__new();
if (evlist == NULL) {
@@ -58,8 +58,11 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
}

if (perf_evlist__open(evlist)) {
+ const char *knob = "/proc/sys/kernel/perf_event_max_sample_rate";
+
err = -errno;
- pr_debug("Couldn't open evlist: %s\n", strerror(errno));
+ pr_debug("Couldn't open evlist: %s\nHint: check %s, using %" PRIu64 " in this test.\n",
+ strerror(errno), knob, (u64)attr.sample_freq);
goto out_delete_maps;
}

tip-bot for Arnaldo Carvalho de Melo

unread,
Nov 12, 2013, 5:00:03 PM11/12/13
to
Commit-ID: 58d925dcede9e8765876707a33a3406011fe1c11
Gitweb: http://git.kernel.org/tip/58d925dcede9e8765876707a33a3406011fe1c11
Author: Arnaldo Carvalho de Melo <ac...@redhat.com>
AuthorDate: Mon, 11 Nov 2013 11:28:02 -0300
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Mon, 11 Nov 2013 15:56:39 -0300

perf machine: Introduce synthesize_threads method out of open coded equivalent

Further simplifications to be done on following patch, as most tools
don't use the callback, using instead just the canned
machine__process_event one.

Cc: Adrian Hunter <adrian...@intel.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/n/tip-r1m0vuuj3c...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-kvm.c | 15 +++------------
tools/perf/builtin-record.c | 12 ++----------
tools/perf/builtin-top.c | 11 +++--------
tools/perf/builtin-trace.c | 11 ++---------
tools/perf/util/machine.c | 12 ++++++++++++
tools/perf/util/machine.h | 4 ++++
6 files changed, 26 insertions(+), 39 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index f36e820..f5d2c4b 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -1544,18 +1544,9 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
}
kvm->session->evlist = kvm->evlist;
perf_session__set_id_hdr_size(kvm->session);
-
-
- if (perf_target__has_task(&kvm->opts.target))
- perf_event__synthesize_thread_map(&kvm->tool,
- kvm->evlist->threads,
- perf_event__process,
- &kvm->session->machines.host, false);
- else
- perf_event__synthesize_threads(&kvm->tool, perf_event__process,
- &kvm->session->machines.host, false);
-
-
+ machine__synthesize_threads(&kvm->session->machines.host, &kvm->tool,
+ &kvm->opts.target, kvm->evlist->threads,
+ perf_event__process, false);
err = kvm_live_open_events(kvm);
if (err)
goto out;
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index afb252c..41d1f37 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -480,16 +480,8 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
perf_event__synthesize_guest_os, tool);
}

- if (perf_target__has_task(&opts->target))
- err = perf_event__synthesize_thread_map(tool, evsel_list->threads,
- process_synthesized_event,
- machine, opts->sample_address);
- else if (perf_target__has_cpu(&opts->target))
- err = perf_event__synthesize_threads(tool, process_synthesized_event,
- machine, opts->sample_address);
- else /* command specified */
- err = 0;
-
+ err = machine__synthesize_threads(machine, tool, &opts->target, evsel_list->threads,
+ process_synthesized_event, opts->sample_address);
if (err != 0)
goto out_delete_session;

diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index cc96d75..c3a936e 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -950,14 +950,9 @@ static int __cmd_top(struct perf_top *top)
if (ret)
goto out_delete;

- if (perf_target__has_task(&opts->target))
- perf_event__synthesize_thread_map(&top->tool, top->evlist->threads,
- perf_event__process,
- &top->session->machines.host, false);
- else
- perf_event__synthesize_threads(&top->tool, perf_event__process,
- &top->session->machines.host, false);
-
+ machine__synthesize_threads(&top->session->machines.host, &top->tool,
+ &opts->target, top->evlist->threads,
+ perf_event__process, false);
ret = perf_top__start_counters(top);
if (ret)
goto out_delete;
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 277c236..7690324 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1340,15 +1340,8 @@ static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist)
if (trace->host == NULL)
return -ENOMEM;

- if (perf_target__has_task(&trace->opts.target)) {
- err = perf_event__synthesize_thread_map(&trace->tool, evlist->threads,
- trace__tool_process,
- trace->host, false);
- } else {
- err = perf_event__synthesize_threads(&trace->tool, trace__tool_process,
- trace->host, false);
- }
-
+ err = machine__synthesize_threads(trace->host, &trace->tool, &trace->opts.target,
+ evlist->threads, trace__tool_process, false);
if (err)
symbol__exit();

diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index ce034c1..9f2c61d 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1394,3 +1394,15 @@ int machine__for_each_thread(struct machine *machine,
}
return rc;
}
+
+int machine__synthesize_threads(struct machine *machine, struct perf_tool *tool,
+ struct perf_target *target, struct thread_map *threads,
+ perf_event__handler_t process, bool data_mmap)
+{
+ if (perf_target__has_task(target))
+ return perf_event__synthesize_thread_map(tool, threads, process, machine, data_mmap);
+ else if (perf_target__has_cpu(target))
+ return perf_event__synthesize_threads(tool, process, machine, data_mmap);
+ /* command specified */
+ return 0;
+}
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index 2389ba8..14a89d2 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -4,6 +4,7 @@
#include <sys/types.h>
#include <linux/rbtree.h>
#include "map.h"
+#include "event.h"

struct addr_location;
struct branch_stack;
@@ -178,4 +179,7 @@ int machine__for_each_thread(struct machine *machine,
int (*fn)(struct thread *thread, void *p),
void *priv);

+int machine__synthesize_threads(struct machine *machine, struct perf_tool *tool,
+ struct perf_target *target, struct thread_map *threads,
+ perf_event__handler_t process, bool data_mmap);
#endif /* __PERF_MACHINE_H */

tip-bot for Adrian Hunter

unread,
Nov 12, 2013, 5:00:03 PM11/12/13
to
Commit-ID: 3fe2130523b2e098085eb4d38cd5b737a97cbee6
Gitweb: http://git.kernel.org/tip/3fe2130523b2e098085eb4d38cd5b737a97cbee6
Author: Adrian Hunter <adrian...@intel.com>
AuthorDate: Tue, 12 Nov 2013 11:45:21 -0300
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Tue, 12 Nov 2013 13:00:37 -0300

perf tests: Compensate lower sample freq with longer test loop

Doesn't work for me:

./perf test -v 19
19: Test software clock events have valid period values :
--- start ---
mmap size 528384B
mmap size 528384B
All (0) samples have period value of 1!
---- end ----
Test software clock events have valid period values: FAILED!

Compensate the lower freq introduced in 67c1e4a53b17 with a longer loop,

Signed-off-by: Adrian Hunter <adrian...@intel.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: Namhyung Kim <namh...@kernel.org>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/r/5281D3B8...@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/tests/sw-clock.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c
index 93a7139..6664a7c 100644
--- a/tools/perf/tests/sw-clock.c
+++ b/tools/perf/tests/sw-clock.c
@@ -9,7 +9,7 @@
#include "util/cpumap.h"
#include "util/thread_map.h"

-#define NR_LOOPS 1000000
+#define NR_LOOPS 10000000

/*
* This test will open software clock events (cpu-clock, task-clock)

tip-bot for Arnaldo Carvalho de Melo

unread,
Nov 12, 2013, 5:00:03 PM11/12/13
to
Commit-ID: 602ad878d41ef097cc9aa2def7830d5bb27a15d8
Gitweb: http://git.kernel.org/tip/602ad878d41ef097cc9aa2def7830d5bb27a15d8
Author: Arnaldo Carvalho de Melo <ac...@redhat.com>
AuthorDate: Tue, 12 Nov 2013 16:46:16 -0300
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Tue, 12 Nov 2013 16:51:03 -0300

perf target: Shorten perf_target__ to target__

Getting unwieldly long, for this app domain should be descriptive enough
and the use of __ to separate the class from the method names should
help with avoiding clashes with other code bases.

Reported-by: David Ahern <dsa...@gmail.com>
Suggested-by: Ingo Molnar <mi...@kernel.org>
Cc: Adrian Hunter <adrian...@intel.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: Namhyung Kim <namh...@kernel.org>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/r/2013111211...@ghostprotocols.net
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-kvm.c | 6 ++---
tools/perf/builtin-record.c | 14 ++++++------
tools/perf/builtin-stat.c | 21 ++++++++---------
tools/perf/builtin-top.c | 14 ++++++------
tools/perf/builtin-trace.c | 10 ++++----
tools/perf/perf.h | 2 +-
tools/perf/tests/task-exit.c | 2 +-
tools/perf/util/evlist.c | 12 ++++------
tools/perf/util/evlist.h | 5 ++--
tools/perf/util/evsel.c | 9 ++++----
tools/perf/util/evsel.h | 3 +--
tools/perf/util/machine.c | 6 ++---
tools/perf/util/machine.h | 4 ++--
tools/perf/util/target.c | 54 +++++++++++++++++++++-----------------------
tools/perf/util/target.h | 44 +++++++++++++++++-------------------
tools/perf/util/top.c | 2 +-
16 files changed, 99 insertions(+), 109 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 346bb59..f8bf5f2 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -1510,13 +1510,13 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
/*
* target related setups
*/
- err = perf_target__validate(&kvm->opts.target);
+ err = target__validate(&kvm->opts.target);
if (err) {
- perf_target__strerror(&kvm->opts.target, err, errbuf, BUFSIZ);
+ target__strerror(&kvm->opts.target, err, errbuf, BUFSIZ);
ui__warning("%s", errbuf);
}

- if (perf_target__none(&kvm->opts.target))
+ if (target__none(&kvm->opts.target))
kvm->opts.target.system_wide = true;


diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 880227e..4d644fe 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -506,7 +506,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
* (apart from group members) have enable_on_exec=1 set,
* so don't spoil it by prematurely enabling them.
*/
- if (!perf_target__none(&opts->target))
+ if (!target__none(&opts->target))
perf_evlist__enable(evsel_list);

/*
@@ -535,7 +535,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
* die with the process and we wait for that. Thus no need to
* disable events in this case.
*/
- if (done && !disabled && !perf_target__none(&opts->target)) {
+ if (done && !disabled && !target__none(&opts->target)) {
perf_evlist__disable(evsel_list);
disabled = true;
}
@@ -906,7 +906,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)

argc = parse_options(argc, argv, record_options, record_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
- if (!argc && perf_target__none(&rec->opts.target))
+ if (!argc && target__none(&rec->opts.target))
usage_with_options(record_usage, record_options);

if (nr_cgroups && !rec->opts.target.system_wide) {
@@ -936,17 +936,17 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
goto out_symbol_exit;
}

- err = perf_target__validate(&rec->opts.target);
+ err = target__validate(&rec->opts.target);
if (err) {
- perf_target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
+ target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
ui__warning("%s", errbuf);
}

- err = perf_target__parse_uid(&rec->opts.target);
+ err = target__parse_uid(&rec->opts.target);
if (err) {
int saved_errno = errno;

- perf_target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
+ target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
ui__error("%s", errbuf);

err = -saved_errno;
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 0fc1c94..ee0d565 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -108,7 +108,7 @@ enum {

static struct perf_evlist *evsel_list;

-static struct perf_target target = {
+static struct target target = {
.uid = UINT_MAX,
};

@@ -294,11 +294,10 @@ static int create_perf_stat_counter(struct perf_evsel *evsel)

attr->inherit = !no_inherit;

- if (perf_target__has_cpu(&target))
+ if (target__has_cpu(&target))
return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel));

- if (!perf_target__has_task(&target) &&
- perf_evsel__is_group_leader(evsel)) {
+ if (!target__has_task(&target) && perf_evsel__is_group_leader(evsel)) {
attr->disabled = 1;
if (!initial_delay)
attr->enable_on_exec = 1;
@@ -1236,7 +1235,7 @@ static void print_stat(int argc, const char **argv)
fprintf(output, "\'system wide");
else if (target.cpu_list)
fprintf(output, "\'CPU(s) %s", target.cpu_list);
- else if (!perf_target__has_task(&target)) {
+ else if (!target__has_task(&target)) {
fprintf(output, "\'%s", argv[0]);
for (i = 1; i < argc; i++)
fprintf(output, " %s", argv[i]);
@@ -1667,7 +1666,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
} else if (big_num_opt == 0) /* User passed --no-big-num */
big_num = false;

- if (!argc && perf_target__none(&target))
+ if (!argc && target__none(&target))
usage_with_options(stat_usage, options);

if (run_count < 0) {
@@ -1680,8 +1679,8 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
}

/* no_aggr, cgroup are for system-wide only */
- if ((aggr_mode != AGGR_GLOBAL || nr_cgroups)
- && !perf_target__has_cpu(&target)) {
+ if ((aggr_mode != AGGR_GLOBAL || nr_cgroups) &&
+ !target__has_cpu(&target)) {
fprintf(stderr, "both cgroup and no-aggregation "
"modes only available in system-wide mode\n");

@@ -1694,14 +1693,14 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
if (add_default_attributes())
goto out;

- perf_target__validate(&target);
+ target__validate(&target);

if (perf_evlist__create_maps(evsel_list, &target) < 0) {
- if (perf_target__has_task(&target)) {
+ if (target__has_task(&target)) {
pr_err("Problems finding threads of monitor\n");
parse_options_usage(stat_usage, options, "p", 1);
parse_options_usage(NULL, options, "t", 1);
- } else if (perf_target__has_cpu(&target)) {
+ } else if (target__has_cpu(&target)) {
perror("failed to parse CPUs map");
parse_options_usage(stat_usage, options, "C", 1);
parse_options_usage(NULL, options, "a", 1);
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 8c520d9..b8f8e29 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -967,7 +967,7 @@ static int __cmd_top(struct perf_top *top)
* XXX 'top' still doesn't start workloads like record, trace, but should,
* so leave the check here.
*/
- if (!perf_target__none(&opts->target))
+ if (!target__none(&opts->target))
perf_evlist__enable(top->evlist);

/* Wait for a minimal set of events before starting the snapshot */
@@ -1053,7 +1053,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
.sym_pcnt_filter = 5,
};
struct perf_record_opts *opts = &top.record_opts;
- struct perf_target *target = &opts->target;
+ struct target *target = &opts->target;
const struct option options[] = {
OPT_CALLBACK('e', "event", &top.evlist, "event",
"event selector. use 'perf list' to list available events",
@@ -1169,24 +1169,24 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)

setup_browser(false);

- status = perf_target__validate(target);
+ status = target__validate(target);
if (status) {
- perf_target__strerror(target, status, errbuf, BUFSIZ);
+ target__strerror(target, status, errbuf, BUFSIZ);
ui__warning("%s", errbuf);
}

- status = perf_target__parse_uid(target);
+ status = target__parse_uid(target);
if (status) {
int saved_errno = errno;

- perf_target__strerror(target, status, errbuf, BUFSIZ);
+ target__strerror(target, status, errbuf, BUFSIZ);
ui__error("%s", errbuf);

status = -saved_errno;
goto out_delete_evlist;
}

- if (perf_target__none(target))
+ if (target__none(target))
target->system_wide = true;

if (perf_evlist__create_maps(top.evlist, target) < 0)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index aa5702f..6b230af 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -2327,21 +2327,21 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
}
}

- err = perf_target__validate(&trace.opts.target);
+ err = target__validate(&trace.opts.target);
if (err) {
- perf_target__strerror(&trace.opts.target, err, bf, sizeof(bf));
+ target__strerror(&trace.opts.target, err, bf, sizeof(bf));
fprintf(trace.output, "%s", bf);
goto out_close;
}

- err = perf_target__parse_uid(&trace.opts.target);
+ err = target__parse_uid(&trace.opts.target);
if (err) {
- perf_target__strerror(&trace.opts.target, err, bf, sizeof(bf));
+ target__strerror(&trace.opts.target, err, bf, sizeof(bf));
fprintf(trace.output, "%s", bf);
goto out_close;
}

- if (!argc && perf_target__none(&trace.opts.target))
+ if (!argc && target__none(&trace.opts.target))
trace.opts.target.system_wide = true;

if (input_name)
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index 6a587e84..b079304 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -248,7 +248,7 @@ enum perf_call_graph_mode {
};

struct perf_record_opts {
- struct perf_target target;
+ struct target target;
int call_graph;
bool group;
bool inherit_stat;
diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c
index c33d95f..d09ab57 100644
--- a/tools/perf/tests/task-exit.c
+++ b/tools/perf/tests/task-exit.c
@@ -28,7 +28,7 @@ int test__task_exit(void)
union perf_event *event;
struct perf_evsel *evsel;
struct perf_evlist *evlist;
- struct perf_target target = {
+ struct target target = {
.uid = UINT_MAX,
.uses_mmap = true,
};
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index cb19044..dc6fa3f 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -811,8 +811,7 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
return perf_evlist__mmap_per_cpu(evlist, prot, mask);
}

-int perf_evlist__create_maps(struct perf_evlist *evlist,
- struct perf_target *target)
+int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
{
evlist->threads = thread_map__new_str(target->pid, target->tid,
target->uid);
@@ -820,9 +819,9 @@ int perf_evlist__create_maps(struct perf_evlist *evlist,
if (evlist->threads == NULL)
return -1;

- if (perf_target__has_task(target))
+ if (target__has_task(target))
evlist->cpus = cpu_map__dummy_new();
- else if (!perf_target__has_cpu(target) && !target->uses_mmap)
+ else if (!target__has_cpu(target) && !target->uses_mmap)
evlist->cpus = cpu_map__dummy_new();
else
evlist->cpus = cpu_map__new(target->cpu_list);
@@ -1031,8 +1030,7 @@ out_err:
return err;
}

-int perf_evlist__prepare_workload(struct perf_evlist *evlist,
- struct perf_target *target,
+int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *target,
const char *argv[], bool pipe_output,
bool want_signal)
{
@@ -1084,7 +1082,7 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist,
exit(-1);
}

- if (perf_target__none(target))
+ if (target__none(target))
evlist->threads->map[0] = evlist->workload.pid;

close(child_ready_pipe[1]);
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index ecaa582..649d6ea 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -102,7 +102,7 @@ void perf_evlist__config(struct perf_evlist *evlist,
int perf_record_opts__config(struct perf_record_opts *opts);

int perf_evlist__prepare_workload(struct perf_evlist *evlist,
- struct perf_target *target,
+ struct target *target,
const char *argv[], bool pipe_output,
bool want_signal);
int perf_evlist__start_workload(struct perf_evlist *evlist);
@@ -134,8 +134,7 @@ static inline void perf_evlist__set_maps(struct perf_evlist *evlist,
evlist->threads = threads;
}

-int perf_evlist__create_maps(struct perf_evlist *evlist,
- struct perf_target *target);
+int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target);
void perf_evlist__delete_maps(struct perf_evlist *evlist);
int perf_evlist__apply_filters(struct perf_evlist *evlist);

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index f95653a..18f7c18 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -645,7 +645,7 @@ void perf_evsel__config(struct perf_evsel *evsel,
}
}

- if (perf_target__has_cpu(&opts->target))
+ if (target__has_cpu(&opts->target))
perf_evsel__set_sample_bit(evsel, CPU);

if (opts->period)
@@ -653,7 +653,7 @@ void perf_evsel__config(struct perf_evsel *evsel,

if (!perf_missing_features.sample_id_all &&
(opts->sample_time || !opts->no_inherit ||
- perf_target__has_cpu(&opts->target)))
+ target__has_cpu(&opts->target)))
perf_evsel__set_sample_bit(evsel, TIME);

if (opts->raw_samples) {
@@ -696,7 +696,7 @@ void perf_evsel__config(struct perf_evsel *evsel,
* Setting enable_on_exec for independent events and
* group leaders for traced executed by perf.
*/
- if (perf_target__none(&opts->target) && perf_evsel__is_group_leader(evsel))
+ if (target__none(&opts->target) && perf_evsel__is_group_leader(evsel))
attr->enable_on_exec = 1;
}

@@ -2006,8 +2006,7 @@ bool perf_evsel__fallback(struct perf_evsel *evsel, int err,
return false;
}

-int perf_evsel__open_strerror(struct perf_evsel *evsel,
- struct perf_target *target,
+int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
int err, char *msg, size_t size)
{
switch (err) {
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 0178233..f502965 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -318,8 +318,7 @@ int perf_evsel__fprintf(struct perf_evsel *evsel,

bool perf_evsel__fallback(struct perf_evsel *evsel, int err,
char *msg, size_t msgsize);
-int perf_evsel__open_strerror(struct perf_evsel *evsel,
- struct perf_target *target,
+int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
int err, char *msg, size_t size);

static inline int perf_evsel__group_idx(struct perf_evsel *evsel)
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 680700b6..0393912 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1396,12 +1396,12 @@ int machine__for_each_thread(struct machine *machine,
}

int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool,
- struct perf_target *target, struct thread_map *threads,
+ struct target *target, struct thread_map *threads,
perf_event__handler_t process, bool data_mmap)
{
- if (perf_target__has_task(target))
+ if (target__has_task(target))
return perf_event__synthesize_thread_map(tool, threads, process, machine, data_mmap);
- else if (perf_target__has_cpu(target))
+ else if (target__has_cpu(target))
return perf_event__synthesize_threads(tool, process, machine, data_mmap);
/* command specified */
return 0;
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index fedd1df..4771330 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -180,10 +180,10 @@ int machine__for_each_thread(struct machine *machine,
void *priv);

int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool,
- struct perf_target *target, struct thread_map *threads,
+ struct target *target, struct thread_map *threads,
perf_event__handler_t process, bool data_mmap);
static inline
-int machine__synthesize_threads(struct machine *machine, struct perf_target *target,
+int machine__synthesize_threads(struct machine *machine, struct target *target,
struct thread_map *threads, bool data_mmap)
{
return __machine__synthesize_threads(machine, NULL, target, threads,
diff --git a/tools/perf/util/target.c b/tools/perf/util/target.c
index 065528b..3c778a0 100644
--- a/tools/perf/util/target.c
+++ b/tools/perf/util/target.c
@@ -13,9 +13,9 @@
#include <string.h>


-enum perf_target_errno perf_target__validate(struct perf_target *target)
+enum target_errno target__validate(struct target *target)
{
- enum perf_target_errno ret = PERF_ERRNO_TARGET__SUCCESS;
+ enum target_errno ret = TARGET_ERRNO__SUCCESS;

if (target->pid)
target->tid = target->pid;
@@ -23,42 +23,42 @@ enum perf_target_errno perf_target__validate(struct perf_target *target)
/* CPU and PID are mutually exclusive */
if (target->tid && target->cpu_list) {
target->cpu_list = NULL;
- if (ret == PERF_ERRNO_TARGET__SUCCESS)
- ret = PERF_ERRNO_TARGET__PID_OVERRIDE_CPU;
+ if (ret == TARGET_ERRNO__SUCCESS)
+ ret = TARGET_ERRNO__PID_OVERRIDE_CPU;
}

/* UID and PID are mutually exclusive */
if (target->tid && target->uid_str) {
target->uid_str = NULL;
- if (ret == PERF_ERRNO_TARGET__SUCCESS)
- ret = PERF_ERRNO_TARGET__PID_OVERRIDE_UID;
+ if (ret == TARGET_ERRNO__SUCCESS)
+ ret = TARGET_ERRNO__PID_OVERRIDE_UID;
}

/* UID and CPU are mutually exclusive */
if (target->uid_str && target->cpu_list) {
target->cpu_list = NULL;
- if (ret == PERF_ERRNO_TARGET__SUCCESS)
- ret = PERF_ERRNO_TARGET__UID_OVERRIDE_CPU;
+ if (ret == TARGET_ERRNO__SUCCESS)
+ ret = TARGET_ERRNO__UID_OVERRIDE_CPU;
}

/* PID and SYSTEM are mutually exclusive */
if (target->tid && target->system_wide) {
target->system_wide = false;
- if (ret == PERF_ERRNO_TARGET__SUCCESS)
- ret = PERF_ERRNO_TARGET__PID_OVERRIDE_SYSTEM;
+ if (ret == TARGET_ERRNO__SUCCESS)
+ ret = TARGET_ERRNO__PID_OVERRIDE_SYSTEM;
}

/* UID and SYSTEM are mutually exclusive */
if (target->uid_str && target->system_wide) {
target->system_wide = false;
- if (ret == PERF_ERRNO_TARGET__SUCCESS)
- ret = PERF_ERRNO_TARGET__UID_OVERRIDE_SYSTEM;
+ if (ret == TARGET_ERRNO__SUCCESS)
+ ret = TARGET_ERRNO__UID_OVERRIDE_SYSTEM;
}

return ret;
}

-enum perf_target_errno perf_target__parse_uid(struct perf_target *target)
+enum target_errno target__parse_uid(struct target *target)
{
struct passwd pwd, *result;
char buf[1024];
@@ -66,7 +66,7 @@ enum perf_target_errno perf_target__parse_uid(struct perf_target *target)

target->uid = UINT_MAX;
if (str == NULL)
- return PERF_ERRNO_TARGET__SUCCESS;
+ return TARGET_ERRNO__SUCCESS;

/* Try user name first */
getpwnam_r(str, &pwd, buf, sizeof(buf), &result);
@@ -79,22 +79,22 @@ enum perf_target_errno perf_target__parse_uid(struct perf_target *target)
int uid = strtol(str, &endptr, 10);

if (*endptr != '\0')
- return PERF_ERRNO_TARGET__INVALID_UID;
+ return TARGET_ERRNO__INVALID_UID;

getpwuid_r(uid, &pwd, buf, sizeof(buf), &result);

if (result == NULL)
- return PERF_ERRNO_TARGET__USER_NOT_FOUND;
+ return TARGET_ERRNO__USER_NOT_FOUND;
}

target->uid = result->pw_uid;
- return PERF_ERRNO_TARGET__SUCCESS;
+ return TARGET_ERRNO__SUCCESS;
}

/*
- * This must have a same ordering as the enum perf_target_errno.
+ * This must have a same ordering as the enum target_errno.
*/
-static const char *perf_target__error_str[] = {
+static const char *target__error_str[] = {
"PID/TID switch overriding CPU",
"PID/TID switch overriding UID",
"UID switch overriding CPU",
@@ -104,7 +104,7 @@ static const char *perf_target__error_str[] = {
"Problems obtaining information for user %s",
};

-int perf_target__strerror(struct perf_target *target, int errnum,
+int target__strerror(struct target *target, int errnum,
char *buf, size_t buflen)
{
int idx;
@@ -124,21 +124,19 @@ int perf_target__strerror(struct perf_target *target, int errnum,
return 0;
}

- if (errnum < __PERF_ERRNO_TARGET__START ||
- errnum >= __PERF_ERRNO_TARGET__END)
+ if (errnum < __TARGET_ERRNO__START || errnum >= __TARGET_ERRNO__END)
return -1;

- idx = errnum - __PERF_ERRNO_TARGET__START;
- msg = perf_target__error_str[idx];
+ idx = errnum - __TARGET_ERRNO__START;
+ msg = target__error_str[idx];

switch (errnum) {
- case PERF_ERRNO_TARGET__PID_OVERRIDE_CPU
- ... PERF_ERRNO_TARGET__UID_OVERRIDE_SYSTEM:
+ case TARGET_ERRNO__PID_OVERRIDE_CPU ... TARGET_ERRNO__UID_OVERRIDE_SYSTEM:
snprintf(buf, buflen, "%s", msg);
break;

- case PERF_ERRNO_TARGET__INVALID_UID:
- case PERF_ERRNO_TARGET__USER_NOT_FOUND:
+ case TARGET_ERRNO__INVALID_UID:
+ case TARGET_ERRNO__USER_NOT_FOUND:
snprintf(buf, buflen, msg, target->uid_str);
break;

diff --git a/tools/perf/util/target.h b/tools/perf/util/target.h
index a4be857..89bab71 100644
--- a/tools/perf/util/target.h
+++ b/tools/perf/util/target.h
@@ -4,7 +4,7 @@
#include <stdbool.h>
#include <sys/types.h>

-struct perf_target {
+struct target {
const char *pid;
const char *tid;
const char *cpu_list;
@@ -14,8 +14,8 @@ struct perf_target {
bool uses_mmap;
};

-enum perf_target_errno {
- PERF_ERRNO_TARGET__SUCCESS = 0,
+enum target_errno {
+ TARGET_ERRNO__SUCCESS = 0,

/*
* Choose an arbitrary negative big number not to clash with standard
@@ -24,42 +24,40 @@ enum perf_target_errno {
*
* http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html
*/
- __PERF_ERRNO_TARGET__START = -10000,
+ __TARGET_ERRNO__START = -10000,

+ /* for target__validate() */
+ TARGET_ERRNO__PID_OVERRIDE_CPU = __TARGET_ERRNO__START,
+ TARGET_ERRNO__PID_OVERRIDE_UID,
+ TARGET_ERRNO__UID_OVERRIDE_CPU,
+ TARGET_ERRNO__PID_OVERRIDE_SYSTEM,
+ TARGET_ERRNO__UID_OVERRIDE_SYSTEM,

- /* for perf_target__validate() */
- PERF_ERRNO_TARGET__PID_OVERRIDE_CPU = __PERF_ERRNO_TARGET__START,
- PERF_ERRNO_TARGET__PID_OVERRIDE_UID,
- PERF_ERRNO_TARGET__UID_OVERRIDE_CPU,
- PERF_ERRNO_TARGET__PID_OVERRIDE_SYSTEM,
- PERF_ERRNO_TARGET__UID_OVERRIDE_SYSTEM,
+ /* for target__parse_uid() */
+ TARGET_ERRNO__INVALID_UID,
+ TARGET_ERRNO__USER_NOT_FOUND,

- /* for perf_target__parse_uid() */
- PERF_ERRNO_TARGET__INVALID_UID,
- PERF_ERRNO_TARGET__USER_NOT_FOUND,
-
- __PERF_ERRNO_TARGET__END,
+ __TARGET_ERRNO__END,
};

-enum perf_target_errno perf_target__validate(struct perf_target *target);
-enum perf_target_errno perf_target__parse_uid(struct perf_target *target);
+enum target_errno target__validate(struct target *target);
+enum target_errno target__parse_uid(struct target *target);

-int perf_target__strerror(struct perf_target *target, int errnum, char *buf,
- size_t buflen);
+int target__strerror(struct target *target, int errnum, char *buf, size_t buflen);

-static inline bool perf_target__has_task(struct perf_target *target)
+static inline bool target__has_task(struct target *target)
{
return target->tid || target->pid || target->uid_str;
}

-static inline bool perf_target__has_cpu(struct perf_target *target)
+static inline bool target__has_cpu(struct target *target)
{
return target->system_wide || target->cpu_list;
}

-static inline bool perf_target__none(struct perf_target *target)
+static inline bool target__none(struct target *target)
{
- return !perf_target__has_task(target) && !perf_target__has_cpu(target);
+ return !target__has_task(target) && !target__has_cpu(target);
}

#endif /* _PERF_TARGET_H */
diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c
index f857b51..ce793c7 100644
--- a/tools/perf/util/top.c
+++ b/tools/perf/util/top.c
@@ -27,7 +27,7 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size)
float ksamples_per_sec;
float esamples_percent;
struct perf_record_opts *opts = &top->record_opts;
- struct perf_target *target = &opts->target;
+ struct target *target = &opts->target;
size_t ret = 0;

if (top->samples) {

tip-bot for Arnaldo Carvalho de Melo

unread,
Nov 12, 2013, 5:10:02 PM11/12/13
to
Commit-ID: 62605dc50c27bf0e4ff69b7b3166f226586aff02
Gitweb: http://git.kernel.org/tip/62605dc50c27bf0e4ff69b7b3166f226586aff02
Author: Arnaldo Carvalho de Melo <ac...@redhat.com>
AuthorDate: Mon, 11 Nov 2013 09:44:09 -0300
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Mon, 11 Nov 2013 15:56:39 -0300

perf record: Synthesize non-exec MMAP records when --data used

When perf_event_attr.mmap_data is set the kernel will generate
PERF_RECORD_MMAP events when non-exec (data, SysV mem) mmaps are
created, so we need to synthesize from /proc/pid/maps for existing
threads, as we do for exec mmaps.

Right now just 'perf record' does it, but any other tool that uses
perf_event__synthesize_thread(s|map) can request it.

Reported-by: Don Zickus <dzi...@redhat.com>
Tested-by: Don Zickus <dzi...@redhat.com>
Cc: Adrian Hunter <adrian...@intel.com>
Cc: Bill Gray <bg...@redhat.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Don Zickus <dzi...@redhat.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Joe Mario <jma...@redhat.com>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Richard Fowles <rfo...@redhat.com>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/n/tip-ihwzraikx2...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-kvm.c | 4 ++--
tools/perf/builtin-record.c | 6 ++---
tools/perf/builtin-top.c | 4 ++--
tools/perf/builtin-trace.c | 4 ++--
tools/perf/tests/code-reading.c | 2 +-
tools/perf/util/event.c | 50 ++++++++++++++++++++++++-----------------
tools/perf/util/event.h | 4 ++--
7 files changed, 42 insertions(+), 32 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index cd9f920..f36e820 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -1550,10 +1550,10 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
perf_event__synthesize_thread_map(&kvm->tool,
kvm->evlist->threads,
perf_event__process,
- &kvm->session->machines.host);
+ &kvm->session->machines.host, false);
else
perf_event__synthesize_threads(&kvm->tool, perf_event__process,
- &kvm->session->machines.host);
+ &kvm->session->machines.host, false);


err = kvm_live_open_events(kvm);
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 15280b5..afb252c 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -482,11 +482,11 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)

if (perf_target__has_task(&opts->target))
err = perf_event__synthesize_thread_map(tool, evsel_list->threads,
- process_synthesized_event,
- machine);
+ process_synthesized_event,
+ machine, opts->sample_address);
else if (perf_target__has_cpu(&opts->target))
err = perf_event__synthesize_threads(tool, process_synthesized_event,
- machine);
+ machine, opts->sample_address);
else /* command specified */
err = 0;

diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 9acca88..cc96d75 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -953,10 +953,10 @@ static int __cmd_top(struct perf_top *top)
if (perf_target__has_task(&opts->target))
perf_event__synthesize_thread_map(&top->tool, top->evlist->threads,
perf_event__process,
- &top->session->machines.host);
+ &top->session->machines.host, false);
else
perf_event__synthesize_threads(&top->tool, perf_event__process,
- &top->session->machines.host);
+ &top->session->machines.host, false);

ret = perf_top__start_counters(top);
if (ret)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 68943ca..277c236 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1343,10 +1343,10 @@ static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist)
if (perf_target__has_task(&trace->opts.target)) {
err = perf_event__synthesize_thread_map(&trace->tool, evlist->threads,
trace__tool_process,
- trace->host);
+ trace->host, false);
} else {
err = perf_event__synthesize_threads(&trace->tool, trace__tool_process,
- trace->host);
+ trace->host, false);
}

if (err)
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 49ccc3b..6d9dc19 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -441,7 +441,7 @@ static int do_test_code_reading(bool try_kcore)
}

ret = perf_event__synthesize_thread_map(NULL, threads,
- perf_event__process, machine);
+ perf_event__process, machine, false);
if (ret < 0) {
pr_debug("perf_event__synthesize_thread_map failed\n");
goto out_err;
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index ec9ae11..6e3a846 100644
struct perf_tool *tool,
- struct machine *machine)
+ struct machine *machine, bool mmap_data)
{
pid_t tgid = perf_event__synthesize_comm(tool, comm_event, pid, full,
process, machine);
if (tgid == -1)
return -1;
return perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid,
- process, machine);
+ process, machine, mmap_data);
}

int perf_event__synthesize_thread_map(struct perf_tool *tool,
struct thread_map *threads,
perf_event__handler_t process,
index f8d70f3..30fec99 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -208,10 +208,10 @@ typedef int (*perf_event__handler_t)(struct perf_tool *tool,
int perf_event__synthesize_thread_map(struct perf_tool *tool,
struct thread_map *threads,
perf_event__handler_t process,
- struct machine *machine);
+ struct machine *machine, bool mmap_data);
int perf_event__synthesize_threads(struct perf_tool *tool,
perf_event__handler_t process,
- struct machine *machine);
+ struct machine *machine, bool mmap_data);
int perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
perf_event__handler_t process,
struct machine *machine,

Namhyung Kim

unread,
Nov 15, 2013, 1:10:01 AM11/15/13
to
Hi Arnaldo,

On Tue, 12 Nov 2013 11:41:01 -0300, Arnaldo Carvalho de Melo wrote:
> Em Tue, Nov 12, 2013 at 09:07:36AM +0200, Adrian Hunter escreveu:
>> -#define NR_LOOPS 1000000
>> +#define NR_LOOPS 10000000
>
> Lower frequency, need to generate more noise, ugh. Adding that, but I
> think this test needs to be reworked, Namhyung?

Hmm.. We might go back to use the default frequency of 4000 (or 1000)
and make the loop based on time like using alarm or setitimer.

Or we can add an outer loop which doubles the inner loop counter if no
samples are collected.

What do you think?

Thanks,
Namhyung

tip-bot for Arnaldo Carvalho de Melo

unread,
Jan 12, 2014, 1:40:02 PM1/12/14
to
Commit-ID: 28b21393fa0472501b5a2a85a0b008b4e3dc154c
Gitweb: http://git.kernel.org/tip/28b21393fa0472501b5a2a85a0b008b4e3dc154c
Author: Arnaldo Carvalho de Melo <ac...@redhat.com>
AuthorDate: Thu, 19 Dec 2013 14:53:53 -0300
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Thu, 19 Dec 2013 16:19:01 -0300

perf report: Rename 'perf_report' to 'report'

Reduce typing, functions use class__method convention, so unlikely to
clash with other libraries.

This actually was discussed in the "Link:" referenced message below.

Cc: Adrian Hunter <adrian...@intel.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: Namhyung Kim <namh...@kernel.org>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/r/2013111211...@ghostprotocols.net
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-report.c | 73 +++++++++++++++++++--------------------------
1 file changed, 31 insertions(+), 42 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 8424053..da156a4 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -39,7 +39,7 @@
#include <dlfcn.h>
#include <linux/bitmap.h>

-struct perf_report {
+struct report {
struct perf_tool tool;
struct perf_session *session;
bool force, use_tui, use_gtk, use_stdio;
@@ -60,14 +60,14 @@ struct perf_report {
DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
};

-static int perf_report_config(const char *var, const char *value, void *cb)
+static int report__config(const char *var, const char *value, void *cb)
{
if (!strcmp(var, "report.group")) {
symbol_conf.event_group = perf_config_bool(var, value);
return 0;
}
if (!strcmp(var, "report.percent-limit")) {
- struct perf_report *rep = cb;
+ struct report *rep = cb;
rep->min_percent = strtof(value, NULL);
return 0;
}
@@ -75,7 +75,7 @@ static int perf_report_config(const char *var, const char *value, void *cb)
return perf_default_config(var, value, cb);
}

-static int report__resolve_callchain(struct perf_report *rep, struct symbol **parent,
+static int report__resolve_callchain(struct report *rep, struct symbol **parent,
struct perf_evsel *evsel, struct addr_location *al,
struct perf_sample *sample, struct machine *machine)
{
@@ -93,14 +93,11 @@ static int hist_entry__append_callchain(struct hist_entry *he, struct perf_sampl
return callchain_append(he->callchain, &callchain_cursor, sample->period);
}

-static int perf_report__add_mem_hist_entry(struct perf_tool *tool,
- struct addr_location *al,
- struct perf_sample *sample,
- struct perf_evsel *evsel,
- struct machine *machine,
- union perf_event *event)
+static int report__add_mem_hist_entry(struct perf_tool *tool, struct addr_location *al,
+ struct perf_sample *sample, struct perf_evsel *evsel,
+ struct machine *machine, union perf_event *event)
{
- struct perf_report *rep = container_of(tool, struct perf_report, tool);
+ struct report *rep = container_of(tool, struct report, tool);
struct symbol *parent = NULL;
u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
struct hist_entry *he;
@@ -150,13 +147,11 @@ out:
return err;
}

-static int perf_report__add_branch_hist_entry(struct perf_tool *tool,
- struct addr_location *al,
- struct perf_sample *sample,
- struct perf_evsel *evsel,
- struct machine *machine)
+static int report__add_branch_hist_entry(struct perf_tool *tool, struct addr_location *al,
+ struct perf_sample *sample, struct perf_evsel *evsel,
+ struct machine *machine)
{
- struct perf_report *rep = container_of(tool, struct perf_report, tool);
+ struct report *rep = container_of(tool, struct report, tool);
struct symbol *parent = NULL;
unsigned i;
struct hist_entry *he;
@@ -208,13 +203,11 @@ out:
return err;
}

-static int perf_evsel__add_hist_entry(struct perf_tool *tool,
- struct perf_evsel *evsel,
- struct addr_location *al,
- struct perf_sample *sample,
- struct machine *machine)
+static int report__add_hist_entry(struct perf_tool *tool, struct perf_evsel *evsel,
+ struct addr_location *al, struct perf_sample *sample,
+ struct machine *machine)
{
- struct perf_report *rep = container_of(tool, struct perf_report, tool);
+ struct report *rep = container_of(tool, struct report, tool);
struct symbol *parent = NULL;
struct hist_entry *he;
int err = report__resolve_callchain(rep, &parent, evsel, al, sample, machine);
@@ -246,7 +239,7 @@ static int process_sample_event(struct perf_tool *tool,
struct perf_evsel *evsel,
struct machine *machine)
{
- struct perf_report *rep = container_of(tool, struct perf_report, tool);
+ struct report *rep = container_of(tool, struct report, tool);
struct addr_location al;
int ret;

@@ -263,21 +256,18 @@ static int process_sample_event(struct perf_tool *tool,
return 0;

if (sort__mode == SORT_MODE__BRANCH) {
- ret = perf_report__add_branch_hist_entry(tool, &al, sample,
- evsel, machine);
+ ret = report__add_branch_hist_entry(tool, &al, sample, evsel, machine);
if (ret < 0)
pr_debug("problem adding lbr entry, skipping event\n");
} else if (rep->mem_mode == 1) {
- ret = perf_report__add_mem_hist_entry(tool, &al, sample,
- evsel, machine, event);
+ ret = report__add_mem_hist_entry(tool, &al, sample, evsel, machine, event);
if (ret < 0)
pr_debug("problem adding mem entry, skipping event\n");
} else {
if (al.map != NULL)
al.map->dso->hit = 1;

- ret = perf_evsel__add_hist_entry(tool, evsel, &al, sample,
- machine);
+ ret = report__add_hist_entry(tool, evsel, &al, sample, machine);
if (ret < 0)
pr_debug("problem incrementing symbol period, skipping event\n");
}
@@ -290,7 +280,7 @@ static int process_read_event(struct perf_tool *tool,
struct perf_evsel *evsel,
struct machine *machine __maybe_unused)
{
- struct perf_report *rep = container_of(tool, struct perf_report, tool);
+ struct report *rep = container_of(tool, struct report, tool);

if (rep->show_threads) {
const char *name = evsel ? perf_evsel__name(evsel) : "unknown";
@@ -309,7 +299,7 @@ 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)
+static int report__setup_sample_type(struct report *rep)
{
struct perf_session *session = rep->session;
u64 sample_type = perf_evlist__combined_sample_type(session->evlist);
@@ -354,8 +344,7 @@ static void sig_handler(int sig __maybe_unused)
session_done = 1;
}

-static size_t hists__fprintf_nr_sample_events(struct perf_report *rep,
- struct hists *hists,
+static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report *rep,
const char *evname, FILE *fp)
{
size_t ret;
@@ -392,7 +381,7 @@ static size_t hists__fprintf_nr_sample_events(struct perf_report *rep,
}

static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
- struct perf_report *rep,
+ struct report *rep,
const char *help)
{
struct perf_evsel *pos;
@@ -405,7 +394,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
!perf_evsel__is_group_leader(pos))
continue;

- hists__fprintf_nr_sample_events(rep, hists, evname, stdout);
+ hists__fprintf_nr_sample_events(hists, rep, evname, stdout);
hists__fprintf(hists, true, 0, 0, rep->min_percent, stdout);
fprintf(stdout, "\n\n");
}
@@ -425,7 +414,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
return 0;
}

-static int __cmd_report(struct perf_report *rep)
+static int __cmd_report(struct report *rep)
{
int ret = -EINVAL;
u64 nr_samples;
@@ -449,7 +438,7 @@ static int __cmd_report(struct perf_report *rep)
if (rep->show_threads)
perf_read_values_init(&rep->show_threads_values);

- ret = perf_report__setup_sample_type(rep);
+ ret = report__setup_sample_type(rep);
if (ret)
return ret;

@@ -568,7 +557,7 @@ static int __cmd_report(struct perf_report *rep)
static int
parse_callchain_opt(const struct option *opt, const char *arg, int unset)
{
- struct perf_report *rep = (struct perf_report *)opt->value;
+ struct report *rep = (struct report *)opt->value;
char *tok, *tok2;
char *endptr;

@@ -688,7 +677,7 @@ static int
parse_percent_limit(const struct option *opt, const char *str,
int unset __maybe_unused)
{
- struct perf_report *rep = opt->value;
+ struct report *rep = opt->value;

rep->min_percent = strtof(str, NULL);
return 0;
@@ -706,7 +695,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
"perf report [<options>]",
NULL
};
- struct perf_report report = {
+ struct report report = {
.tool = {
.sample = process_sample_event,
.mmap = perf_event__process_mmap,
@@ -822,7 +811,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
.mode = PERF_DATA_MODE_READ,
};

- perf_config(perf_report_config, &report);
+ perf_config(report__config, &report);

argc = parse_options(argc, argv, options, report_usage, 0);

tip-bot for Arnaldo Carvalho de Melo

unread,
Jan 12, 2014, 1:40:02 PM1/12/14
to
Commit-ID: b40067964f09a5b4d9e133dec225007ee0a13050
Gitweb: http://git.kernel.org/tip/b40067964f09a5b4d9e133dec225007ee0a13050
Author: Arnaldo Carvalho de Melo <ac...@redhat.com>
AuthorDate: Thu, 19 Dec 2013 14:43:45 -0300
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Thu, 19 Dec 2013 14:43:45 -0300

perf tools: Rename 'perf_record_opts' to 'record_opts

Reduce typing, functions use class__method convention, so unlikely to
clash with other libraries.

This actually was discussed in the "Link:" referenced message below.

Cc: Adrian Hunter <adrian...@intel.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: Namhyung Kim <namh...@kernel.org>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Stephane Eranian <era...@google.com>
Link: http://lkml.kernel.org/r/2013111211...@ghostprotocols.net
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-kvm.c | 2 +-
tools/perf/builtin-record.c | 18 +++++++++---------
tools/perf/builtin-top.c | 8 ++++----
tools/perf/builtin-trace.c | 2 +-
tools/perf/perf.h | 2 +-
tools/perf/tests/code-reading.c | 2 +-
tools/perf/tests/keep-tracking.c | 2 +-
tools/perf/tests/open-syscall-tp-fields.c | 2 +-
tools/perf/tests/perf-record.c | 2 +-
tools/perf/tests/perf-time-to-tsc.c | 2 +-
tools/perf/util/callchain.h | 2 +-
tools/perf/util/evlist.h | 7 +++----
tools/perf/util/evsel.c | 3 +--
tools/perf/util/evsel.h | 4 ++--
tools/perf/util/record.c | 9 ++++-----
tools/perf/util/top.c | 2 +-
tools/perf/util/top.h | 2 +-
17 files changed, 34 insertions(+), 37 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 154b397..5a80da6 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -89,7 +89,7 @@ struct exit_reasons_table {

struct perf_kvm_stat {
struct perf_tool tool;
- struct perf_record_opts opts;
+ struct record_opts opts;
struct perf_evlist *evlist;
struct perf_session *session;

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index f2624d4..6ec0cbc 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -64,7 +64,7 @@ static void __handle_on_exit_funcs(void)

struct record {
struct perf_tool tool;
- struct perf_record_opts opts;
+ struct record_opts opts;
u64 bytes_written;
struct perf_data_file file;
struct perf_evlist *evlist;
@@ -178,7 +178,7 @@ static int record__open(struct record *rec)
struct perf_evsel *pos;
struct perf_evlist *evlist = rec->evlist;
struct perf_session *session = rec->session;
- struct perf_record_opts *opts = &rec->opts;
+ struct record_opts *opts = &rec->opts;
int rc = 0;

perf_evlist__config(evlist, opts);
@@ -348,7 +348,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
const bool forks = argc > 0;
struct machine *machine;
struct perf_tool *tool = &rec->tool;
- struct perf_record_opts *opts = &rec->opts;
+ struct record_opts *opts = &rec->opts;
struct perf_evlist *evsel_list = rec->evlist;
struct perf_data_file *file = &rec->file;
struct perf_session *session;
@@ -657,7 +657,7 @@ static int get_stack_size(char *str, unsigned long *_size)
}
#endif /* HAVE_LIBUNWIND_SUPPORT */

-int record_parse_callchain(const char *arg, struct perf_record_opts *opts)
+int record_parse_callchain(const char *arg, struct record_opts *opts)
{
char *tok, *name, *saveptr = NULL;
char *buf;
@@ -713,7 +713,7 @@ int record_parse_callchain(const char *arg, struct perf_record_opts *opts)
return ret;
}

-static void callchain_debug(struct perf_record_opts *opts)
+static void callchain_debug(struct record_opts *opts)
{
pr_debug("callchain: type %d\n", opts->call_graph);

@@ -726,7 +726,7 @@ int record_parse_callchain_opt(const struct option *opt,
const char *arg,
int unset)
{
- struct perf_record_opts *opts = opt->value;
+ struct record_opts *opts = opt->value;
int ret;

/* --no-call-graph */
@@ -747,7 +747,7 @@ int record_callchain_opt(const struct option *opt,
const char *arg __maybe_unused,
int unset __maybe_unused)
{
- struct perf_record_opts *opts = opt->value;
+ struct record_opts *opts = opt->value;

if (opts->call_graph == CALLCHAIN_NONE)
opts->call_graph = CALLCHAIN_FP;
@@ -796,7 +796,7 @@ const char record_callchain_help[] = CALLCHAIN_HELP "fp";
/*
* XXX Will stay a global variable till we fix builtin-script.c to stop messing
* with it and switch to use the library functions in perf_evlist that came
- * from builtin-record.c, i.e. use perf_record_opts,
+ * from builtin-record.c, i.e. use record_opts,
* perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record',
* using pipes, etc.
*/
@@ -944,7 +944,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
if (perf_evlist__create_maps(evsel_list, &rec->opts.target) < 0)
usage_with_options(record_usage, record_options);

- if (perf_record_opts__config(&rec->opts)) {
+ if (record_opts__config(&rec->opts)) {
err = -EINVAL;
goto out_free_fd;
}
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 2c6cb66..172e91a 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -854,7 +854,7 @@ static int perf_top__start_counters(struct perf_top *top)
char msg[512];
struct perf_evsel *counter;
struct perf_evlist *evlist = top->evlist;
- struct perf_record_opts *opts = &top->record_opts;
+ struct record_opts *opts = &top->record_opts;

perf_evlist__config(evlist, opts);

@@ -906,7 +906,7 @@ static int perf_top__setup_sample_type(struct perf_top *top __maybe_unused)

static int __cmd_top(struct perf_top *top)
{
- struct perf_record_opts *opts = &top->record_opts;
+ struct record_opts *opts = &top->record_opts;
pthread_t thread;
int ret;

@@ -1028,7 +1028,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
.max_stack = PERF_MAX_STACK_DEPTH,
.sym_pcnt_filter = 5,
};
- struct perf_record_opts *opts = &top.record_opts;
+ struct record_opts *opts = &top.record_opts;
struct target *target = &opts->target;
const struct option options[] = {
OPT_CALLBACK('e', "event", &top.evlist, "event",
@@ -1179,7 +1179,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
if (top.delay_secs < 1)
top.delay_secs = 1;

- if (perf_record_opts__config(opts)) {
+ if (record_opts__config(opts)) {
status = -EINVAL;
goto out_delete_maps;
}
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 56bbca5..f64b5b0 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1159,7 +1159,7 @@ struct trace {
int max;
struct syscall *table;
} syscalls;
- struct perf_record_opts opts;
+ struct record_opts opts;
struct machine *host;
u64 base_time;
bool full_time;
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index b23fed5..b1cc84b 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -247,7 +247,7 @@ enum perf_call_graph_mode {
CALLCHAIN_DWARF
};

-struct perf_record_opts {
+struct record_opts {
struct target target;
int call_graph;
bool group;
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 85d4919..4248d1e 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -391,7 +391,7 @@ static int do_test_code_reading(bool try_kcore)
struct machines machines;
struct machine *machine;
struct thread *thread;
- struct perf_record_opts opts = {
+ struct record_opts opts = {
.mmap_pages = UINT_MAX,
.user_freq = UINT_MAX,
.user_interval = ULLONG_MAX,
diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c
index 376c356..27eb751 100644
--- a/tools/perf/tests/keep-tracking.c
+++ b/tools/perf/tests/keep-tracking.c
@@ -51,7 +51,7 @@ static int find_comm(struct perf_evlist *evlist, const char *comm)
*/
int test__keep_tracking(void)
{
- struct perf_record_opts opts = {
+ struct record_opts opts = {
.mmap_pages = UINT_MAX,
.user_freq = UINT_MAX,
.user_interval = ULLONG_MAX,
diff --git a/tools/perf/tests/open-syscall-tp-fields.c b/tools/perf/tests/open-syscall-tp-fields.c
index 41cc0ba..774620a 100644
--- a/tools/perf/tests/open-syscall-tp-fields.c
+++ b/tools/perf/tests/open-syscall-tp-fields.c
@@ -6,7 +6,7 @@

int test__syscall_open_tp_fields(void)
{
- struct perf_record_opts opts = {
+ struct record_opts opts = {
.target = {
.uid = UINT_MAX,
.uses_mmap = true,
diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c
index 93a62b0..eeba562 100644
--- a/tools/perf/tests/perf-record.c
+++ b/tools/perf/tests/perf-record.c
@@ -34,7 +34,7 @@ realloc:

int test__PERF_RECORD(void)
{
- struct perf_record_opts opts = {
+ struct record_opts opts = {
.target = {
.uid = UINT_MAX,
.uses_mmap = true,
diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c
index 4ca1b93..c6398b9 100644
--- a/tools/perf/tests/perf-time-to-tsc.c
+++ b/tools/perf/tests/perf-time-to-tsc.c
@@ -46,7 +46,7 @@ static u64 rdtsc(void)
*/
int test__perf_time_to_tsc(void)
{
- struct perf_record_opts opts = {
+ struct record_opts opts = {
.mmap_pages = UINT_MAX,
.user_freq = UINT_MAX,
.user_interval = ULLONG_MAX,
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 4f7f989..08b25af 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -146,7 +146,7 @@ static inline void callchain_cursor_advance(struct callchain_cursor *cursor)

struct option;

-int record_parse_callchain(const char *arg, struct perf_record_opts *opts);
+int record_parse_callchain(const char *arg, struct record_opts *opts);
int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset);
int record_callchain_opt(const struct option *opt, const char *arg, int unset);

diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 9f64ede..2fe5195 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -12,7 +12,7 @@
struct pollfd;
struct thread_map;
struct cpu_map;
-struct perf_record_opts;
+struct record_opts;

#define PERF_EVLIST__HLIST_BITS 8
#define PERF_EVLIST__HLIST_SIZE (1 << PERF_EVLIST__HLIST_BITS)
@@ -97,9 +97,8 @@ void perf_evlist__close(struct perf_evlist *evlist);

void perf_evlist__set_id_pos(struct perf_evlist *evlist);
bool perf_can_sample_identifier(void);
-void perf_evlist__config(struct perf_evlist *evlist,
- struct perf_record_opts *opts);
-int perf_record_opts__config(struct perf_record_opts *opts);
+void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts);
+int record_opts__config(struct record_opts *opts);

int perf_evlist__prepare_workload(struct perf_evlist *evlist,
struct target *target,
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 01ff4cf..6874e04 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -528,8 +528,7 @@ int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size)
* enable/disable events specifically, as there's no
* initial traced exec call.
*/
-void perf_evsel__config(struct perf_evsel *evsel,
- struct perf_record_opts *opts)
+void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
{
struct perf_evsel *leader = evsel->leader;
struct perf_event_attr *attr = &evsel->attr;
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 8120eeb..f1b3256 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -96,7 +96,7 @@ struct perf_evsel {
struct cpu_map;
struct thread_map;
struct perf_evlist;
-struct perf_record_opts;
+struct record_opts;

struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx);

@@ -120,7 +120,7 @@ void perf_evsel__exit(struct perf_evsel *evsel);
void perf_evsel__delete(struct perf_evsel *evsel);

void perf_evsel__config(struct perf_evsel *evsel,
- struct perf_record_opts *opts);
+ struct record_opts *opts);

int __perf_evsel__sample_size(u64 sample_type);
void perf_evsel__calc_id_pos(struct perf_evsel *evsel);
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
index e510453..104a475 100644
--- a/tools/perf/util/record.c
+++ b/tools/perf/util/record.c
@@ -74,8 +74,7 @@ bool perf_can_sample_identifier(void)
return perf_probe_api(perf_probe_sample_identifier);
}

-void perf_evlist__config(struct perf_evlist *evlist,
- struct perf_record_opts *opts)
+void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts)
{
struct perf_evsel *evsel;
bool use_sample_identifier = false;
@@ -123,7 +122,7 @@ static int get_max_rate(unsigned int *rate)
return filename__read_int(path, (int *) rate);
}

-static int perf_record_opts__config_freq(struct perf_record_opts *opts)
+static int record_opts__config_freq(struct record_opts *opts)
{
bool user_freq = opts->user_freq != UINT_MAX;
unsigned int max_rate;
@@ -173,9 +172,9 @@ static int perf_record_opts__config_freq(struct perf_record_opts *opts)
return 0;
}

-int perf_record_opts__config(struct perf_record_opts *opts)
+int record_opts__config(struct record_opts *opts)
{
- return perf_record_opts__config_freq(opts);
+ return record_opts__config_freq(opts);
}

bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str)
diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c
index ce793c7..8e517de 100644
--- a/tools/perf/util/top.c
+++ b/tools/perf/util/top.c
@@ -26,7 +26,7 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size)
float samples_per_sec;
float ksamples_per_sec;
float esamples_percent;
- struct perf_record_opts *opts = &top->record_opts;
+ struct record_opts *opts = &top->record_opts;
struct target *target = &opts->target;
size_t ret = 0;

diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h
index 88cfeaf..dab14d0 100644
--- a/tools/perf/util/top.h
+++ b/tools/perf/util/top.h
@@ -14,7 +14,7 @@ struct perf_session;
struct perf_top {
struct perf_tool tool;
struct perf_evlist *evlist;
- struct perf_record_opts record_opts;
+ struct record_opts record_opts;
/*
* Symbols will be added here in perf_event__process_sample and will
* get out after decayed.
0 new messages