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

[PATCH 13/20] tools lib traceevent: Get rid of malloc_or_die() in find_event()

3 views
Skip to first unread message

Arnaldo Carvalho de Melo

unread,
Dec 13, 2013, 10:20:01 AM12/13/13
to
From: Namhyung Kim <namh...@kernel.org>

Make it return pevent_errno to distinguish malloc allocation failure.
Since it'll be returned to user later, add more error code.

Signed-off-by: Namhyung Kim <namh...@kernel.org>
Reviewed-by: Steven Rostedt <ros...@goodmis.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namhyu...@lge.com>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Steven Rostedt <ros...@goodmis.org>
Link: http://lkml.kernel.org/r/1386833777-3790-6-gi...@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/lib/traceevent/event-parse.h | 4 +++-
tools/lib/traceevent/parse-filter.c | 27 +++++++++++++++++++--------
2 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index 6e23f197175f..abdfd3c606ed 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -356,7 +356,9 @@ enum pevent_flag {
_PE(READ_FORMAT_FAILED, "failed to read event format"), \
_PE(READ_PRINT_FAILED, "failed to read event print fmt"), \
_PE(OLD_FTRACE_ARG_FAILED,"failed to allocate field name for ftrace"),\
- _PE(INVALID_ARG_TYPE, "invalid argument type")
+ _PE(INVALID_ARG_TYPE, "invalid argument type"), \
+ _PE(INVALID_EVENT_NAME, "invalid event name"), \
+ _PE(EVENT_NOT_FOUND, "No event found")

#undef _PE
#define _PE(__code, __str) PEVENT_ERRNO__ ## __code
diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c
index 246ee81e1f93..a0ab040e8f71 100644
--- a/tools/lib/traceevent/parse-filter.c
+++ b/tools/lib/traceevent/parse-filter.c
@@ -287,7 +287,7 @@ static int event_match(struct event_format *event,
!regexec(ereg, event->name, 0, NULL, 0);
}

-static int
+static enum pevent_errno
find_event(struct pevent *pevent, struct event_list **events,
char *sys_name, char *event_name)
{
@@ -306,23 +306,31 @@ find_event(struct pevent *pevent, struct event_list **events,
sys_name = NULL;
}

- reg = malloc_or_die(strlen(event_name) + 3);
+ reg = malloc(strlen(event_name) + 3);
+ if (reg == NULL)
+ return PEVENT_ERRNO__MEM_ALLOC_FAILED;
+
sprintf(reg, "^%s$", event_name);

ret = regcomp(&ereg, reg, REG_ICASE|REG_NOSUB);
free(reg);

if (ret)
- return -1;
+ return PEVENT_ERRNO__INVALID_EVENT_NAME;

if (sys_name) {
- reg = malloc_or_die(strlen(sys_name) + 3);
+ reg = malloc(strlen(sys_name) + 3);
+ if (reg == NULL) {
+ regfree(&ereg);
+ return PEVENT_ERRNO__MEM_ALLOC_FAILED;
+ }
+
sprintf(reg, "^%s$", sys_name);
ret = regcomp(&sreg, reg, REG_ICASE|REG_NOSUB);
free(reg);
if (ret) {
regfree(&ereg);
- return -1;
+ return PEVENT_ERRNO__INVALID_EVENT_NAME;
}
}

@@ -342,9 +350,9 @@ find_event(struct pevent *pevent, struct event_list **events,
regfree(&sreg);

if (!match)
- return -1;
+ return PEVENT_ERRNO__EVENT_NOT_FOUND;
if (fail)
- return -2;
+ return PEVENT_ERRNO__MEM_ALLOC_FAILED;

return 0;
}
@@ -1312,7 +1320,10 @@ int pevent_filter_add_filter_str(struct event_filter *filter,
/* Find this event */
ret = find_event(pevent, &events, strim(sys_name), strim(event_name));
if (ret < 0) {
- if (event_name)
+ if (ret == PEVENT_ERRNO__MEM_ALLOC_FAILED)
+ show_error(error_str,
+ "Memory allocation failure");
+ else if (event_name)
show_error(error_str,
"No event found under '%s.%s'",
sys_name, event_name);
--
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,
Dec 13, 2013, 10:20:01 AM12/13/13
to
From: Namhyung Kim <namh...@kernel.org>

To do that, make the function returns the error code. Also pass
error_str so that it can set proper error message when error occurred.

Signed-off-by: Namhyung Kim <namh...@kernel.org>
Reviewed-by: Steven Rostedt <ros...@goodmis.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namhyu...@lge.com>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Steven Rostedt <ros...@goodmis.org>
Link: http://lkml.kernel.org/r/1386833777-3790-9-gi...@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/lib/traceevent/event-parse.h | 5 +-
tools/lib/traceevent/parse-filter.c | 94 +++++++++++++++++++++++--------------
2 files changed, 64 insertions(+), 35 deletions(-)

diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index 89e4dfd40db6..5e4392d8e2d4 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -364,7 +364,10 @@ enum pevent_flag {
_PE(ILLEGAL_LVALUE, "illegal lvalue for string comparison"), \
_PE(INVALID_REGEX, "regex did not compute"), \
_PE(ILLEGAL_STRING_CMP, "illegal comparison for string"), \
- _PE(ILLEGAL_INTEGER_CMP,"illegal comparison for integer")
+ _PE(ILLEGAL_INTEGER_CMP,"illegal comparison for integer"), \
+ _PE(REPARENT_NOT_OP, "cannot reparent other than OP"), \
+ _PE(REPARENT_FAILED, "failed to reparent filter OP"), \
+ _PE(BAD_FILTER_ARG, "bad arg in filter tree")

#undef _PE
#define _PE(__code, __str) PEVENT_ERRNO__ ## __code
diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c
index 774c3e4c1d9f..9b05892566e0 100644
--- a/tools/lib/traceevent/parse-filter.c
+++ b/tools/lib/traceevent/parse-filter.c
@@ -784,15 +784,18 @@ enum filter_vals {
FILTER_VAL_TRUE,
};

-void reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child,
- struct filter_arg *arg)
+static enum pevent_errno
+reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child,
+ struct filter_arg *arg, char **error_str)
{
struct filter_arg *other_child;
struct filter_arg **ptr;

if (parent->type != FILTER_ARG_OP &&
- arg->type != FILTER_ARG_OP)
- die("can not reparent other than OP");
+ arg->type != FILTER_ARG_OP) {
+ show_error(error_str, "can not reparent other than OP");
+ return PEVENT_ERRNO__REPARENT_NOT_OP;
+ }

/* Get the sibling */
if (old_child->op.right == arg) {
@@ -801,8 +804,10 @@ void reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child,
} else if (old_child->op.left == arg) {
ptr = &old_child->op.left;
other_child = old_child->op.right;
- } else
- die("Error in reparent op, find other child");
+ } else {
+ show_error(error_str, "Error in reparent op, find other child");
+ return PEVENT_ERRNO__REPARENT_FAILED;
+ }

/* Detach arg from old_child */
*ptr = NULL;
@@ -813,23 +818,29 @@ void reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child,
*parent = *arg;
/* Free arg without recussion */
free(arg);
- return;
+ return 0;
}

if (parent->op.right == old_child)
ptr = &parent->op.right;
else if (parent->op.left == old_child)
ptr = &parent->op.left;
- else
- die("Error in reparent op");
+ else {
+ show_error(error_str, "Error in reparent op");
+ return PEVENT_ERRNO__REPARENT_FAILED;
+ }
+
*ptr = arg;

free_arg(old_child);
+ return 0;
}

-enum filter_vals test_arg(struct filter_arg *parent, struct filter_arg *arg)
+/* Returns either filter_vals (success) or pevent_errno (failfure) */
+static int test_arg(struct filter_arg *parent, struct filter_arg *arg,
+ char **error_str)
{
- enum filter_vals lval, rval;
+ int lval, rval;

switch (arg->type) {

@@ -844,63 +855,68 @@ enum filter_vals test_arg(struct filter_arg *parent, struct filter_arg *arg)
return FILTER_VAL_NORM;

case FILTER_ARG_EXP:
- lval = test_arg(arg, arg->exp.left);
+ lval = test_arg(arg, arg->exp.left, error_str);
if (lval != FILTER_VAL_NORM)
return lval;
- rval = test_arg(arg, arg->exp.right);
+ rval = test_arg(arg, arg->exp.right, error_str);
if (rval != FILTER_VAL_NORM)
return rval;
return FILTER_VAL_NORM;

case FILTER_ARG_NUM:
- lval = test_arg(arg, arg->num.left);
+ lval = test_arg(arg, arg->num.left, error_str);
if (lval != FILTER_VAL_NORM)
return lval;
- rval = test_arg(arg, arg->num.right);
+ rval = test_arg(arg, arg->num.right, error_str);
if (rval != FILTER_VAL_NORM)
return rval;
return FILTER_VAL_NORM;

case FILTER_ARG_OP:
if (arg->op.type != FILTER_OP_NOT) {
- lval = test_arg(arg, arg->op.left);
+ lval = test_arg(arg, arg->op.left, error_str);
switch (lval) {
case FILTER_VAL_NORM:
break;
case FILTER_VAL_TRUE:
if (arg->op.type == FILTER_OP_OR)
return FILTER_VAL_TRUE;
- rval = test_arg(arg, arg->op.right);
+ rval = test_arg(arg, arg->op.right, error_str);
if (rval != FILTER_VAL_NORM)
return rval;

- reparent_op_arg(parent, arg, arg->op.right);
- return FILTER_VAL_NORM;
+ return reparent_op_arg(parent, arg, arg->op.right,
+ error_str);

case FILTER_VAL_FALSE:
if (arg->op.type == FILTER_OP_AND)
return FILTER_VAL_FALSE;
- rval = test_arg(arg, arg->op.right);
+ rval = test_arg(arg, arg->op.right, error_str);
if (rval != FILTER_VAL_NORM)
return rval;

- reparent_op_arg(parent, arg, arg->op.right);
- return FILTER_VAL_NORM;
+ return reparent_op_arg(parent, arg, arg->op.right,
+ error_str);
+
+ default:
+ return lval;
}
}

- rval = test_arg(arg, arg->op.right);
+ rval = test_arg(arg, arg->op.right, error_str);
switch (rval) {
case FILTER_VAL_NORM:
+ default:
break;
+
case FILTER_VAL_TRUE:
if (arg->op.type == FILTER_OP_OR)
return FILTER_VAL_TRUE;
if (arg->op.type == FILTER_OP_NOT)
return FILTER_VAL_FALSE;

- reparent_op_arg(parent, arg, arg->op.left);
- return FILTER_VAL_NORM;
+ return reparent_op_arg(parent, arg, arg->op.left,
+ error_str);

case FILTER_VAL_FALSE:
if (arg->op.type == FILTER_OP_AND)
@@ -908,26 +924,27 @@ enum filter_vals test_arg(struct filter_arg *parent, struct filter_arg *arg)
if (arg->op.type == FILTER_OP_NOT)
return FILTER_VAL_TRUE;

- reparent_op_arg(parent, arg, arg->op.left);
- return FILTER_VAL_NORM;
+ return reparent_op_arg(parent, arg, arg->op.left,
+ error_str);
}

- return FILTER_VAL_NORM;
+ return rval;
default:
- die("bad arg in filter tree");
+ show_error(error_str, "bad arg in filter tree");
+ return PEVENT_ERRNO__BAD_FILTER_ARG;
}
return FILTER_VAL_NORM;
}

/* Remove any unknown event fields */
-static struct filter_arg *collapse_tree(struct filter_arg *arg)
+static struct filter_arg *collapse_tree(struct filter_arg *arg, char **error_str)
{
enum filter_vals ret;

- ret = test_arg(arg, arg);
+ ret = test_arg(arg, arg, error_str);
switch (ret) {
case FILTER_VAL_NORM:
- return arg;
+ break;

case FILTER_VAL_TRUE:
case FILTER_VAL_FALSE:
@@ -936,7 +953,16 @@ static struct filter_arg *collapse_tree(struct filter_arg *arg)
if (arg) {
arg->type = FILTER_ARG_BOOLEAN;
arg->boolean.value = ret == FILTER_VAL_TRUE;
+ } else {
+ show_error(error_str, "Failed to allocate filter arg");
}
+ break;
+
+ default:
+ /* test_arg() already set the error_str */
+ free_arg(arg);
+ arg = NULL;
+ break;
}

return arg;
@@ -1152,9 +1178,9 @@ process_filter(struct event_format *event, struct filter_arg **parg,
if (!current_op)
current_op = current_exp;

- current_op = collapse_tree(current_op);
+ current_op = collapse_tree(current_op, error_str);
if (current_op == NULL)
- goto fail_alloc;
+ goto fail;

*parg = current_op;

Arnaldo Carvalho de Melo

unread,
Dec 13, 2013, 10:20:02 AM12/13/13
to
From: Adrian Hunter <adrian...@intel.com>

Move functions mem_bswap_32() and mem_bswap_64() so they can be reused.

Signed-off-by: Adrian Hunter <adrian...@intel.com>
Cc: Andi Kleen <a...@linux.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/1386765443-26966-21-git-se...@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/session.c | 21 ---------------------
tools/perf/util/session.h | 2 --
tools/perf/util/util.c | 22 ++++++++++++++++++++++
tools/perf/util/util.h | 3 +++
4 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index e748f29c53cf..989b2e377626 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -247,27 +247,6 @@ void perf_tool__fill_defaults(struct perf_tool *tool)
}
}

-void mem_bswap_32(void *src, int byte_size)
-{
- u32 *m = src;
- while (byte_size > 0) {
- *m = bswap_32(*m);
- byte_size -= sizeof(u32);
- ++m;
- }
-}
-
-void mem_bswap_64(void *src, int byte_size)
-{
- u64 *m = src;
-
- while (byte_size > 0) {
- *m = bswap_64(*m);
- byte_size -= sizeof(u64);
- ++m;
- }
-}
-
static void swap_sample_id_all(union perf_event *event, void *data)
{
void *end = (void *) event + event->header.size;
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 2a3955ea4fd8..9c25d49900af 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -74,8 +74,6 @@ int perf_session__resolve_callchain(struct perf_session *session,

bool perf_session__has_traces(struct perf_session *session, const char *msg);

-void mem_bswap_64(void *src, int byte_size);
-void mem_bswap_32(void *src, int byte_size);
void perf_event__attr_swap(struct perf_event_attr *attr);

int perf_session__create_kernel_maps(struct perf_session *session);
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index 8f63dba212d7..42ad667bb317 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -10,6 +10,7 @@
#include <string.h>
#include <errno.h>
#include <limits.h>
+#include <byteswap.h>
#include <linux/kernel.h>

/*
@@ -515,3 +516,24 @@ int perf_event_paranoid(void)

return value;
}
+
+void mem_bswap_32(void *src, int byte_size)
+{
+ u32 *m = src;
+ while (byte_size > 0) {
+ *m = bswap_32(*m);
+ byte_size -= sizeof(u32);
+ ++m;
+ }
+}
+
+void mem_bswap_64(void *src, int byte_size)
+{
+ u64 *m = src;
+
+ while (byte_size > 0) {
+ *m = bswap_64(*m);
+ byte_size -= sizeof(u64);
+ ++m;
+ }
+}
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 1e7d4136cc82..a1eea3e809a3 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -323,5 +323,8 @@ int filename__read_int(const char *filename, int *value);
int filename__read_str(const char *filename, char **buf, size_t *sizep);
int perf_event_paranoid(void);

+void mem_bswap_64(void *src, int byte_size);
+void mem_bswap_32(void *src, int byte_size);
+
const char *get_filename_for_perf_kvm(void);
#endif /* GIT_COMPAT_UTIL_H */

Arnaldo Carvalho de Melo

unread,
Dec 13, 2013, 10:20:02 AM12/13/13
to
From: David Ahern <dsa...@gmail.com>

Commit 1902efe7f for the new comm infra added the wrong check for return
code on thread__set_comm. err == 0 is normal, so don't return at that
point unless err != 0.

Signed-off-by: David Ahern <dsa...@gmail.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Link: http://lkml.kernel.org/r/1386736538-23525-1-g...@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/thread.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 49eaf1d7d89d..e3948612543e 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -126,7 +126,7 @@ int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp)
if (!comm)
return -ENOMEM;
err = thread__set_comm(thread, comm, timestamp);
- if (!err)
+ if (err)
return err;
thread->comm_set = true;

Arnaldo Carvalho de Melo

unread,
Dec 13, 2013, 10:20:02 AM12/13/13
to
From: Namhyung Kim <namhyu...@lge.com>

So that it can return a proper pevent_errno value.

Signed-off-by: Namhyung Kim <namh...@kernel.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Steven Rostedt <ros...@goodmis.org>
Link: http://lkml.kernel.org/r/1386833777-3790-10-gi...@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/lib/traceevent/event-parse.h | 3 ++-
tools/lib/traceevent/parse-filter.c | 20 ++++++++++----------
2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index 5e4392d8e2d4..57b66aed8122 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -367,7 +367,8 @@ enum pevent_flag {
_PE(ILLEGAL_INTEGER_CMP,"illegal comparison for integer"), \
_PE(REPARENT_NOT_OP, "cannot reparent other than OP"), \
_PE(REPARENT_FAILED, "failed to reparent filter OP"), \
- _PE(BAD_FILTER_ARG, "bad arg in filter tree")
+ _PE(BAD_FILTER_ARG, "bad arg in filter tree"), \
+ _PE(UNEXPECTED_TYPE, "unexpected type (not a value)")

#undef _PE
#define _PE(__code, __str) PEVENT_ERRNO__ ## __code
diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c
index 9b05892566e0..8d71208f0131 100644
--- a/tools/lib/traceevent/parse-filter.c
+++ b/tools/lib/traceevent/parse-filter.c
@@ -368,9 +368,9 @@ static void free_events(struct event_list *events)
}
}

-static struct filter_arg *
+static enum pevent_errno
create_arg_item(struct event_format *event, const char *token,
- enum event_type type, char **error_str)
+ enum event_type type, struct filter_arg **parg, char **error_str)
{
struct format_field *field;
struct filter_arg *arg;
@@ -378,7 +378,7 @@ create_arg_item(struct event_format *event, const char *token,
arg = allocate_arg();
if (arg == NULL) {
show_error(error_str, "failed to allocate filter arg");
- return NULL;
+ return PEVENT_ERRNO__MEM_ALLOC_FAILED;
}

switch (type) {
@@ -392,7 +392,7 @@ create_arg_item(struct event_format *event, const char *token,
if (!arg->value.str) {
free_arg(arg);
show_error(error_str, "failed to allocate string filter arg");
- return NULL;
+ return PEVENT_ERRNO__MEM_ALLOC_FAILED;
}
break;
case EVENT_ITEM:
@@ -420,11 +420,11 @@ create_arg_item(struct event_format *event, const char *token,
break;
default:
free_arg(arg);
- show_error(error_str, "expected a value but found %s",
- token);
- return NULL;
+ show_error(error_str, "expected a value but found %s", token);
+ return PEVENT_ERRNO__UNEXPECTED_TYPE;
}
- return arg;
+ *parg = arg;
+ return 0;
}

static struct filter_arg *
@@ -993,8 +993,8 @@ process_filter(struct event_format *event, struct filter_arg **parg,
case EVENT_SQUOTE:
case EVENT_DQUOTE:
case EVENT_ITEM:
- arg = create_arg_item(event, token, type, error_str);
- if (!arg)
+ ret = create_arg_item(event, token, type, &arg, error_str);
+ if (ret < 0)
goto fail;
if (!left_item)
left_item = arg;

Arnaldo Carvalho de Melo

unread,
Dec 13, 2013, 10:20:02 AM12/13/13
to
From: Namhyung Kim <namhyu...@lge.com>

Refactor the pevent_filter_add_filter_str() to return a proper error
code and get rid of the third error_str argument.

Signed-off-by: Namhyung Kim <namh...@kernel.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Steven Rostedt <ros...@goodmis.org>
Link: http://lkml.kernel.org/r/1386833777-3790-12-gi...@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/lib/traceevent/event-parse.h | 8 ++--
tools/lib/traceevent/parse-filter.c | 78 +++++++++++--------------------------
2 files changed, 27 insertions(+), 59 deletions(-)

diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index da942d59cc3a..089964e56ed4 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -372,7 +372,8 @@ enum pevent_flag {
_PE(ILLEGAL_TOKEN, "illegal token"), \
_PE(INVALID_PAREN, "open parenthesis cannot come here"), \
_PE(UNBALANCED_PAREN, "unbalanced number of parenthesis"), \
- _PE(UNKNOWN_TOKEN, "unknown token")
+ _PE(UNKNOWN_TOKEN, "unknown token"), \
+ _PE(FILTER_NOT_FOUND, "no filter found")

#undef _PE
#define _PE(__code, __str) PEVENT_ERRNO__ ## __code
@@ -863,9 +864,8 @@ enum filter_trivial_type {
FILTER_TRIVIAL_BOTH,
};

-int pevent_filter_add_filter_str(struct event_filter *filter,
- const char *filter_str,
- char **error_str);
+enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter,
+ const char *filter_str);


int pevent_filter_match(struct event_filter *filter,
diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c
index 5aa5012a17ee..78440d73e0ad 100644
--- a/tools/lib/traceevent/parse-filter.c
+++ b/tools/lib/traceevent/parse-filter.c
@@ -1209,7 +1209,7 @@ process_filter(struct event_format *event, struct filter_arg **parg,
return ret;
}

-static int
+static enum pevent_errno
process_event(struct event_format *event, const char *filter_str,
struct filter_arg **parg, char **error_str)
{
@@ -1218,21 +1218,15 @@ process_event(struct event_format *event, const char *filter_str,
pevent_buffer_init(filter_str, strlen(filter_str));

ret = process_filter(event, parg, error_str, 0);
- if (ret == 1) {
- show_error(error_str,
- "Unbalanced number of ')'");
- return -1;
- }
if (ret < 0)
return ret;

/* If parg is NULL, then make it into FALSE */
if (!*parg) {
*parg = allocate_arg();
- if (*parg == NULL) {
- show_error(error_str, "failed to allocate filter arg");
- return -1;
- }
+ if (*parg == NULL)
+ return PEVENT_ERRNO__MEM_ALLOC_FAILED;
+
(*parg)->type = FILTER_ARG_BOOLEAN;
(*parg)->boolean.value = FILTER_FALSE;
}
@@ -1240,13 +1234,13 @@ process_event(struct event_format *event, const char *filter_str,
return 0;
}

-static int filter_event(struct event_filter *filter,
- struct event_format *event,
- const char *filter_str, char **error_str)
+static enum pevent_errno
+filter_event(struct event_filter *filter, struct event_format *event,
+ const char *filter_str, char **error_str)
{
struct filter_type *filter_type;
struct filter_arg *arg;
- int ret;
+ enum pevent_errno ret;

if (filter_str) {
ret = process_event(event, filter_str, &arg, error_str);
@@ -1256,20 +1250,16 @@ static int filter_event(struct event_filter *filter,
} else {
/* just add a TRUE arg */
arg = allocate_arg();
- if (arg == NULL) {
- show_error(error_str, "failed to allocate filter arg");
- return -1;
- }
+ if (arg == NULL)
+ return PEVENT_ERRNO__MEM_ALLOC_FAILED;
+
arg->type = FILTER_ARG_BOOLEAN;
arg->boolean.value = FILTER_TRUE;
}

filter_type = add_filter_type(filter, event->id);
- if (filter_type == NULL) {
- show_error(error_str, "failed to add a new filter: %s",
- filter_str ? filter_str : "true");
- return -1;
- }
+ if (filter_type == NULL)
+ return PEVENT_ERRNO__MEM_ALLOC_FAILED;

if (filter_type->filter)
free_arg(filter_type->filter);
@@ -1282,18 +1272,12 @@ static int filter_event(struct event_filter *filter,
* pevent_filter_add_filter_str - add a new filter
* @filter: the event filter to add to
* @filter_str: the filter string that contains the filter
- * @error_str: string containing reason for failed filter
- *
- * Returns 0 if the filter was successfully added
- * -1 if there was an error.
*
- * On error, if @error_str points to a string pointer,
- * it is set to the reason that the filter failed.
- * This string must be freed with "free".
+ * Returns 0 if the filter was successfully added or a
+ * negative error code.
*/
-int pevent_filter_add_filter_str(struct event_filter *filter,
- const char *filter_str,
- char **error_str)
+enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter,
+ const char *filter_str)
{
struct pevent *pevent = filter->pevent;
struct event_list *event;
@@ -1304,23 +1288,20 @@ int pevent_filter_add_filter_str(struct event_filter *filter,
char *event_name = NULL;
char *sys_name = NULL;
char *sp;
- int rtn = 0;
+ enum pevent_errno rtn = 0; /* PEVENT_ERRNO__SUCCESS */
int len;
int ret;
+ char *error_str = NULL;

/* clear buffer to reset show error */
pevent_buffer_init("", 0);

- if (error_str)
- *error_str = NULL;
-
filter_start = strchr(filter_str, ':');
if (filter_start)
len = filter_start - filter_str;
else
len = strlen(filter_str);

-
do {
next_event = strchr(filter_str, ',');
if (next_event &&
@@ -1333,10 +1314,9 @@ int pevent_filter_add_filter_str(struct event_filter *filter,

this_event = malloc(len + 1);
if (this_event == NULL) {
- show_error(error_str, "Memory allocation failure");
/* This can only happen when events is NULL, but still */
free_events(events);
- return -1;
+ return PEVENT_ERRNO__MEM_ALLOC_FAILED;
}
memcpy(this_event, filter_str, len);
this_event[len] = 0;
@@ -1350,30 +1330,18 @@ int pevent_filter_add_filter_str(struct event_filter *filter,
event_name = strtok_r(NULL, "/", &sp);

if (!sys_name) {
- show_error(error_str, "No filter found");
/* This can only happen when events is NULL, but still */
free_events(events);
free(this_event);
- return -1;
+ return PEVENT_ERRNO__FILTER_NOT_FOUND;
}

/* Find this event */
ret = find_event(pevent, &events, strim(sys_name), strim(event_name));
if (ret < 0) {
- if (ret == PEVENT_ERRNO__MEM_ALLOC_FAILED)
- show_error(error_str,
- "Memory allocation failure");
- else if (event_name)
- show_error(error_str,
- "No event found under '%s.%s'",
- sys_name, event_name);
- else
- show_error(error_str,
- "No event found under '%s'",
- sys_name);
free_events(events);
free(this_event);
- return -1;
+ return ret;
}
free(this_event);
} while (filter_str);
@@ -1385,7 +1353,7 @@ int pevent_filter_add_filter_str(struct event_filter *filter,
/* filter starts here */
for (event = events; event; event = event->next) {
ret = filter_event(filter, event->event, filter_start,
- error_str);
+ &error_str);
/* Failures are returned if a parse error happened */
if (ret < 0)
rtn = ret;

Arnaldo Carvalho de Melo

unread,
Dec 13, 2013, 10:20:02 AM12/13/13
to
From: Adrian Hunter <adrian...@intel.com>

Add a function to move a selected event to the
front of the list.

This is needed because it is not possible
to use the PERF_EVENT_IOC_SET_OUTPUT IOCTL
from an Instruction Tracing event to a
non-Instruction Tracing event. Thus the
Instruction Tracing event must come first.

Cc: Andi Kleen <a...@linux.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/1386765443-26966-24-git-se...@linux.intel.com
Signed-off-by: Adrian Hunter <adrian...@intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/evlist.c | 17 +++++++++++++++++
tools/perf/util/evlist.h | 3 +++
2 files changed, 20 insertions(+)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 2eb7378e4c40..0b31cee34874 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1212,3 +1212,20 @@ int perf_evlist__strerror_open(struct perf_evlist *evlist __maybe_unused,

return 0;
}
+
+void perf_evlist__to_front(struct perf_evlist *evlist,
+ struct perf_evsel *move_evsel)
+{
+ struct perf_evsel *evsel, *n;
+ LIST_HEAD(move);
+
+ if (move_evsel == perf_evlist__first(evlist))
+ return;
+
+ list_for_each_entry_safe(evsel, n, &evlist->entries, node) {
+ if (evsel->leader == move_evsel->leader)
+ list_move_tail(&evsel->node, &move);
+ }
+
+ list_splice(&move, &evlist->entries);
+}
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 8a04aae95a18..9f64ede3ecbd 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -194,5 +194,8 @@ static inline void perf_mmap__write_tail(struct perf_mmap *md,
}

bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str);
+void perf_evlist__to_front(struct perf_evlist *evlist,
+ struct perf_evsel *move_evsel);
+

#endif /* __PERF_EVLIST_H */

Arnaldo Carvalho de Melo

unread,
Dec 13, 2013, 10:20:02 AM12/13/13
to
From: Adrian Hunter <adrian...@intel.com>

Add a function to return the value of
/proc/sys/kernel/perf_event_paranoid.

This will be used to determine default values for mmap size because perf
is not subject to mmap limits when perf_event_paranoid is less than
zero.

Signed-off-by: Adrian Hunter <adrian...@intel.com>
Cc: Andi Kleen <a...@linux.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/1386765443-26966-12-git-se...@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/evlist.c | 3 +--
tools/perf/util/util.c | 19 +++++++++++++++++++
tools/perf/util/util.h | 1 +
3 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index af250556b33f..2eb7378e4c40 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1191,8 +1191,7 @@ int perf_evlist__strerror_open(struct perf_evlist *evlist __maybe_unused,
"Error:\t%s.\n"
"Hint:\tCheck /proc/sys/kernel/perf_event_paranoid setting.", emsg);

- if (filename__read_int("/proc/sys/kernel/perf_event_paranoid", &value))
- break;
+ value = perf_event_paranoid();

printed += scnprintf(buf + printed, size - printed, "\nHint:\t");

diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index 4a57609c0b43..8f63dba212d7 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -1,5 +1,6 @@
#include "../perf.h"
#include "util.h"
+#include "fs.h"
#include <sys/mman.h>
#ifdef HAVE_BACKTRACE_SUPPORT
#include <execinfo.h>
@@ -8,6 +9,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
+#include <limits.h>
#include <linux/kernel.h>

/*
@@ -496,3 +498,20 @@ const char *get_filename_for_perf_kvm(void)

return filename;
}
+
+int perf_event_paranoid(void)
+{
+ char path[PATH_MAX];
+ const char *procfs = procfs__mountpoint();
+ int value;
+
+ if (!procfs)
+ return INT_MAX;
+
+ scnprintf(path, PATH_MAX, "%s/sys/kernel/perf_event_paranoid", procfs);
+
+ if (filename__read_int(path, &value))
+ return INT_MAX;
+
+ return value;
+}
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 0171213d1d4d..1e7d4136cc82 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -321,6 +321,7 @@ void free_srcline(char *srcline);

int filename__read_int(const char *filename, int *value);
int filename__read_str(const char *filename, char **buf, size_t *sizep);
+int perf_event_paranoid(void);

const char *get_filename_for_perf_kvm(void);
#endif /* GIT_COMPAT_UTIL_H */

Arnaldo Carvalho de Melo

unread,
Dec 13, 2013, 10:20:02 AM12/13/13
to
From: Ramkumar Ramachandra <arta...@gmail.com>

Currently, there is no way to enumerate the subcommands under 'perf
kvm', so hardcode them.

Signed-off-by: Ramkumar Ramachandra <arta...@gmail.com>
Link: http://lkml.kernel.org/r/1386758056-24618-2-gi...@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/perf-completion.sh | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/tools/perf/perf-completion.sh b/tools/perf/perf-completion.sh
index 49494882d9bb..496e2abb5482 100644
--- a/tools/perf/perf-completion.sh
+++ b/tools/perf/perf-completion.sh
@@ -121,6 +121,10 @@ __perf_main ()
elif [[ $prev == "-e" && "${words[1]}" == @(record|stat|top) ]]; then
evts=$($cmd list --raw-dump)
__perfcomp_colon "$evts" "$cur"
+ # List subcommands for 'perf kvm'
+ elif [[ $prev == "kvm" ]]; then
+ subcmds="top record report diff buildid-list stat"
+ __perfcomp_colon "$subcmds" "$cur"
# List long option names
elif [[ $cur == --* ]]; then
subcmd=${words[1]}

Arnaldo Carvalho de Melo

unread,
Dec 13, 2013, 10:20:02 AM12/13/13
to
From: Namhyung Kim <namhyu...@lge.com>

So that it can return a proper pevent_errno value.

Signed-off-by: Namhyung Kim <namh...@kernel.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Steven Rostedt <ros...@goodmis.org>
Link: http://lkml.kernel.org/r/1386833777-3790-11-gi...@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/lib/traceevent/event-parse.h | 6 +++-
tools/lib/traceevent/parse-filter.c | 64 +++++++++++++++++++++----------------
2 files changed, 42 insertions(+), 28 deletions(-)

diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index 57b66aed8122..da942d59cc3a 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -368,7 +368,11 @@ enum pevent_flag {
_PE(REPARENT_NOT_OP, "cannot reparent other than OP"), \
_PE(REPARENT_FAILED, "failed to reparent filter OP"), \
_PE(BAD_FILTER_ARG, "bad arg in filter tree"), \
- _PE(UNEXPECTED_TYPE, "unexpected type (not a value)")
+ _PE(UNEXPECTED_TYPE, "unexpected type (not a value)"), \
+ _PE(ILLEGAL_TOKEN, "illegal token"), \
+ _PE(INVALID_PAREN, "open parenthesis cannot come here"), \
+ _PE(UNBALANCED_PAREN, "unbalanced number of parenthesis"), \
+ _PE(UNKNOWN_TOKEN, "unknown token")

#undef _PE
#define _PE(__code, __str) PEVENT_ERRNO__ ## __code
diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c
index 8d71208f0131..5aa5012a17ee 100644
--- a/tools/lib/traceevent/parse-filter.c
+++ b/tools/lib/traceevent/parse-filter.c
@@ -937,9 +937,10 @@ static int test_arg(struct filter_arg *parent, struct filter_arg *arg,
}

/* Remove any unknown event fields */
-static struct filter_arg *collapse_tree(struct filter_arg *arg, char **error_str)
+static int collapse_tree(struct filter_arg *arg,
+ struct filter_arg **arg_collapsed, char **error_str)
{
- enum filter_vals ret;
+ int ret;

ret = test_arg(arg, arg, error_str);
switch (ret) {
@@ -955,6 +956,7 @@ static struct filter_arg *collapse_tree(struct filter_arg *arg, char **error_str
arg->boolean.value = ret == FILTER_VAL_TRUE;
} else {
show_error(error_str, "Failed to allocate filter arg");
+ ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
}
break;

@@ -965,10 +967,11 @@ static struct filter_arg *collapse_tree(struct filter_arg *arg, char **error_str
break;
}

- return arg;
+ *arg_collapsed = arg;
+ return ret;
}

-static int
+static enum pevent_errno
process_filter(struct event_format *event, struct filter_arg **parg,
char **error_str, int not)
{
@@ -982,7 +985,7 @@ process_filter(struct event_format *event, struct filter_arg **parg,
enum filter_op_type btype;
enum filter_exp_type etype;
enum filter_cmp_type ctype;
- int ret;
+ enum pevent_errno ret;

*parg = NULL;

@@ -1007,20 +1010,20 @@ process_filter(struct event_format *event, struct filter_arg **parg,
if (not) {
arg = NULL;
if (current_op)
- goto fail_print;
+ goto fail_syntax;
free(token);
*parg = current_exp;
return 0;
}
} else
- goto fail_print;
+ goto fail_syntax;
arg = NULL;
break;

case EVENT_DELIM:
if (*token == ',') {
- show_error(error_str,
- "Illegal token ','");
+ show_error(error_str, "Illegal token ','");
+ ret = PEVENT_ERRNO__ILLEGAL_TOKEN;
goto fail;
}

@@ -1028,19 +1031,23 @@ process_filter(struct event_format *event, struct filter_arg **parg,
if (left_item) {
show_error(error_str,
"Open paren can not come after item");
+ ret = PEVENT_ERRNO__INVALID_PAREN;
goto fail;
}
if (current_exp) {
show_error(error_str,
"Open paren can not come after expression");
+ ret = PEVENT_ERRNO__INVALID_PAREN;
goto fail;
}

ret = process_filter(event, &arg, error_str, 0);
- if (ret != 1) {
- if (ret == 0)
+ if (ret != PEVENT_ERRNO__UNBALANCED_PAREN) {
+ if (ret == 0) {
show_error(error_str,
"Unbalanced number of '('");
+ ret = PEVENT_ERRNO__UNBALANCED_PAREN;
+ }
goto fail;
}
ret = 0;
@@ -1048,7 +1055,7 @@ process_filter(struct event_format *event, struct filter_arg **parg,
/* A not wants just one expression */
if (not) {
if (current_op)
- goto fail_print;
+ goto fail_syntax;
*parg = arg;
return 0;
}
@@ -1063,19 +1070,19 @@ process_filter(struct event_format *event, struct filter_arg **parg,

} else { /* ')' */
if (!current_op && !current_exp)
- goto fail_print;
+ goto fail_syntax;

/* Make sure everything is finished at this level */
if (current_exp && !check_op_done(current_exp))
- goto fail_print;
+ goto fail_syntax;
if (current_op && !check_op_done(current_op))
- goto fail_print;
+ goto fail_syntax;

if (current_op)
*parg = current_op;
else
*parg = current_exp;
- return 1;
+ return PEVENT_ERRNO__UNBALANCED_PAREN;
}
break;

@@ -1087,21 +1094,22 @@ process_filter(struct event_format *event, struct filter_arg **parg,
case OP_BOOL:
/* Logic ops need a left expression */
if (!current_exp && !current_op)
- goto fail_print;
+ goto fail_syntax;
/* fall through */
case OP_NOT:
/* logic only processes ops and exp */
if (left_item)
- goto fail_print;
+ goto fail_syntax;
break;
case OP_EXP:
case OP_CMP:
if (!left_item)
- goto fail_print;
+ goto fail_syntax;
break;
case OP_NONE:
show_error(error_str,
"Unknown op token %s", token);
+ ret = PEVENT_ERRNO__UNKNOWN_TOKEN;
goto fail;
}

@@ -1152,7 +1160,7 @@ process_filter(struct event_format *event, struct filter_arg **parg,
ret = add_left(arg, left_item);
if (ret < 0) {
arg = NULL;
- goto fail_print;
+ goto fail_syntax;
}
current_exp = arg;
break;
@@ -1161,25 +1169,25 @@ process_filter(struct event_format *event, struct filter_arg **parg,
}
arg = NULL;
if (ret < 0)
- goto fail_print;
+ goto fail_syntax;
break;
case EVENT_NONE:
break;
case EVENT_ERROR:
goto fail_alloc;
default:
- goto fail_print;
+ goto fail_syntax;
}
} while (type != EVENT_NONE);

if (!current_op && !current_exp)
- goto fail_print;
+ goto fail_syntax;

if (!current_op)
current_op = current_exp;

- current_op = collapse_tree(current_op, error_str);
- if (current_op == NULL)
+ ret = collapse_tree(current_op, parg, error_str);
+ if (ret < 0)
goto fail;

*parg = current_op;
@@ -1188,15 +1196,17 @@ process_filter(struct event_format *event, struct filter_arg **parg,

fail_alloc:
show_error(error_str, "failed to allocate filter arg");
+ ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
goto fail;
- fail_print:
+ fail_syntax:
show_error(error_str, "Syntax error");
+ ret = PEVENT_ERRNO__SYNTAX_ERROR;
fail:
free_arg(current_op);
free_arg(current_exp);
free_arg(arg);
free(token);
- return -1;
+ return ret;
}

static int

Arnaldo Carvalho de Melo

unread,
Dec 13, 2013, 10:20:03 AM12/13/13
to
From: Adrian Hunter <adrian...@intel.com>

Add a function to determine whether an event can be selected.

This function is needed to allow a tool to automatically select
additional events, but only if they are available.

Signed-off-by: Adrian Hunter <adrian...@intel.com>
Cc: Andi Kleen <a...@linux.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/1386765443-26966-18-git-se...@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/evlist.h | 2 ++
tools/perf/util/record.c | 37 +++++++++++++++++++++++++++++++++++++
2 files changed, 39 insertions(+)

diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 649d6ea98a84..8a04aae95a18 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -193,4 +193,6 @@ static inline void perf_mmap__write_tail(struct perf_mmap *md,
pc->data_tail = tail;
}

+bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str);
+
#endif /* __PERF_EVLIST_H */
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
index c8845b107f60..e5104538c354 100644
--- a/tools/perf/util/record.c
+++ b/tools/perf/util/record.c
@@ -177,3 +177,40 @@ int perf_record_opts__config(struct perf_record_opts *opts)
{
return perf_record_opts__config_freq(opts);
}
+
+bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str)
+{
+ struct perf_evlist *temp_evlist;
+ struct perf_evsel *evsel;
+ int err, fd, cpu;
+ bool ret = false;
+
+ temp_evlist = perf_evlist__new();
+ if (!temp_evlist)
+ return false;
+
+ err = parse_events(temp_evlist, str);
+ if (err)
+ goto out_delete;
+
+ evsel = perf_evlist__last(temp_evlist);
+
+ if (!evlist || cpu_map__empty(evlist->cpus)) {
+ struct cpu_map *cpus = cpu_map__new(NULL);
+
+ cpu = cpus ? cpus->map[0] : 0;
+ cpu_map__delete(cpus);
+ } else {
+ cpu = evlist->cpus->map[0];
+ }
+
+ fd = sys_perf_event_open(&evsel->attr, -1, cpu, -1, 0);
+ if (fd >= 0) {
+ close(fd);
+ ret = true;
+ }
+
+out_delete:
+ perf_evlist__delete(temp_evlist);
+ return ret;
+}

Arnaldo Carvalho de Melo

unread,
Dec 13, 2013, 10:20:03 AM12/13/13
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

Eventually this should be useful to other tools/ living utilities.

For now don't try to build any .a, just trying the minimal approach of
separating existing code into multiple .c files that can then be
included wherever they are needed, using whatever build machinery
already in place.

Cc: Adrian Hunter <adrian...@intel.com>
Cc: Borislav Petkov <b...@alien8.de>
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-pfa8i5zpf4...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/lib/symbol/kallsyms.c | 58 +++++++++++++++++++++++++++++++++++++
tools/lib/symbol/kallsyms.h | 24 +++++++++++++++
tools/perf/MANIFEST | 2 ++
tools/perf/Makefile.perf | 5 ++++
tools/perf/util/event.c | 1 +
tools/perf/util/machine.c | 1 +
tools/perf/util/symbol-elf.c | 1 +
tools/perf/util/symbol.c | 69 +-------------------------------------------
tools/perf/util/symbol.h | 3 --
9 files changed, 93 insertions(+), 71 deletions(-)
create mode 100644 tools/lib/symbol/kallsyms.c
create mode 100644 tools/lib/symbol/kallsyms.h

diff --git a/tools/lib/symbol/kallsyms.c b/tools/lib/symbol/kallsyms.c
new file mode 100644
index 000000000000..18bc271a4bbc
--- /dev/null
+++ b/tools/lib/symbol/kallsyms.c
@@ -0,0 +1,58 @@
+#include "symbol/kallsyms.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+int kallsyms__parse(const char *filename, void *arg,
+ int (*process_symbol)(void *arg, const char *name,
+ char type, u64 start))
+{
+ char *line = NULL;
+ size_t n;
+ int err = -1;
+ FILE *file = fopen(filename, "r");
+
+ if (file == NULL)
+ goto out_failure;
+
+ err = 0;
+
+ while (!feof(file)) {
+ u64 start;
+ int line_len, len;
+ char symbol_type;
+ char *symbol_name;
+
+ line_len = getline(&line, &n, file);
+ if (line_len < 0 || !line)
+ break;
+
+ line[--line_len] = '\0'; /* \n */
+
+ len = hex2u64(line, &start);
+
+ len++;
+ if (len + 2 >= line_len)
+ continue;
+
+ symbol_type = line[len];
+ len += 2;
+ symbol_name = line + len;
+ len = line_len - len;
+
+ if (len >= KSYM_NAME_LEN) {
+ err = -1;
+ break;
+ }
+
+ err = process_symbol(arg, symbol_name, symbol_type, start);
+ if (err)
+ break;
+ }
+
+ free(line);
+ fclose(file);
+ return err;
+
+out_failure:
+ return -1;
+}
diff --git a/tools/lib/symbol/kallsyms.h b/tools/lib/symbol/kallsyms.h
new file mode 100644
index 000000000000..6084f5e18b3c
--- /dev/null
+++ b/tools/lib/symbol/kallsyms.h
@@ -0,0 +1,24 @@
+#ifndef __TOOLS_KALLSYMS_H_
+#define __TOOLS_KALLSYMS_H_ 1
+
+#include <elf.h>
+#include <linux/ctype.h>
+#include <linux/types.h>
+
+#ifndef KSYM_NAME_LEN
+#define KSYM_NAME_LEN 256
+#endif
+
+static inline u8 kallsyms2elf_type(char type)
+{
+ if (type == 'W')
+ return STB_WEAK;
+
+ return isupper(type) ? STB_GLOBAL : STB_LOCAL;
+}
+
+int kallsyms__parse(const char *filename, void *arg,
+ int (*process_symbol)(void *arg, const char *name,
+ char type, u64 start));
+
+#endif /* __TOOLS_KALLSYMS_H_ */
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST
index 025de796067c..3170a7ff5782 100644
--- a/tools/perf/MANIFEST
+++ b/tools/perf/MANIFEST
@@ -2,6 +2,8 @@ tools/perf
tools/scripts
tools/lib/traceevent
tools/lib/lk
+tools/lib/symbol/kallsyms.c
+tools/lib/symbol/kallsyms.h
include/linux/const.h
include/linux/perf_event.h
include/linux/rbtree.h
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 9a8cf376f874..fad61079e795 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -202,6 +202,7 @@ $(OUTPUT)util/pmu.o: $(OUTPUT)util/pmu-flex.c $(OUTPUT)util/pmu-bison.c

LIB_FILE=$(OUTPUT)libperf.a

+LIB_H += ../lib/symbol/kallsyms.h
LIB_H += ../../include/uapi/linux/perf_event.h
LIB_H += ../../include/linux/rbtree.h
LIB_H += ../../include/linux/list.h
@@ -312,6 +313,7 @@ LIB_OBJS += $(OUTPUT)util/evlist.o
LIB_OBJS += $(OUTPUT)util/evsel.o
LIB_OBJS += $(OUTPUT)util/exec_cmd.o
LIB_OBJS += $(OUTPUT)util/help.o
+LIB_OBJS += $(OUTPUT)util/kallsyms.o
LIB_OBJS += $(OUTPUT)util/levenshtein.o
LIB_OBJS += $(OUTPUT)util/parse-options.o
LIB_OBJS += $(OUTPUT)util/parse-events.o
@@ -672,6 +674,9 @@ $(OUTPUT)ui/browsers/map.o: ui/browsers/map.c $(OUTPUT)PERF-CFLAGS
$(OUTPUT)ui/browsers/scripts.o: ui/browsers/scripts.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<

+$(OUTPUT)util/kallsyms.o: ../lib/symbol/kallsyms.c $(OUTPUT)PERF-CFLAGS
+ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $<
+
$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index c77814bf01e1..694876877ae2 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -7,6 +7,7 @@
#include "strlist.h"
#include "thread.h"
#include "thread_map.h"
+#include "symbol/kallsyms.h"

static const char *perf_event__names[] = {
[0] = "TOTAL",
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 751454bcde69..c78cc84f433e 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -9,6 +9,7 @@
#include "strlist.h"
#include "thread.h"
#include <stdbool.h>
+#include <symbol/kallsyms.h>
#include "unwind.h"

int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index eed0b96302af..bf0ce29567b6 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -6,6 +6,7 @@
#include <inttypes.h>

#include "symbol.h"
+#include <symbol/kallsyms.h>
#include "debug.h"

#ifndef HAVE_ELF_GETPHDRNUM_SUPPORT
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index e377c2e96191..61eb1cddf01a 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -18,12 +18,9 @@

#include <elf.h>
#include <limits.h>
+#include <symbol/kallsyms.h>
#include <sys/utsname.h>

-#ifndef KSYM_NAME_LEN
-#define KSYM_NAME_LEN 256
-#endif
-
static int dso__load_kernel_sym(struct dso *dso, struct map *map,
symbol_filter_t filter);
static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
@@ -446,62 +443,6 @@ size_t dso__fprintf_symbols_by_name(struct dso *dso,
return ret;
}

-int kallsyms__parse(const char *filename, void *arg,
- int (*process_symbol)(void *arg, const char *name,
- char type, u64 start))
-{
- char *line = NULL;
- size_t n;
- int err = -1;
- FILE *file = fopen(filename, "r");
-
- if (file == NULL)
- goto out_failure;
-
- err = 0;
-
- while (!feof(file)) {
- u64 start;
- int line_len, len;
- char symbol_type;
- char *symbol_name;
-
- line_len = getline(&line, &n, file);
- if (line_len < 0 || !line)
- break;
-
- line[--line_len] = '\0'; /* \n */
-
- len = hex2u64(line, &start);
-
- len++;
- if (len + 2 >= line_len)
- continue;
-
- symbol_type = line[len];
- len += 2;
- symbol_name = line + len;
- len = line_len - len;
-
- if (len >= KSYM_NAME_LEN) {
- err = -1;
- break;
- }
-
- err = process_symbol(arg, symbol_name,
- symbol_type, start);
- if (err)
- break;
- }
-
- free(line);
- fclose(file);
- return err;
-
-out_failure:
- return -1;
-}
-
int modules__parse(const char *filename, void *arg,
int (*process_module)(void *arg, const char *name,
u64 start))
@@ -565,14 +506,6 @@ struct process_kallsyms_args {
struct dso *dso;
};

-static u8 kallsyms2elf_type(char type)
-{
- if (type == 'W')
- return STB_WEAK;
-
- return isupper(type) ? STB_GLOBAL : STB_LOCAL;
-}
-
bool symbol__is_idle(struct symbol *sym)
{
const char * const idle_symbols[] = {
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 6de9c2b8a601..8a9d910c5345 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -221,9 +221,6 @@ struct symbol *dso__first_symbol(struct dso *dso, enum map_type type);

int filename__read_build_id(const char *filename, void *bf, size_t size);
int sysfs__read_build_id(const char *filename, void *bf, size_t size);
-int kallsyms__parse(const char *filename, void *arg,
- int (*process_symbol)(void *arg, const char *name,
- char type, u64 start));
int modules__parse(const char *filename, void *arg,
int (*process_module)(void *arg, const char *name,
u64 start));

Arnaldo Carvalho de Melo

unread,
Dec 13, 2013, 10:20:01 AM12/13/13
to
From: Namhyung Kim <namh...@kernel.org>

Signed-off-by: Namhyung Kim <namh...@kernel.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namhyu...@lge.com>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Steven Rostedt <ros...@goodmis.org>
Link: http://lkml.kernel.org/r/1386833777-3790-2-gi...@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/lib/traceevent/parse-filter.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c
index ab402fb2dcf7..d4b0bac80dc8 100644
--- a/tools/lib/traceevent/parse-filter.c
+++ b/tools/lib/traceevent/parse-filter.c
@@ -56,7 +56,21 @@ static void show_error(char **error_str, const char *fmt, ...)
index = pevent_get_input_buf_ptr();
len = input ? strlen(input) : 0;

- error = malloc_or_die(MAX_ERR_STR_SIZE + (len*2) + 3);
+ error = malloc(MAX_ERR_STR_SIZE + (len*2) + 3);
+ if (error == NULL) {
+ /*
+ * Maybe it's due to len is too long.
+ * Retry without the input buffer part.
+ */
+ len = 0;
+
+ error = malloc(MAX_ERR_STR_SIZE);
+ if (error == NULL) {
+ /* no memory */
+ *error_str = NULL;
+ return;
+ }
+ }

if (len) {
strcpy(error, input);

Arnaldo Carvalho de Melo

unread,
Dec 13, 2013, 10:20:02 AM12/13/13
to
From: Namhyung Kim <namh...@kernel.org>

Signed-off-by: Namhyung Kim <namh...@kernel.org>
Reviewed-by: Steven Rostedt <ros...@goodmis.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namhyu...@lge.com>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Steven Rostedt <ros...@goodmis.org>
Link: http://lkml.kernel.org/r/1386833777-3790-5-gi...@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/lib/traceevent/parse-filter.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c
index ab9cefe320b4..246ee81e1f93 100644
--- a/tools/lib/traceevent/parse-filter.c
+++ b/tools/lib/traceevent/parse-filter.c
@@ -109,7 +109,11 @@ static enum event_type read_token(char **tok)
(strcmp(token, "=") == 0 || strcmp(token, "!") == 0) &&
pevent_peek_char() == '~') {
/* append it */
- *tok = malloc_or_die(3);
+ *tok = malloc(3);
+ if (*tok == NULL) {
+ free_token(token);
+ return EVENT_ERROR;
+ }
sprintf(*tok, "%c%c", *token, '~');
free_token(token);
/* Now remove the '~' from the buffer */
@@ -1123,6 +1127,8 @@ process_filter(struct event_format *event, struct filter_arg **parg,
break;
case EVENT_NONE:
break;
+ case EVENT_ERROR:
+ goto fail_alloc;
default:
goto fail_print;

Arnaldo Carvalho de Melo

unread,
Dec 13, 2013, 10:20:01 AM12/13/13
to
From: Namhyung Kim <namh...@kernel.org>

The realloc() should check return value and not to overwrite previous
pointer in case of error.

Signed-off-by: Namhyung Kim <namh...@kernel.org>
Reviewed-by: Steven Rostedt <ros...@goodmis.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namhyu...@lge.com>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Steven Rostedt <ros...@goodmis.org>
Link: http://lkml.kernel.org/r/1386833777-3790-3-gi...@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/lib/traceevent/parse-filter.c | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c
index d4b0bac80dc8..767de4f1e8ee 100644
--- a/tools/lib/traceevent/parse-filter.c
+++ b/tools/lib/traceevent/parse-filter.c
@@ -161,11 +161,13 @@ add_filter_type(struct event_filter *filter, int id)
if (filter_type)
return filter_type;

- filter->event_filters = realloc(filter->event_filters,
- sizeof(*filter->event_filters) *
- (filter->filters + 1));
- if (!filter->event_filters)
- die("Could not allocate filter");
+ filter_type = realloc(filter->event_filters,
+ sizeof(*filter->event_filters) *
+ (filter->filters + 1));
+ if (!filter_type)
+ return NULL;
+
+ filter->event_filters = filter_type;

for (i = 0; i < filter->filters; i++) {
if (filter->event_filters[i].event_id > id)
@@ -1180,6 +1182,12 @@ static int filter_event(struct event_filter *filter,
}

filter_type = add_filter_type(filter, event->id);
+ if (filter_type == NULL) {
+ show_error(error_str, "failed to add a new filter: %s",
+ filter_str ? filter_str : "true");
+ return -1;
+ }
+
if (filter_type->filter)
free_arg(filter_type->filter);
filter_type->filter = arg;
@@ -1417,6 +1425,9 @@ static int copy_filter_type(struct event_filter *filter,
arg->boolean.value = 0;

filter_type = add_filter_type(filter, event->id);
+ if (filter_type == NULL)
+ return -1;
+
filter_type->filter = arg;

free(str);

Arnaldo Carvalho de Melo

unread,
Dec 13, 2013, 10:20:03 AM12/13/13
to
From: Namhyung Kim <namh...@kernel.org>

The test_filter() function is for testing given filter is matched to a
given record. However it doesn't handle error cases properly so add a
new argument err to save error info during the test and also pass it to
internal test functions.

The return value of pevent_filter_match() also converted to pevent_errno
to indicate an exact error case.

Signed-off-by: Namhyung Kim <namh...@kernel.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namhyu...@lge.com>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Steven Rostedt <ros...@goodmis.org>
Link: http://lkml.kernel.org/r/1386833777-3790-13-gi...@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/lib/traceevent/event-parse.h | 21 ++++--
tools/lib/traceevent/parse-filter.c | 135 +++++++++++++++++++++++-------------
2 files changed, 99 insertions(+), 57 deletions(-)

diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index 089964e56ed4..3ad784f5f647 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -357,6 +357,8 @@ enum pevent_flag {
_PE(READ_PRINT_FAILED, "failed to read event print fmt"), \
_PE(OLD_FTRACE_ARG_FAILED,"failed to allocate field name for ftrace"),\
_PE(INVALID_ARG_TYPE, "invalid argument type"), \
+ _PE(INVALID_EXP_TYPE, "invalid expression type"), \
+ _PE(INVALID_OP_TYPE, "invalid operator type"), \
_PE(INVALID_EVENT_NAME, "invalid event name"), \
_PE(EVENT_NOT_FOUND, "no event found"), \
_PE(SYNTAX_ERROR, "syntax error"), \
@@ -373,12 +375,16 @@ enum pevent_flag {
_PE(INVALID_PAREN, "open parenthesis cannot come here"), \
_PE(UNBALANCED_PAREN, "unbalanced number of parenthesis"), \
_PE(UNKNOWN_TOKEN, "unknown token"), \
- _PE(FILTER_NOT_FOUND, "no filter found")
+ _PE(FILTER_NOT_FOUND, "no filter found"), \
+ _PE(NOT_A_NUMBER, "must have number field"), \
+ _PE(NO_FILTER, "no filters exists"), \
+ _PE(FILTER_MISS, "record does not match to filter")

#undef _PE
#define _PE(__code, __str) PEVENT_ERRNO__ ## __code
enum pevent_errno {
PEVENT_ERRNO__SUCCESS = 0,
+ PEVENT_ERRNO__FILTER_MATCH = PEVENT_ERRNO__SUCCESS,

/*
* Choose an arbitrary negative big number not to clash with standard
@@ -853,10 +859,11 @@ struct event_filter {

struct event_filter *pevent_filter_alloc(struct pevent *pevent);

-#define FILTER_NONE -2
-#define FILTER_NOEXIST -1
-#define FILTER_MISS 0
-#define FILTER_MATCH 1
+/* for backward compatibility */
+#define FILTER_NONE PEVENT_ERRNO__FILTER_NOT_FOUND
+#define FILTER_NOEXIST PEVENT_ERRNO__NO_FILTER
+#define FILTER_MISS PEVENT_ERRNO__FILTER_MISS
+#define FILTER_MATCH PEVENT_ERRNO__FILTER_MATCH

enum filter_trivial_type {
FILTER_TRIVIAL_FALSE,
@@ -868,8 +875,8 @@ enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter,
const char *filter_str);


-int pevent_filter_match(struct event_filter *filter,
- struct pevent_record *record);
+enum pevent_errno pevent_filter_match(struct event_filter *filter,
+ struct pevent_record *record);

int pevent_event_filtered(struct event_filter *filter,
int event_id);
diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c
index 78440d73e0ad..9303c55128db 100644
--- a/tools/lib/traceevent/parse-filter.c
+++ b/tools/lib/traceevent/parse-filter.c
@@ -1678,8 +1678,8 @@ int pevent_filter_event_has_trivial(struct event_filter *filter,
}
}

-static int test_filter(struct event_format *event,
- struct filter_arg *arg, struct pevent_record *record);
+static int test_filter(struct event_format *event, struct filter_arg *arg,
+ struct pevent_record *record, enum pevent_errno *err);

static const char *
get_comm(struct event_format *event, struct pevent_record *record)
@@ -1725,15 +1725,24 @@ get_value(struct event_format *event,
}

static unsigned long long
-get_arg_value(struct event_format *event, struct filter_arg *arg, struct pevent_record *record);
+get_arg_value(struct event_format *event, struct filter_arg *arg,
+ struct pevent_record *record, enum pevent_errno *err);

static unsigned long long
-get_exp_value(struct event_format *event, struct filter_arg *arg, struct pevent_record *record)
+get_exp_value(struct event_format *event, struct filter_arg *arg,
+ struct pevent_record *record, enum pevent_errno *err)
{
unsigned long long lval, rval;

- lval = get_arg_value(event, arg->exp.left, record);
- rval = get_arg_value(event, arg->exp.right, record);
+ lval = get_arg_value(event, arg->exp.left, record, err);
+ rval = get_arg_value(event, arg->exp.right, record, err);
+
+ if (*err) {
+ /*
+ * There was an error, no need to process anymore.
+ */
+ return 0;
+ }

switch (arg->exp.type) {
case FILTER_EXP_ADD:
@@ -1768,39 +1777,51 @@ get_exp_value(struct event_format *event, struct filter_arg *arg, struct pevent_

case FILTER_EXP_NOT:
default:
- die("error in exp");
+ if (!*err)
+ *err = PEVENT_ERRNO__INVALID_EXP_TYPE;
}
return 0;
}

static unsigned long long
-get_arg_value(struct event_format *event, struct filter_arg *arg, struct pevent_record *record)
+get_arg_value(struct event_format *event, struct filter_arg *arg,
+ struct pevent_record *record, enum pevent_errno *err)
{
switch (arg->type) {
case FILTER_ARG_FIELD:
return get_value(event, arg->field.field, record);

case FILTER_ARG_VALUE:
- if (arg->value.type != FILTER_NUMBER)
- die("must have number field!");
+ if (arg->value.type != FILTER_NUMBER) {
+ if (!*err)
+ *err = PEVENT_ERRNO__NOT_A_NUMBER;
+ }
return arg->value.val;

case FILTER_ARG_EXP:
- return get_exp_value(event, arg, record);
+ return get_exp_value(event, arg, record, err);

default:
- die("oops in filter");
+ if (!*err)
+ *err = PEVENT_ERRNO__INVALID_ARG_TYPE;
}
return 0;
}

-static int test_num(struct event_format *event,
- struct filter_arg *arg, struct pevent_record *record)
+static int test_num(struct event_format *event, struct filter_arg *arg,
+ struct pevent_record *record, enum pevent_errno *err)
{
unsigned long long lval, rval;

- lval = get_arg_value(event, arg->num.left, record);
- rval = get_arg_value(event, arg->num.right, record);
+ lval = get_arg_value(event, arg->num.left, record, err);
+ rval = get_arg_value(event, arg->num.right, record, err);
+
+ if (*err) {
+ /*
+ * There was an error, no need to process anymore.
+ */
+ return 0;
+ }

switch (arg->num.type) {
case FILTER_CMP_EQ:
@@ -1822,7 +1843,8 @@ static int test_num(struct event_format *event,
return lval <= rval;

default:
- /* ?? */
+ if (!*err)
+ *err = PEVENT_ERRNO__ILLEGAL_INTEGER_CMP;
return 0;
}
}
@@ -1869,8 +1891,8 @@ static const char *get_field_str(struct filter_arg *arg, struct pevent_record *r
return val;
}

-static int test_str(struct event_format *event,
- struct filter_arg *arg, struct pevent_record *record)
+static int test_str(struct event_format *event, struct filter_arg *arg,
+ struct pevent_record *record, enum pevent_errno *err)
{
const char *val;

@@ -1894,48 +1916,57 @@ static int test_str(struct event_format *event,
return regexec(&arg->str.reg, val, 0, NULL, 0);

default:
- /* ?? */
+ if (!*err)
+ *err = PEVENT_ERRNO__ILLEGAL_STRING_CMP;
return 0;
}
}

-static int test_op(struct event_format *event,
- struct filter_arg *arg, struct pevent_record *record)
+static int test_op(struct event_format *event, struct filter_arg *arg,
+ struct pevent_record *record, enum pevent_errno *err)
{
switch (arg->op.type) {
case FILTER_OP_AND:
- return test_filter(event, arg->op.left, record) &&
- test_filter(event, arg->op.right, record);
+ return test_filter(event, arg->op.left, record, err) &&
+ test_filter(event, arg->op.right, record, err);

case FILTER_OP_OR:
- return test_filter(event, arg->op.left, record) ||
- test_filter(event, arg->op.right, record);
+ return test_filter(event, arg->op.left, record, err) ||
+ test_filter(event, arg->op.right, record, err);

case FILTER_OP_NOT:
- return !test_filter(event, arg->op.right, record);
+ return !test_filter(event, arg->op.right, record, err);

default:
- /* ?? */
+ if (!*err)
+ *err = PEVENT_ERRNO__INVALID_OP_TYPE;
return 0;
}
}

-static int test_filter(struct event_format *event,
- struct filter_arg *arg, struct pevent_record *record)
+static int test_filter(struct event_format *event, struct filter_arg *arg,
+ struct pevent_record *record, enum pevent_errno *err)
{
+ if (*err) {
+ /*
+ * There was an error, no need to process anymore.
+ */
+ return 0;
+ }
+
switch (arg->type) {
case FILTER_ARG_BOOLEAN:
/* easy case */
return arg->boolean.value;

case FILTER_ARG_OP:
- return test_op(event, arg, record);
+ return test_op(event, arg, record, err);

case FILTER_ARG_NUM:
- return test_num(event, arg, record);
+ return test_num(event, arg, record, err);

case FILTER_ARG_STR:
- return test_str(event, arg, record);
+ return test_str(event, arg, record, err);

case FILTER_ARG_EXP:
case FILTER_ARG_VALUE:
@@ -1944,11 +1975,11 @@ static int test_filter(struct event_format *event,
* Expressions, fields and values evaluate
* to true if they return non zero
*/
- return !!get_arg_value(event, arg, record);
+ return !!get_arg_value(event, arg, record, err);

default:
- die("oops!");
- /* ?? */
+ if (!*err)
+ *err = PEVENT_ERRNO__INVALID_ARG_TYPE;
return 0;
}
}
@@ -1961,8 +1992,7 @@ static int test_filter(struct event_format *event,
* Returns 1 if filter found for @event_id
* otherwise 0;
*/
-int pevent_event_filtered(struct event_filter *filter,
- int event_id)
+int pevent_event_filtered(struct event_filter *filter, int event_id)
{
struct filter_type *filter_type;

@@ -1979,31 +2009,36 @@ int pevent_event_filtered(struct event_filter *filter,
* @filter: filter struct with filter information
* @record: the record to test against the filter
*
- * Returns:
- * 1 - filter found for event and @record matches
- * 0 - filter found for event and @record does not match
- * -1 - no filter found for @record's event
- * -2 - if no filters exist
+ * Returns: match result or error code (prefixed with PEVENT_ERRNO__)
+ * FILTER_MATCH - filter found for event and @record matches
+ * FILTER_MISS - filter found for event and @record does not match
+ * FILTER_NOT_FOUND - no filter found for @record's event
+ * NO_FILTER - if no filters exist
+ * otherwise - error occurred during test
*/
-int pevent_filter_match(struct event_filter *filter,
- struct pevent_record *record)
+enum pevent_errno pevent_filter_match(struct event_filter *filter,
+ struct pevent_record *record)
{
struct pevent *pevent = filter->pevent;
struct filter_type *filter_type;
int event_id;
+ int ret;
+ enum pevent_errno err = 0;

if (!filter->filters)
- return FILTER_NONE;
+ return PEVENT_ERRNO__NO_FILTER;

event_id = pevent_data_type(pevent, record);

filter_type = find_filter_type(filter, event_id);
-
if (!filter_type)
- return FILTER_NOEXIST;
+ return PEVENT_ERRNO__FILTER_NOT_FOUND;
+
+ ret = test_filter(filter_type->event, filter_type->filter, record, &err);
+ if (err)
+ return err;

- return test_filter(filter_type->event, filter_type->filter, record) ?
- FILTER_MATCH : FILTER_MISS;
+ return ret ? PEVENT_ERRNO__FILTER_MATCH : PEVENT_ERRNO__FILTER_MISS;
}

static char *op_to_str(struct event_filter *filter, struct filter_arg *arg)

Arnaldo Carvalho de Melo

unread,
Dec 13, 2013, 10:20:03 AM12/13/13
to
From: Adrian Hunter <adrian...@intel.com>

It will be necessary to predetermine header->data_offset to allow space
for attributes that are added later. Consequently, do not change
header->data_offset if it is non-zero.

Signed-off-by: Adrian Hunter <adrian...@intel.com>
Cc: Andi Kleen <a...@linux.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/1386765443-26966-17-git-se...@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/header.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 0bb830f6b49c..61c54213704b 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -2327,7 +2327,8 @@ int perf_session__write_header(struct perf_session *session,
}
}

- header->data_offset = lseek(fd, 0, SEEK_CUR);
+ if (!header->data_offset)
+ header->data_offset = lseek(fd, 0, SEEK_CUR);
header->feat_offset = header->data_offset + header->data_size;

if (at_exit) {

Arnaldo Carvalho de Melo

unread,
Dec 13, 2013, 10:20:03 AM12/13/13
to
From: Namhyung Kim <namh...@kernel.org>

Refactor it to return appropriate pevent_errno value.

Signed-off-by: Namhyung Kim <namh...@kernel.org>
Reviewed-by: Steven Rostedt <ros...@goodmis.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namhyu...@lge.com>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Steven Rostedt <ros...@goodmis.org>
Link: http://lkml.kernel.org/r/1386833777-3790-7-gi...@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/lib/traceevent/event-parse.h | 8 +++++++-
tools/lib/traceevent/parse-filter.c | 34 +++++++++++++++++++---------------
2 files changed, 26 insertions(+), 16 deletions(-)

diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index abdfd3c606ed..89e4dfd40db6 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -358,7 +358,13 @@ enum pevent_flag {
_PE(OLD_FTRACE_ARG_FAILED,"failed to allocate field name for ftrace"),\
_PE(INVALID_ARG_TYPE, "invalid argument type"), \
_PE(INVALID_EVENT_NAME, "invalid event name"), \
- _PE(EVENT_NOT_FOUND, "No event found")
+ _PE(EVENT_NOT_FOUND, "no event found"), \
+ _PE(SYNTAX_ERROR, "syntax error"), \
+ _PE(ILLEGAL_RVALUE, "illegal rvalue"), \
+ _PE(ILLEGAL_LVALUE, "illegal lvalue for string comparison"), \
+ _PE(INVALID_REGEX, "regex did not compute"), \
+ _PE(ILLEGAL_STRING_CMP, "illegal comparison for string"), \
+ _PE(ILLEGAL_INTEGER_CMP,"illegal comparison for integer")

#undef _PE
#define _PE(__code, __str) PEVENT_ERRNO__ ## __code
diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c
index a0ab040e8f71..c08ce594cabe 100644
--- a/tools/lib/traceevent/parse-filter.c
+++ b/tools/lib/traceevent/parse-filter.c
@@ -473,8 +473,8 @@ create_arg_cmp(enum filter_exp_type etype)
return arg;
}

-static int add_right(struct filter_arg *op, struct filter_arg *arg,
- char **error_str)
+static enum pevent_errno
+add_right(struct filter_arg *op, struct filter_arg *arg, char **error_str)
{
struct filter_arg *left;
char *str;
@@ -505,9 +505,8 @@ static int add_right(struct filter_arg *op, struct filter_arg *arg,
case FILTER_ARG_FIELD:
break;
default:
- show_error(error_str,
- "Illegal rvalue");
- return -1;
+ show_error(error_str, "Illegal rvalue");
+ return PEVENT_ERRNO__ILLEGAL_RVALUE;
}

/*
@@ -554,7 +553,7 @@ static int add_right(struct filter_arg *op, struct filter_arg *arg,
if (left->type != FILTER_ARG_FIELD) {
show_error(error_str,
"Illegal lvalue for string comparison");
- return -1;
+ return PEVENT_ERRNO__ILLEGAL_LVALUE;
}

/* Make sure this is a valid string compare */
@@ -573,25 +572,31 @@ static int add_right(struct filter_arg *op, struct filter_arg *arg,
show_error(error_str,
"RegEx '%s' did not compute",
str);
- return -1;
+ return PEVENT_ERRNO__INVALID_REGEX;
}
break;
default:
show_error(error_str,
"Illegal comparison for string");
- return -1;
+ return PEVENT_ERRNO__ILLEGAL_STRING_CMP;
}

op->type = FILTER_ARG_STR;
op->str.type = op_type;
op->str.field = left->field.field;
op->str.val = strdup(str);
- if (!op->str.val)
- die("malloc string");
+ if (!op->str.val) {
+ show_error(error_str, "Failed to allocate string filter");
+ return PEVENT_ERRNO__MEM_ALLOC_FAILED;
+ }
/*
* Need a buffer to copy data for tests
*/
- op->str.buffer = malloc_or_die(op->str.field->size + 1);
+ op->str.buffer = malloc(op->str.field->size + 1);
+ if (!op->str.buffer) {
+ show_error(error_str, "Failed to allocate string filter");
+ return PEVENT_ERRNO__MEM_ALLOC_FAILED;
+ }
/* Null terminate this buffer */
op->str.buffer[op->str.field->size] = 0;

@@ -609,7 +614,7 @@ static int add_right(struct filter_arg *op, struct filter_arg *arg,
case FILTER_CMP_NOT_REGEX:
show_error(error_str,
"Op not allowed with integers");
- return -1;
+ return PEVENT_ERRNO__ILLEGAL_INTEGER_CMP;

default:
break;
@@ -629,9 +634,8 @@ static int add_right(struct filter_arg *op, struct filter_arg *arg,
return 0;

out_fail:
- show_error(error_str,
- "Syntax error");
- return -1;
+ show_error(error_str, "Syntax error");
+ return PEVENT_ERRNO__SYNTAX_ERROR;
}

static struct filter_arg *

Arnaldo Carvalho de Melo

unread,
Dec 13, 2013, 10:20:01 AM12/13/13
to
From: Namhyung Kim <namhyu...@lge.com>

So that it can propagate error properly.

Signed-off-by: Namhyung Kim <namh...@kernel.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Steven Rostedt <ros...@goodmis.org>
Link: http://lkml.kernel.org/r/1386833777-3790-8-gi...@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/lib/traceevent/parse-filter.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c
index c08ce594cabe..774c3e4c1d9f 100644
--- a/tools/lib/traceevent/parse-filter.c
+++ b/tools/lib/traceevent/parse-filter.c
@@ -648,7 +648,7 @@ rotate_op_right(struct filter_arg *a, struct filter_arg *b)
return arg;
}

-static int add_left(struct filter_arg *op, struct filter_arg *arg)
+static enum pevent_errno add_left(struct filter_arg *op, struct filter_arg *arg)
{
switch (op->type) {
case FILTER_ARG_EXP:
@@ -667,11 +667,11 @@ static int add_left(struct filter_arg *op, struct filter_arg *arg)
/* left arg of compares must be a field */
if (arg->type != FILTER_ARG_FIELD &&
arg->type != FILTER_ARG_BOOLEAN)
- return -1;
+ return PEVENT_ERRNO__INVALID_ARG_TYPE;
op->num.left = arg;
break;
default:
- return -1;
+ return PEVENT_ERRNO__INVALID_ARG_TYPE;
}
return 0;

Arnaldo Carvalho de Melo

unread,
Dec 13, 2013, 10:20:01 AM12/13/13
to
From: Namhyung Kim <namh...@kernel.org>

Also check return value and handle it.

Signed-off-by: Namhyung Kim <namh...@kernel.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namhyu...@lge.com>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Steven Rostedt <ros...@goodmis.org>
Link: http://lkml.kernel.org/r/1386833777-3790-4-gi...@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/lib/traceevent/parse-filter.c | 48 ++++++++++++++++++++++++++++++-------
1 file changed, 40 insertions(+), 8 deletions(-)

diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c
index 767de4f1e8ee..ab9cefe320b4 100644
--- a/tools/lib/traceevent/parse-filter.c
+++ b/tools/lib/traceevent/parse-filter.c
@@ -211,12 +211,7 @@ struct event_filter *pevent_filter_alloc(struct pevent *pevent)

static struct filter_arg *allocate_arg(void)
{
- struct filter_arg *arg;
-
- arg = malloc_or_die(sizeof(*arg));
- memset(arg, 0, sizeof(*arg));
-
- return arg;
+ return calloc(1, sizeof(struct filter_arg));
}

static void free_arg(struct filter_arg *arg)
@@ -369,6 +364,10 @@ create_arg_item(struct event_format *event, const char *token,
struct filter_arg *arg;

arg = allocate_arg();
+ if (arg == NULL) {
+ show_error(error_str, "failed to allocate filter arg");
+ return NULL;
+ }

switch (type) {

@@ -422,6 +421,9 @@ create_arg_op(enum filter_op_type btype)
struct filter_arg *arg;

arg = allocate_arg();
+ if (!arg)
+ return NULL;
+
arg->type = FILTER_ARG_OP;
arg->op.type = btype;

@@ -434,6 +436,9 @@ create_arg_exp(enum filter_exp_type etype)
struct filter_arg *arg;

arg = allocate_arg();
+ if (!arg)
+ return NULL;
+
arg->type = FILTER_ARG_EXP;
arg->op.type = etype;

@@ -446,6 +451,9 @@ create_arg_cmp(enum filter_exp_type etype)
struct filter_arg *arg;

arg = allocate_arg();
+ if (!arg)
+ return NULL;
+
/* Use NUM and change if necessary */
arg->type = FILTER_ARG_NUM;
arg->op.type = etype;
@@ -909,8 +917,10 @@ static struct filter_arg *collapse_tree(struct filter_arg *arg)
case FILTER_VAL_FALSE:
free_arg(arg);
arg = allocate_arg();
- arg->type = FILTER_ARG_BOOLEAN;
- arg->boolean.value = ret == FILTER_VAL_TRUE;
+ if (arg) {
+ arg->type = FILTER_ARG_BOOLEAN;
+ arg->boolean.value = ret == FILTER_VAL_TRUE;
+ }
}

return arg;
@@ -1057,6 +1067,8 @@ process_filter(struct event_format *event, struct filter_arg **parg,
switch (op_type) {
case OP_BOOL:
arg = create_arg_op(btype);
+ if (arg == NULL)
+ goto fail_alloc;
if (current_op)
ret = add_left(arg, current_op);
else
@@ -1067,6 +1079,8 @@ process_filter(struct event_format *event, struct filter_arg **parg,

case OP_NOT:
arg = create_arg_op(btype);
+ if (arg == NULL)
+ goto fail_alloc;
if (current_op)
ret = add_right(current_op, arg, error_str);
if (ret < 0)
@@ -1086,6 +1100,8 @@ process_filter(struct event_format *event, struct filter_arg **parg,
arg = create_arg_exp(etype);
else
arg = create_arg_cmp(ctype);
+ if (arg == NULL)
+ goto fail_alloc;

if (current_op)
ret = add_right(current_op, arg, error_str);
@@ -1119,11 +1135,16 @@ process_filter(struct event_format *event, struct filter_arg **parg,
current_op = current_exp;

current_op = collapse_tree(current_op);
+ if (current_op == NULL)
+ goto fail_alloc;

*parg = current_op;

return 0;

+ fail_alloc:
+ show_error(error_str, "failed to allocate filter arg");
+ goto fail;
fail_print:
show_error(error_str, "Syntax error");
fail:
@@ -1154,6 +1175,10 @@ process_event(struct event_format *event, const char *filter_str,
/* If parg is NULL, then make it into FALSE */
if (!*parg) {
*parg = allocate_arg();
+ if (*parg == NULL) {
+ show_error(error_str, "failed to allocate filter arg");
+ return -1;
+ }
(*parg)->type = FILTER_ARG_BOOLEAN;
(*parg)->boolean.value = FILTER_FALSE;
}
@@ -1177,6 +1202,10 @@ static int filter_event(struct event_filter *filter,
} else {
/* just add a TRUE arg */
arg = allocate_arg();
+ if (arg == NULL) {
+ show_error(error_str, "failed to allocate filter arg");
+ return -1;
+ }
arg->type = FILTER_ARG_BOOLEAN;
arg->boolean.value = FILTER_TRUE;
}
@@ -1418,6 +1447,9 @@ static int copy_filter_type(struct event_filter *filter,
if (strcmp(str, "TRUE") == 0 || strcmp(str, "FALSE") == 0) {
/* Add trivial event */
arg = allocate_arg();
+ if (arg == NULL)
+ return -1;
+
arg->type = FILTER_ARG_BOOLEAN;
if (strcmp(str, "TRUE") == 0)
arg->boolean.value = 1;

Arnaldo Carvalho de Melo

unread,
Dec 13, 2013, 10:20:01 AM12/13/13
to
From: Arnaldo Carvalho de Melo <ac...@ghostprotocols.net>

Hi Ingo,

Please consider pulling,

Regards,

- Arnaldo

The following changes since commit c7f2e3cd6c1f4932ccc4135d050eae3f7c7aef63:

perf: Optimize ring-buffer write by depending on control dependencies (2013-12-11 15:53:22 +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 41e12e580a7b0c151199f927193548b84d3e874c:

tools lib traceevent: Refactor pevent_filter_match() to get rid of die() (2013-12-13 10:30:22 -0300)

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

Fixes:

. Fix inverted error verification bug in thread__fork, from David Ahern.

New features:

. Shell completion for 'perf kvm', from Ramkumar Ramachandra.

Refactorings:

. Get rid of panic() like calls in libtraceevent, from Namyung Kim.

. Start carving out symbol parsing routines from perf, just moving routines to
topic files in tools/lib/symbol/, tools that want to use it need to integrate
it directly, i.e. no tools/lib/symbol/Makefile is provided.

. Assorted refactoring patches, moving code around and adding
utility evlist methods that will be used in the IPT patchset,
from Adrian Hunter.

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

----------------------------------------------------------------
Adrian Hunter (5):
perf tools: Add perf_event_paranoid()
perf header: Allow header->data_offset to be predetermined
perf evlist: Add can_select_event() method
perf tools: Move mem_bswap32/64 to util.c
perf evlist: Add perf_evlist__to_front()

Arnaldo Carvalho de Melo (1):
tools lib symbol: Start carving out symbol parsing routines from perf

David Ahern (1):
perf tools: Fix inverted error verification bug in thread__fork

Namhyung Kim (12):
tools lib traceevent: Get rid of malloc_or_die() in show_error()
tools lib traceevent: Get rid of die in add_filter_type()
tools lib traceevent: Get rid of malloc_or_die() allocate_arg()
tools lib traceevent: Get rid of malloc_or_die() in read_token()
tools lib traceevent: Get rid of malloc_or_die() in find_event()
tools lib traceevent: Get rid of die() in add_right()
tools lib traceevent: Make add_left() return pevent_errno
tools lib traceevent: Get rid of die() in reparent_op_arg()
tools lib traceevent: Refactor create_arg_item()
tools lib traceevent: Refactor process_filter()
tools lib traceevent: Make pevent_filter_add_filter_str() return pevent_errno
tools lib traceevent: Refactor pevent_filter_match() to get rid of die()

Ramkumar Ramachandra (1):
perf completion: Complete 'perf kvm'

tools/lib/symbol/kallsyms.c | 58 +++++
tools/lib/symbol/kallsyms.h | 24 ++
tools/lib/traceevent/event-parse.h | 43 ++-
tools/lib/traceevent/parse-filter.c | 507 ++++++++++++++++++++++--------------
tools/perf/MANIFEST | 2 +
tools/perf/Makefile.perf | 5 +
tools/perf/perf-completion.sh | 4 +
tools/perf/util/event.c | 1 +
tools/perf/util/evlist.c | 20 +-
tools/perf/util/evlist.h | 5 +
tools/perf/util/header.c | 3 +-
tools/perf/util/machine.c | 1 +
tools/perf/util/record.c | 37 +++
tools/perf/util/session.c | 21 --
tools/perf/util/session.h | 2 -
tools/perf/util/symbol-elf.c | 1 +
tools/perf/util/symbol.c | 69 +----
tools/perf/util/symbol.h | 3 -
tools/perf/util/thread.c | 2 +-
tools/perf/util/util.c | 41 +++
tools/perf/util/util.h | 4 +
21 files changed, 550 insertions(+), 303 deletions(-)
create mode 100644 tools/lib/symbol/kallsyms.c
create mode 100644 tools/lib/symbol/kallsyms.h

Ingo Molnar

unread,
Dec 16, 2013, 9:00:02 AM12/16/13
to
Pulled, thanks a lot Arnaldo!

Ingo

tip-bot for Arnaldo Carvalho de Melo

unread,
Dec 16, 2013, 10:40:03 AM12/16/13
to
Commit-ID: c506c96b61fa96c9a52ad4d25e895e45c1692650
Gitweb: http://git.kernel.org/tip/c506c96b61fa96c9a52ad4d25e895e45c1692650
Author: Arnaldo Carvalho de Melo <ac...@redhat.com>
AuthorDate: Wed, 11 Dec 2013 09:15:00 -0300
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Fri, 13 Dec 2013 10:30:20 -0300

tools lib symbol: Start carving out symbol parsing routines from perf

Eventually this should be useful to other tools/ living utilities.

For now don't try to build any .a, just trying the minimal approach of
separating existing code into multiple .c files that can then be
included wherever they are needed, using whatever build machinery
already in place.

Cc: Adrian Hunter <adrian...@intel.com>
Cc: Borislav Petkov <b...@alien8.de>
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-pfa8i5zpf4...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/lib/symbol/kallsyms.c | 58 +++++++++++++++++++++++++++++++++++++
tools/lib/symbol/kallsyms.h | 24 +++++++++++++++
tools/perf/MANIFEST | 2 ++
tools/perf/Makefile.perf | 5 ++++
tools/perf/util/event.c | 1 +
tools/perf/util/machine.c | 1 +
tools/perf/util/symbol-elf.c | 1 +
tools/perf/util/symbol.c | 69 +-------------------------------------------
tools/perf/util/symbol.h | 3 --
9 files changed, 93 insertions(+), 71 deletions(-)

diff --git a/tools/lib/symbol/kallsyms.c b/tools/lib/symbol/kallsyms.c
new file mode 100644
index 0000000..18bc271
index 0000000..6084f5e
index 025de79..3170a7f 100644
--- a/tools/perf/MANIFEST
+++ b/tools/perf/MANIFEST
@@ -2,6 +2,8 @@ tools/perf
tools/scripts
tools/lib/traceevent
tools/lib/lk
+tools/lib/symbol/kallsyms.c
+tools/lib/symbol/kallsyms.h
include/linux/const.h
include/linux/perf_event.h
include/linux/rbtree.h
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 9a8cf37..fad6107 100644
index c77814b..6948768 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -7,6 +7,7 @@
#include "strlist.h"
#include "thread.h"
#include "thread_map.h"
+#include "symbol/kallsyms.h"

static const char *perf_event__names[] = {
[0] = "TOTAL",
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 751454b..c78cc84 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -9,6 +9,7 @@
#include "strlist.h"
#include "thread.h"
#include <stdbool.h>
+#include <symbol/kallsyms.h>
#include "unwind.h"

int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index eed0b96..bf0ce29 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -6,6 +6,7 @@
#include <inttypes.h>

#include "symbol.h"
+#include <symbol/kallsyms.h>
#include "debug.h"

#ifndef HAVE_ELF_GETPHDRNUM_SUPPORT
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index e377c2e..61eb1cd 100644
index 6de9c2b..8a9d910 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -221,9 +221,6 @@ struct symbol *dso__first_symbol(struct dso *dso, enum map_type type);

int filename__read_build_id(const char *filename, void *bf, size_t size);
int sysfs__read_build_id(const char *filename, void *bf, size_t size);
-int kallsyms__parse(const char *filename, void *arg,
- int (*process_symbol)(void *arg, const char *name,
- char type, u64 start));
int modules__parse(const char *filename, void *arg,
int (*process_module)(void *arg, const char *name,
u64 start));

Arnaldo Carvalho de Melo

unread,
Dec 20, 2013, 2:20:04 PM12/20/13
to
From: Arnaldo Carvalho de Melo <ac...@ghostprotocols.net>

Hi Ingo,

Please consider pulling,

Best regards,

- Arnaldo

The following changes since commit fa6e8e5f7cbf85f364ebd5a90525dbbe9de2083b:

Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core (2013-12-18 14:07:26 +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 a419e512731892c3e7e661cd96e7f7d6a7acdc91:

perf stat: Do not show stats if workload fails (2013-12-20 13:37:50 -0300)

----------------------------------------------------------------
User visible changes:

Improvements:

. Do not show stats if workload fails in 'stat' (David Ahern)

. Print session information only if --stdio is given (Namhyung Kim)

Developer stuff:

Fixes:

. Get rid of a duplicate va_end() in error reporting (Namhyung Kim)

. If a hist entry doesn't have symbol information, compare it with its
address. Affects upcoming new feature (--cumulate) (Namhyung Kim)

Improvements:

. Make libtraceevent install target quieter (Jiri Olsa)

. Make tests/make output more compact (Jiri Olsa)

New APIs:

. Introduce pevent_filter_strerror() in libtraceevent, similar in
purpose to libc's strerror() function. (Namhyung Kim)

Refactorings:

. Use perf_data_file methods to write output file in 'record' and
'inject' (Jiri Olsa)

. Use pr_*() functions where applicable in 'report' (Namhyumg Kim)

. Add 'machine' 'addr_location' struct to have full picture (machine,
thread, map, symbol, addr) for a (partially) resolved address, reducing
function signatures (Arnaldo Carvalho de Melo)

. Reduce code duplication in the histogram entry creation/insertion. (Arnaldo Carvalho de Melo)

. Auto allocate annotation histogram data structures, (Arnaldo Carvalho de Melo)

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

----------------------------------------------------------------
Arnaldo Carvalho de Melo (16):
perf annotate: Auto allocate symbol per addr hist buckets
perf hists: Leave symbol addr hist bucket auto alloc to symbol layer
perf annotate: Add inc_samples method to addr_map_symbol
perf top: Use hist_entry__inc_addr_sample
perf annotate: Adopt methods from hists
perf annotate: Make symbol__inc_addr_samples private
perf report: Introduce helpers for processing callchains
perf record: Simplify perf_record__write
perf record: Rename 'perf_record' to plain 'record'
perf tools: Rename 'perf_record_opts' to 'record_opts
perf report: Rename 'perf_report' to 'report'
perf ui browser: Remove misplaced __maybe_unused
perf scripting python: Shorten function signatures
perf scripting perl: Shorten function signatures
perf mem: Remove unused parameter from dump_raw_samples()
perf symbols: Add 'machine' member to struct addr_location

David Ahern (1):
perf stat: Do not show stats if workload fails

Jiri Olsa (11):
perf inject: Handle output file via perf_data_file object
perf record: Use perf_data_file__write for output file
perf tests: Factor make install tests
perf tools: Making QUIET_(CLEAN|INSTAL) variables global
tools lib traceevent: Remove print_app_build variable
tools lib traceevent: Use global QUIET_CC build output
tools lib traceevent: Add global QUIET_CC_FPIC build output
tools lib traceevent: Use global QUIET_LINK build output
tools lib traceevent: Use global QUIET_INSTALL build output
tools lib traceevent: Use global QUIET_CLEAN build output
tools lib traceevent: Use global 'O' processing code

Namhyung Kim (7):
perf sort: Compare addresses if no symbol info
perf sort: Do not compare dso again
perf hists: Do not pass period and weight to add_hist_entry()
tools lib traceevent: Introduce pevent_filter_strerror()
perf tools: Get rid of a duplicate va_end() in error reporting routine
perf report: Use pr_*() functions where applicable
perf report: Print session information only if --stdio is given

tools/lib/traceevent/Makefile | 85 +++----
tools/lib/traceevent/event-parse.c | 17 +-
tools/lib/traceevent/event-parse.h | 7 +-
tools/lib/traceevent/parse-filter.c | 98 ++++----
tools/perf/builtin-annotate.c | 10 +-
tools/perf/builtin-inject.c | 65 +++---
tools/perf/builtin-kvm.c | 2 +-
tools/perf/builtin-mem.c | 5 +-
tools/perf/builtin-record.c | 94 ++++----
tools/perf/builtin-report.c | 259 +++++++--------------
tools/perf/builtin-script.c | 16 +-
tools/perf/builtin-stat.c | 11 +-
tools/perf/builtin-top.c | 23 +-
tools/perf/builtin-trace.c | 2 +-
tools/perf/config/utilities.mak | 7 -
tools/perf/perf.h | 2 +-
tools/perf/tests/code-reading.c | 2 +-
tools/perf/tests/keep-tracking.c | 2 +-
tools/perf/tests/make | 38 ++-
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/ui/browser.c | 2 +-
tools/perf/util/annotate.c | 41 +++-
tools/perf/util/annotate.h | 9 +-
tools/perf/util/callchain.h | 2 +-
tools/perf/util/debug.c | 1 -
tools/perf/util/event.c | 1 +
tools/perf/util/evlist.h | 7 +-
tools/perf/util/evsel.c | 3 +-
tools/perf/util/evsel.h | 4 +-
tools/perf/util/hist.c | 21 +-
tools/perf/util/hist.h | 3 -
tools/perf/util/record.c | 9 +-
.../perf/util/scripting-engines/trace-event-perl.c | 19 +-
.../util/scripting-engines/trace-event-python.c | 25 +-
tools/perf/util/session.c | 4 +-
tools/perf/util/session.h | 2 +-
tools/perf/util/sort.c | 22 +-
tools/perf/util/symbol.h | 1 +
tools/perf/util/top.c | 2 +-
tools/perf/util/top.h | 2 +-
tools/perf/util/trace-event-scripting.c | 3 +-
tools/perf/util/trace-event.h | 1 -
tools/scripts/Makefile.include | 4 +
45 files changed, 415 insertions(+), 524 deletions(-)

Arnaldo Carvalho de Melo

unread,
Dec 20, 2013, 2:30:01 PM12/20/13
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

Since now symbol__addr_inc_samples() does the auto alloc, no need to do
it prior to calling hist_entry__inc_addr_samples.

Acked-by: Namhyung Kim <namh...@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/n/tip-6ife7xq2ke...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-annotate.c | 10 +---------
tools/perf/builtin-report.c | 38 ++++----------------------------------
2 files changed, 5 insertions(+), 43 deletions(-)

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 6fd52c8fa682..4136f9970fd5 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -69,15 +69,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel,
if (he == NULL)
return -ENOMEM;

- ret = 0;
- if (he->ms.sym != NULL) {
- struct annotation *notes = symbol__annotation(he->ms.sym);
- if (notes->src == NULL && symbol__alloc_hist(he->ms.sym) < 0)
- return -ENOMEM;
-
- ret = hist_entry__inc_addr_samples(he, evsel->idx, al->addr);
- }
-
+ ret = hist_entry__inc_addr_samples(he, evsel->idx, al->addr);
evsel->hists.stats.total_period += sample->period;
hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);
return ret;
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index b75fc361b9bd..0615a63ae355 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -122,23 +122,9 @@ static int perf_report__add_mem_hist_entry(struct perf_tool *tool,
if (!he)
return -ENOMEM;

- /*
- * In the TUI browser, we are doing integrated annotation,
- * so we don't allocate the extra space needed because the stdio
- * code will not use it.
- */
- if (sort__has_sym && he->ms.sym && use_browser > 0) {
- struct annotation *notes = symbol__annotation(he->ms.sym);
-
- assert(evsel != NULL);
-
- if (notes->src == NULL && symbol__alloc_hist(he->ms.sym) < 0)
- goto out;
-
- err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr);
- if (err)
- goto out;
- }
+ err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr);
+ if (err)
+ goto out;

mx = he->mem_info;
err = symbol__inc_addr_samples(mx->daddr.sym, mx->daddr.map,
@@ -259,26 +245,10 @@ static int perf_evsel__add_hist_entry(struct perf_tool *tool,
if (err)
return err;
}
- /*
- * Only in the TUI browser we are doing integrated annotation,
- * so we don't allocated the extra space needed because the stdio
- * code will not use it.
- */
- if (he->ms.sym != NULL && use_browser == 1 && sort__has_sym) {
- struct annotation *notes = symbol__annotation(he->ms.sym);
-
- assert(evsel != NULL);
-
- err = -ENOMEM;
- if (notes->src == NULL && symbol__alloc_hist(he->ms.sym) < 0)
- goto out;
-
- err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr);
- }

+ err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr);
evsel->hists.stats.total_period += sample->period;
hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);
-out:
return err;
}

--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Dec 20, 2013, 2:30:01 PM12/20/13
to
From: Jiri Olsa <jo...@redhat.com>

Changing the file output code to use the newly
added perf_data_file__write interface.

No functional change intended.

Signed-off-by: Jiri Olsa <jo...@redhat.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Namhyung Kim <namh...@kernel.org>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: David Ahern <dsa...@gmail.com>
Cc: Adrian Hunter <adrian...@intel.com>
Cc: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-record.c | 23 +++++++++--------------
1 file changed, 9 insertions(+), 14 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index c1c1200d2f0a..8eed3d752c80 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -76,24 +76,19 @@ struct perf_record {
long samples;
};

-static int perf_record__write(struct perf_record *rec, void *buf, size_t size)
+static ssize_t perf_record__write(struct perf_record *rec,
+ void *buf, size_t size)
{
- struct perf_data_file *file = &rec->file;
-
- while (size) {
- ssize_t ret = write(file->fd, buf, size);
-
- if (ret < 0) {
- pr_err("failed to write perf data, error: %m\n");
- return -1;
- }
-
- size -= ret;
- buf += ret;
+ struct perf_session *session = rec->session;
+ ssize_t ret;

- rec->bytes_written += ret;
+ ret = perf_data_file__write(session->file, buf, size);
+ if (ret < 0) {
+ pr_err("failed to write perf data, error: %m\n");
+ return -1;
}

+ rec->bytes_written += ret;
return 0;
}

--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Dec 20, 2013, 2:30:01 PM12/20/13
to
From: Namhyung Kim <namhyu...@lge.com>

The va_end() in _eprintf() should be removed since the caller also
invokes va_end().

Signed-off-by: Namhyung Kim <namh...@kernel.org>
Acked-by: Jiri Olsa <jo...@redhat.com>
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/1387436411-20160-4-gi...@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/debug.c | 1 -
1 file changed, 1 deletion(-)

diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c
index 8640a9121e72..299b55586502 100644
--- a/tools/perf/util/debug.c
+++ b/tools/perf/util/debug.c
@@ -25,7 +25,6 @@ static int _eprintf(int level, const char *fmt, va_list args)
ui_helpline__vshow(fmt, args);
else
ret = vfprintf(stderr, fmt, args);
- va_end(args);
}

return ret;
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Dec 20, 2013, 2:30:01 PM12/20/13
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

Since there are three calls that could receive just the struct
addr_map_symbol pointer and call the symbol method.

Acked-by: Namhyung Kim <namh...@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/n/tip-d728gz1org...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-report.c | 11 +++--------
tools/perf/util/annotate.c | 5 +++++
tools/perf/util/annotate.h | 3 +++
3 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 0615a63ae355..9a20c9efb84b 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -127,8 +127,7 @@ static int perf_report__add_mem_hist_entry(struct perf_tool *tool,
goto out;

mx = he->mem_info;
- err = symbol__inc_addr_samples(mx->daddr.sym, mx->daddr.map,
- evsel->idx, mx->daddr.al_addr);
+ err = addr_map_symbol__inc_samples(&mx->daddr, evsel->idx);
if (err)
goto out;

@@ -190,15 +189,11 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,
1, 1, 0);
if (he) {
bx = he->branch_info;
- err = symbol__inc_addr_samples(bx->from.sym,
- bx->from.map, evsel->idx,
- bx->from.al_addr);
+ err = addr_map_symbol__inc_samples(&bx->from, evsel->idx);
if (err)
goto out;

- err = symbol__inc_addr_samples(bx->to.sym,
- bx->to.map, evsel->idx,
- bx->to.al_addr);
+ err = addr_map_symbol__inc_samples(&bx->to, evsel->idx);
if (err)
goto out;

diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 93614cd3948f..2812e7b78d0f 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -503,6 +503,11 @@ int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
return __symbol__inc_addr_samples(sym, map, notes, evidx, addr);
}

+int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, int evidx)
+{
+ return symbol__inc_addr_samples(ams->sym, ams->map, evidx, ams->al_addr);
+}
+
static void disasm_line__init_ins(struct disasm_line *dl)
{
dl->ins = ins__find(dl->name);
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index 834b7b57b788..8de10b1ef027 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -134,6 +134,9 @@ static inline struct annotation *symbol__annotation(struct symbol *sym)

int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
int evidx, u64 addr);
+
+int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, int evidx);
+
int symbol__alloc_hist(struct symbol *sym);
void symbol__annotate_zero_histograms(struct symbol *sym);

--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Dec 20, 2013, 2:30:02 PM12/20/13
to
From: Jiri Olsa <jo...@redhat.com>

Using the perf_data_file object to handle output file processing.

No functional change intended.

Signed-off-by: Jiri Olsa <jo...@redhat.com>
Cc: Adrian Hunter <adrian...@intel.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: Namhyung Kim <namh...@kernel.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Link: http://lkml.kernel.org/n/tip-01j9ophd7t...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-inject.c | 65 +++++++++++++++++++--------------------------
1 file changed, 27 insertions(+), 38 deletions(-)

diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 6a2508589460..c9f6d74e1fd7 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -22,14 +22,13 @@
#include <linux/list.h>

struct perf_inject {
- struct perf_tool tool;
- bool build_ids;
- bool sched_stat;
- const char *input_name;
- int pipe_output,
- output;
- u64 bytes_written;
- struct list_head samples;
+ struct perf_tool tool;
+ bool build_ids;
+ bool sched_stat;
+ const char *input_name;
+ struct perf_data_file output;
+ u64 bytes_written;
+ struct list_head samples;
};

struct event_entry {
@@ -42,21 +41,14 @@ static int perf_event__repipe_synth(struct perf_tool *tool,
union perf_event *event)
{
struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
- uint32_t size;
- void *buf = event;
+ ssize_t size;

- size = event->header.size;
-
- while (size) {
- int ret = write(inject->output, buf, size);
- if (ret < 0)
- return -errno;
-
- size -= ret;
- buf += ret;
- inject->bytes_written += ret;
- }
+ size = perf_data_file__write(&inject->output, event,
+ event->header.size);
+ if (size < 0)
+ return -errno;

+ inject->bytes_written += size;
return 0;
}

@@ -80,7 +72,7 @@ static int perf_event__repipe_attr(struct perf_tool *tool,
if (ret)
return ret;

- if (!inject->pipe_output)
+ if (&inject->output.is_pipe)
return 0;

return perf_event__repipe_synth(tool, event);
@@ -355,6 +347,7 @@ static int __cmd_inject(struct perf_inject *inject)
.path = inject->input_name,
.mode = PERF_DATA_MODE_READ,
};
+ struct perf_data_file *file_out = &inject->output;

signal(SIGINT, sig_handler);

@@ -391,14 +384,14 @@ static int __cmd_inject(struct perf_inject *inject)
}
}

- if (!inject->pipe_output)
- lseek(inject->output, session->header.data_offset, SEEK_SET);
+ if (!file_out->is_pipe)
+ lseek(file_out->fd, session->header.data_offset, SEEK_SET);

ret = perf_session__process_events(session, &inject->tool);

- if (!inject->pipe_output) {
+ if (!file_out->is_pipe) {
session->header.data_size = inject->bytes_written;
- perf_session__write_header(session, session->evlist, inject->output, true);
+ perf_session__write_header(session, session->evlist, file_out->fd, true);
}

perf_session__delete(session);
@@ -427,14 +420,17 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)
},
.input_name = "-",
.samples = LIST_HEAD_INIT(inject.samples),
+ .output = {
+ .path = "-",
+ .mode = PERF_DATA_MODE_WRITE,
+ },
};
- const char *output_name = "-";
const struct option options[] = {
OPT_BOOLEAN('b', "build-ids", &inject.build_ids,
"Inject build-ids into the output stream"),
OPT_STRING('i', "input", &inject.input_name, "file",
"input file name"),
- OPT_STRING('o', "output", &output_name, "file",
+ OPT_STRING('o', "output", &inject.output.path, "file",
"output file name"),
OPT_BOOLEAN('s', "sched-stat", &inject.sched_stat,
"Merge sched-stat and sched-switch for getting events "
@@ -456,16 +452,9 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)
if (argc)
usage_with_options(inject_usage, options);

- if (!strcmp(output_name, "-")) {
- inject.pipe_output = 1;
- inject.output = STDOUT_FILENO;
- } else {
- inject.output = open(output_name, O_CREAT | O_WRONLY | O_TRUNC,
- S_IRUSR | S_IWUSR);
- if (inject.output < 0) {
- perror("failed to create output file");
- return -1;
- }
+ if (perf_data_file__open(&inject.output)) {
+ perror("failed to create output file");
+ return -1;
}

if (symbol__init() < 0)
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Dec 20, 2013, 2:30:02 PM12/20/13
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

Those are just wrappers to annotation methods, so move them to
annotate.c

Acked-by: Namhyung Kim <namh...@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/n/tip-336h7z0bi2...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/annotate.c | 10 ++++++++++
tools/perf/util/annotate.h | 5 +++++
tools/perf/util/hist.c | 11 -----------
tools/perf/util/hist.h | 3 ---
4 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 2812e7b78d0f..91e25269bb27 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -508,6 +508,11 @@ int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, int evidx)
return symbol__inc_addr_samples(ams->sym, ams->map, evidx, ams->al_addr);
}

+int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 ip)
+{
+ return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip);
+}
+
static void disasm_line__init_ins(struct disasm_line *dl)
{
dl->ins = ins__find(dl->name);
@@ -1393,3 +1398,8 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map,

return 0;
}
+
+int hist_entry__annotate(struct hist_entry *he, size_t privsize)
+{
+ return symbol__annotate(he->ms.sym, he->ms.map, privsize);
+}
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index 8de10b1ef027..43727a9b93cd 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -137,10 +137,15 @@ int symbol__inc_addr_samples(struct symbol *sym, struct map *map,

int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, int evidx);

+int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 addr);
+
int symbol__alloc_hist(struct symbol *sym);
void symbol__annotate_zero_histograms(struct symbol *sym);

int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize);
+
+int hist_entry__annotate(struct hist_entry *he, size_t privsize);
+
int symbol__annotate_init(struct map *map __maybe_unused, struct symbol *sym);
int symbol__annotate_printf(struct symbol *sym, struct map *map,
struct perf_evsel *evsel, bool full_paths,
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 63234e37583c..6cd4823a7a8b 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -1,4 +1,3 @@
-#include "annotate.h"
#include "util.h"
#include "build-id.h"
#include "hist.h"
@@ -807,16 +806,6 @@ void hists__filter_by_symbol(struct hists *hists)
}
}

-int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 ip)
-{
- return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip);
-}
-
-int hist_entry__annotate(struct hist_entry *he, size_t privsize)
-{
- return symbol__annotate(he->ms.sym, he->ms.map, privsize);
-}
-
void events_stats__inc(struct events_stats *stats, u32 type)
{
++stats->nr_events[0];
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index b621347a1585..a59743fa3ef7 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -111,9 +111,6 @@ size_t events_stats__fprintf(struct events_stats *stats, FILE *fp);
size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
int max_cols, float min_pcnt, FILE *fp);

-int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 addr);
-int hist_entry__annotate(struct hist_entry *he, size_t privsize);
-
void hists__filter_by_dso(struct hists *hists);
void hists__filter_by_thread(struct hists *hists);
void hists__filter_by_symbol(struct hists *hists);
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Dec 20, 2013, 2:30:02 PM12/20/13
to
From: Jiri Olsa <jo...@redhat.com>

Removing print_app_build variable, because it's not needed.

Signed-off-by: Jiri Olsa <jo...@redhat.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...@kernel.org>
Cc: Namhyung Kim <namh...@kernel.org>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Steven Rostedt <ros...@goodmis.org>
Link: http://lkml.kernel.org/r/1387460527-15030-4-...@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/lib/traceevent/Makefile | 6 ------
1 file changed, 6 deletions(-)

diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index 0d9cbb426b44..022c987d25b6 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -151,7 +151,6 @@ override CFLAGS += $(udis86-flags) -D_GNU_SOURCE
ifeq ($(VERBOSE),1)
Q =
print_compile =
- print_app_build =
print_fpic_compile =
print_shared_lib_compile =
print_plugin_obj_compile =
@@ -160,7 +159,6 @@ ifeq ($(VERBOSE),1)
else
Q = @
print_compile = echo ' CC '$(OBJ);
- print_app_build = echo ' BUILD '$(OBJ);
print_fpic_compile = echo ' CC FPIC '$(OBJ);
print_shared_lib_compile = echo ' BUILD SHARED LIB '$(OBJ);
print_plugin_obj_compile = echo ' CC FPIC '$(OBJ);
@@ -173,10 +171,6 @@ do_fpic_compile = \
($(print_fpic_compile) \
$(CC) -c $(CFLAGS) $(EXT) -fPIC $< -o $@)

-do_app_build = \
- ($(print_app_build) \
- $(CC) $^ -rdynamic -o $@ $(CONFIG_LIBS) $(LIBS))
-
do_compile_shared_library = \
($(print_shared_lib_compile) \
$(CC) --shared $^ -o $@)
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Dec 20, 2013, 2:30:02 PM12/20/13
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

Since it is now accessed just thru addr_map_symbol and hist_entry
wrappers.

Acked-by: Namhyung Kim <namh...@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/n/tip-gjoam7wcfr...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/annotate.c | 4 ++--
tools/perf/util/annotate.h | 3 ---
2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 91e25269bb27..27ab7b59dbf4 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -486,8 +486,8 @@ static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map,
return 0;
}

-int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
- int evidx, u64 addr)
+static int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
+ int evidx, u64 addr)
{
struct annotation *notes;

diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index 43727a9b93cd..b2aef59d6bb2 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -132,9 +132,6 @@ static inline struct annotation *symbol__annotation(struct symbol *sym)
return &a->annotation;
}

-int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
- int evidx, u64 addr);
-
int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, int evidx);

int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 addr);
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Dec 27, 2013, 3:10:02 PM12/27/13
to
Em Fri, Dec 20, 2013 at 04:08:35PM -0300, Arnaldo Carvalho de Melo escreveu:
> User visible changes:
>
> Improvements:
>
> . Do not show stats if workload fails in 'stat' (David Ahern)

Hi Ingo,

Please hold on, as reported elsewhere, the above change broke
'perf stat valid-workload', so I removed it from my tree.

I'll resubmit soon with a bunch more,

Thanks,

- Arnaldo

Arnaldo Carvalho de Melo

unread,
Dec 27, 2013, 3:50:02 PM12/27/13
to
From: Arnaldo Carvalho de Melo <ac...@ghostprotocols.net>

Hi Ingo,

This one has the 34 out of 35 patches from the previous pull req, removing
the 'perf stat' one about not printing stats for workloads we failed to start, that
requires more thinking and introduced a regression.

I'm suppressing those first 34 patches, they are unchanged from last pull
req.

Please consider pulling, the next one probably will be in 2014 :-)

Best Regards and happy holidays!

- Arnaldo

The following changes since commit fa6e8e5f7cbf85f364ebd5a90525dbbe9de2083b:

Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core (2013-12-18 14:07:26 +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 74cf249d5cf7de84c88cca69a2f13b13d500ff94:

perf tools: Use zfree to help detect use after free bugs (2013-12-27 17:08:19 -0300)

----------------------------------------------------------------
User visible changes:

Improvements:

. Support showing source code, asking for variables to be collected
at probe time and other 'perf probe' operations that use DWARF information.

This supports only binaries with debugging information at this time, detached
debuginfo (aka debuginfo packages) support should come in later patches.
(Masami Hiramatsu)

. Add a perf.data file header window in the 'perf report' TUI, associated
with the 'i' hotkey, providing a counterpart to the --header option in the
stdio UI. (Namhyung Kim)

. Guest related improvements to 'perf kvm', including allowing to
specify a directory with guest specific /proc information. (Dongsheng Yang)

. Print session information only if --stdio is given (Namhyung Kim)

Developer stuff:

Fixes:

. Get rid of a duplicate va_end() in error reporting (Namhyung Kim)

. If a hist entry doesn't have symbol information, compare it with its
address. Affects upcoming new feature (--cumulate) (Namhyung Kim)

Improvements:

. Make libtraceevent install target quieter (Jiri Olsa)

. Make tests/make output more compact (Jiri Olsa)

. Ignore generated files in feature-checks (Chunwei Chen)

New APIs:

. Introduce pevent_filter_strerror() in libtraceevent, similar in
purpose to libc's strerror() function. (Namhyung Kim)

Refactorings:

. Use perf_data_file methods to write output file in 'record' and
'inject' (Jiri Olsa)

. Use pr_*() functions where applicable in 'report' (Namhyumg Kim)

. Add 'machine' 'addr_location' struct to have full picture (machine,
thread, map, symbol, addr) for a (partially) resolved address, reducing
function signatures (Arnaldo Carvalho de Melo)

. Reduce code duplication in the histogram entry creation/insertion. (Arnaldo Carvalho de Melo)

. Auto allocate annotation histogram data structures, (Arnaldo Carvalho de Melo)

. No need to test against NULL before calling free, also set
freed memory in struct pointers to NULL, to help fixing use after
free bugs. (Arnaldo Carvalho de Melo>

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

----------------------------------------------------------------
Arnaldo Carvalho de Melo (19):
perf annotate: Auto allocate symbol per addr hist buckets
perf hists: Leave symbol addr hist bucket auto alloc to symbol layer
perf annotate: Add inc_samples method to addr_map_symbol
perf top: Use hist_entry__inc_addr_sample
perf annotate: Adopt methods from hists
perf annotate: Make symbol__inc_addr_samples private
perf report: Introduce helpers for processing callchains
perf record: Simplify perf_record__write
perf record: Rename 'perf_record' to plain 'record'
perf tools: Rename 'perf_record_opts' to 'record_opts
perf report: Rename 'perf_report' to 'report'
perf ui browser: Remove misplaced __maybe_unused
perf scripting python: Shorten function signatures
perf scripting perl: Shorten function signatures
perf mem: Remove unused parameter from dump_raw_samples()
perf symbols: Add 'machine' member to struct addr_location
perf tools: No need to test against NULL before calling free()
perf tools: Introduce zfree
perf tools: Use zfree to help detect use after free bugs

Chunwei Chen (1):
perf config: Ignore generated files in feature-checks

Dongsheng Yang (6):
perf kvm: Fix kvm report without guestmount.
perf tools: Add support for PERF_RECORD_MISC_GUEST_USER in thread__find_addr_map().
perf tools: Find the proc info under machine->root_dir.
perf tools: Set event->header.misc to PERF_RECORD_MISC_GUEST_USER if machine is guest.
perf tools: Use machine->pid for tgid if machine is guest.
perf tools: Do not synthesize the treads of default guest.

Jiri Olsa (11):
perf inject: Handle output file via perf_data_file object
perf record: Use perf_data_file__write for output file
perf tests: Factor make install tests
perf tools: Making QUIET_(CLEAN|INSTAL) variables global
tools lib traceevent: Remove print_app_build variable
tools lib traceevent: Use global QUIET_CC build output
tools lib traceevent: Add global QUIET_CC_FPIC build output
tools lib traceevent: Use global QUIET_LINK build output
tools lib traceevent: Use global QUIET_INSTALL build output
tools lib traceevent: Use global QUIET_CLEAN build output
tools lib traceevent: Use global 'O' processing code

Masami Hiramatsu (2):
perf probe: Expand given path to absolute path
perf probe: Support basic dwarf-based operations on uprobe events

Namhyung Kim (10):
perf sort: Compare addresses if no symbol info
perf sort: Do not compare dso again
perf hists: Do not pass period and weight to add_hist_entry()
tools lib traceevent: Introduce pevent_filter_strerror()
perf tools: Get rid of a duplicate va_end() in error reporting routine
perf report: Use pr_*() functions where applicable
perf report: Print session information only if --stdio is given
perf ui/tui: Protect windows by ui__lock
perf ui/tui: Split help message for perf top and report
perf ui/tui: Implement header window

tools/lib/traceevent/Makefile | 85 +++----
tools/lib/traceevent/event-parse.c | 17 +-
tools/lib/traceevent/event-parse.h | 7 +-
tools/lib/traceevent/parse-filter.c | 98 ++++----
tools/perf/Makefile.perf | 1 +
tools/perf/arch/common.c | 3 +-
tools/perf/builtin-annotate.c | 13 +-
tools/perf/builtin-diff.c | 2 +-
tools/perf/builtin-inject.c | 65 +++---
tools/perf/builtin-kvm.c | 6 +-
tools/perf/builtin-mem.c | 5 +-
tools/perf/builtin-probe.c | 17 +-
tools/perf/builtin-record.c | 94 ++++----
tools/perf/builtin-report.c | 259 +++++++--------------
tools/perf/builtin-sched.c | 2 +-
tools/perf/builtin-script.c | 22 +-
tools/perf/builtin-stat.c | 6 +-
tools/perf/builtin-timechart.c | 3 +-
tools/perf/builtin-top.c | 23 +-
tools/perf/builtin-trace.c | 14 +-
tools/perf/config/Makefile | 6 +-
tools/perf/config/feature-checks/.gitignore | 2 +
tools/perf/config/feature-checks/Makefile | 110 ++++-----
tools/perf/config/utilities.mak | 7 -
tools/perf/perf.h | 2 +-
tools/perf/tests/code-reading.c | 2 +-
tools/perf/tests/keep-tracking.c | 2 +-
tools/perf/tests/make | 38 ++-
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/ui/browser.c | 8 +-
tools/perf/ui/browser.h | 2 +
tools/perf/ui/browsers/header.c | 127 ++++++++++
tools/perf/ui/browsers/hists.c | 63 +++--
tools/perf/ui/browsers/scripts.c | 3 +-
tools/perf/ui/gtk/util.c | 3 +-
tools/perf/ui/stdio/hist.c | 2 +-
tools/perf/ui/tui/util.c | 19 +-
tools/perf/util/alias.c | 6 +-
tools/perf/util/annotate.c | 73 ++++--
tools/perf/util/annotate.h | 9 +-
tools/perf/util/callchain.h | 2 +-
tools/perf/util/cgroup.c | 2 +-
tools/perf/util/comm.c | 2 +-
tools/perf/util/debug.c | 1 -
tools/perf/util/dso.c | 9 +-
tools/perf/util/event.c | 45 ++--
tools/perf/util/evlist.c | 9 +-
tools/perf/util/evlist.h | 7 +-
tools/perf/util/evsel.c | 17 +-
tools/perf/util/evsel.h | 4 +-
tools/perf/util/header.c | 15 +-
tools/perf/util/help.c | 7 +-
tools/perf/util/hist.c | 27 +--
tools/perf/util/hist.h | 3 -
tools/perf/util/machine.c | 12 +-
tools/perf/util/parse-events.c | 8 +-
tools/perf/util/pmu.c | 2 +-
tools/perf/util/probe-event.c | 234 +++++++++++++------
tools/perf/util/probe-event.h | 1 +
tools/perf/util/probe-finder.c | 33 +--
tools/perf/util/record.c | 9 +-
.../perf/util/scripting-engines/trace-event-perl.c | 22 +-
.../util/scripting-engines/trace-event-python.c | 28 +--
tools/perf/util/session.c | 33 +--
tools/perf/util/session.h | 2 +-
tools/perf/util/sort.c | 22 +-
tools/perf/util/srcline.c | 6 +-
tools/perf/util/strbuf.c | 2 +-
tools/perf/util/strfilter.c | 2 +-
tools/perf/util/string.c | 2 +-
tools/perf/util/strlist.c | 3 +-
tools/perf/util/svghelper.c | 5 +-
tools/perf/util/symbol-elf.c | 2 +-
tools/perf/util/symbol-minimal.c | 3 +-
tools/perf/util/symbol.c | 11 +-
tools/perf/util/symbol.h | 1 +
tools/perf/util/thread_map.c | 20 +-
tools/perf/util/top.c | 2 +-
tools/perf/util/top.h | 2 +-
tools/perf/util/trace-event-info.c | 10 +-
tools/perf/util/trace-event-scripting.c | 3 +-
tools/perf/util/trace-event.h | 1 -
tools/perf/util/util.h | 2 +
tools/perf/util/values.c | 14 +-
tools/scripts/Makefile.include | 4 +
87 files changed, 1001 insertions(+), 882 deletions(-)
create mode 100644 tools/perf/config/feature-checks/.gitignore
create mode 100644 tools/perf/ui/browsers/header.c

Arnaldo Carvalho de Melo

unread,
Dec 27, 2013, 3:50:03 PM12/27/13
to
From: Dongsheng Yang <yangd...@cn.fujitsu.com>

When we synthesize the mmap events of user space, if machine is guest,
we should set the event->header.misc to PERF_RECORD_MISC_GUEST_USER,
rather than PERF_RECORD_MISC_USER.

Signed-off-by: Dongsheng Yang <yangd...@cn.fujitsu.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namhyu...@lge.com>
Link: http://lkml.kernel.org/r/e6f8ff6505d2db8a4b21bff8e448bb9be...@cn.fujitsu.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/event.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index a61726ea01a9..07c07833de53 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -220,7 +220,10 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
/*
* Just like the kernel, see __perf_event_mmap in kernel/perf_event.c
*/
- event->header.misc = PERF_RECORD_MISC_USER;
+ if (machine__is_host(machine))
+ event->header.misc = PERF_RECORD_MISC_USER;
+ else
+ event->header.misc = PERF_RECORD_MISC_GUEST_USER;

if (prot[2] != 'x') {
if (!mmap_data || prot[0] != 'r')
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Dec 27, 2013, 3:50:03 PM12/27/13
to
From: Masami Hiramatsu <masami.hi...@hitachi.com>

Expand given path to absolute path in the option parser, except for a
module name.

Since realpath at later stage in processing several probe point, can be
called several times (even if currently doesn't, it can happen when we
expands the feature), it is waste of the performance.

Processing it once at the early stage can avoid that.

Changes from previous one:
- Fix not to print null string.
- Allocate memory for given path/module name everytime.

Signed-off-by: Masami Hiramatsu <masami.hi...@hitachi.com>
Cc: "David A. Long" <dave...@linaro.org>
Cc: "Steven Rostedt (Red Hat)" <ros...@goodmis.org>
Cc: David Ahern <dsa...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Namhyung Kim <namh...@kernel.org>
Cc: Oleg Nesterov <ol...@redhat.com>
Cc: Srikar Dronamraju <sri...@linux.vnet.ibm.com>
Cc: syst...@sourceware.org
Cc: yrl.pp-m...@hitachi.com
Link: http://lkml.kernel.org/r/20131226054150.2...@kbuild-fedora.novalocal
[ Clarified the pr_warning message as per David Ahern's suggestion ]
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-probe.c | 15 ++++++++++++++-
tools/perf/util/probe-event.c | 11 ++---------
2 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index c98ccb570509..1792a3f1f4ce 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -169,6 +169,7 @@ static int opt_set_target(const struct option *opt, const char *str,
int unset __maybe_unused)
{
int ret = -ENOENT;
+ char *tmp;

if (str && !params.target) {
if (!strcmp(opt->long_name, "exec"))
@@ -180,7 +181,19 @@ static int opt_set_target(const struct option *opt, const char *str,
else
return ret;

- params.target = str;
+ /* Expand given path to absolute path, except for modulename */
+ if (params.uprobes || strchr(str, '/')) {
+ tmp = realpath(str, NULL);
+ if (!tmp) {
+ pr_warning("Failed to get the absolute path of %s: %m\n", str);
+ return ret;
+ }
+ } else {
+ tmp = strdup(str);
+ if (!tmp)
+ return -ENOMEM;
+ }
+ params.target = tmp;
ret = 0;
}

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 544ac1898a9f..68013b91377c 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -2281,7 +2281,7 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec)
struct perf_probe_point *pp = &pev->point;
struct symbol *sym;
struct map *map = NULL;
- char *function = NULL, *name = NULL;
+ char *function = NULL;
int ret = -EINVAL;
unsigned long long vaddr = 0;

@@ -2297,12 +2297,7 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec)
goto out;
}

- name = realpath(exec, NULL);
- if (!name) {
- pr_warning("Cannot find realpath for %s.\n", exec);
- goto out;
- }
- map = dso__new_map(name);
+ map = dso__new_map(exec);
if (!map) {
pr_warning("Cannot find appropriate DSO for %s.\n", exec);
goto out;
@@ -2367,7 +2362,5 @@ out:
}
if (function)
free(function);
- if (name)
- free(name);
return ret;
}
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Dec 27, 2013, 3:50:02 PM12/27/13
to
From: Dongsheng Yang <yangd...@cn.fujitsu.com>

As the default guest is designed to handle orphan kernel symboles with
--guestkallsysms and --guestmodules, it has no user space.

So we should skip synthesizing threads if machine is default guest.

Signed-off-by: Dongsheng Yang <yangd...@cn.fujitsu.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namhyu...@lge.com>
Link: http://lkml.kernel.org/r/e9ddb5dac6f963169657218b12ceb3c20...@cn.fujitsu.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/event.c | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 2905771a1f49..45a76c69a9ed 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -133,6 +133,9 @@ static pid_t perf_event__synthesize_comm(struct perf_tool *tool,
goto out;
}

+ if (machine__is_default_guest(machine))
+ return 0;
+
snprintf(filename, sizeof(filename), "%s/proc/%d/task",
machine->root_dir, pid);

@@ -183,6 +186,9 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
FILE *fp;
int rc = 0;

+ if (machine__is_default_guest(machine))
+ return 0;
+
snprintf(filename, sizeof(filename), "%s/proc/%d/maps",
machine->root_dir, pid);

@@ -409,6 +415,9 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
if (mmap_event == NULL)
goto out_free_comm;

+ if (machine__is_default_guest(machine))
+ return 0;
+
snprintf(proc_path, sizeof(proc_path), "%s/proc", machine->root_dir);
proc = opendir(proc_path);

--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Dec 27, 2013, 3:50:02 PM12/27/13
to
From: Dongsheng Yang <yangd...@cn.fujitsu.com>

When we synthesize the threads, we are looking for the infomation under
/proc. But it is only for host.

This patch look for the path of proc under machine->root_dir, then
XXX__synthesize_threads() functions can support guest machines.

Signed-off-by: Dongsheng Yang <yangd...@cn.fujitsu.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namhyu...@lge.com>
Link: http://lkml.kernel.org/r/927b937da9177a079abafe4532fa9c9b6...@cn.fujitsu.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/event.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 484e99464a00..a61726ea01a9 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -129,7 +129,8 @@ static pid_t perf_event__synthesize_comm(struct perf_tool *tool,
goto out;
}

- snprintf(filename, sizeof(filename), "/proc/%d/task", pid);
+ snprintf(filename, sizeof(filename), "%s/proc/%d/task",
+ machine->root_dir, pid);

tasks = opendir(filename);
if (tasks == NULL) {
@@ -178,7 +179,8 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
FILE *fp;
int rc = 0;

- snprintf(filename, sizeof(filename), "/proc/%d/maps", pid);
+ snprintf(filename, sizeof(filename), "%s/proc/%d/maps",
+ machine->root_dir, pid);

fp = fopen(filename, "r");
if (fp == NULL) {
@@ -387,6 +389,7 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
struct machine *machine, bool mmap_data)
{
DIR *proc;
+ char proc_path[PATH_MAX];
struct dirent dirent, *next;
union perf_event *comm_event, *mmap_event;
int err = -1;
@@ -399,7 +402,9 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
if (mmap_event == NULL)
goto out_free_comm;

- proc = opendir("/proc");
+ snprintf(proc_path, sizeof(proc_path), "%s/proc", machine->root_dir);
+ proc = opendir(proc_path);
+
if (proc == NULL)
goto out_free_mmap;

--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Dec 27, 2013, 3:50:02 PM12/27/13
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

For the frequent idiom of:

free(ptr);
ptr = NULL;

Make it expect a pointer to the pointer being freed, so that it becomes
clear at first sight that the variable being freed is being modified.

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-pfw02ezuab...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/arch/common.c | 3 +--
tools/perf/builtin-annotate.c | 3 +--
tools/perf/builtin-stat.c | 6 ++----
tools/perf/builtin-timechart.c | 3 +--
tools/perf/builtin-trace.c | 12 ++++--------
tools/perf/ui/browser.c | 6 ++----
tools/perf/ui/browsers/hists.c | 6 ++----
tools/perf/ui/gtk/util.c | 3 +--
tools/perf/util/alias.c | 6 ++----
tools/perf/util/annotate.c | 12 ++++--------
tools/perf/util/dso.c | 9 +++------
tools/perf/util/evlist.c | 9 +++------
tools/perf/util/evsel.c | 6 ++----
tools/perf/util/header.c | 3 +--
tools/perf/util/help.c | 3 +--
tools/perf/util/machine.c | 12 +++++-------
tools/perf/util/probe-event.c | 6 ++----
tools/perf/util/probe-finder.c | 24 ++++++++----------------
tools/perf/util/symbol.c | 9 +++------
tools/perf/util/thread_map.c | 10 ++++------
tools/perf/util/trace-event-info.c | 6 ++----
tools/perf/util/util.h | 2 ++
22 files changed, 56 insertions(+), 103 deletions(-)

diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c
index aacef07ebf31..42faf369211c 100644
--- a/tools/perf/arch/common.c
+++ b/tools/perf/arch/common.c
@@ -154,8 +154,7 @@ static int perf_session_env__lookup_binutils_path(struct perf_session_env *env,
}
if (lookup_path(buf))
goto out;
- free(buf);
- buf = NULL;
+ zfree(&buf);
}

if (!strcmp(arch, "arm"))
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 4136f9970fd5..ab65057a0317 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -180,8 +180,7 @@ find_next:
* symbol, free he->ms.sym->src to signal we already
* processed this symbol.
*/
- free(notes->src);
- notes->src = NULL;
+ zfree(&notes->src);
}
}
}
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index dab98b50c9fe..106a5e5b7842 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -185,8 +185,7 @@ static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)

static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
{
- free(evsel->priv);
- evsel->priv = NULL;
+ zfree(&evsel->priv);
}

static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel)
@@ -208,8 +207,7 @@ static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel)

static void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel)
{
- free(evsel->prev_raw_counts);
- evsel->prev_raw_counts = NULL;
+ zfree(&evsel->prev_raw_counts);
}

static void perf_evlist__free_stats(struct perf_evlist *evlist)
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 20d4212fa337..652af0b66a62 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -488,8 +488,7 @@ static const char *cat_backtrace(union perf_event *event,
* It seems the callchain is corrupted.
* Discard all.
*/
- free(p);
- p = NULL;
+ zfree(&p);
goto exit;
}
continue;
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index f64b5b0aa8b1..c5b4bc51175c 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -146,8 +146,7 @@ static int perf_evsel__init_tp_ptr_field(struct perf_evsel *evsel,

static void perf_evsel__delete_priv(struct perf_evsel *evsel)
{
- free(evsel->priv);
- evsel->priv = NULL;
+ zfree(&evsel->priv);
perf_evsel__delete(evsel);
}

@@ -165,8 +164,7 @@ static int perf_evsel__init_syscall_tp(struct perf_evsel *evsel, void *handler)
return -ENOMEM;

out_delete:
- free(evsel->priv);
- evsel->priv = NULL;
+ zfree(&evsel->priv);
return -ENOENT;
}

@@ -1278,10 +1276,8 @@ static size_t syscall_arg__scnprintf_close_fd(char *bf, size_t size,
size_t printed = syscall_arg__scnprintf_fd(bf, size, arg);
struct thread_trace *ttrace = arg->thread->priv;

- if (ttrace && fd >= 0 && fd <= ttrace->paths.max) {
- free(ttrace->paths.table[fd]);
- ttrace->paths.table[fd] = NULL;
- }
+ if (ttrace && fd >= 0 && fd <= ttrace->paths.max)
+ zfree(&ttrace->paths.table[fd]);

return printed;
}
diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c
index 94223d404f43..d11541d4d7d7 100644
--- a/tools/perf/ui/browser.c
+++ b/tools/perf/ui/browser.c
@@ -256,8 +256,7 @@ int ui_browser__show(struct ui_browser *browser, const char *title,
__ui_browser__show_title(browser, title);

browser->title = title;
- free(browser->helpline);
- browser->helpline = NULL;
+ zfree(&browser->helpline);

va_start(ap, helpline);
err = vasprintf(&browser->helpline, helpline, ap);
@@ -272,8 +271,7 @@ void ui_browser__hide(struct ui_browser *browser)
{
pthread_mutex_lock(&ui__lock);
ui_helpline__pop();
- free(browser->helpline);
- browser->helpline = NULL;
+ zfree(&browser->helpline);
pthread_mutex_unlock(&ui__lock);
}

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 0d9dd99507ee..022d1731b801 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -1267,10 +1267,8 @@ static inline void free_popup_options(char **options, int n)
{
int i;

- for (i = 0; i < n; ++i) {
- free(options[i]);
- options[i] = NULL;
- }
+ for (i = 0; i < n; ++i)
+ zfree(&options[i]);
}

/* Check whether the browser is for 'top' or 'report' */
diff --git a/tools/perf/ui/gtk/util.c b/tools/perf/ui/gtk/util.c
index 696c1fbe4248..52e7fc48af9f 100644
--- a/tools/perf/ui/gtk/util.c
+++ b/tools/perf/ui/gtk/util.c
@@ -23,8 +23,7 @@ int perf_gtk__deactivate_context(struct perf_gtk_context **ctx)
if (!perf_gtk__is_active_context(*ctx))
return -1;

- free(*ctx);
- *ctx = NULL;
+ zfree(ctx);
return 0;
}

diff --git a/tools/perf/util/alias.c b/tools/perf/util/alias.c
index e6d134773d0a..c0b43ee40d95 100644
--- a/tools/perf/util/alias.c
+++ b/tools/perf/util/alias.c
@@ -55,8 +55,7 @@ int split_cmdline(char *cmdline, const char ***argv)
src++;
c = cmdline[src];
if (!c) {
- free(*argv);
- *argv = NULL;
+ zfree(argv);
return error("cmdline ends with \\");
}
}
@@ -68,8 +67,7 @@ int split_cmdline(char *cmdline, const char ***argv)
cmdline[dst] = 0;

if (quoted) {
- free(*argv);
- *argv = NULL;
+ zfree(argv);
return error("unclosed quote");
}

diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 27ab7b59dbf4..a78721d14694 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -185,8 +185,7 @@ static int lock__parse(struct ins_operands *ops)
return 0;

out_free_ops:
- free(ops->locked.ops);
- ops->locked.ops = NULL;
+ zfree(&ops->locked.ops);
return 0;
}

@@ -256,8 +255,7 @@ static int mov__parse(struct ins_operands *ops)
return 0;

out_free_source:
- free(ops->source.raw);
- ops->source.raw = NULL;
+ zfree(&ops->source.raw);
return -1;
}

@@ -560,8 +558,7 @@ static int disasm_line__parse(char *line, char **namep, char **rawp)
return 0;

out_free_name:
- free(*namep);
- *namep = NULL;
+ zfree(namep);
return -1;
}

@@ -1113,8 +1110,7 @@ static void symbol__free_source_line(struct symbol *sym, int len)
src_line = (void *)src_line + sizeof_src_line;
}

- free(notes->src->lines);
- notes->src->lines = NULL;
+ zfree(&notes->src->lines);
}

/* Get the filename:line for the colored entries */
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 4ddeecb9ff85..4045d086d9d9 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -497,21 +497,18 @@ void dso__delete(struct dso *dso)
symbols__delete(&dso->symbols[i]);

if (dso->short_name_allocated) {
- free((char *)dso->short_name);
- dso->short_name = NULL;
+ zfree((char **)&dso->short_name);
dso->short_name_allocated = false;
}

if (dso->long_name_allocated) {
- free((char *)dso->long_name);
- dso->long_name = NULL;
+ zfree((char **)&dso->long_name);
dso->long_name_allocated = false;
}

dso_cache__free(&dso->cache);
dso__free_a2l(dso);
- free(dso->symsrc_filename);
- dso->symsrc_filename = NULL;
+ zfree(&dso->symsrc_filename);
free(dso);
}

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index da3182914984..b08a7ecdcea1 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -101,10 +101,8 @@ static void perf_evlist__purge(struct perf_evlist *evlist)

void perf_evlist__exit(struct perf_evlist *evlist)
{
- free(evlist->mmap);
- free(evlist->pollfd);
- evlist->mmap = NULL;
- evlist->pollfd = NULL;
+ zfree(&evlist->mmap);
+ zfree(&evlist->pollfd);
}

void perf_evlist__delete(struct perf_evlist *evlist)
@@ -587,8 +585,7 @@ void perf_evlist__munmap(struct perf_evlist *evlist)
for (i = 0; i < evlist->nr_mmaps; i++)
__perf_evlist__munmap(evlist, i);

- free(evlist->mmap);
- evlist->mmap = NULL;
+ zfree(&evlist->mmap);
}

static int perf_evlist__alloc_mmap(struct perf_evlist *evlist)
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 6874e0485693..93b6031d5459 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -750,8 +750,7 @@ void perf_evsel__free_id(struct perf_evsel *evsel)
{
xyarray__delete(evsel->sample_id);
evsel->sample_id = NULL;
- free(evsel->id);
- evsel->id = NULL;
+ zfree(&evsel->id);
}

void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
@@ -1960,8 +1959,7 @@ bool perf_evsel__fallback(struct perf_evsel *evsel, int err,
evsel->attr.type = PERF_TYPE_SOFTWARE;
evsel->attr.config = PERF_COUNT_SW_CPU_CLOCK;

- free(evsel->name);
- evsel->name = NULL;
+ zfree(&evsel->name);
return true;
}

diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 10730b0af804..20f3a9c97bd8 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -1324,8 +1324,7 @@ read_event_desc(struct perf_header *ph, int fd)
}
}
out:
- if (buf)
- free(buf);
+ free(buf);
return events;
error:
if (events)
diff --git a/tools/perf/util/help.c b/tools/perf/util/help.c
index 8b1f6e891b8a..7b68978e50d2 100644
--- a/tools/perf/util/help.c
+++ b/tools/perf/util/help.c
@@ -263,9 +263,8 @@ static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old)

for (i = 0; i < old->cnt; i++)
cmds->names[cmds->cnt++] = old->names[i];
- free(old->names);
+ zfree(&old->names);
old->cnt = 0;
- old->names = NULL;
}

const char *help_unknown_cmd(const char *cmd)
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index c78cc84f433e..a98538dc465a 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -102,8 +102,7 @@ void machine__exit(struct machine *machine)
map_groups__exit(&machine->kmaps);
dsos__delete(&machine->user_dsos);
dsos__delete(&machine->kernel_dsos);
- free(machine->root_dir);
- machine->root_dir = NULL;
+ zfree(&machine->root_dir);
}

void machine__delete(struct machine *machine)
@@ -562,11 +561,10 @@ void machine__destroy_kernel_maps(struct machine *machine)
* on one of them.
*/
if (type == MAP__FUNCTION) {
- free((char *)kmap->ref_reloc_sym->name);
- kmap->ref_reloc_sym->name = NULL;
- free(kmap->ref_reloc_sym);
- }
- kmap->ref_reloc_sym = NULL;
+ zfree((char **)&kmap->ref_reloc_sym->name);
+ zfree(&kmap->ref_reloc_sym);
+ } else
+ kmap->ref_reloc_sym = NULL;
}

map__delete(machine->vmlinux_maps[type]);
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 095a98ec7444..4d3cd1a0278a 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -506,15 +506,13 @@ static int get_real_path(const char *raw_path, const char *comp_dir,
case EFAULT:
raw_path = strchr(++raw_path, '/');
if (!raw_path) {
- free(*new_path);
- *new_path = NULL;
+ zfree(new_path);
return -ENOENT;
}
continue;

default:
- free(*new_path);
- *new_path = NULL;
+ zfree(new_path);
return -errno;
}
}
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 8c087359b7ce..6d8796e38d7f 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -226,10 +226,8 @@ struct debuginfo *debuginfo__new(const char *path)
if (!dbg)
return NULL;

- if (debuginfo__init_offline_dwarf(dbg, path) < 0) {
- free(dbg);
- dbg = NULL;
- }
+ if (debuginfo__init_offline_dwarf(dbg, path) < 0)
+ zfree(&dbg);

return dbg;
}
@@ -241,10 +239,8 @@ struct debuginfo *debuginfo__new_online_kernel(unsigned long addr)
if (!dbg)
return NULL;

- if (debuginfo__init_online_kernel_dwarf(dbg, (Dwarf_Addr)addr) < 0) {
- free(dbg);
- dbg = NULL;
- }
+ if (debuginfo__init_online_kernel_dwarf(dbg, (Dwarf_Addr)addr) < 0)
+ zfree(&dbg);

return dbg;
}
@@ -1302,8 +1298,7 @@ int debuginfo__find_trace_events(struct debuginfo *dbg,

ret = debuginfo__find_probes(dbg, &tf.pf);
if (ret < 0) {
- free(*tevs);
- *tevs = NULL;
+ zfree(tevs);
return ret;
}

@@ -1417,8 +1412,7 @@ int debuginfo__find_available_vars_at(struct debuginfo *dbg,
free(af.vls[af.nvls].point.symbol);
strlist__delete(af.vls[af.nvls].vars);
}
- free(af.vls);
- *vls = NULL;
+ zfree(vls);
return ret;
}

@@ -1522,8 +1516,7 @@ post:
if (fname) {
ppt->file = strdup(fname);
if (ppt->file == NULL) {
- free(ppt->function);
- ppt->function = NULL;
+ zfree(&ppt->function);
ret = -ENOMEM;
goto end;
}
@@ -1577,8 +1570,7 @@ static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf)
else
ret = 0; /* Lines are not found */
else {
- free(lf->lr->path);
- lf->lr->path = NULL;
+ zfree(&lf->lr->path);
}
return ret;
}
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 923d00040bbf..fd9e1a4fad16 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1621,13 +1621,10 @@ static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,

static void vmlinux_path__exit(void)
{
- while (--vmlinux_path__nr_entries >= 0) {
- free(vmlinux_path[vmlinux_path__nr_entries]);
- vmlinux_path[vmlinux_path__nr_entries] = NULL;
- }
+ while (--vmlinux_path__nr_entries >= 0)
+ zfree(&vmlinux_path[vmlinux_path__nr_entries]);

- free(vmlinux_path);
- vmlinux_path = NULL;
+ zfree(&vmlinux_path);
}

static int vmlinux_path__init(void)
diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c
index 9b5f856cc280..cf44644a4058 100644
--- a/tools/perf/util/thread_map.c
+++ b/tools/perf/util/thread_map.c
@@ -9,6 +9,7 @@
#include "strlist.h"
#include <string.h>
#include "thread_map.h"
+#include "util.h"

/* Skip "." and ".." directories */
static int filter(const struct dirent *dir)
@@ -138,8 +139,7 @@ out_free_namelist:
free(namelist);

out_free_closedir:
- free(threads);
- threads = NULL;
+ zfree(&threads);
goto out_closedir;
}

@@ -210,8 +210,7 @@ out_free_namelist:
free(namelist);

out_free_threads:
- free(threads);
- threads = NULL;
+ zfree(&threads);
goto out;
}

@@ -262,8 +261,7 @@ out:
return threads;

out_free_threads:
- free(threads);
- threads = NULL;
+ zfree(&threads);
goto out;
}

diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c
index c354b95a2348..9f73bf43862c 100644
--- a/tools/perf/util/trace-event-info.c
+++ b/tools/perf/util/trace-event-info.c
@@ -562,10 +562,8 @@ out:
output_fd = fd;
}

- if (err) {
- free(tdata);
- tdata = NULL;
- }
+ if (err)
+ zfree(&tdata);

put_tracepoints_path(tps);
return tdata;
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 9a2c268ad718..6995d66f225c 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -186,6 +186,8 @@ static inline void *zalloc(size_t size)
return calloc(1, size);
}

+#define zfree(ptr) ({ free(*ptr); *ptr = NULL; })
+
static inline int has_extension(const char *filename, const char *ext)
{
size_t len = strlen(filename);
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Dec 27, 2013, 4:00:02 PM12/27/13
to
From: Namhyung Kim <namhyu...@lge.com>

Sometimes perf top TUI breaks display with concurrent help/input window
and pr_* messages since they're not protected by ui__lock.

You can check it by pressing (and not releasing) 'h' key on a "perf top
-vvv" TUI session.

Signed-off-by: Namhyung Kim <namh...@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/1388036284-32342-2-gi...@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/ui/tui/util.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/tools/perf/ui/tui/util.c b/tools/perf/ui/tui/util.c
index 092902e30cee..bf890f72fe80 100644
--- a/tools/perf/ui/tui/util.c
+++ b/tools/perf/ui/tui/util.c
@@ -92,6 +92,8 @@ int ui_browser__input_window(const char *title, const char *text, char *input,
t = sep + 1;
}

+ pthread_mutex_lock(&ui__lock);
+
max_len += 2;
nr_lines += 8;
y = SLtt_Screen_Rows / 2 - nr_lines / 2;
@@ -120,13 +122,19 @@ int ui_browser__input_window(const char *title, const char *text, char *input,
SLsmg_write_nstring((char *)exit_msg, max_len);
SLsmg_refresh();

+ pthread_mutex_unlock(&ui__lock);
+
x += 2;
len = 0;
key = ui__getch(delay_secs);
while (key != K_TIMER && key != K_ENTER && key != K_ESC) {
+ pthread_mutex_lock(&ui__lock);
+
if (key == K_BKSPC) {
- if (len == 0)
+ if (len == 0) {
+ pthread_mutex_unlock(&ui__lock);
goto next_key;
+ }
SLsmg_gotorc(y, x + --len);
SLsmg_write_char(' ');
} else {
@@ -136,6 +144,8 @@ int ui_browser__input_window(const char *title, const char *text, char *input,
}
SLsmg_refresh();

+ pthread_mutex_unlock(&ui__lock);
+
/* XXX more graceful overflow handling needed */
if (len == sizeof(buf) - 1) {
ui_helpline__push("maximum size of symbol name reached!");
@@ -174,6 +184,8 @@ int ui__question_window(const char *title, const char *text,
t = sep + 1;
}

+ pthread_mutex_lock(&ui__lock);
+
max_len += 2;
nr_lines += 4;
y = SLtt_Screen_Rows / 2 - nr_lines / 2,
@@ -195,6 +207,9 @@ int ui__question_window(const char *title, const char *text,
SLsmg_gotorc(y + nr_lines - 1, x);
SLsmg_write_nstring((char *)exit_msg, max_len);
SLsmg_refresh();
+
+ pthread_mutex_unlock(&ui__lock);
+
return ui__getch(delay_secs);
}

@@ -215,9 +230,7 @@ static int __ui__warning(const char *title, const char *format, va_list args)
if (vasprintf(&s, format, args) > 0) {
int key;

- pthread_mutex_lock(&ui__lock);
key = ui__question_window(title, s, "Press any key...", 0);
- pthread_mutex_unlock(&ui__lock);
free(s);
return key;
}
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Dec 27, 2013, 4:00:02 PM12/27/13
to
From: Namhyung Kim <namhyu...@lge.com>

Implement a simple, full-screen header window which shows session header
(metadata) information. Press 'i' key to display the header window.

Signed-off-by: Namhyung Kim <namh...@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/1388036284-32342-4-gi...@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/Makefile.perf | 1 +
tools/perf/ui/browser.h | 2 +
tools/perf/ui/browsers/header.c | 127 ++++++++++++++++++++++++++++++++++++++++
tools/perf/ui/browsers/hists.c | 6 ++
4 files changed, 136 insertions(+)
create mode 100644 tools/perf/ui/browsers/header.c

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 97a2145e4cc6..3638b0bd20dc 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -489,6 +489,7 @@ ifndef NO_SLANG
LIB_OBJS += $(OUTPUT)ui/browsers/hists.o
LIB_OBJS += $(OUTPUT)ui/browsers/map.o
LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o
+ LIB_OBJS += $(OUTPUT)ui/browsers/header.o
LIB_OBJS += $(OUTPUT)ui/tui/setup.o
LIB_OBJS += $(OUTPUT)ui/tui/util.o
LIB_OBJS += $(OUTPUT)ui/tui/helpline.o
diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h
index 7d45d2f53601..118cca29dd26 100644
--- a/tools/perf/ui/browser.h
+++ b/tools/perf/ui/browser.h
@@ -59,6 +59,8 @@ int ui_browser__help_window(struct ui_browser *browser, const char *text);
bool ui_browser__dialog_yesno(struct ui_browser *browser, const char *text);
int ui_browser__input_window(const char *title, const char *text, char *input,
const char *exit_msg, int delay_sec);
+struct perf_session_env;
+int tui__header_window(struct perf_session_env *env);

void ui_browser__argv_seek(struct ui_browser *browser, off_t offset, int whence);
unsigned int ui_browser__argv_refresh(struct ui_browser *browser);
diff --git a/tools/perf/ui/browsers/header.c b/tools/perf/ui/browsers/header.c
new file mode 100644
index 000000000000..89c16b988618
--- /dev/null
+++ b/tools/perf/ui/browsers/header.c
@@ -0,0 +1,127 @@
+#include "util/cache.h"
+#include "util/debug.h"
+#include "ui/browser.h"
+#include "ui/ui.h"
+#include "ui/util.h"
+#include "ui/libslang.h"
+#include "util/header.h"
+#include "util/session.h"
+
+static void ui_browser__argv_write(struct ui_browser *browser,
+ void *entry, int row)
+{
+ char **arg = entry;
+ char *str = *arg;
+ char empty[] = " ";
+ bool current_entry = ui_browser__is_current_entry(browser, row);
+ unsigned long offset = (unsigned long)browser->priv;
+
+ if (offset >= strlen(str))
+ str = empty;
+ else
+ str = str + offset;
+
+ ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED :
+ HE_COLORSET_NORMAL);
+
+ slsmg_write_nstring(str, browser->width);
+}
+
+static int list_menu__run(struct ui_browser *menu)
+{
+ int key;
+ unsigned long offset;
+ const char help[] =
+ "h/?/F1 Show this window\n"
+ "UP/DOWN/PGUP\n"
+ "PGDN/SPACE\n"
+ "LEFT/RIGHT Navigate\n"
+ "q/ESC/CTRL+C Exit browser";
+
+ if (ui_browser__show(menu, "Header information", "Press 'q' to exit") < 0)
+ return -1;
+
+ while (1) {
+ key = ui_browser__run(menu, 0);
+
+ switch (key) {
+ case K_RIGHT:
+ offset = (unsigned long)menu->priv;
+ offset += 10;
+ menu->priv = (void *)offset;
+ continue;
+ case K_LEFT:
+ offset = (unsigned long)menu->priv;
+ if (offset >= 10)
+ offset -= 10;
+ menu->priv = (void *)offset;
+ continue;
+ case K_F1:
+ case 'h':
+ case '?':
+ ui_browser__help_window(menu, help);
+ continue;
+ case K_ESC:
+ case 'q':
+ case CTRL('c'):
+ key = -1;
+ break;
+ default:
+ continue;
+ }
+
+ break;
+ }
+
+ ui_browser__hide(menu);
+ return key;
+}
+
+static int ui__list_menu(int argc, char * const argv[])
+{
+ struct ui_browser menu = {
+ .entries = (void *)argv,
+ .refresh = ui_browser__argv_refresh,
+ .seek = ui_browser__argv_seek,
+ .write = ui_browser__argv_write,
+ .nr_entries = argc,
+ };
+
+ return list_menu__run(&menu);
+}
+
+int tui__header_window(struct perf_session_env *env)
+{
+ int i, argc = 0;
+ char **argv;
+ struct perf_session *session;
+ char *ptr, *pos;
+ size_t size;
+ FILE *fp = open_memstream(&ptr, &size);
+
+ session = container_of(env, struct perf_session, header.env);
+ perf_header__fprintf_info(session, fp, true);
+ fclose(fp);
+
+ for (pos = ptr, argc = 0; (pos = strchr(pos, '\n')) != NULL; pos++)
+ argc++;
+
+ argv = calloc(argc + 1, sizeof(*argv));
+ if (argv == NULL)
+ goto out;
+
+ argv[0] = pos = ptr;
+ for (i = 1; (pos = strchr(pos, '\n')) != NULL; i++) {
+ *pos++ = '\0';
+ argv[i] = pos;
+ }
+
+ BUG_ON(i != argc + 1);
+
+ ui__list_menu(argc, argv);
+
+out:
+ free(argv);
+ free(ptr);
+ return 0;
+}
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index d43ec79ea4e3..0d9dd99507ee 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -1417,6 +1417,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,

/* help messages are sorted by lexical order of the hotkey */
const char report_help[] = HIST_BROWSER_HELP_COMMON
+ "i Show header information\n"
"P Print histograms to perf.hist.N\n"
"r Run available scripts\n"
"s Switch to another data file in PWD\n"
@@ -1513,6 +1514,11 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
if (is_report_browser(hbt))
goto do_data_switch;
continue;
+ case 'i':
+ /* env->arch is NULL for live-mode (i.e. perf top) */
+ if (env->arch)
+ tui__header_window(env);
+ continue;
case K_F1:
case 'h':
case '?':
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Dec 27, 2013, 4:00:02 PM12/27/13
to
From: Dongsheng Yang <yangd...@cn.fujitsu.com>

Currently, if we use perf kvm --guestkallsyms --guestmodules report, we
can not get the perf information from perf data file. All sample are
shown as unknown.

Reproducing steps:
# perf kvm --guestkallsyms /tmp/kallsyms --guestmodules /tmp/modules record -a sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.624 MB perf.data.guest (~27260 samples) ]
# perf kvm --guestkallsyms /tmp/kallsyms --guestmodules /tmp/modules report |grep %
100.00% [guest/6471] [unknown] [g] 0xffffffff8164f330

This bug was introduced by 207b57926 (perf kvm: Fix regression with guest machine creation).
In original code, it uses perf_session__find_machine(), it means we deliver symbol to machine
which has the same pid, if no machine found, deliver it to *default* guest. But if we use
perf_session__findnew_machine() here, if no machine was found, new machine with pid will be built
and added. Then the default guest which with pid == 0 will never get a symbol.

And because the new machine initialized here has no kernel map created, the symbol delivered to
it will be marked as "unknown".

This patch here is to revert commit 207b57926 and fix the SEGFAULT bug in another way.

Verification steps:
# ./perf kvm --guestkallsyms /home/kallsyms --guestmodules /home/modules record -a sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.651 MB perf.data.guest (~28437 samples) ]
# ./perf kvm --guestkallsyms /home/kallsyms --guestmodules /home/modules report |grep %
22.64% :6471 [guest.kernel.kallsyms] [g] update_rq_clock.part.70
19.99% :6471 [guest.kernel.kallsyms] [g] d_free
18.46% :6471 [guest.kernel.kallsyms] [g] bio_phys_segments
16.25% :6471 [guest.kernel.kallsyms] [g] dequeue_task
12.78% :6471 [guest.kernel.kallsyms] [g] __switch_to
7.91% :6471 [guest.kernel.kallsyms] [g] scheduler_tick
1.75% :6471 [guest.kernel.kallsyms] [g] native_apic_mem_write
0.21% :6471 [guest.kernel.kallsyms] [g] apic_timer_interrupt

Signed-off-by: Dongsheng Yang <yangd...@cn.fujitsu.com>
Acked-by: David Ahern <dsa...@gmail.com>
Cc: sta...@vger.kernel.org # 3.3+
Cc: David Ahern <dsa...@gmail.com>
Link: http://lkml.kernel.org/r/1387564907-3045-1-git-...@cn.fujitsu.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/session.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index cbacaab3e9c4..d3a857be9682 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -830,6 +830,7 @@ static struct machine *
struct perf_sample *sample)
{
const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+ struct machine *machine;

if (perf_guest &&
((cpumode == PERF_RECORD_MISC_GUEST_KERNEL) ||
@@ -842,7 +843,11 @@ static struct machine *
else
pid = sample->pid;

- return perf_session__findnew_machine(session, pid);
+ machine = perf_session__find_machine(session, pid);
+ if (!machine)
+ machine = perf_session__findnew_machine(session,
+ DEFAULT_GUEST_KERNEL_ID);
+ return machine;
}

return &session->machines.host;
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Dec 27, 2013, 4:00:02 PM12/27/13
to
From: Namhyung Kim <namhyu...@lge.com>

Some hotkeys don't work for perf top so split help messages for them.

It'll be helpful to a future modification. Also sort the message by
alphabetical order of the hotkey.

Signed-off-by: Namhyung Kim <namh...@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/1388036284-32342-3-gi...@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/ui/browsers/hists.c | 49 ++++++++++++++++++++++++++----------------
1 file changed, 30 insertions(+), 19 deletions(-)

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index a440e03cd8c2..d43ec79ea4e3 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -1400,6 +1400,35 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
char script_opt[64];
int delay_secs = hbt ? hbt->refresh : 0;

+#define HIST_BROWSER_HELP_COMMON \
+ "h/?/F1 Show this window\n" \
+ "UP/DOWN/PGUP\n" \
+ "PGDN/SPACE Navigate\n" \
+ "q/ESC/CTRL+C Exit browser\n\n" \
+ "For multiple event sessions:\n\n" \
+ "TAB/UNTAB Switch events\n\n" \
+ "For symbolic views (--sort has sym):\n\n" \
+ "-> Zoom into DSO/Threads & Annotate current symbol\n" \
+ "<- Zoom out\n" \
+ "a Annotate current symbol\n" \
+ "C Collapse all callchains\n" \
+ "d Zoom into current DSO\n" \
+ "E Expand all callchains\n" \
+
+ /* help messages are sorted by lexical order of the hotkey */
+ const char report_help[] = HIST_BROWSER_HELP_COMMON
+ "P Print histograms to perf.hist.N\n"
+ "r Run available scripts\n"
+ "s Switch to another data file in PWD\n"
+ "t Zoom into current Thread\n"
+ "V Verbose (DSO names in callchains, etc)\n"
+ "/ Filter symbol by name";
+ const char top_help[] = HIST_BROWSER_HELP_COMMON
+ "P Print histograms to perf.hist.N\n"
+ "t Zoom into current Thread\n"
+ "V Verbose (DSO names in callchains, etc)\n"
+ "/ Filter symbol by name";
+
if (browser == NULL)
return -1;

@@ -1488,25 +1517,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
case 'h':
case '?':
ui_browser__help_window(&browser->b,
- "h/?/F1 Show this window\n"
- "UP/DOWN/PGUP\n"
- "PGDN/SPACE Navigate\n"
- "q/ESC/CTRL+C Exit browser\n\n"
- "For multiple event sessions:\n\n"
- "TAB/UNTAB Switch events\n\n"
- "For symbolic views (--sort has sym):\n\n"
- "-> Zoom into DSO/Threads & Annotate current symbol\n"
- "<- Zoom out\n"
- "a Annotate current symbol\n"
- "C Collapse all callchains\n"
- "E Expand all callchains\n"
- "d Zoom into current DSO\n"
- "t Zoom into current Thread\n"
- "r Run available scripts('perf report' only)\n"
- "s Switch to another data file in PWD ('perf report' only)\n"
- "P Print histograms to perf.hist.N\n"
- "V Verbose (DSO names in callchains, etc)\n"
- "/ Filter symbol by name");
+ is_report_browser(hbt) ? report_help : top_help);
continue;
case K_ENTER:
case K_RIGHT:
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Dec 27, 2013, 4:00:02 PM12/27/13
to
From: Dongsheng Yang <yangd...@cn.fujitsu.com>

When we synthesize an comm event, if machine is guest, we should
use the pid of machine as the event->comm.pid, rather than tgid
of thread.

Signed-off-by: Dongsheng Yang <yangd...@cn.fujitsu.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namhyu...@lge.com>
Link: http://lkml.kernel.org/r/22455abe107c618a361e7b667ad0f098f...@cn.fujitsu.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/event.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 07c07833de53..2905771a1f49 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -106,8 +106,12 @@ static pid_t perf_event__synthesize_comm(struct perf_tool *tool,

memset(&event->comm, 0, sizeof(event->comm));

- tgid = perf_event__get_comm_tgid(pid, event->comm.comm,
- sizeof(event->comm.comm));
+ if (machine__is_host(machine))
+ tgid = perf_event__get_comm_tgid(pid, event->comm.comm,
+ sizeof(event->comm.comm));
+ else
+ tgid = machine->pid;
+
if (tgid < 0)
goto out;

--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Dec 27, 2013, 4:00:02 PM12/27/13
to
From: Chunwei Chen <tux...@gmail.com>

1. Rename the test-* binary files to test-*.bin for easier pattern matching as
suggested by Ingo.
2. Ignore *.bin and *.d files.

Signed-off-by: Chunwei Chen <tux...@gmail.com>
Reviewed-by: Ingo Molnar <mi...@kernel.org>
Acked-by: Jiri Olsa <jo...@redhat.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Link: http://lkml.kernel.org/r/52B52B9...@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/config/Makefile | 6 +-
tools/perf/config/feature-checks/.gitignore | 2 +
tools/perf/config/feature-checks/Makefile | 110 ++++++++++++++--------------
3 files changed, 60 insertions(+), 58 deletions(-)
create mode 100644 tools/perf/config/feature-checks/.gitignore

diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 5a1f4df3c3a8..14faeeb0d752 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -126,7 +126,7 @@ endif

feature_check = $(eval $(feature_check_code))
define feature_check_code
- feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS) $(FEATURE_CHECK_CFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -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) $(FEATURE_CHECK_CFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -C config/feature-checks test-$1.bin >/dev/null 2>/dev/null && echo 1 || echo 0)
endef

feature_set = $(eval $(feature_set_code))
@@ -173,7 +173,7 @@ CORE_FEATURE_TESTS = \
# to skip the print-out of the long features list if the file
# existed before and after it was built:
#
-ifeq ($(wildcard $(OUTPUT)config/feature-checks/test-all),)
+ifeq ($(wildcard $(OUTPUT)config/feature-checks/test-all.bin),)
test-all-failed := 1
else
test-all-failed := 0
@@ -203,7 +203,7 @@ ifeq ($(feature-all), 1)
#
$(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_set,$(feat)))
else
- $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" 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 $(addsuffix .bin,$(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/.gitignore b/tools/perf/config/feature-checks/.gitignore
new file mode 100644
index 000000000000..80f3da0c3515
--- /dev/null
+++ b/tools/perf/config/feature-checks/.gitignore
@@ -0,0 +1,2 @@
+*.d
+*.bin
diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile
index bc86462e80a2..7cf6fcdacebe 100644
--- a/tools/perf/config/feature-checks/Makefile
+++ b/tools/perf/config/feature-checks/Makefile
@@ -1,90 +1,90 @@

FILES= \
- test-all \
- test-backtrace \
- test-bionic \
- test-dwarf \
- test-fortify-source \
- test-glibc \
- test-gtk2 \
- test-gtk2-infobar \
- test-hello \
- test-libaudit \
- test-libbfd \
- test-liberty \
- test-liberty-z \
- test-cplus-demangle \
- test-libelf \
- test-libelf-getphdrnum \
- test-libelf-mmap \
- test-libnuma \
- test-libperl \
- test-libpython \
- test-libpython-version \
- test-libslang \
- test-libunwind \
- test-libunwind-debug-frame \
- test-on-exit \
- test-stackprotector-all \
- test-timerfd
+ test-all.bin \
+ test-backtrace.bin \
+ test-bionic.bin \
+ test-dwarf.bin \
+ test-fortify-source.bin \
+ test-glibc.bin \
+ test-gtk2.bin \
+ test-gtk2-infobar.bin \
+ test-hello.bin \
+ test-libaudit.bin \
+ test-libbfd.bin \
+ test-liberty.bin \
+ test-liberty-z.bin \
+ test-cplus-demangle.bin \
+ test-libelf.bin \
+ test-libelf-getphdrnum.bin \
+ test-libelf-mmap.bin \
+ test-libnuma.bin \
+ test-libperl.bin \
+ test-libpython.bin \
+ test-libpython-version.bin \
+ test-libslang.bin \
+ test-libunwind.bin \
+ test-libunwind-debug-frame.bin \
+ test-on-exit.bin \
+ test-stackprotector-all.bin \
+ test-timerfd.bin

CC := $(CC) -MD

all: $(FILES)

-BUILD = $(CC) $(CFLAGS) -o $(OUTPUT)$@ $@.c $(LDFLAGS)
+BUILD = $(CC) $(CFLAGS) -o $(OUTPUT)$@ $(patsubst %.bin,%.c,$@) $(LDFLAGS)

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

-test-all:
+test-all.bin:
$(BUILD) -Werror -fstack-protector-all -O2 -Werror -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -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:
+test-hello.bin:
$(BUILD)

-test-stackprotector-all:
+test-stackprotector-all.bin:
$(BUILD) -Werror -fstack-protector-all

-test-fortify-source:
+test-fortify-source.bin:
$(BUILD) -O2 -Werror -D_FORTIFY_SOURCE=2

-test-bionic:
+test-bionic.bin:
$(BUILD)

-test-libelf:
+test-libelf.bin:
$(BUILD) -lelf

-test-glibc:
+test-glibc.bin:
$(BUILD)

-test-dwarf:
+test-dwarf.bin:
$(BUILD) -ldw

-test-libelf-mmap:
+test-libelf-mmap.bin:
$(BUILD) -lelf

-test-libelf-getphdrnum:
+test-libelf-getphdrnum.bin:
$(BUILD) -lelf

-test-libnuma:
+test-libnuma.bin:
$(BUILD) -lnuma

-test-libunwind:
+test-libunwind.bin:
$(BUILD) -lelf

-test-libunwind-debug-frame:
+test-libunwind-debug-frame.bin:
$(BUILD) -lelf

-test-libaudit:
+test-libaudit.bin:
$(BUILD) -laudit

-test-libslang:
+test-libslang.bin:
$(BUILD) -I/usr/include/slang -lslang

-test-gtk2:
+test-gtk2.bin:
$(BUILD) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)

-test-gtk2-infobar:
+test-gtk2-infobar.bin:
$(BUILD) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)

grep-libs = $(filter -l%,$(1))
@@ -96,7 +96,7 @@ PERL_EMBED_LIBADD = $(call grep-libs,$(PERL_EMBED_LDOPTS))
PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null`
FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS)

-test-libperl:
+test-libperl.bin:
$(BUILD) $(FLAGS_PERL_EMBED)

override PYTHON := python
@@ -113,31 +113,31 @@ PYTHON_EMBED_LIBADD = $(call grep-libs,$(PYTHON_EMBED_LDOPTS))
PYTHON_EMBED_CCOPTS = $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null)
FLAGS_PYTHON_EMBED = $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS)

-test-libpython:
+test-libpython.bin:
$(BUILD) $(FLAGS_PYTHON_EMBED)

-test-libpython-version:
+test-libpython-version.bin:
$(BUILD) $(FLAGS_PYTHON_EMBED)

-test-libbfd:
+test-libbfd.bin:
$(BUILD) -DPACKAGE='"perf"' -lbfd -ldl

-test-liberty:
+test-liberty.bin:
$(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty

-test-liberty-z:
+test-liberty-z.bin:
$(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty -lz

-test-cplus-demangle:
+test-cplus-demangle.bin:
$(BUILD) -liberty

-test-on-exit:
+test-on-exit.bin:
$(BUILD)

-test-backtrace:
+test-backtrace.bin:
$(BUILD)

-test-timerfd:
+test-timerfd.bin:
$(BUILD)

-include *.d
--
1.8.1.4

Ingo Molnar

unread,
Jan 12, 2014, 11:50:02 AM1/12/14
to

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

Pulled, thanks a lot Arnaldo!

Ingo

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 3:50:02 PM1/13/14
to
From: Arnaldo Carvalho de Melo <ac...@ghostprotocols.net>

Hi Ingo,

There are more patchkits outstanding that I have to revisit/retest, but
lets get this first batch in to keep pull reqs at a reasonable size.

Please consider pulling,

- Arnaldo

The following changes since commit 1341f3e4c0276aae3de6d902c9202265d89fe438:

Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core (2014-01-12 17:39:47 +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 26f7f9877234e6b9ed87eff4ca450631bafe0182:

perf tools: Remove unused test-volatile-register-var.c (2014-01-13 17:20:05 -0300)

----------------------------------------------------------------
New features:

. perf record: Add --initial-delay option (Andi Kleen)

. Column colouring improvements in 'diff' (Ramkumar Ramachandra)

Fixes:

. Don't show counter information when workload fails (Arnaldo Carvalho de Melo)

. Fixup leak on error path in parse events test. (Arnaldo Carvalho de Melo)

. Fix --delay option in 'stat' man page (Andi Kleen)

. Use the DWARF unwind info only if loaded (Jean Pihet):

Developer stuff:

. Improve forked workload error reporting by sending the errno in the signal
data queueing integer field, using sigqueue and by doing the signal setup in
the evlist methods, removing open coded equivalents in various tools. (Arnaldo Carvalho de Melo)

. Do more auto exit cleanup shores in the 'evlist' destructor, so that the tools
don't have to all do that sequence. (Arnaldo Carvalho de Melo)

. Pack 'struct perf_session_env' and 'struct trace' (Arnaldo Carvalho de Melo)

. Include tools/lib/api/ in MANIFEST, fixing detached tarballs (Arnaldo Carvalho de Melo)

. Add test for building detached source tarballs (Arnaldo Carvalho de Melo)

. Shut up libtracevent plugins make message (Jiri Olsa)

. Fix installation tests path setup (Jiri Olsa)

. Fix id_hdr_size initialization (Jiri Olsa)

. Move some header files from tools/perf/ to tools/include/ to make them available to
other tools/ dwelling codebases (Namhyung Kim)

. Fix 'probe' build when DWARF support libraries not present (Arnaldo Carvalho de Melo)

Refactorings:

. Move logic to warn about kptr_restrict'ed kernels to separate
function in 'report' (Arnaldo Carvalho de Melo)

. Move hist browser selection code to separate function (Arnaldo Carvalho de Melo)

. Move histogram entries collapsing to separate function (Arnaldo Carvalho de Melo)

. Introduce evlist__for_each() & friends (Arnaldo Carvalho de Melo)

. Automate setup of FEATURE_CHECK_(C|LD)FLAGS-all variables (Jiri Olsa)

. Move arch setup into seprate Makefile (Jiri Olsa)

Trivial stuff:

. Remove misplaced __maybe_unused in 'stat' (Arnaldo Carvalho de Melo)

. Remove old evsel_list usage in 'record' (Arnaldo Carvalho de Melo)

. Comment typo fix (Cody P Schafer)

. Remove unused test-volatile-register-var.c (Yann Droneaud)

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

----------------------------------------------------------------
Andi Kleen (2):
perf stat: Fix --delay option in man page
perf record: Add --initial-delay option

Arnaldo Carvalho de Melo (18):
perf stat: Don't show counter information when workload fails
perf evlist: Send the errno in the signal when workload fails
perf evlist: Move the SIGUSR1 error reporting logic to prepare_workload
perf record: Remove old evsel_list usage
perf evlist: Move destruction of maps to evlist destructor
perf evlist: Close fds on destructor
perf evlist: Auto unmap on destructor
perf tests: Fixup leak on error path in parse events test
perf stat: Remove misplaced __maybe_unused
perf header: Pack 'struct perf_session_env'
perf trace: Pack 'struct trace'
perf report: Move logic to warn about kptr_restrict'ed kernels to separate function
perf report: Move hist browser selection code to separate function
perf report: Move histogram entries collapsing to separate function
perf evlist: Introduce evlist__for_each() & friends
perf tools: Include tools/lib/api/ in MANIFEST
perf tools: Add test for building detached source tarballs
perf probe: Fix build when DWARF support libraries not present

Cody P Schafer (1):
tools perf: Comment typo fix

Jean Pihet (1):
perf tools: Use the DWARF unwind info only if loaded

Jiri Olsa (7):
perf tools: Move arch setup into seprate Makefile
perf tests: Fix installation tests path setup
tools lib traceevent: Replace tabs with spaces for all non-commands statements
tools lib traceevent: Shut up plugins make message
perf tools: Automate setup of FEATURE_CHECK_(C|LD)FLAGS-all variables
perf machine: Fix id_hdr_size initialization
perf tools: Make perf_event__synthesize_mmap_events global

Namhyung Kim (4):
tools include: Move perf's linux/compiler.h to a generic place
tools include: Define likely/unlikely in linux/compiler.h
tools include: Move perf's bug.h to a generic place
tools include: Include <linux/compiler.h> from asm/bug.h

Ramkumar Ramachandra (4):
perf tools: Generalize percent_color_snprintf()
perf diff: Color the Delta column
perf diff: Color the Ratio column
perf diff: Color the Weighted Diff column

Yann Droneaud (1):
perf tools: Remove unused test-volatile-register-var.c

tools/{perf/util => }/include/asm/bug.h | 9 +-
tools/{perf/util => }/include/linux/compiler.h | 12 +-
tools/lib/traceevent/Makefile | 59 ++++---
tools/perf/Documentation/perf-record.txt | 4 +
tools/perf/Documentation/perf-stat.txt | 2 +-
tools/perf/MANIFEST | 4 +-
tools/perf/Makefile.perf | 4 +-
tools/perf/builtin-annotate.c | 2 +-
tools/perf/builtin-diff.c | 98 ++++++++++-
tools/perf/builtin-evlist.c | 2 +-
tools/perf/builtin-inject.c | 2 +-
tools/perf/builtin-kvm.c | 6 +-
tools/perf/builtin-record.c | 82 +++++----
tools/perf/builtin-report.c | 192 ++++++++++++---------
tools/perf/builtin-script.c | 5 +-
tools/perf/builtin-stat.c | 66 ++++---
tools/perf/builtin-top.c | 14 +-
tools/perf/builtin-trace.c | 30 ++--
tools/perf/config/Makefile | 67 ++++---
tools/perf/config/Makefile.arch | 22 +++
.../feature-checks/test-volatile-register-var.c | 6 -
tools/perf/perf.h | 1 +
tools/perf/tests/code-reading.c | 7 +-
tools/perf/tests/evsel-roundtrip-name.c | 2 +-
tools/perf/tests/hists_link.c | 4 +-
tools/perf/tests/keep-tracking.c | 7 +-
tools/perf/tests/make | 40 +++--
tools/perf/tests/mmap-basic.c | 25 ++-
tools/perf/tests/open-syscall-tp-fields.c | 16 +-
tools/perf/tests/parse-events.c | 10 +-
tools/perf/tests/perf-record.c | 21 +--
tools/perf/tests/perf-targz-src-pkg | 21 +++
tools/perf/tests/perf-time-to-tsc.c | 6 -
tools/perf/tests/sw-clock.c | 18 +-
tools/perf/tests/task-exit.c | 33 ++--
tools/perf/ui/browsers/hists.c | 5 +-
tools/perf/ui/gtk/hists.c | 2 +-
tools/perf/util/cgroup.c | 4 +-
tools/perf/util/color.c | 15 +-
tools/perf/util/color.h | 1 +
tools/perf/util/event.c | 12 +-
tools/perf/util/event.h | 7 +
tools/perf/util/evlist.c | 78 +++++----
tools/perf/util/evlist.h | 69 +++++++-
tools/perf/util/evsel.c | 3 +-
tools/perf/util/header.c | 19 +-
tools/perf/util/header.h | 10 +-
tools/perf/util/machine.c | 1 +
tools/perf/util/parse-events.c | 5 +-
tools/perf/util/pmu.c | 2 +-
tools/perf/util/probe-event.c | 5 +-
tools/perf/util/python.c | 3 +-
tools/perf/util/record.c | 6 +-
tools/perf/util/session.c | 6 +-
tools/perf/util/unwind.c | 8 +-
55 files changed, 724 insertions(+), 436 deletions(-)
rename tools/{perf/util => }/include/asm/bug.h (81%)
rename tools/{perf/util => }/include/linux/compiler.h (64%)
create mode 100644 tools/perf/config/Makefile.arch
delete mode 100644 tools/perf/config/feature-checks/test-volatile-register-var.c
create mode 100755 tools/perf/tests/perf-targz-src-pkg

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 3:50:02 PM1/13/14
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

To be consistent with other places, use just 'evlist' for the evsel list
variable, and since we have it in 'struct record', use it directly from
there.

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-396bnfvmlx...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-record.c | 43 +++++++++++++++++++------------------------
1 file changed, 19 insertions(+), 24 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index ea7c3060e8e7..6dcb8aae908c 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -324,7 +324,6 @@ out:

static void record__init_features(struct record *rec)
{
- struct perf_evlist *evsel_list = rec->evlist;
struct perf_session *session = rec->session;
int feat;

@@ -334,7 +333,7 @@ static void record__init_features(struct record *rec)
if (rec->no_buildid)
perf_header__clear_feat(&session->header, HEADER_BUILD_ID);

- if (!have_tracepoints(&evsel_list->entries))
+ if (!have_tracepoints(&rec->evlist->entries))
perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);

if (!rec->opts.branch_stack)
@@ -365,7 +364,6 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
struct machine *machine;
struct perf_tool *tool = &rec->tool;
struct record_opts *opts = &rec->opts;
- struct perf_evlist *evsel_list = rec->evlist;
struct perf_data_file *file = &rec->file;
struct perf_session *session;
bool disabled = false;
@@ -388,7 +386,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
record__init_features(rec);

if (forks) {
- err = perf_evlist__prepare_workload(evsel_list, &opts->target,
+ err = perf_evlist__prepare_workload(rec->evlist, &opts->target,
argv, file->is_pipe,
workload_exec_failed_signal);
if (err < 0) {
@@ -402,7 +400,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
goto out_delete_session;
}

- if (!evsel_list->nr_groups)
+ if (!rec->evlist->nr_groups)
perf_header__clear_feat(&session->header, HEADER_GROUP_DESC);

/*
@@ -415,7 +413,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
if (err < 0)
goto out_delete_session;
} else {
- err = perf_session__write_header(session, evsel_list,
+ err = perf_session__write_header(session, rec->evlist,
file->fd, false);
if (err < 0)
goto out_delete_session;
@@ -439,7 +437,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
goto out_delete_session;
}

- if (have_tracepoints(&evsel_list->entries)) {
+ if (have_tracepoints(&rec->evlist->entries)) {
/*
* FIXME err <= 0 here actually means that
* there were no tracepoints so its not really
@@ -448,7 +446,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
* return this more properly and also
* propagate errors that now are calling die()
*/
- err = perf_event__synthesize_tracing_data(tool, file->fd, evsel_list,
+ err = perf_event__synthesize_tracing_data(tool, file->fd, rec->evlist,
process_synthesized_event);
if (err <= 0) {
pr_err("Couldn't record tracing data.\n");
@@ -480,7 +478,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
perf_event__synthesize_guest_os, tool);
}

- err = __machine__synthesize_threads(machine, tool, &opts->target, evsel_list->threads,
+ err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads,
process_synthesized_event, opts->sample_address);
if (err != 0)
goto out_delete_session;
@@ -502,13 +500,13 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
* so don't spoil it by prematurely enabling them.
*/
if (!target__none(&opts->target))
- perf_evlist__enable(evsel_list);
+ perf_evlist__enable(rec->evlist);

/*
* Let the child rip
*/
if (forks)
- perf_evlist__start_workload(evsel_list);
+ perf_evlist__start_workload(rec->evlist);

for (;;) {
int hits = rec->samples;
@@ -521,7 +519,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
if (hits == rec->samples) {
if (done)
break;
- err = poll(evsel_list->pollfd, evsel_list->nr_fds, -1);
+ err = poll(rec->evlist->pollfd, rec->evlist->nr_fds, -1);
waking++;
}

@@ -531,7 +529,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
* disable events in this case.
*/
if (done && !disabled && !target__none(&opts->target)) {
- perf_evlist__disable(evsel_list);
+ perf_evlist__disable(rec->evlist);
disabled = true;
}
}
@@ -901,16 +899,13 @@ const struct option record_options[] = {
int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
{
int err = -ENOMEM;
- struct perf_evlist *evsel_list;
struct record *rec = &record;
char errbuf[BUFSIZ];

- evsel_list = perf_evlist__new();
- if (evsel_list == NULL)
+ rec->evlist = perf_evlist__new();
+ if (rec->evlist == NULL)
return -ENOMEM;

- rec->evlist = evsel_list;
-
argc = parse_options(argc, argv, record_options, record_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
if (!argc && target__none(&rec->opts.target))
@@ -937,8 +932,8 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
if (rec->no_buildid_cache || rec->no_buildid)
disable_buildid_cache();

- if (evsel_list->nr_entries == 0 &&
- perf_evlist__add_default(evsel_list) < 0) {
+ if (rec->evlist->nr_entries == 0 &&
+ perf_evlist__add_default(rec->evlist) < 0) {
pr_err("Not enough memory for event selector list\n");
goto out_symbol_exit;
}
@@ -964,7 +959,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
}

err = -ENOMEM;
- if (perf_evlist__create_maps(evsel_list, &rec->opts.target) < 0)
+ if (perf_evlist__create_maps(rec->evlist, &rec->opts.target) < 0)
usage_with_options(record_usage, record_options);

if (record_opts__config(&rec->opts)) {
@@ -974,10 +969,10 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)

err = __cmd_record(&record, argc, argv);

- perf_evlist__munmap(evsel_list);
- perf_evlist__close(evsel_list);
+ perf_evlist__munmap(rec->evlist);
+ perf_evlist__close(rec->evlist);
out_free_fd:
- perf_evlist__delete_maps(evsel_list);
+ perf_evlist__delete_maps(rec->evlist);
out_symbol_exit:
symbol__exit();
return err;
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 3:50:02 PM1/13/14
to
From: Andi Kleen <a...@linux.intel.com>

perf stat has a --delay option to delay measuring the workload.

This is useful to skip measuring the startup phase of the program, which
is often very different from the main workload.

The same is useful for perf record when sampling.

--no-delay was already taken, so add a --initial-delay
to perf record too.
-D was already taken for record, so there is only a long option.

v2: Don't disable group members (Namhyung Kim)
v3: port to latest perf/core
rename to --initial-delay to avoid conflict with --no-delay

Signed-off-by: Andi Kleen <a...@linux.intel.com>
Acked-by: Namhyung Kim <namh...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namh...@kernel.org>
Link: http://lkml.kernel.org/r/1389476307-2124-1-...@firstfloor.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/Documentation/perf-record.txt | 4 ++++
tools/perf/builtin-record.c | 9 ++++++++-
tools/perf/perf.h | 1 +
tools/perf/util/evsel.c | 3 ++-
4 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index c407897f0435..82bffac036e1 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -209,6 +209,10 @@ overrides that and uses per-thread mmaps. A side-effect of that is that
inheritance is automatically disabled. --per-thread is ignored with a warning
if combined with -a or -C options.

+--initial-delay msecs::
+After starting the program, wait msecs before measuring. This is useful to
+filter out the startup phase of the program, which is often very different.
+
SEE ALSO
--------
linkperf:perf-stat[1], linkperf:perf-list[1]
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 88600158400e..07d4cf8d3fd3 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -499,7 +499,7 @@ static int __cmd_record(struct 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 (!target__none(&opts->target))
+ if (!target__none(&opts->target) && !opts->initial_delay)
perf_evlist__enable(rec->evlist);

/*
@@ -508,6 +508,11 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
if (forks)
perf_evlist__start_workload(rec->evlist);

+ if (opts->initial_delay) {
+ usleep(opts->initial_delay * 1000);
+ perf_evlist__enable(rec->evlist);
+ }
+
for (;;) {
int hits = rec->samples;

@@ -877,6 +882,8 @@ const struct option record_options[] = {
OPT_CALLBACK('G', "cgroup", &record.evlist, "name",
"monitor event in cgroup name only",
parse_cgroups),
+ OPT_UINTEGER(0, "initial-delay", &record.opts.initial_delay,
+ "ms to wait before starting measurement after program start"),
OPT_STRING('u', "uid", &record.opts.target.uid_str, "user",
"user to profile"),

diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index b1cc84b01d5b..af1ce6e14a93 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -269,6 +269,7 @@ struct record_opts {
u64 user_interval;
u16 stack_dump_size;
bool sample_transaction;
+ unsigned initial_delay;
};

#endif
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index ade8d9c1c431..cd4630abfa43 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -658,7 +658,8 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
* Setting enable_on_exec for independent events and
* group leaders for traced executed by perf.
*/
- if (target__none(&opts->target) && perf_evsel__is_group_leader(evsel))
+ if (target__none(&opts->target) && perf_evsel__is_group_leader(evsel) &&
+ !opts->initial_delay)
attr->enable_on_exec = 1;
}

--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 3:50:03 PM1/13/14
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

For the common evsel list traversal, so that it becomes more compact.

Use the opportunity to start ditching the 'perf_' from 'perf_evlist__',
as discussed, as the whole conversion touches a lot of places, lets do
it piecemeal when we have the chance due to other work, like in this
case.

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-qnkx7dzm2h...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-annotate.c | 2 +-
tools/perf/builtin-diff.c | 7 ++--
tools/perf/builtin-evlist.c | 2 +-
tools/perf/builtin-inject.c | 2 +-
tools/perf/builtin-kvm.c | 2 +-
tools/perf/builtin-record.c | 2 +-
tools/perf/builtin-report.c | 8 ++--
tools/perf/builtin-script.c | 5 +--
tools/perf/builtin-stat.c | 32 ++++++++--------
tools/perf/builtin-top.c | 8 ++--
tools/perf/tests/evsel-roundtrip-name.c | 2 +-
tools/perf/tests/hists_link.c | 4 +-
tools/perf/tests/mmap-basic.c | 2 +-
tools/perf/tests/parse-events.c | 4 +-
tools/perf/ui/browsers/hists.c | 5 ++-
tools/perf/ui/gtk/hists.c | 2 +-
tools/perf/util/cgroup.c | 4 +-
tools/perf/util/evlist.c | 40 ++++++++++----------
tools/perf/util/evlist.h | 65 +++++++++++++++++++++++++++++++++
tools/perf/util/header.c | 19 +++++-----
tools/perf/util/parse-events.c | 5 +--
tools/perf/util/python.c | 3 +-
tools/perf/util/record.c | 6 +--
tools/perf/util/session.c | 6 +--
24 files changed, 151 insertions(+), 86 deletions(-)

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index ab65057a0317..0da603b79b61 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -232,7 +232,7 @@ static int __cmd_annotate(struct perf_annotate *ann)
perf_session__fprintf_dsos(session, stdout);

total_nr_samples = 0;
- list_for_each_entry(pos, &session->evlist->entries, node) {
+ evlist__for_each(session->evlist, pos) {
struct hists *hists = &pos->hists;
u32 nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];

diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index e6a0844bc2f0..987cac3b4bba 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -356,9 +356,10 @@ static struct perf_evsel *evsel_match(struct perf_evsel *evsel,
{
struct perf_evsel *e;

- list_for_each_entry(e, &evlist->entries, node)
+ evlist__for_each(evlist, e) {
if (perf_evsel__match2(evsel, e))
return e;
+ }

return NULL;
}
@@ -367,7 +368,7 @@ static void perf_evlist__collapse_resort(struct perf_evlist *evlist)
{
struct perf_evsel *evsel;

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
struct hists *hists = &evsel->hists;

hists__collapse_resort(hists, NULL);
@@ -614,7 +615,7 @@ static void data_process(void)
struct perf_evsel *evsel_base;
bool first = true;

- list_for_each_entry(evsel_base, &evlist_base->entries, node) {
+ evlist__for_each(evlist_base, evsel_base) {
struct data__file *d;
int i;

diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c
index 20b0f12763b0..c99e0de7e54a 100644
--- a/tools/perf/builtin-evlist.c
+++ b/tools/perf/builtin-evlist.c
@@ -29,7 +29,7 @@ static int __cmd_evlist(const char *file_name, struct perf_attr_details *details
if (session == NULL)
return -ENOMEM;

- list_for_each_entry(pos, &session->evlist->entries, node)
+ evlist__for_each(session->evlist, pos)
perf_evsel__fprintf(pos, details, stdout);

perf_session__delete(session);
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index c9f6d74e1fd7..b3466018bbd7 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -369,7 +369,7 @@ static int __cmd_inject(struct perf_inject *inject)

inject->tool.ordered_samples = true;

- list_for_each_entry(evsel, &session->evlist->entries, node) {
+ evlist__for_each(session->evlist, evsel) {
const char *name = perf_evsel__name(evsel);

if (!strcmp(name, "sched:sched_switch")) {
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 858b11bf6711..a7350519c63f 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -1174,7 +1174,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm)
* Note: exclude_{guest,host} do not apply here.
* This command processes KVM tracepoints from host only
*/
- list_for_each_entry(pos, &evlist->entries, node) {
+ evlist__for_each(evlist, pos) {
struct perf_event_attr *attr = &pos->attr;

/* make sure these *are* set */
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index cb00b53c200f..88600158400e 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -183,7 +183,7 @@ static int record__open(struct record *rec)

perf_evlist__config(evlist, opts);

- list_for_each_entry(pos, &evlist->entries, node) {
+ evlist__for_each(evlist, pos) {
try_again:
if (perf_evsel__open(pos, evlist->cpus, evlist->threads) < 0) {
if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) {
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index cff9465847f2..46864dd7eb83 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -384,7 +384,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
{
struct perf_evsel *pos;

- list_for_each_entry(pos, &evlist->entries, node) {
+ evlist__for_each(evlist, pos) {
struct hists *hists = &pos->hists;
const char *evname = perf_evsel__name(pos);

@@ -495,7 +495,7 @@ static u64 report__collapse_hists(struct report *rep)
* Count number of histogram entries to use when showing progress,
* reusing nr_samples variable.
*/
- list_for_each_entry(pos, &rep->session->evlist->entries, node)
+ evlist__for_each(rep->session->evlist, pos)
nr_samples += pos->hists.nr_entries;

ui_progress__init(&prog, nr_samples, "Merging related events...");
@@ -505,7 +505,7 @@ static u64 report__collapse_hists(struct report *rep)
*/
nr_samples = 0;

- list_for_each_entry(pos, &rep->session->evlist->entries, node) {
+ evlist__for_each(rep->session->evlist, pos) {
struct hists *hists = &pos->hists;

if (pos->idx == 0)
@@ -582,7 +582,7 @@ static int __cmd_report(struct report *rep)
return 0;
}

- list_for_each_entry(pos, &session->evlist->entries, node)
+ evlist__for_each(session->evlist, pos)
hists__output_resort(&pos->hists);

return report__browse_hists(rep);
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 6040000bdfa6..9e9c91f5b7fa 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -603,7 +603,7 @@ static int process_attr(struct perf_tool *tool, union perf_event *event,
if (evsel->attr.type >= PERF_TYPE_MAX)
return 0;

- list_for_each_entry(pos, &evlist->entries, node) {
+ evlist__for_each(evlist, pos) {
if (pos->attr.type == evsel->attr.type && pos != evsel)
return 0;
}
@@ -1309,8 +1309,7 @@ static int check_ev_match(char *dir_name, char *scriptname,
snprintf(evname, len + 1, "%s", p);

match = 0;
- list_for_each_entry(pos,
- &session->evlist->entries, node) {
+ evlist__for_each(session->evlist, pos) {
if (!strcmp(perf_evsel__name(pos), evname)) {
match = 1;
break;
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index b27b2645eb3c..8b0e1c9234d9 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -214,7 +214,7 @@ static void perf_evlist__free_stats(struct perf_evlist *evlist)
{
struct perf_evsel *evsel;

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
perf_evsel__free_stat_priv(evsel);
perf_evsel__free_counts(evsel);
perf_evsel__free_prev_raw_counts(evsel);
@@ -225,7 +225,7 @@ static int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw)
{
struct perf_evsel *evsel;

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
if (perf_evsel__alloc_stat_priv(evsel) < 0 ||
perf_evsel__alloc_counts(evsel, perf_evsel__nr_cpus(evsel)) < 0 ||
(alloc_raw && perf_evsel__alloc_prev_raw_counts(evsel) < 0))
@@ -259,7 +259,7 @@ static void perf_stat__reset_stats(struct perf_evlist *evlist)
{
struct perf_evsel *evsel;

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
perf_evsel__reset_stat_priv(evsel);
perf_evsel__reset_counts(evsel, perf_evsel__nr_cpus(evsel));
}
@@ -326,13 +326,13 @@ static struct perf_evsel *nth_evsel(int n)

/* Assumes this only called when evsel_list does not change anymore. */
if (!array) {
- list_for_each_entry(ev, &evsel_list->entries, node)
+ evlist__for_each(evsel_list, ev)
array_len++;
array = malloc(array_len * sizeof(void *));
if (!array)
exit(ENOMEM);
j = 0;
- list_for_each_entry(ev, &evsel_list->entries, node)
+ evlist__for_each(evsel_list, ev)
array[j++] = ev;
}
if (n < array_len)
@@ -440,13 +440,13 @@ static void print_interval(void)
char prefix[64];

if (aggr_mode == AGGR_GLOBAL) {
- list_for_each_entry(counter, &evsel_list->entries, node) {
+ evlist__for_each(evsel_list, counter) {
ps = counter->priv;
memset(ps->res_stats, 0, sizeof(ps->res_stats));
read_counter_aggr(counter);
}
} else {
- list_for_each_entry(counter, &evsel_list->entries, node) {
+ evlist__for_each(evsel_list, counter) {
ps = counter->priv;
memset(ps->res_stats, 0, sizeof(ps->res_stats));
read_counter(counter);
@@ -483,12 +483,12 @@ static void print_interval(void)
print_aggr(prefix);
break;
case AGGR_NONE:
- list_for_each_entry(counter, &evsel_list->entries, node)
+ evlist__for_each(evsel_list, counter)
print_counter(counter, prefix);
break;
case AGGR_GLOBAL:
default:
- list_for_each_entry(counter, &evsel_list->entries, node)
+ evlist__for_each(evsel_list, counter)
print_counter_aggr(counter, prefix);
}

@@ -504,7 +504,7 @@ static void handle_initial_delay(void)
nthreads = thread_map__nr(evsel_list->threads);

usleep(initial_delay * 1000);
- list_for_each_entry(counter, &evsel_list->entries, node)
+ evlist__for_each(evsel_list, counter)
perf_evsel__enable(counter, ncpus, nthreads);
}
}
@@ -552,7 +552,7 @@ static int __run_perf_stat(int argc, const char **argv)
if (group)
perf_evlist__set_leader(evsel_list);

- list_for_each_entry(counter, &evsel_list->entries, node) {
+ evlist__for_each(evsel_list, counter) {
if (create_perf_stat_counter(counter) < 0) {
/*
* PPC returns ENXIO for HW counters until 2.6.37
@@ -630,13 +630,13 @@ static int __run_perf_stat(int argc, const char **argv)
update_stats(&walltime_nsecs_stats, t1 - t0);

if (aggr_mode == AGGR_GLOBAL) {
- list_for_each_entry(counter, &evsel_list->entries, node) {
+ evlist__for_each(evsel_list, counter) {
read_counter_aggr(counter);
perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter),
thread_map__nr(evsel_list->threads));
}
} else {
- list_for_each_entry(counter, &evsel_list->entries, node) {
+ evlist__for_each(evsel_list, counter) {
read_counter(counter);
perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter), 1);
}
@@ -1117,7 +1117,7 @@ static void print_aggr(char *prefix)

for (s = 0; s < aggr_map->nr; s++) {
id = aggr_map->map[s];
- list_for_each_entry(counter, &evsel_list->entries, node) {
+ evlist__for_each(evsel_list, counter) {
val = ena = run = 0;
nr = 0;
for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
@@ -1328,11 +1328,11 @@ static void print_stat(int argc, const char **argv)
print_aggr(NULL);
break;
case AGGR_GLOBAL:
- list_for_each_entry(counter, &evsel_list->entries, node)
+ evlist__for_each(evsel_list, counter)
print_counter_aggr(counter, NULL);
break;
case AGGR_NONE:
- list_for_each_entry(counter, &evsel_list->entries, node)
+ evlist__for_each(evsel_list, counter)
print_counter(counter, NULL);
break;
default:
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index e0fd0aa57f06..569dd87690ef 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -482,7 +482,7 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c)

fprintf(stderr, "\nAvailable events:");

- list_for_each_entry(top->sym_evsel, &top->evlist->entries, node)
+ evlist__for_each(top->evlist, top->sym_evsel)
fprintf(stderr, "\n\t%d %s", top->sym_evsel->idx, perf_evsel__name(top->sym_evsel));

prompt_integer(&counter, "Enter details event counter");
@@ -493,7 +493,7 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c)
sleep(1);
break;
}
- list_for_each_entry(top->sym_evsel, &top->evlist->entries, node)
+ evlist__for_each(top->evlist, top->sym_evsel)
if (top->sym_evsel->idx == counter)
break;
} else
@@ -575,7 +575,7 @@ static void *display_thread_tui(void *arg)
* Zooming in/out UIDs. For now juse use whatever the user passed
* via --uid.
*/
- list_for_each_entry(pos, &top->evlist->entries, node)
+ evlist__for_each(top->evlist, pos)
pos->hists.uid_filter_str = top->record_opts.target.uid_str;

perf_evlist__tui_browse_hists(top->evlist, help, &hbt, top->min_percent,
@@ -858,7 +858,7 @@ static int perf_top__start_counters(struct perf_top *top)

perf_evlist__config(evlist, opts);

- list_for_each_entry(counter, &evlist->entries, node) {
+ evlist__for_each(evlist, counter) {
try_again:
if (perf_evsel__open(counter, top->evlist->cpus,
top->evlist->threads) < 0) {
diff --git a/tools/perf/tests/evsel-roundtrip-name.c b/tools/perf/tests/evsel-roundtrip-name.c
index 0197bda9c461..465cdbc345cf 100644
--- a/tools/perf/tests/evsel-roundtrip-name.c
+++ b/tools/perf/tests/evsel-roundtrip-name.c
@@ -79,7 +79,7 @@ static int __perf_evsel__name_array_test(const char *names[], int nr_names)
}

err = 0;
- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
if (strcmp(perf_evsel__name(evsel), names[evsel->idx])) {
--err;
pr_debug("%s != %s\n", perf_evsel__name(evsel), names[evsel->idx]);
diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c
index 173bf42cc03e..2b6519e0e36f 100644
--- a/tools/perf/tests/hists_link.c
+++ b/tools/perf/tests/hists_link.c
@@ -208,7 +208,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
* However the second evsel also has a collapsed entry for
* "bash [libc] malloc" so total 9 entries will be in the tree.
*/
- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
for (k = 0; k < ARRAY_SIZE(fake_common_samples); k++) {
const union perf_event event = {
.header = {
@@ -466,7 +466,7 @@ int test__hists_link(void)
if (err < 0)
goto out;

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
hists__collapse_resort(&evsel->hists, NULL);

if (verbose > 2)
diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c
index aef25f0ff9cc..142263492f6f 100644
--- a/tools/perf/tests/mmap-basic.c
+++ b/tools/perf/tests/mmap-basic.c
@@ -126,7 +126,7 @@ int test__basic_mmap(void)
}

err = 0;
- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) {
pr_debug("expected %d %s events, got %d\n",
expected_nr_events[evsel->idx],
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
index 41dee5e67f63..4db0ae617d70 100644
--- a/tools/perf/tests/parse-events.c
+++ b/tools/perf/tests/parse-events.c
@@ -30,7 +30,7 @@ static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist)
TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1);
TEST_ASSERT_VAL("wrong number of groups", 0 == evlist->nr_groups);

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
TEST_ASSERT_VAL("wrong type",
PERF_TYPE_TRACEPOINT == evsel->attr.type);
TEST_ASSERT_VAL("wrong sample_type",
@@ -201,7 +201,7 @@ test__checkevent_tracepoint_multi_modifier(struct perf_evlist *evlist)

TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1);

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
TEST_ASSERT_VAL("wrong exclude_user",
!evsel->attr.exclude_user);
TEST_ASSERT_VAL("wrong exclude_kernel",
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index a7045ea6d1d5..b720b92eba6e 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -1938,7 +1938,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,

ui_helpline__push("Press ESC to exit");

- list_for_each_entry(pos, &evlist->entries, node) {
+ evlist__for_each(evlist, pos) {
const char *ev_name = perf_evsel__name(pos);
size_t line_len = strlen(ev_name) + 7;

@@ -1970,9 +1970,10 @@ single_entry:
struct perf_evsel *pos;

nr_entries = 0;
- list_for_each_entry(pos, &evlist->entries, node)
+ evlist__for_each(evlist, pos) {
if (perf_evsel__is_group_leader(pos))
nr_entries++;
+ }

if (nr_entries == 1)
goto single_entry;
diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c
index 2ca66cc1160f..5b95c44f3435 100644
--- a/tools/perf/ui/gtk/hists.c
+++ b/tools/perf/ui/gtk/hists.c
@@ -375,7 +375,7 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist,

gtk_container_add(GTK_CONTAINER(window), vbox);

- list_for_each_entry(pos, &evlist->entries, node) {
+ evlist__for_each(evlist, pos) {
struct hists *hists = &pos->hists;
const char *evname = perf_evsel__name(pos);
GtkWidget *scrolled_window;
diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c
index 0922aa4218c2..88f7be399432 100644
--- a/tools/perf/util/cgroup.c
+++ b/tools/perf/util/cgroup.c
@@ -81,7 +81,7 @@ static int add_cgroup(struct perf_evlist *evlist, char *str)
/*
* check if cgrp is already defined, if so we reuse it
*/
- list_for_each_entry(counter, &evlist->entries, node) {
+ evlist__for_each(evlist, counter) {
cgrp = counter->cgrp;
if (!cgrp)
continue;
@@ -110,7 +110,7 @@ static int add_cgroup(struct perf_evlist *evlist, char *str)
* if add cgroup N, then need to find event N
*/
n = 0;
- list_for_each_entry(counter, &evlist->entries, node) {
+ evlist__for_each(evlist, counter) {
if (n == nr_cgroups)
goto found;
n++;
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 0810f5ca77d7..40bd2c04df8a 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -81,7 +81,7 @@ static void perf_evlist__update_id_pos(struct perf_evlist *evlist)
{
struct perf_evsel *evsel;

- list_for_each_entry(evsel, &evlist->entries, node)
+ evlist__for_each(evlist, evsel)
perf_evsel__calc_id_pos(evsel);

perf_evlist__set_id_pos(evlist);
@@ -91,7 +91,7 @@ static void perf_evlist__purge(struct perf_evlist *evlist)
{
struct perf_evsel *pos, *n;

- list_for_each_entry_safe(pos, n, &evlist->entries, node) {
+ evlist__for_each_safe(evlist, n, pos) {
list_del_init(&pos->node);
perf_evsel__delete(pos);
}
@@ -148,7 +148,7 @@ void __perf_evlist__set_leader(struct list_head *list)

leader->nr_members = evsel->idx - leader->idx + 1;

- list_for_each_entry(evsel, list, node) {
+ __evlist__for_each(list, evsel) {
evsel->leader = leader;
}
}
@@ -207,7 +207,7 @@ static int perf_evlist__add_attrs(struct perf_evlist *evlist,
return 0;

out_delete_partial_list:
- list_for_each_entry_safe(evsel, n, &head, node)
+ __evlist__for_each_safe(&head, n, evsel)
perf_evsel__delete(evsel);
return -1;
}
@@ -228,7 +228,7 @@ perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id)
{
struct perf_evsel *evsel;

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
if (evsel->attr.type == PERF_TYPE_TRACEPOINT &&
(int)evsel->attr.config == id)
return evsel;
@@ -243,7 +243,7 @@ perf_evlist__find_tracepoint_by_name(struct perf_evlist *evlist,
{
struct perf_evsel *evsel;

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
if ((evsel->attr.type == PERF_TYPE_TRACEPOINT) &&
(strcmp(evsel->name, name) == 0))
return evsel;
@@ -273,7 +273,7 @@ void perf_evlist__disable(struct perf_evlist *evlist)
int nr_threads = thread_map__nr(evlist->threads);

for (cpu = 0; cpu < nr_cpus; cpu++) {
- list_for_each_entry(pos, &evlist->entries, node) {
+ evlist__for_each(evlist, pos) {
if (!perf_evsel__is_group_leader(pos) || !pos->fd)
continue;
for (thread = 0; thread < nr_threads; thread++)
@@ -291,7 +291,7 @@ void perf_evlist__enable(struct perf_evlist *evlist)
int nr_threads = thread_map__nr(evlist->threads);

for (cpu = 0; cpu < nr_cpus; cpu++) {
- list_for_each_entry(pos, &evlist->entries, node) {
+ evlist__for_each(evlist, pos) {
if (!perf_evsel__is_group_leader(pos) || !pos->fd)
continue;
for (thread = 0; thread < nr_threads; thread++)
@@ -630,7 +630,7 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
{
struct perf_evsel *evsel;

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
int fd = FD(evsel, cpu, thread);

if (*output == -1) {
@@ -806,7 +806,7 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
pr_debug("mmap size %zuB\n", evlist->mmap_len);
mask = evlist->mmap_len - page_size - 1;

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
evsel->sample_id == NULL &&
perf_evsel__alloc_id(evsel, cpu_map__nr(cpus), threads->nr) < 0)
@@ -849,7 +849,7 @@ int perf_evlist__apply_filters(struct perf_evlist *evlist)
const int ncpus = cpu_map__nr(evlist->cpus),
nthreads = thread_map__nr(evlist->threads);

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
if (evsel->filter == NULL)
continue;

@@ -868,7 +868,7 @@ int perf_evlist__set_filter(struct perf_evlist *evlist, const char *filter)
const int ncpus = cpu_map__nr(evlist->cpus),
nthreads = thread_map__nr(evlist->threads);

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
err = perf_evsel__set_filter(evsel, ncpus, nthreads, filter);
if (err)
break;
@@ -887,7 +887,7 @@ bool perf_evlist__valid_sample_type(struct perf_evlist *evlist)
if (evlist->id_pos < 0 || evlist->is_pos < 0)
return false;

- list_for_each_entry(pos, &evlist->entries, node) {
+ evlist__for_each(evlist, pos) {
if (pos->id_pos != evlist->id_pos ||
pos->is_pos != evlist->is_pos)
return false;
@@ -903,7 +903,7 @@ u64 __perf_evlist__combined_sample_type(struct perf_evlist *evlist)
if (evlist->combined_sample_type)
return evlist->combined_sample_type;

- list_for_each_entry(evsel, &evlist->entries, node)
+ evlist__for_each(evlist, evsel)
evlist->combined_sample_type |= evsel->attr.sample_type;

return evlist->combined_sample_type;
@@ -921,7 +921,7 @@ bool perf_evlist__valid_read_format(struct perf_evlist *evlist)
u64 read_format = first->attr.read_format;
u64 sample_type = first->attr.sample_type;

- list_for_each_entry_continue(pos, &evlist->entries, node) {
+ evlist__for_each(evlist, pos) {
if (read_format != pos->attr.read_format)
return false;
}
@@ -978,7 +978,7 @@ bool perf_evlist__valid_sample_id_all(struct perf_evlist *evlist)
{
struct perf_evsel *first = perf_evlist__first(evlist), *pos = first;

- list_for_each_entry_continue(pos, &evlist->entries, node) {
+ evlist__for_each_continue(evlist, pos) {
if (first->attr.sample_id_all != pos->attr.sample_id_all)
return false;
}
@@ -1004,7 +1004,7 @@ void perf_evlist__close(struct perf_evlist *evlist)
int ncpus = cpu_map__nr(evlist->cpus);
int nthreads = thread_map__nr(evlist->threads);

- list_for_each_entry_reverse(evsel, &evlist->entries, node)
+ evlist__for_each_reverse(evlist, evsel)
perf_evsel__close(evsel, ncpus, nthreads);
}

@@ -1015,7 +1015,7 @@ int perf_evlist__open(struct perf_evlist *evlist)

perf_evlist__update_id_pos(evlist);

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
err = perf_evsel__open(evsel, evlist->cpus, evlist->threads);
if (err < 0)
goto out_err;
@@ -1154,7 +1154,7 @@ size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp)
struct perf_evsel *evsel;
size_t printed = 0;

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
printed += fprintf(fp, "%s%s", evsel->idx ? ", " : "",
perf_evsel__name(evsel));
}
@@ -1233,7 +1233,7 @@ void perf_evlist__to_front(struct perf_evlist *evlist,
if (move_evsel == perf_evlist__first(evlist))
return;

- list_for_each_entry_safe(evsel, n, &evlist->entries, node) {
+ evlist__for_each_safe(evlist, n, evsel) {
if (evsel->leader == move_evsel->leader)
list_move_tail(&evsel->node, &move);
}
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 518e521c801d..f5173cd63693 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -196,5 +196,70 @@ bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str);
void perf_evlist__to_front(struct perf_evlist *evlist,
struct perf_evsel *move_evsel);

+/**
+ * __evlist__for_each - iterate thru all the evsels
+ * @list: list_head instance to iterate
+ * @evsel: struct evsel iterator
+ */
+#define __evlist__for_each(list, evsel) \
+ list_for_each_entry(evsel, list, node)
+
+/**
+ * evlist__for_each - iterate thru all the evsels
+ * @evlist: evlist instance to iterate
+ * @evsel: struct evsel iterator
+ */
+#define evlist__for_each(evlist, evsel) \
+ __evlist__for_each(&(evlist)->entries, evsel)
+
+/**
+ * __evlist__for_each_continue - continue iteration thru all the evsels
+ * @list: list_head instance to iterate
+ * @evsel: struct evsel iterator
+ */
+#define __evlist__for_each_continue(list, evsel) \
+ list_for_each_entry_continue(evsel, list, node)
+
+/**
+ * evlist__for_each_continue - continue iteration thru all the evsels
+ * @evlist: evlist instance to iterate
+ * @evsel: struct evsel iterator
+ */
+#define evlist__for_each_continue(evlist, evsel) \
+ __evlist__for_each_continue(&(evlist)->entries, evsel)
+
+/**
+ * __evlist__for_each_reverse - iterate thru all the evsels in reverse order
+ * @list: list_head instance to iterate
+ * @evsel: struct evsel iterator
+ */
+#define __evlist__for_each_reverse(list, evsel) \
+ list_for_each_entry_reverse(evsel, list, node)
+
+/**
+ * evlist__for_each_reverse - iterate thru all the evsels in reverse order
+ * @evlist: evlist instance to iterate
+ * @evsel: struct evsel iterator
+ */
+#define evlist__for_each_reverse(evlist, evsel) \
+ __evlist__for_each_reverse(&(evlist)->entries, evsel)
+
+/**
+ * __evlist__for_each_safe - safely iterate thru all the evsels
+ * @list: list_head instance to iterate
+ * @tmp: struct evsel temp iterator
+ * @evsel: struct evsel iterator
+ */
+#define __evlist__for_each_safe(list, tmp, evsel) \
+ list_for_each_entry_safe(evsel, tmp, list, node)
+
+/**
+ * evlist__for_each_safe - safely iterate thru all the evsels
+ * @evlist: evlist instance to iterate
+ * @evsel: struct evsel iterator
+ * @tmp: struct evsel temp iterator
+ */
+#define evlist__for_each_safe(evlist, tmp, evsel) \
+ __evlist__for_each_safe(&(evlist)->entries, tmp, evsel)

#endif /* __PERF_EVLIST_H */
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index a4a60b7887ee..bb3e0ede6183 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -643,8 +643,7 @@ static int write_event_desc(int fd, struct perf_header *h __maybe_unused,
if (ret < 0)
return ret;

- list_for_each_entry(evsel, &evlist->entries, node) {
-
+ evlist__for_each(evlist, evsel) {
ret = do_write(fd, &evsel->attr, sz);
if (ret < 0)
return ret;
@@ -1092,7 +1091,7 @@ static int write_group_desc(int fd, struct perf_header *h __maybe_unused,
if (ret < 0)
return ret;

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
if (perf_evsel__is_group_leader(evsel) &&
evsel->nr_members > 1) {
const char *name = evsel->group_name ?: "{anon_group}";
@@ -1487,7 +1486,7 @@ static void print_group_desc(struct perf_header *ph, int fd __maybe_unused,

session = container_of(ph, struct perf_session, header);

- list_for_each_entry(evsel, &session->evlist->entries, node) {
+ evlist__for_each(session->evlist, evsel) {
if (perf_evsel__is_group_leader(evsel) &&
evsel->nr_members > 1) {
fprintf(fp, "# group: %s{%s", evsel->group_name ?: "",
@@ -1768,7 +1767,7 @@ perf_evlist__find_by_index(struct perf_evlist *evlist, int idx)
{
struct perf_evsel *evsel;

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
if (evsel->idx == idx)
return evsel;
}
@@ -2071,7 +2070,7 @@ static int process_group_desc(struct perf_file_section *section __maybe_unused,
session->evlist->nr_groups = nr_groups;

i = nr = 0;
- list_for_each_entry(evsel, &session->evlist->entries, node) {
+ evlist__for_each(session->evlist, evsel) {
if (evsel->idx == (int) desc[i].leader_idx) {
evsel->leader = evsel;
/* {anon_group} is a dummy name */
@@ -2298,7 +2297,7 @@ int perf_session__write_header(struct perf_session *session,

lseek(fd, sizeof(f_header), SEEK_SET);

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(session->evlist, evsel) {
evsel->id_offset = lseek(fd, 0, SEEK_CUR);
err = do_write(fd, evsel->id, evsel->ids * sizeof(u64));
if (err < 0) {
@@ -2309,7 +2308,7 @@ int perf_session__write_header(struct perf_session *session,

attr_offset = lseek(fd, 0, SEEK_CUR);

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
f_attr = (struct perf_file_attr){
.attr = evsel->attr,
.ids = {
@@ -2742,7 +2741,7 @@ static int perf_evlist__prepare_tracepoint_events(struct perf_evlist *evlist,
{
struct perf_evsel *pos;

- list_for_each_entry(pos, &evlist->entries, node) {
+ evlist__for_each(evlist, pos) {
if (pos->attr.type == PERF_TYPE_TRACEPOINT &&
perf_evsel__prepare_tracepoint_event(pos, pevent))
return -1;
@@ -2890,7 +2889,7 @@ int perf_event__synthesize_attrs(struct perf_tool *tool,
struct perf_evsel *evsel;
int err = 0;

- list_for_each_entry(evsel, &session->evlist->entries, node) {
+ evlist__for_each(session->evlist, evsel) {
err = perf_event__synthesize_attr(tool, &evsel->attr, evsel->ids,
evsel->id, process);
if (err) {
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 0153435b8427..a7f1b6a91fdd 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -820,8 +820,7 @@ int parse_events__modifier_event(struct list_head *list, char *str, bool add)
if (!add && get_event_modifier(&mod, str, NULL))
return -EINVAL;

- list_for_each_entry(evsel, list, node) {
-
+ __evlist__for_each(list, evsel) {
if (add && get_event_modifier(&mod, str, evsel))
return -EINVAL;

@@ -845,7 +844,7 @@ int parse_events_name(struct list_head *list, char *name)
{
struct perf_evsel *evsel;

- list_for_each_entry(evsel, list, node) {
+ __evlist__for_each(list, evsel) {
if (!evsel->name)
evsel->name = strdup(name);
}
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index 4bf8ace7f511..122669c18ff4 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -908,9 +908,10 @@ static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i)
if (i >= pevlist->evlist.nr_entries)
return NULL;

- list_for_each_entry(pos, &pevlist->evlist.entries, node)
+ evlist__for_each(&pevlist->evlist, pos) {
if (i-- == 0)
break;
+ }

return Py_BuildValue("O", container_of(pos, struct pyrf_evsel, evsel));
}
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
index 104a47563d39..373762501dad 100644
--- a/tools/perf/util/record.c
+++ b/tools/perf/util/record.c
@@ -89,19 +89,19 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts)
if (evlist->cpus->map[0] < 0)
opts->no_inherit = true;

- list_for_each_entry(evsel, &evlist->entries, node)
+ evlist__for_each(evlist, evsel)
perf_evsel__config(evsel, opts);

if (evlist->nr_entries > 1) {
struct perf_evsel *first = perf_evlist__first(evlist);

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
if (evsel->attr.sample_type == first->attr.sample_type)
continue;
use_sample_identifier = perf_can_sample_identifier();
break;
}
- list_for_each_entry(evsel, &evlist->entries, node)
+ evlist__for_each(evlist, evsel)
perf_evsel__set_sample_id(evsel, use_sample_identifier);
}

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 8ffe29c55d0f..7acc03e8f3b2 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1384,7 +1384,7 @@ bool perf_session__has_traces(struct perf_session *session, const char *msg)
{
struct perf_evsel *evsel;

- list_for_each_entry(evsel, &session->evlist->entries, node) {
+ evlist__for_each(session->evlist, evsel) {
if (evsel->attr.type == PERF_TYPE_TRACEPOINT)
return true;
}
@@ -1442,7 +1442,7 @@ size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp)

ret += events_stats__fprintf(&session->stats, fp);

- list_for_each_entry(pos, &session->evlist->entries, node) {
+ evlist__for_each(session->evlist, pos) {
ret += fprintf(fp, "%s stats:\n", perf_evsel__name(pos));
ret += events_stats__fprintf(&pos->hists.stats, fp);
}
@@ -1464,7 +1464,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
{
struct perf_evsel *pos;

- list_for_each_entry(pos, &session->evlist->entries, node) {
+ evlist__for_each(session->evlist, pos) {
if (pos->attr.type == type)
return pos;
}
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 3:50:03 PM1/13/14
to
From: Andi Kleen <a...@linux.intel.com>

The --delay option was documented as --initial-delay in the manpage. Fix this.

Signed-off-by: Andi Kleen <a...@linux.intel.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namh...@kernel.org>
Link: http://lkml.kernel.org/r/1389132847-31982-1-...@firstfloor.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/Documentation/perf-stat.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index 80c7da6732f2..29ee857c09c6 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -133,7 +133,7 @@ use --per-core in addition to -a. (system-wide). The output includes the
core number and the number of online logical processors on that physical processor.

-D msecs::
---initial-delay msecs::
+--delay msecs::
After starting the program, wait msecs before measuring. This is useful to
filter out the startup phase of the program, which is often very different.

--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:02 PM1/13/14
to
From: Ramkumar Ramachandra <arta...@gmail.com>

In

$ perf diff -c wdiff:M,N

color the numbers in the Weighted Diff column using color_snprintf(),
picking the colors using get_percent_color().

Signed-off-by: Ramkumar Ramachandra <arta...@gmail.com>
Acked-by: Jiri Olsa <jo...@redhat.com>
Cc: Jiri Olsa <jo...@redhat.com>
Link: http://lkml.kernel.org/r/1388390555-10808-1-gi...@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-diff.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)

diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 73d8bffdd484..a77e31246c00 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -778,6 +778,7 @@ static int __hpp__color_compare(struct perf_hpp_fmt *fmt,
container_of(fmt, struct diff_hpp_fmt, fmt);
struct hist_entry *pair = get_pair_fmt(he, dfmt);
double diff;
+ s64 wdiff;
char pfmt[20] = " ";

if (!pair)
@@ -806,6 +807,18 @@ static int __hpp__color_compare(struct perf_hpp_fmt *fmt,
scnprintf(pfmt, 20, "%%%d.6f", dfmt->header_width);
return value_color_snprintf(hpp->buf, hpp->size,
pfmt, diff);
+ case COMPUTE_WEIGHTED_DIFF:
+ if (he->dummy)
+ goto dummy_print;
+ if (pair->diff.computed)
+ wdiff = pair->diff.wdiff;
+ else
+ wdiff = compute_wdiff(he, pair);
+
+ scnprintf(pfmt, 20, "%%14ld", dfmt->header_width);
+ return color_snprintf(hpp->buf, hpp->size,
+ get_percent_color(wdiff),
+ pfmt, wdiff);
default:
BUG_ON(1);
}
@@ -826,6 +839,12 @@ static int hpp__color_ratio(struct perf_hpp_fmt *fmt,
return __hpp__color_compare(fmt, hpp, he, COMPUTE_RATIO);
}

+static int hpp__color_wdiff(struct perf_hpp_fmt *fmt,
+ struct perf_hpp *hpp, struct hist_entry *he)
+{
+ return __hpp__color_compare(fmt, hpp, he, COMPUTE_WEIGHTED_DIFF);
+}
+
static void
hpp__entry_unpair(struct hist_entry *he, int idx, char *buf, size_t size)
{
@@ -1007,6 +1026,9 @@ static void data__hpp_register(struct data__file *d, int idx)
case PERF_HPP_DIFF__RATIO:
fmt->color = hpp__color_ratio;
break;
+ case PERF_HPP_DIFF__WEIGHTED_DIFF:
+ fmt->color = hpp__color_wdiff;
+ break;
default:
break;
}
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:02 PM1/13/14
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

When 553873e1df63 renamed tools/lib/lk to tools/lib/api we forgot to
do the switch in tools/perf/MANIFEST, breaking tarball building:

[acme@ssdandy linux]$ make perf-targz-src-pkg
TAR
[acme@ssdandy linux]$ tar xf perf-3.13.0-rc4.tar.gz -C /tmp/tmp.OgdYyvp77p/
[acme@ssdandy linux]$ make -C /tmp/tmp.OgdYyvp77p/perf-3.13.0-rc4/tools/perf
make: Entering directory
`/tmp/tmp.OgdYyvp77p/perf-3.13.0-rc4/tools/perf'
BUILD: Doing 'make -j8' parallel build
FLEX util/pmu-flex.c
CC util/evlist.o
CC util/evsel.o
util/evsel.c:12:28: fatal error: api/fs/debugfs.h: No such file or directory compilation terminated.
In file included from util/cache.h:5:0,
<SNIP>

Fix it.

Cc: Adrian Hunter <adrian...@intel.com>
Cc: Borislav Petkov <b...@suse.de>
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-1wwjs01rt3...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/MANIFEST | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST
index 4e535354f162..f41572d0dd76 100644
--- a/tools/perf/MANIFEST
+++ b/tools/perf/MANIFEST
@@ -1,7 +1,7 @@
tools/perf
tools/scripts
tools/lib/traceevent
-tools/lib/lk
+tools/lib/api
tools/lib/symbol/kallsyms.c
tools/lib/symbol/kallsyms.h
tools/include/asm/bug.h
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:03 PM1/13/14
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

Since it is safe to call perf_evlist__close() multiple times, autoclose
it and remove the calls to the close from existing tools, reducing the
tooling boilerplate.

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-2kq9v7p1ru...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-record.c | 1 -
tools/perf/builtin-trace.c | 4 +---
tools/perf/tests/code-reading.c | 1 -
tools/perf/tests/keep-tracking.c | 1 -
tools/perf/tests/mmap-basic.c | 11 ++++-------
tools/perf/tests/open-syscall-tp-fields.c | 4 +---
tools/perf/tests/perf-record.c | 4 +---
tools/perf/tests/perf-time-to-tsc.c | 1 -
tools/perf/tests/sw-clock.c | 4 +---
tools/perf/tests/task-exit.c | 4 +---
tools/perf/util/evlist.c | 1 +
11 files changed, 10 insertions(+), 26 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 5149b41e63d1..b7f5e438276b 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -970,7 +970,6 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
err = __cmd_record(&record, argc, argv);

perf_evlist__munmap(rec->evlist);
- perf_evlist__close(rec->evlist);
out_symbol_exit:
symbol__exit();
return err;
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index f4ddd14b8a9b..aa8a5f46c361 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1909,7 +1909,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
err = perf_evlist__mmap(evlist, trace->opts.mmap_pages, false);
if (err < 0) {
fprintf(trace->output, "Couldn't mmap the events: %s\n", strerror(errno));
- goto out_close_evlist;
+ goto out_delete_evlist;
}

perf_evlist__enable(evlist);
@@ -1994,8 +1994,6 @@ out_disable:
}

perf_evlist__munmap(evlist);
-out_close_evlist:
- perf_evlist__close(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
out:
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index ddbc7756620c..2c0ce723749f 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -541,7 +541,6 @@ static int do_test_code_reading(bool try_kcore)
out_err:
if (evlist) {
perf_evlist__munmap(evlist);
- perf_evlist__close(evlist);
perf_evlist__delete(evlist);
} else {
cpu_map__delete(cpus);
diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c
index f9bc1fcd17cd..dd1c677510bd 100644
--- a/tools/perf/tests/keep-tracking.c
+++ b/tools/perf/tests/keep-tracking.c
@@ -143,7 +143,6 @@ out_err:
if (evlist) {
perf_evlist__disable(evlist);
perf_evlist__munmap(evlist);
- perf_evlist__close(evlist);
perf_evlist__delete(evlist);
} else {
cpu_map__delete(cpus);
diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c
index bbb334d2a864..111dd4a917ad 100644
--- a/tools/perf/tests/mmap-basic.c
+++ b/tools/perf/tests/mmap-basic.c
@@ -68,7 +68,7 @@ int test__basic_mmap(void)
evsels[i] = perf_evsel__newtp("syscalls", name);
if (evsels[i] == NULL) {
pr_debug("perf_evsel__new\n");
- goto out_free_evlist;
+ goto out_delete_evlist;
}

evsels[i]->attr.wakeup_events = 1;
@@ -80,7 +80,7 @@ int test__basic_mmap(void)
pr_debug("failed to open counter: %s, "
"tweak /proc/sys/kernel/perf_event_paranoid?\n",
strerror(errno));
- goto out_close_fd;
+ goto out_delete_evlist;
}

nr_events[i] = 0;
@@ -90,7 +90,7 @@ int test__basic_mmap(void)
if (perf_evlist__mmap(evlist, 128, true) < 0) {
pr_debug("failed to mmap events: %d (%s)\n", errno,
strerror(errno));
- goto out_close_fd;
+ goto out_delete_evlist;
}

for (i = 0; i < nsyscalls; ++i)
@@ -138,10 +138,7 @@ int test__basic_mmap(void)

out_munmap:
perf_evlist__munmap(evlist);
-out_close_fd:
- for (i = 0; i < nsyscalls; ++i)
- perf_evsel__close_fd(evsels[i], 1, threads->nr);
-out_free_evlist:
+out_delete_evlist:
perf_evlist__delete(evlist);
cpus = NULL;
threads = NULL;
diff --git a/tools/perf/tests/open-syscall-tp-fields.c b/tools/perf/tests/open-syscall-tp-fields.c
index 595b577172a6..0a00638a9ebb 100644
--- a/tools/perf/tests/open-syscall-tp-fields.c
+++ b/tools/perf/tests/open-syscall-tp-fields.c
@@ -54,7 +54,7 @@ int test__syscall_open_tp_fields(void)
err = perf_evlist__mmap(evlist, UINT_MAX, false);
if (err < 0) {
pr_debug("perf_evlist__mmap: %s\n", strerror(errno));
- goto out_close_evlist;
+ goto out_delete_evlist;
}

perf_evlist__enable(evlist);
@@ -112,8 +112,6 @@ out_ok:
err = 0;
out_munmap:
perf_evlist__munmap(evlist);
-out_close_evlist:
- perf_evlist__close(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
out:
diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c
index 266da9d41300..682978e66efe 100644
--- a/tools/perf/tests/perf-record.c
+++ b/tools/perf/tests/perf-record.c
@@ -132,7 +132,7 @@ int test__PERF_RECORD(void)
err = perf_evlist__mmap(evlist, opts.mmap_pages, false);
if (err < 0) {
pr_debug("perf_evlist__mmap: %s\n", strerror(errno));
- goto out_close_evlist;
+ goto out_delete_evlist;
}

/*
@@ -304,8 +304,6 @@ found_exit:
}
out_err:
perf_evlist__munmap(evlist);
-out_close_evlist:
- perf_evlist__close(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
out:
diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c
index 97d08fff1f8d..3d50f2d2a4d5 100644
--- a/tools/perf/tests/perf-time-to-tsc.c
+++ b/tools/perf/tests/perf-time-to-tsc.c
@@ -167,7 +167,6 @@ out_err:
if (evlist) {
perf_evlist__disable(evlist);
perf_evlist__munmap(evlist);
- perf_evlist__close(evlist);
perf_evlist__delete(evlist);
}

diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c
index 266d38127ba6..b366f0edca79 100644
--- a/tools/perf/tests/sw-clock.c
+++ b/tools/perf/tests/sw-clock.c
@@ -70,7 +70,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
if (err < 0) {
pr_debug("failed to mmap event: %d (%s)\n", errno,
strerror(errno));
- goto out_close_evlist;
+ goto out_delete_evlist;
}

perf_evlist__enable(evlist);
@@ -107,8 +107,6 @@ next_event:

out_unmap_evlist:
perf_evlist__munmap(evlist);
-out_close_evlist:
- perf_evlist__close(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
return err;
diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c
index fdeb2aa46a50..5511a0a929cd 100644
--- a/tools/perf/tests/task-exit.c
+++ b/tools/perf/tests/task-exit.c
@@ -89,7 +89,7 @@ int test__task_exit(void)
if (perf_evlist__mmap(evlist, 128, true) < 0) {
pr_debug("failed to mmap events: %d (%s)\n", errno,
strerror(errno));
- goto out_close_evlist;
+ goto out_delete_evlist;
}

perf_evlist__start_workload(evlist);
@@ -113,8 +113,6 @@ retry:
}

perf_evlist__munmap(evlist);
-out_close_evlist:
- perf_evlist__close(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
return err;
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 143eaf05178f..a083bdc4680e 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -107,6 +107,7 @@ void perf_evlist__exit(struct perf_evlist *evlist)

void perf_evlist__delete(struct perf_evlist *evlist)
{
+ perf_evlist__close(evlist);
cpu_map__delete(evlist->cpus);
thread_map__delete(evlist->threads);
evlist->cpus = NULL;
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:03 PM1/13/14
to
From: Jiri Olsa <jo...@redhat.com>

The tabbed indentation in non-commands statements could be sometimes
considered as follow up for the rule command in the Makefile.

This error is hard to find, so as a precaution replacing tabs with
spaces for all non-commands statements.

Signed-off-by: Jiri Olsa <jo...@redhat.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>
Cc: Steven Rostedt <ros...@goodmis.org>
Link: http://marc.info/?t=136484403900003&r=1&w=2
Link: http://lkml.kernel.org/r/2014010209...@krava.brq.redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/lib/traceevent/Makefile | 54 +++++++++++++++++++++----------------------
1 file changed, 27 insertions(+), 27 deletions(-)

diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index ca4ab78425d1..76fe0aeb874e 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -86,8 +86,8 @@ ifeq ($(BUILD_SRC),)
ifneq ($(OUTPUT),)

define build_output
- $(if $(VERBOSE:1=),@)+$(MAKE) -C $(OUTPUT) \
- BUILD_SRC=$(CURDIR)/ -f $(CURDIR)/Makefile $1
+ $(if $(VERBOSE:1=),@)+$(MAKE) -C $(OUTPUT) \
+ BUILD_SRC=$(CURDIR)/ -f $(CURDIR)/Makefile $1
endef

all: sub-make
@@ -221,23 +221,23 @@ $(PLUGINS): %.so: %.o
$(QUIET_LINK)$(CC) $(CFLAGS) -shared -nostartfiles -o $@ $<

define make_version.h
- (echo '/* This file is automatically generated. Do not modify. */'; \
- echo \#define VERSION_CODE $(shell \
- expr $(VERSION) \* 256 + $(PATCHLEVEL)); \
- echo '#define EXTRAVERSION ' $(EXTRAVERSION); \
- echo '#define VERSION_STRING "'$(VERSION).$(PATCHLEVEL).$(EXTRAVERSION)'"'; \
- echo '#define FILE_VERSION '$(FILE_VERSION); \
- ) > $1
+ (echo '/* This file is automatically generated. Do not modify. */'; \
+ echo \#define VERSION_CODE $(shell \
+ expr $(VERSION) \* 256 + $(PATCHLEVEL)); \
+ echo '#define EXTRAVERSION ' $(EXTRAVERSION); \
+ echo '#define VERSION_STRING "'$(VERSION).$(PATCHLEVEL).$(EXTRAVERSION)'"'; \
+ echo '#define FILE_VERSION '$(FILE_VERSION); \
+ ) > $1
endef

define update_version.h
- ($(call make_version.h, $@.tmp); \
- if [ -r $@ ] && cmp -s $@ $@.tmp; then \
- rm -f $@.tmp; \
- else \
- echo ' UPDATE $@'; \
- mv -f $@.tmp $@; \
- fi);
+ ($(call make_version.h, $@.tmp); \
+ if [ -r $@ ] && cmp -s $@ $@.tmp; then \
+ rm -f $@.tmp; \
+ else \
+ echo ' UPDATE $@'; \
+ mv -f $@.tmp $@; \
+ fi);
endef

ep_version.h: force
@@ -246,13 +246,13 @@ ep_version.h: force
VERSION_FILES = ep_version.h

define update_dir
- (echo $1 > $@.tmp; \
- if [ -r $@ ] && cmp -s $@ $@.tmp; then \
- rm -f $@.tmp; \
- else \
- echo ' UPDATE $@'; \
- mv -f $@.tmp $@; \
- fi);
+ (echo $1 > $@.tmp; \
+ if [ -r $@ ] && cmp -s $@ $@.tmp; then \
+ rm -f $@.tmp; \
+ else \
+ echo ' UPDATE $@'; \
+ mv -f $@.tmp $@; \
+ fi);
endef

## make deps
@@ -262,10 +262,10 @@ all_deps := $(all_objs:%.o=.%.d)

# let .d file also depends on the source and header files
define check_deps
- @set -e; $(RM) $@; \
- $(CC) -MM $(CFLAGS) $< > $@.$$$$; \
- sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
- $(RM) $@.$$$$
+ @set -e; $(RM) $@; \
+ $(CC) -MM $(CFLAGS) $< > $@.$$$$; \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ $(RM) $@.$$$$
endef

$(all_deps): .%.d: $(src)/%.c
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:02 PM1/13/14
to
From: Jiri Olsa <jo...@redhat.com>

Currently installation tests work only over x86_64, adding arch check to
make it work over i386 as well.

NOTE looks like x86 is the only arch running tests, we need some
IS_(32/64) flag to make this generic.

Signed-off-by: Jiri Olsa <jo...@redhat.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: Jiri Olsa <jo...@redhat.com>
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/1388759553-12974-2-...@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/tests/make | 30 ++++++++++++++++++++----------
1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index f641c35f2321..e341088de8f3 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -1,6 +1,16 @@
PERF := .
MK := Makefile

+include config/Makefile.arch
+
+# FIXME looks like x86 is the only arch running tests ;-)
+# we need some IS_(32/64) flag to make this generic
+ifeq ($(IS_X86_64),1)
+lib = lib64
+else
+lib = lib
+endif
+
has = $(shell which $1 2>/dev/null)

# standard single make variable specified
@@ -118,16 +128,16 @@ installed_files_bin := bin/perf
installed_files_bin += etc/bash_completion.d/perf
installed_files_bin += libexec/perf-core/perf-archive

-installed_files_plugins := lib64/traceevent/plugins/plugin_cfg80211.so
-installed_files_plugins += lib64/traceevent/plugins/plugin_scsi.so
-installed_files_plugins += lib64/traceevent/plugins/plugin_xen.so
-installed_files_plugins += lib64/traceevent/plugins/plugin_function.so
-installed_files_plugins += lib64/traceevent/plugins/plugin_sched_switch.so
-installed_files_plugins += lib64/traceevent/plugins/plugin_mac80211.so
-installed_files_plugins += lib64/traceevent/plugins/plugin_kvm.so
-installed_files_plugins += lib64/traceevent/plugins/plugin_kmem.so
-installed_files_plugins += lib64/traceevent/plugins/plugin_hrtimer.so
-installed_files_plugins += lib64/traceevent/plugins/plugin_jbd2.so
+installed_files_plugins := $(lib)/traceevent/plugins/plugin_cfg80211.so
+installed_files_plugins += $(lib)/traceevent/plugins/plugin_scsi.so
+installed_files_plugins += $(lib)/traceevent/plugins/plugin_xen.so
+installed_files_plugins += $(lib)/traceevent/plugins/plugin_function.so
+installed_files_plugins += $(lib)/traceevent/plugins/plugin_sched_switch.so
+installed_files_plugins += $(lib)/traceevent/plugins/plugin_mac80211.so
+installed_files_plugins += $(lib)/traceevent/plugins/plugin_kvm.so
+installed_files_plugins += $(lib)/traceevent/plugins/plugin_kmem.so
+installed_files_plugins += $(lib)/traceevent/plugins/plugin_hrtimer.so
+installed_files_plugins += $(lib)/traceevent/plugins/plugin_jbd2.so

installed_files_all := $(installed_files_bin)
installed_files_all += $(installed_files_plugins)
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:03 PM1/13/14
to
From: Jiri Olsa <jo...@redhat.com>

Making perf_event__synthesize_mmap_events global, it will be used in
following patch from test code.

Signed-off-by: Jiri Olsa <jo...@redhat.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...@kernel.org>
Cc: Jean Pihet <jean....@linaro.org>
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/1389098853-14466-4-...@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/event.c | 12 ++++++------
tools/perf/util/event.h | 7 +++++++
2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 45a76c69a9ed..1fc1c2f04772 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -175,12 +175,12 @@ out:
return tgid;
}

-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,
- bool mmap_data)
+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,
+ bool mmap_data)
{
char filename[PATH_MAX];
FILE *fp;
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 30fec9901e44..faf6e219be21 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -266,6 +266,13 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type,
const struct perf_sample *sample,
bool swapped);

+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,
+ bool mmap_data);
+
size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp);
size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp);
size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp);
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:03 PM1/13/14
to
From: Namhyung Kim <namh...@kernel.org>

So that it can be shared with others like libtraceevent.

Signed-off-by: Namhyung Kim <namh...@kernel.org>
Acked-by: Borislav Petkov <b...@suse.de>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namhyu...@lge.com>
Cc: Steven Rostedt <ros...@goodmis.org>
Link: http://lkml.kernel.org/r/1389276059-8829-2-gi...@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/include/linux/compiler.h | 30 ++++++++++++++++++++++++++++++
tools/perf/Makefile.perf | 2 +-
tools/perf/config/Makefile | 1 +
tools/perf/util/include/linux/compiler.h | 30 ------------------------------
4 files changed, 32 insertions(+), 31 deletions(-)
create mode 100644 tools/include/linux/compiler.h
delete mode 100644 tools/perf/util/include/linux/compiler.h

diff --git a/tools/include/linux/compiler.h b/tools/include/linux/compiler.h
new file mode 100644
index 000000000000..0135ccf2a00c
--- /dev/null
+++ b/tools/include/linux/compiler.h
@@ -0,0 +1,30 @@
+#ifndef _TOOLS_LINUX_COMPILER_H_
+#define _TOOLS_LINUX_COMPILER_H_
+
+#ifndef __always_inline
+# define __always_inline inline __attribute__((always_inline))
+#endif
+
+#define __user
+
+#ifndef __attribute_const__
+# define __attribute_const__
+#endif
+
+#ifndef __maybe_unused
+# define __maybe_unused __attribute__((unused))
+#endif
+
+#ifndef __packed
+# define __packed __attribute__((__packed__))
+#endif
+
+#ifndef __force
+# define __force
+#endif
+
+#ifndef __weak
+# define __weak __attribute__((weak))
+#endif
+
+#endif /* _TOOLS_LINUX_COMPILER_H */
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 3638b0bd20dc..6be06767da7b 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -211,7 +211,7 @@ LIB_H += ../../include/linux/hash.h
LIB_H += ../../include/linux/stringify.h
LIB_H += util/include/linux/bitmap.h
LIB_H += util/include/linux/bitops.h
-LIB_H += util/include/linux/compiler.h
+LIB_H += ../include/linux/compiler.h
LIB_H += util/include/linux/const.h
LIB_H += util/include/linux/ctype.h
LIB_H += util/include/linux/kernel.h
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 5d15b43b03c6..01dd43df0d04 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -232,6 +232,7 @@ endif

CFLAGS += -I$(src-perf)/util/include
CFLAGS += -I$(src-perf)/arch/$(ARCH)/include
+CFLAGS += -I$(srctree)/tools/include/
CFLAGS += -I$(srctree)/arch/$(ARCH)/include/uapi
CFLAGS += -I$(srctree)/arch/$(ARCH)/include
CFLAGS += -I$(srctree)/include/uapi
diff --git a/tools/perf/util/include/linux/compiler.h b/tools/perf/util/include/linux/compiler.h
deleted file mode 100644
index b003ad7200b2..000000000000
--- a/tools/perf/util/include/linux/compiler.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef _PERF_LINUX_COMPILER_H_
-#define _PERF_LINUX_COMPILER_H_
-
-#ifndef __always_inline
-# define __always_inline inline __attribute__((always_inline))
-#endif
-
-#define __user
-
-#ifndef __attribute_const__
-# define __attribute_const__
-#endif
-
-#ifndef __maybe_unused
-# define __maybe_unused __attribute__((unused))
-#endif
-
-#ifndef __packed
-# define __packed __attribute__((__packed__))
-#endif
-
-#ifndef __force
-# define __force
-#endif
-
-#ifndef __weak
-# define __weak __attribute__((weak))
-#endif
-
-#endif
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:03 PM1/13/14
to
From: Namhyung Kim <namh...@kernel.org>

Signed-off-by: Namhyung Kim <namh...@kernel.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namhyu...@lge.com>
Cc: Steven Rostedt <ros...@goodmis.org>
Link: http://lkml.kernel.org/r/1389276059-8829-3-gi...@kernel.org
[ Added the new header to tools/perf/MANIFEST ]
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/include/linux/compiler.h | 8 ++++++++
tools/perf/MANIFEST | 1 +
2 files changed, 9 insertions(+)

diff --git a/tools/include/linux/compiler.h b/tools/include/linux/compiler.h
index 0135ccf2a00c..fbc6665c6d53 100644
--- a/tools/include/linux/compiler.h
+++ b/tools/include/linux/compiler.h
@@ -27,4 +27,12 @@
# define __weak __attribute__((weak))
#endif

+#ifndef likely
+# define likely(x) __builtin_expect(!!(x), 1)
+#endif
+
+#ifndef unlikely
+# define unlikely(x) __builtin_expect(!!(x), 0)
+#endif
+
#endif /* _TOOLS_LINUX_COMPILER_H */
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST
index 3170a7ff5782..285f28f7f821 100644
--- a/tools/perf/MANIFEST
+++ b/tools/perf/MANIFEST
@@ -4,6 +4,7 @@ tools/lib/traceevent
tools/lib/lk
tools/lib/symbol/kallsyms.c
tools/lib/symbol/kallsyms.h
+tools/include/linux/compiler.h
include/linux/const.h
include/linux/perf_event.h
include/linux/rbtree.h
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:03 PM1/13/14
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

So that we have the boilerplate in the preparation method, instead of
open coded in tools wanting the reporting when the exec fails.

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-purbdzcphd...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-record.c | 16 ++--------------
tools/perf/builtin-stat.c | 17 ++---------------
tools/perf/builtin-trace.c | 2 +-
tools/perf/tests/perf-record.c | 3 +--
tools/perf/tests/task-exit.c | 19 ++++++++++++++-----
tools/perf/util/evlist.c | 12 ++++++++++--
tools/perf/util/evlist.h | 3 ++-
7 files changed, 32 insertions(+), 40 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index f987d385c6f0..ea7c3060e8e7 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -390,7 +390,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
if (forks) {
err = perf_evlist__prepare_workload(evsel_list, &opts->target,
argv, file->is_pipe,
- true);
+ workload_exec_failed_signal);
if (err < 0) {
pr_err("Couldn't run the workload!\n");
goto out_delete_session;
@@ -507,20 +507,8 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
/*
* Let the child rip
*/
- if (forks) {
- struct sigaction act = {
- .sa_flags = SA_SIGINFO,
- .sa_sigaction = workload_exec_failed_signal,
- };
- /*
- * perf_evlist__prepare_workload will, after we call
- * perf_evlist__start_Workload, send a SIGUSR1 if the exec call
- * fails, that we will catch in workload_signal to flip
- * workload_exec_errno.
- */
- sigaction(SIGUSR1, &act, NULL);
+ if (forks)
perf_evlist__start_workload(evsel_list);
- }

for (;;) {
int hits = rec->samples;
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 9d0d52d55ee6..f8456cad656d 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -58,7 +58,6 @@
#include "util/thread.h"
#include "util/thread_map.h"

-#include <signal.h>
#include <stdlib.h>
#include <sys/prctl.h>
#include <locale.h>
@@ -542,8 +541,8 @@ static int __run_perf_stat(int argc, const char **argv)
}

if (forks) {
- if (perf_evlist__prepare_workload(evsel_list, &target, argv,
- false, true) < 0) {
+ if (perf_evlist__prepare_workload(evsel_list, &target, argv, false,
+ workload_exec_failed_signal) < 0) {
perror("failed to prepare workload");
return -1;
}
@@ -598,18 +597,6 @@ static int __run_perf_stat(int argc, const char **argv)
clock_gettime(CLOCK_MONOTONIC, &ref_time);

if (forks) {
- struct sigaction act = {
- .sa_flags = SA_SIGINFO,
- .sa_sigaction = workload_exec_failed_signal,
- };
- /*
- * perf_evlist__prepare_workload will, after we call
- * perf_evlist__start_Workload, send a SIGUSR1 if the exec call
- * fails, that we will catch in workload_signal to flip
- * workload_exec_errno.
- */
- sigaction(SIGUSR1, &act, NULL);
-
perf_evlist__start_workload(evsel_list);
handle_initial_delay();

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index c5b4bc51175c..5498eacf8fc6 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1895,7 +1895,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)

if (forks) {
err = perf_evlist__prepare_workload(evlist, &trace->opts.target,
- argv, false, false);
+ argv, false, NULL);
if (err < 0) {
fprintf(trace->output, "Couldn't run the workload!\n");
goto out_delete_maps;
diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c
index eeba562920e9..fa0ed35afb9a 100644
--- a/tools/perf/tests/perf-record.c
+++ b/tools/perf/tests/perf-record.c
@@ -83,8 +83,7 @@ int test__PERF_RECORD(void)
* so that we have time to open the evlist (calling sys_perf_event_open
* on all the fds) and then mmap them.
*/
- err = perf_evlist__prepare_workload(evlist, &opts.target, argv,
- false, false);
+ err = perf_evlist__prepare_workload(evlist, &opts.target, argv, false, NULL);
if (err < 0) {
pr_debug("Couldn't run the workload!\n");
goto out_delete_maps;
diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c
index d09ab579119e..44e339d4e297 100644
--- a/tools/perf/tests/task-exit.c
+++ b/tools/perf/tests/task-exit.c
@@ -9,12 +9,21 @@
static int exited;
static int nr_exit;

-static void sig_handler(int sig)
+static void sig_handler(int sig __maybe_unused)
{
exited = 1;
+}

- if (sig == SIGUSR1)
- nr_exit = -1;
+/*
+ * perf_evlist__prepare_workload will send a SIGUSR1 if the fork fails, since
+ * we asked by setting its exec_error to this handler.
+ */
+static void workload_exec_failed_signal(int signo __maybe_unused,
+ siginfo_t *info __maybe_unused,
+ void *ucontext __maybe_unused)
+{
+ exited = 1;
+ nr_exit = -1;
}

/*
@@ -35,7 +44,6 @@ int test__task_exit(void)
const char *argv[] = { "true", NULL };

signal(SIGCHLD, sig_handler);
- signal(SIGUSR1, sig_handler);

evlist = perf_evlist__new_default();
if (evlist == NULL) {
@@ -57,7 +65,8 @@ int test__task_exit(void)
goto out_delete_maps;
}

- err = perf_evlist__prepare_workload(evlist, &target, argv, false, true);
+ err = perf_evlist__prepare_workload(evlist, &target, argv, false,
+ workload_exec_failed_signal);
if (err < 0) {
pr_debug("Couldn't run the workload!\n");
goto out_delete_maps;
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 4a30c87d24ec..96b3ef547db4 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1029,7 +1029,7 @@ out_err:

int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *target,
const char *argv[], bool pipe_output,
- bool want_signal)
+ void (*exec_error)(int signo, siginfo_t *info, void *ucontext))
{
int child_ready_pipe[2], go_pipe[2];
char bf;
@@ -1073,7 +1073,7 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *tar

execvp(argv[0], (char **)argv);

- if (want_signal) {
+ if (exec_error) {
union sigval val;

val.sival_int = errno;
@@ -1084,6 +1084,14 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *tar
exit(-1);
}

+ if (exec_error) {
+ struct sigaction act = {
+ .sa_flags = SA_SIGINFO,
+ .sa_sigaction = exec_error,
+ };
+ sigaction(SIGUSR1, &act, NULL);
+ }
+
if (target__none(target))
evlist->threads->map[0] = evlist->workload.pid;

diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 2fe51958ed85..18d1222c0762 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -103,7 +103,8 @@ int record_opts__config(struct record_opts *opts);
int perf_evlist__prepare_workload(struct perf_evlist *evlist,
struct target *target,
const char *argv[], bool pipe_output,
- bool want_signal);
+ void (*exec_error)(int signo, siginfo_t *info,
+ void *ucontext));
int perf_evlist__start_workload(struct perf_evlist *evlist);

int perf_evlist__parse_mmap_pages(const struct option *opt,
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:03 PM1/13/14
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

Test one of the main kernel Makefile targets to generate a perf sources
tarball suitable for build outside the full kernel sources.

This is to test that the tools/perf/MANIFEST file lists all the files
needed to be in such tarball, which sometimes gets broken when we move
files around, like when we made some files that were in tools/perf/
available to other tools/ codebases by moving it to tools/include/, etc.

Now everytime we use 'make -C tools/perf -f tests/make' this test will
be performed, helping detect such problems earlier in the devel cycle.

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-gyivwbbu2j...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/tests/make | 10 ++++++++--
tools/perf/tests/perf-targz-src-pkg | 21 +++++++++++++++++++++
2 files changed, 29 insertions(+), 2 deletions(-)
create mode 100755 tools/perf/tests/perf-targz-src-pkg

diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index e341088de8f3..00544b8b644b 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -216,10 +216,16 @@ $(run_O):
rm -rf $$TMP_O \
rm -rf $$TMP_DEST

-all: $(run) $(run_O)
+tarpkg:
+ @cmd="$(PERF)/tests/perf-targz-src-pkg $(PERF)"; \
+ echo "- $@: $$cmd" && echo $$cmd > $@ && \
+ ( eval $$cmd ) >> $@ 2>&1
+
+
+all: $(run) $(run_O) tarpkg
@echo OK

out: $(run_O)
@echo OK

-.PHONY: all $(run) $(run_O) clean
+.PHONY: all $(run) $(run_O) tarpkg clean
diff --git a/tools/perf/tests/perf-targz-src-pkg b/tools/perf/tests/perf-targz-src-pkg
new file mode 100755
index 000000000000..238aa3927c71
--- /dev/null
+++ b/tools/perf/tests/perf-targz-src-pkg
@@ -0,0 +1,21 @@
+#!/bin/sh
+# Test one of the main kernel Makefile targets to generate a perf sources tarball
+# suitable for build outside the full kernel sources.
+#
+# This is to test that the tools/perf/MANIFEST file lists all the files needed to
+# be in such tarball, which sometimes gets broken when we move files around,
+# like when we made some files that were in tools/perf/ available to other tools/
+# codebases by moving it to tools/include/, etc.
+
+PERF=$1
+cd ${PERF}/../..
+make perf-targz-src-pkg > /dev/null
+TARBALL=$(ls -rt perf-*.tar.gz)
+TMP_DEST=$(mktemp -d)
+tar xf ${TARBALL} -C $TMP_DEST
+rm -f ${TARBALL}
+cd - > /dev/null
+make -C $TMP_DEST/perf*/tools/perf > /dev/null 2>&1
+RC=$?
+rm -rf ${TMP_DEST}
+exit $RC
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:03 PM1/13/14
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

Instead of requiring tools to do an extra destructor call just before
calling perf_evlist__delete.

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-0jd2ptzyik...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-kvm.c | 4 +---
tools/perf/builtin-record.c | 4 +---
tools/perf/builtin-stat.c | 8 +++-----
tools/perf/builtin-top.c | 6 ++----
tools/perf/builtin-trace.c | 6 ++----
tools/perf/tests/code-reading.c | 5 ++---
tools/perf/tests/keep-tracking.c | 5 ++---
tools/perf/tests/mmap-basic.c | 2 ++
tools/perf/tests/open-syscall-tp-fields.c | 4 +---
tools/perf/tests/perf-record.c | 10 ++++------
tools/perf/tests/perf-time-to-tsc.c | 4 ----
tools/perf/tests/sw-clock.c | 10 ++++------
tools/perf/tests/task-exit.c | 9 ++++-----
tools/perf/util/evlist.c | 12 ++++--------
tools/perf/util/evlist.h | 1 -
15 files changed, 32 insertions(+), 58 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index a6ec1052c291..858b11bf6711 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -1556,10 +1556,8 @@ out:
if (kvm->session)
perf_session__delete(kvm->session);
kvm->session = NULL;
- if (kvm->evlist) {
- perf_evlist__delete_maps(kvm->evlist);
+ if (kvm->evlist)
perf_evlist__delete(kvm->evlist);
- }

return err;
}
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 6dcb8aae908c..5149b41e63d1 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -964,15 +964,13 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)

if (record_opts__config(&rec->opts)) {
err = -EINVAL;
- goto out_free_fd;
+ goto out_symbol_exit;
}

err = __cmd_record(&record, argc, argv);

perf_evlist__munmap(rec->evlist);
perf_evlist__close(rec->evlist);
-out_free_fd:
- perf_evlist__delete_maps(rec->evlist);
out_symbol_exit:
symbol__exit();
return err;
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index f8456cad656d..6ca076660de5 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1782,14 +1782,14 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
if (interval && interval < 100) {
pr_err("print interval must be >= 100ms\n");
parse_options_usage(stat_usage, options, "I", 1);
- goto out_free_maps;
+ goto out;
}

if (perf_evlist__alloc_stats(evsel_list, interval))
- goto out_free_maps;
+ goto out;

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

/*
* We dont want to block the signals - that would cause
@@ -1821,8 +1821,6 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
print_stat(argc, argv);

perf_evlist__free_stats(evsel_list);
-out_free_maps:
- perf_evlist__delete_maps(evsel_list);
out:
perf_evlist__delete(evsel_list);
return status;
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 172e91a9ce62..e0fd0aa57f06 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -1171,7 +1171,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
if (!top.evlist->nr_entries &&
perf_evlist__add_default(top.evlist) < 0) {
ui__error("Not enough memory for event selector list\n");
- goto out_delete_maps;
+ goto out_delete_evlist;
}

symbol_conf.nr_events = top.evlist->nr_entries;
@@ -1181,7 +1181,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)

if (record_opts__config(opts)) {
status = -EINVAL;
- goto out_delete_maps;
+ goto out_delete_evlist;
}

top.sym_evsel = perf_evlist__first(top.evlist);
@@ -1206,8 +1206,6 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)

status = __cmd_top(&top);

-out_delete_maps:
- perf_evlist__delete_maps(top.evlist);
out_delete_evlist:
perf_evlist__delete(top.evlist);

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 5498eacf8fc6..f4ddd14b8a9b 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1885,7 +1885,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
err = trace__symbols_init(trace, evlist);
if (err < 0) {
fprintf(trace->output, "Problems initializing symbol libraries!\n");
- goto out_delete_maps;
+ goto out_delete_evlist;
}

perf_evlist__config(evlist, &trace->opts);
@@ -1898,7 +1898,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
argv, false, NULL);
if (err < 0) {
fprintf(trace->output, "Couldn't run the workload!\n");
- goto out_delete_maps;
+ goto out_delete_evlist;
}
}

@@ -1996,8 +1996,6 @@ out_disable:
perf_evlist__munmap(evlist);
out_close_evlist:
perf_evlist__close(evlist);
-out_delete_maps:
- perf_evlist__delete_maps(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
out:
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 4248d1e96848..ddbc7756620c 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -543,11 +543,10 @@ out_err:
perf_evlist__munmap(evlist);
perf_evlist__close(evlist);
perf_evlist__delete(evlist);
- }
- if (cpus)
+ } else {
cpu_map__delete(cpus);
- if (threads)
thread_map__delete(threads);
+ }
machines__destroy_kernel_maps(&machines);
machine__delete_threads(machine);
machines__exit(&machines);
diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c
index 27eb75142b88..f9bc1fcd17cd 100644
--- a/tools/perf/tests/keep-tracking.c
+++ b/tools/perf/tests/keep-tracking.c
@@ -145,11 +145,10 @@ out_err:
perf_evlist__munmap(evlist);
perf_evlist__close(evlist);
perf_evlist__delete(evlist);
- }
- if (cpus)
+ } else {
cpu_map__delete(cpus);
- if (threads)
thread_map__delete(threads);
+ }

return err;
}
diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c
index d64ab79c6d35..bbb334d2a864 100644
--- a/tools/perf/tests/mmap-basic.c
+++ b/tools/perf/tests/mmap-basic.c
@@ -143,6 +143,8 @@ out_close_fd:
perf_evsel__close_fd(evsels[i], 1, threads->nr);
out_free_evlist:
perf_evlist__delete(evlist);
+ cpus = NULL;
+ threads = NULL;
out_free_cpus:
cpu_map__delete(cpus);
out_free_threads:
diff --git a/tools/perf/tests/open-syscall-tp-fields.c b/tools/perf/tests/open-syscall-tp-fields.c
index 774620a5aecb..595b577172a6 100644
--- a/tools/perf/tests/open-syscall-tp-fields.c
+++ b/tools/perf/tests/open-syscall-tp-fields.c
@@ -48,7 +48,7 @@ int test__syscall_open_tp_fields(void)
err = perf_evlist__open(evlist);
if (err < 0) {
pr_debug("perf_evlist__open: %s\n", strerror(errno));
- goto out_delete_maps;
+ goto out_delete_evlist;
}

err = perf_evlist__mmap(evlist, UINT_MAX, false);
@@ -114,8 +114,6 @@ out_munmap:
perf_evlist__munmap(evlist);
out_close_evlist:
perf_evlist__close(evlist);
-out_delete_maps:
- perf_evlist__delete_maps(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
out:
diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c
index fa0ed35afb9a..266da9d41300 100644
--- a/tools/perf/tests/perf-record.c
+++ b/tools/perf/tests/perf-record.c
@@ -86,7 +86,7 @@ int test__PERF_RECORD(void)
err = perf_evlist__prepare_workload(evlist, &opts.target, argv, false, NULL);
if (err < 0) {
pr_debug("Couldn't run the workload!\n");
- goto out_delete_maps;
+ goto out_delete_evlist;
}

/*
@@ -101,7 +101,7 @@ int test__PERF_RECORD(void)
err = sched__get_first_possible_cpu(evlist->workload.pid, &cpu_mask);
if (err < 0) {
pr_debug("sched__get_first_possible_cpu: %s\n", strerror(errno));
- goto out_delete_maps;
+ goto out_delete_evlist;
}

cpu = err;
@@ -111,7 +111,7 @@ int test__PERF_RECORD(void)
*/
if (sched_setaffinity(evlist->workload.pid, cpu_mask_size, &cpu_mask) < 0) {
pr_debug("sched_setaffinity: %s\n", strerror(errno));
- goto out_delete_maps;
+ goto out_delete_evlist;
}

/*
@@ -121,7 +121,7 @@ int test__PERF_RECORD(void)
err = perf_evlist__open(evlist);
if (err < 0) {
pr_debug("perf_evlist__open: %s\n", strerror(errno));
- goto out_delete_maps;
+ goto out_delete_evlist;
}

/*
@@ -306,8 +306,6 @@ out_err:
perf_evlist__munmap(evlist);
out_close_evlist:
perf_evlist__close(evlist);
-out_delete_maps:
- perf_evlist__delete_maps(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
out:
diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c
index c6398b90e897..97d08fff1f8d 100644
--- a/tools/perf/tests/perf-time-to-tsc.c
+++ b/tools/perf/tests/perf-time-to-tsc.c
@@ -170,10 +170,6 @@ out_err:
perf_evlist__close(evlist);
perf_evlist__delete(evlist);
}
- if (cpus)
- cpu_map__delete(cpus);
- if (threads)
- thread_map__delete(threads);

return err;
}
diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c
index 6664a7cd828c..266d38127ba6 100644
--- a/tools/perf/tests/sw-clock.c
+++ b/tools/perf/tests/sw-clock.c
@@ -45,7 +45,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
evsel = perf_evsel__new(&attr);
if (evsel == NULL) {
pr_debug("perf_evsel__new\n");
- goto out_free_evlist;
+ goto out_delete_evlist;
}
perf_evlist__add(evlist, evsel);

@@ -54,7 +54,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
if (!evlist->cpus || !evlist->threads) {
err = -ENOMEM;
pr_debug("Not enough memory to create thread/cpu maps\n");
- goto out_delete_maps;
+ goto out_delete_evlist;
}

if (perf_evlist__open(evlist)) {
@@ -63,7 +63,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
err = -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;
+ goto out_delete_evlist;
}

err = perf_evlist__mmap(evlist, 128, true);
@@ -109,9 +109,7 @@ out_unmap_evlist:
perf_evlist__munmap(evlist);
out_close_evlist:
perf_evlist__close(evlist);
-out_delete_maps:
- perf_evlist__delete_maps(evlist);
-out_free_evlist:
+out_delete_evlist:
perf_evlist__delete(evlist);
return err;
}
diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c
index 44e339d4e297..fdeb2aa46a50 100644
--- a/tools/perf/tests/task-exit.c
+++ b/tools/perf/tests/task-exit.c
@@ -62,14 +62,14 @@ int test__task_exit(void)
if (!evlist->cpus || !evlist->threads) {
err = -ENOMEM;
pr_debug("Not enough memory to create thread/cpu maps\n");
- goto out_delete_maps;
+ goto out_delete_evlist;
}

err = perf_evlist__prepare_workload(evlist, &target, argv, false,
workload_exec_failed_signal);
if (err < 0) {
pr_debug("Couldn't run the workload!\n");
- goto out_delete_maps;
+ goto out_delete_evlist;
}

evsel = perf_evlist__first(evlist);
@@ -83,7 +83,7 @@ int test__task_exit(void)
err = perf_evlist__open(evlist);
if (err < 0) {
pr_debug("Couldn't open the evlist: %s\n", strerror(-err));
- goto out_delete_maps;
+ goto out_delete_evlist;
}

if (perf_evlist__mmap(evlist, 128, true) < 0) {
@@ -115,8 +115,7 @@ retry:
perf_evlist__munmap(evlist);
out_close_evlist:
perf_evlist__close(evlist);
-out_delete_maps:
- perf_evlist__delete_maps(evlist);
+out_delete_evlist:
perf_evlist__delete(evlist);
return err;
}
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 96b3ef547db4..143eaf05178f 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -107,6 +107,10 @@ void perf_evlist__exit(struct perf_evlist *evlist)

void perf_evlist__delete(struct perf_evlist *evlist)
{
+ cpu_map__delete(evlist->cpus);
+ thread_map__delete(evlist->threads);
+ evlist->cpus = NULL;
+ evlist->threads = NULL;
perf_evlist__purge(evlist);
perf_evlist__exit(evlist);
free(evlist);
@@ -833,14 +837,6 @@ out_delete_threads:
return -1;
}

-void perf_evlist__delete_maps(struct perf_evlist *evlist)
-{
- cpu_map__delete(evlist->cpus);
- thread_map__delete(evlist->threads);
- evlist->cpus = NULL;
- evlist->threads = NULL;
-}
-
int perf_evlist__apply_filters(struct perf_evlist *evlist)
{
struct perf_evsel *evsel;
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 18d1222c0762..518e521c801d 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -135,7 +135,6 @@ static inline void perf_evlist__set_maps(struct perf_evlist *evlist,
}

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);

void __perf_evlist__set_leader(struct list_head *list);
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:03 PM1/13/14
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

Further uncluttering the main 'report' function by group related code in
separate function.

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-b594zsbwke...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-report.c | 73 ++++++++++++++++++++++++++++-----------------
1 file changed, 45 insertions(+), 28 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 03941ad8fc46..cff9465847f2 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -486,13 +486,55 @@ static int report__browse_hists(struct report *rep)
return ret;
}

+static u64 report__collapse_hists(struct report *rep)
+{
+ struct ui_progress prog;
+ struct perf_evsel *pos;
+ u64 nr_samples = 0;
+ /*
+ * Count number of histogram entries to use when showing progress,
+ * reusing nr_samples variable.
+ */
+ list_for_each_entry(pos, &rep->session->evlist->entries, node)
+ nr_samples += pos->hists.nr_entries;
+
+ ui_progress__init(&prog, nr_samples, "Merging related events...");
+ /*
+ * Count total number of samples, will be used to check if this
+ * session had any.
+ */
+ nr_samples = 0;
+
+ list_for_each_entry(pos, &rep->session->evlist->entries, node) {
+ struct hists *hists = &pos->hists;
+
+ if (pos->idx == 0)
+ hists->symbol_filter_str = rep->symbol_filter_str;
+
+ hists__collapse_resort(hists, &prog);
+ nr_samples += hists->stats.nr_events[PERF_RECORD_SAMPLE];
+
+ /* Non-group events are considered as leader */
+ if (symbol_conf.event_group &&
+ !perf_evsel__is_group_leader(pos)) {
+ struct hists *leader_hists = &pos->leader->hists;
+
+ hists__match(leader_hists, hists);
+ hists__link(leader_hists, hists);
+ }
+ }
+
+ ui_progress__finish();
+
+ return nr_samples;
+}
+
static int __cmd_report(struct report *rep)
{
- int ret = -EINVAL;
+ int ret;
u64 nr_samples;
struct perf_session *session = rep->session;
struct perf_evsel *pos;
- struct ui_progress prog;
struct perf_data_file *file = session->file;

signal(SIGINT, sig_handler);
@@ -530,32 +572,7 @@ static int __cmd_report(struct report *rep)
}
}

- nr_samples = 0;
- list_for_each_entry(pos, &session->evlist->entries, node)
- nr_samples += pos->hists.nr_entries;
-
- ui_progress__init(&prog, nr_samples, "Merging related events...");
-
- nr_samples = 0;
- list_for_each_entry(pos, &session->evlist->entries, node) {
- struct hists *hists = &pos->hists;
-
- if (pos->idx == 0)
- hists->symbol_filter_str = rep->symbol_filter_str;
-
- hists__collapse_resort(hists, &prog);
- nr_samples += hists->stats.nr_events[PERF_RECORD_SAMPLE];
-
- /* Non-group events are considered as leader */
- if (symbol_conf.event_group &&
- !perf_evsel__is_group_leader(pos)) {
- struct hists *leader_hists = &pos->leader->hists;
-
- hists__match(leader_hists, hists);
- hists__link(leader_hists, hists);
- }
- }
- ui_progress__finish();
+ nr_samples = report__collapse_hists(rep);

if (session_done())
return 0;
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:03 PM1/13/14
to
From: Yann Droneaud <ydro...@opteya.com>

Since commit 01287e2cb7ad, test-volatile-register-var.c is no more built
as part of the automatic feature check.

This patch remove the unneeded file.

Signed-off-by: Yann Droneaud <ydro...@opteya.com>
Cc: David Ahern <dsa...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
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/339d86ad76741ed929defd18541f774b...@opteya.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/config/feature-checks/test-volatile-register-var.c | 6 ------
1 file changed, 6 deletions(-)
delete mode 100644 tools/perf/config/feature-checks/test-volatile-register-var.c

diff --git a/tools/perf/config/feature-checks/test-volatile-register-var.c b/tools/perf/config/feature-checks/test-volatile-register-var.c
deleted file mode 100644
index c9f398d87868..000000000000
--- a/tools/perf/config/feature-checks/test-volatile-register-var.c
+++ /dev/null
@@ -1,6 +0,0 @@
-#include <stdio.h>
-
-int main(void)
-{
- return puts("hi");
-}
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:04 PM1/13/14
to
From: Jean Pihet <jean....@linaro.org>

Use the info only if it has been found in the .debug_frame section of
the ELF binary.

Signed-off-by: Jean Pihet <jean....@linaro.org>
Acked-by: Jiri Olsa <jo...@redhat.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Will Deacon <will....@arm.com>
Cc: linaro...@lists.linaro.org
Cc: pat...@linaro.org
Link: http://lkml.kernel.org/r/1387212194-8028-1-git...@linaro.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/unwind.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/unwind.c b/tools/perf/util/unwind.c
index 0efd5393de85..416f22bf3693 100644
--- a/tools/perf/util/unwind.c
+++ b/tools/perf/util/unwind.c
@@ -340,10 +340,10 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
/* Check the .debug_frame section for unwinding info */
if (!read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) {
memset(&di, 0, sizeof(di));
- dwarf_find_debug_frame(0, &di, ip, 0, map->dso->name,
- map->start, map->end);
- return dwarf_search_unwind_table(as, ip, &di, pi,
- need_unwind_info, arg);
+ if (dwarf_find_debug_frame(0, &di, ip, 0, map->dso->name,
+ map->start, map->end))
+ return dwarf_search_unwind_table(as, ip, &di, pi,
+ need_unwind_info, arg);
}
#endif

--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:04 PM1/13/14
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

When a tool uses perf_evlist__start_workload and the supplied workload
fails (e.g.: its binary wasn't found), perror was being used to print
the error reason.

This is undesirable, as the caller may be a GUI, when it wants to have
total control of the error reporting process.

So move to using sigaction(SA_SIGINFO) + siginfo_t->sa_value->sival_int
to communicate to the caller the errno and let it print it using the UI
of its choosing.

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-epgcv7kjq8...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-record.c | 39 +++++++++++++++++++++++++++++++++++++--
tools/perf/builtin-stat.c | 21 +++++++++++++++------
tools/perf/util/evlist.c | 11 ++++++++---
3 files changed, 60 insertions(+), 11 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 6ec0cbc2a5d5..f987d385c6f0 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -341,6 +341,22 @@ static void record__init_features(struct record *rec)
perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
}

+static volatile int workload_exec_errno;
+
+/*
+ * perf_evlist__prepare_workload will send a SIGUSR1
+ * if the fork fails, since we asked by setting its
+ * want_signal to true.
+ */
+static void workload_exec_failed_signal(int signo, siginfo_t *info,
+ void *ucontext __maybe_unused)
+{
+ workload_exec_errno = info->si_value.sival_int;
+ done = 1;
+ signr = signo;
+ child_finished = 1;
+}
+
static int __cmd_record(struct record *rec, int argc, const char **argv)
{
int err;
@@ -359,7 +375,6 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
on_exit(record__sig_exit, rec);
signal(SIGCHLD, sig_handler);
signal(SIGINT, sig_handler);
- signal(SIGUSR1, sig_handler);
signal(SIGTERM, sig_handler);

session = perf_session__new(file, false, NULL);
@@ -492,8 +507,20 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
/*
* Let the child rip
*/
- if (forks)
+ if (forks) {
+ struct sigaction act = {
+ .sa_flags = SA_SIGINFO,
+ .sa_sigaction = workload_exec_failed_signal,
+ };
+ /*
+ * perf_evlist__prepare_workload will, after we call
+ * perf_evlist__start_Workload, send a SIGUSR1 if the exec call
+ * fails, that we will catch in workload_signal to flip
+ * workload_exec_errno.
+ */
+ sigaction(SIGUSR1, &act, NULL);
perf_evlist__start_workload(evsel_list);
+ }

for (;;) {
int hits = rec->samples;
@@ -521,6 +548,14 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
}
}

+ if (forks && workload_exec_errno) {
+ char msg[512];
+ const char *emsg = strerror_r(workload_exec_errno, msg, sizeof(msg));
+ pr_err("Workload failed: %s\n", emsg);
+ err = -1;
+ goto out_delete_session;
+ }
+
if (quiet || signr == SIGUSR1)
return 0;

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 1c76c7a66f78..9d0d52d55ee6 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -58,6 +58,7 @@
#include "util/thread.h"
#include "util/thread_map.h"

+#include <signal.h>
#include <stdlib.h>
#include <sys/prctl.h>
#include <locale.h>
@@ -509,16 +510,17 @@ static void handle_initial_delay(void)
}
}

-static volatile bool workload_exec_failed;
+static volatile int workload_exec_errno;

/*
* perf_evlist__prepare_workload will send a SIGUSR1
* if the fork fails, since we asked by setting its
* want_signal to true.
*/
-static void workload_exec_failed_signal(int signo __maybe_unused)
+static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *info,
+ void *ucontext __maybe_unused)
{
- workload_exec_failed = true;
+ workload_exec_errno = info->si_value.sival_int;
}

static int __run_perf_stat(int argc, const char **argv)
@@ -596,13 +598,17 @@ static int __run_perf_stat(int argc, const char **argv)
clock_gettime(CLOCK_MONOTONIC, &ref_time);

if (forks) {
+ struct sigaction act = {
+ .sa_flags = SA_SIGINFO,
+ .sa_sigaction = workload_exec_failed_signal,
+ };
/*
* perf_evlist__prepare_workload will, after we call
* perf_evlist__start_Workload, send a SIGUSR1 if the exec call
* fails, that we will catch in workload_signal to flip
- * workload_exec_failed.
+ * workload_exec_errno.
*/
- signal(SIGUSR1, workload_exec_failed_signal);
+ sigaction(SIGUSR1, &act, NULL);

perf_evlist__start_workload(evsel_list);
handle_initial_delay();
@@ -615,8 +621,11 @@ static int __run_perf_stat(int argc, const char **argv)
}
wait(&status);

- if (workload_exec_failed)
+ if (workload_exec_errno) {
+ const char *emsg = strerror_r(workload_exec_errno, msg, sizeof(msg));
+ pr_err("Workload failed: %s\n", emsg);
return -1;
+ }

if (WIFSIGNALED(status))
psignal(WTERMSIG(status), argv[0]);
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index b08a7ecdcea1..4a30c87d24ec 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1073,9 +1073,14 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *tar

execvp(argv[0], (char **)argv);

- perror(argv[0]);
- if (want_signal)
- kill(getppid(), SIGUSR1);
+ if (want_signal) {
+ union sigval val;
+
+ val.sival_int = errno;
+ if (sigqueue(getppid(), SIGUSR1, val))
+ perror(argv[0]);
+ } else
+ perror(argv[0]);
exit(-1);
}

--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:04 PM1/13/14
to
From: Jiri Olsa <jo...@redhat.com>

Instead of explicitly adding same value into
FEATURE_CHECK_(C|LD)FLAGS-all variables we can do that automatically.

Signed-off-by: Jiri Olsa <jo...@redhat.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...@kernel.org>
Cc: Jean Pihet <jean....@linaro.org>
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/1389098853-14466-2-...@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/config/Makefile | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index f2bc659d20af..5d15b43b03c6 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -53,9 +53,6 @@ else
FEATURE_CHECK_LDFLAGS-libunwind = $(LIBUNWIND_LDFLAGS)
FEATURE_CHECK_CFLAGS-libunwind-debug-frame = $(LIBUNWIND_CFLAGS)
FEATURE_CHECK_LDFLAGS-libunwind-debug-frame = $(LIBUNWIND_LDFLAGS)
- # and the flags for the test-all case
- FEATURE_CHECK_CFLAGS-all += $(LIBUNWIND_CFLAGS)
- FEATURE_CHECK_LDFLAGS-all += $(LIBUNWIND_LDFLAGS)
endif

ifeq ($(NO_PERF_REGS),0)
@@ -152,6 +149,17 @@ CORE_FEATURE_TESTS = \
stackprotector-all \
timerfd

+# Set FEATURE_CHECK_(C|LD)FLAGS-all for all CORE_FEATURE_TESTS features.
+# If in the future we need per-feature checks/flags for features not
+# mentioned in this list we need to refactor this ;-).
+set_test_all_flags = $(eval $(set_test_all_flags_code))
+define set_test_all_flags_code
+ FEATURE_CHECK_CFLAGS-all += $(FEATURE_CHECK_CFLAGS-$(1))
+ FEATURE_CHECK_LDFLAGS-all += $(FEATURE_CHECK_LDFLAGS-$(1))
+endef
+
+$(foreach feat,$(CORE_FEATURE_TESTS),$(call set_test_all_flags,$(feat)))
+
#
# So here we detect whether test-all was rebuilt, to be able
# to skip the print-out of the long features list if the file
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:04 PM1/13/14
to
From: Jiri Olsa <jo...@redhat.com>

The id_hdr_size field was not properly initialized, set it to zero, as
the machine struct may have come from some non zeroing allocation
routine or from the stack without any field being initialized.

Signed-off-by: Jiri Olsa <jo...@redhat.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...@kernel.org>
Cc: Jean Pihet <jean....@linaro.org>
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/1389098853-14466-3-...@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/machine.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index a98538dc465a..0130279aac51 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -27,6 +27,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
machine->pid = pid;

machine->symbol_filter = NULL;
+ machine->id_hdr_size = 0;

machine->root_dir = strdup(root_dir);
if (machine->root_dir == NULL)
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:04 PM1/13/14
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

When starting a workload 'stat' wasn't using prepare_workload evlist
method's signal based exec() error reporting mechanism.

Use it so that the we don't report 'not counted' counters.

Before:

[acme@zoo linux]$ perf stat dfadsfa
dfadsfa: No such file or directory

Performance counter stats for 'dfadsfa':

<not counted> task-clock
<not counted> context-switches
<not counted> cpu-migrations
<not counted> page-faults
<not counted> cycles
<not counted> stalled-cycles-frontend
<not supported> stalled-cycles-backend
<not counted> instructions
<not counted> branches
<not counted> branch-misses

0.001831462 seconds time elapsed

[acme@zoo linux]$

After:

[acme@zoo linux]$ perf stat dfadsfa
dfadsfa: No such file or directory
[acme@zoo linux]$

Reported-by: David Ahern <dsa...@gmail.com>
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-5yui3bv7e3...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-stat.c | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 106a5e5b7842..1c76c7a66f78 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -509,6 +509,18 @@ static void handle_initial_delay(void)
}
}

+static volatile bool workload_exec_failed;
+
+/*
+ * perf_evlist__prepare_workload will send a SIGUSR1
+ * if the fork fails, since we asked by setting its
+ * want_signal to true.
+ */
+static void workload_exec_failed_signal(int signo __maybe_unused)
+{
+ workload_exec_failed = true;
+}
+
static int __run_perf_stat(int argc, const char **argv)
{
char msg[512];
@@ -529,7 +541,7 @@ static int __run_perf_stat(int argc, const char **argv)

if (forks) {
if (perf_evlist__prepare_workload(evsel_list, &target, argv,
- false, false) < 0) {
+ false, true) < 0) {
perror("failed to prepare workload");
return -1;
}
@@ -584,6 +596,14 @@ static int __run_perf_stat(int argc, const char **argv)
clock_gettime(CLOCK_MONOTONIC, &ref_time);

if (forks) {
+ /*
+ * perf_evlist__prepare_workload will, after we call
+ * perf_evlist__start_Workload, send a SIGUSR1 if the exec call
+ * fails, that we will catch in workload_signal to flip
+ * workload_exec_failed.
+ */
+ signal(SIGUSR1, workload_exec_failed_signal);
+
perf_evlist__start_workload(evsel_list);
handle_initial_delay();

@@ -594,6 +614,10 @@ static int __run_perf_stat(int argc, const char **argv)
}
}
wait(&status);
+
+ if (workload_exec_failed)
+ return -1;
+
if (WIFSIGNALED(status))
psignal(WTERMSIG(status), argv[0]);
} else {
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:04 PM1/13/14
to
From: Namhyung Kim <namh...@kernel.org>

So that it can be shared with others like libtraceevent.

Signed-off-by: Namhyung Kim <namh...@kernel.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namhyu...@lge.com>
Cc: Steven Rostedt <ros...@goodmis.org>
Link: http://lkml.kernel.org/r/1389276059-8829-4-gi...@kernel.org
[ Added the new header to tools/perf/MANIFEST ]
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/include/asm/bug.h | 23 +++++++++++++++++++++++
tools/perf/MANIFEST | 1 +
tools/perf/Makefile.perf | 2 +-
tools/perf/util/include/asm/bug.h | 22 ----------------------
4 files changed, 25 insertions(+), 23 deletions(-)
create mode 100644 tools/include/asm/bug.h
delete mode 100644 tools/perf/util/include/asm/bug.h

diff --git a/tools/include/asm/bug.h b/tools/include/asm/bug.h
new file mode 100644
index 000000000000..eca78df7b8f2
--- /dev/null
+++ b/tools/include/asm/bug.h
@@ -0,0 +1,23 @@
+#ifndef _TOOLS_ASM_BUG_H
+#define _TOOLS_ASM_BUG_H
+
+#define __WARN_printf(arg...) do { fprintf(stderr, arg); } while (0)
+
+#define WARN(condition, format...) ({ \
+ int __ret_warn_on = !!(condition); \
+ if (unlikely(__ret_warn_on)) \
+ __WARN_printf(format); \
+ unlikely(__ret_warn_on); \
+})
+
+#define WARN_ONCE(condition, format...) ({ \
+ static int __warned; \
+ int __ret_warn_once = !!(condition); \
+ \
+ if (unlikely(__ret_warn_once)) \
+ if (WARN(!__warned, format)) \
+ __warned = 1; \
+ unlikely(__ret_warn_once); \
+})
+
+#endif /* _TOOLS_ASM_BUG_H */
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST
index 285f28f7f821..4e535354f162 100644
--- a/tools/perf/MANIFEST
+++ b/tools/perf/MANIFEST
@@ -4,6 +4,7 @@ tools/lib/traceevent
tools/lib/lk
tools/lib/symbol/kallsyms.c
tools/lib/symbol/kallsyms.h
+tools/include/asm/bug.h
tools/include/linux/compiler.h
include/linux/const.h
include/linux/perf_event.h
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 6be06767da7b..87d7726cee2d 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -226,7 +226,7 @@ LIB_H += util/include/linux/string.h
LIB_H += util/include/linux/types.h
LIB_H += util/include/linux/linkage.h
LIB_H += util/include/asm/asm-offsets.h
-LIB_H += util/include/asm/bug.h
+LIB_H += ../include/asm/bug.h
LIB_H += util/include/asm/byteorder.h
LIB_H += util/include/asm/hweight.h
LIB_H += util/include/asm/swab.h
diff --git a/tools/perf/util/include/asm/bug.h b/tools/perf/util/include/asm/bug.h
deleted file mode 100644
index 7fcc6810adc2..000000000000
--- a/tools/perf/util/include/asm/bug.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef _PERF_ASM_GENERIC_BUG_H
-#define _PERF_ASM_GENERIC_BUG_H
-
-#define __WARN_printf(arg...) do { fprintf(stderr, arg); } while (0)
-
-#define WARN(condition, format...) ({ \
- int __ret_warn_on = !!(condition); \
- if (unlikely(__ret_warn_on)) \
- __WARN_printf(format); \
- unlikely(__ret_warn_on); \
-})
-
-#define WARN_ONCE(condition, format...) ({ \
- static int __warned; \
- int __ret_warn_once = !!(condition); \
- \
- if (unlikely(__ret_warn_once)) \
- if (WARN(!__warned, format)) \
- __warned = 1; \
- unlikely(__ret_warn_once); \
-})
-#endif
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:04 PM1/13/14
to
From: Cody P Schafer <co...@linux.vnet.ibm.com>

s/temr/term/

Signed-off-by: Cody P Schafer <co...@linux.vnet.ibm.com>
Cc: Andi Kleen <a...@linux.intel.com>
Cc: Ingo Molnar <mi...@redhat.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Sukadev Bhattiprolu <suk...@linux.vnet.ibm.com>
Link: http://lkml.kernel.org/r/1389199434-21761-1-...@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/pmu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 0934d645ebdc..d9cab4d27192 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -505,7 +505,7 @@ static __u64 pmu_format_value(unsigned long *format, __u64 value)

/*
* Setup one of config[12] attr members based on the
- * user input data - temr parameter.
+ * user input data - term parameter.
*/
static int pmu_config_term(struct list_head *formats,
struct perf_event_attr *attr,
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:04 PM1/13/14
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

That 'argc' argument _is_ being used.

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-t2gsxc15zu...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-stat.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 6ca076660de5..b27b2645eb3c 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -645,7 +645,7 @@ static int __run_perf_stat(int argc, const char **argv)
return WEXITSTATUS(status);
}

-static int run_perf_stat(int argc __maybe_unused, const char **argv)
+static int run_perf_stat(int argc, const char **argv)
{
int ret;

--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:04 PM1/13/14
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

Removing further boilerplate after making sure perf_evlist__munmap can
be called multiple times for the same evlist.

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-o0luenuld4...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-record.c | 2 --
tools/perf/builtin-trace.c | 1 -
tools/perf/tests/code-reading.c | 1 -
tools/perf/tests/keep-tracking.c | 1 -
tools/perf/tests/mmap-basic.c | 10 ++++------
tools/perf/tests/open-syscall-tp-fields.c | 8 +++-----
tools/perf/tests/perf-record.c | 4 +---
tools/perf/tests/perf-time-to-tsc.c | 1 -
tools/perf/tests/sw-clock.c | 4 +---
tools/perf/tests/task-exit.c | 1 -
tools/perf/util/evlist.c | 4 ++++
11 files changed, 13 insertions(+), 24 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index b7f5e438276b..cb00b53c200f 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -968,8 +968,6 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
}

err = __cmd_record(&record, argc, argv);
-
- perf_evlist__munmap(rec->evlist);
out_symbol_exit:
symbol__exit();
return err;
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index aa8a5f46c361..399b4b91b456 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1993,7 +1993,6 @@ out_disable:
}
}

- perf_evlist__munmap(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
out:
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 2c0ce723749f..653a8fe2db95 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -540,7 +540,6 @@ static int do_test_code_reading(bool try_kcore)
err = TEST_CODE_READING_OK;
out_err:
if (evlist) {
- perf_evlist__munmap(evlist);
perf_evlist__delete(evlist);
} else {
cpu_map__delete(cpus);
diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c
index dd1c677510bd..497957f269d8 100644
--- a/tools/perf/tests/keep-tracking.c
+++ b/tools/perf/tests/keep-tracking.c
@@ -142,7 +142,6 @@ int test__keep_tracking(void)
out_err:
if (evlist) {
perf_evlist__disable(evlist);
- perf_evlist__munmap(evlist);
perf_evlist__delete(evlist);
} else {
cpu_map__delete(cpus);
diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c
index 111dd4a917ad..aef25f0ff9cc 100644
--- a/tools/perf/tests/mmap-basic.c
+++ b/tools/perf/tests/mmap-basic.c
@@ -105,13 +105,13 @@ int test__basic_mmap(void)
if (event->header.type != PERF_RECORD_SAMPLE) {
pr_debug("unexpected %s event\n",
perf_event__name(event->header.type));
- goto out_munmap;
+ goto out_delete_evlist;
}

err = perf_evlist__parse_sample(evlist, event, &sample);
if (err) {
pr_err("Can't parse sample, err = %d\n", err);
- goto out_munmap;
+ goto out_delete_evlist;
}

err = -1;
@@ -119,7 +119,7 @@ int test__basic_mmap(void)
if (evsel == NULL) {
pr_debug("event with id %" PRIu64
" doesn't map to an evsel\n", sample.id);
- goto out_munmap;
+ goto out_delete_evlist;
}
nr_events[evsel->idx]++;
perf_evlist__mmap_consume(evlist, 0);
@@ -132,12 +132,10 @@ int test__basic_mmap(void)
expected_nr_events[evsel->idx],
perf_evsel__name(evsel), nr_events[evsel->idx]);
err = -1;
- goto out_munmap;
+ goto out_delete_evlist;
}
}

-out_munmap:
- perf_evlist__munmap(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
cpus = NULL;
diff --git a/tools/perf/tests/open-syscall-tp-fields.c b/tools/perf/tests/open-syscall-tp-fields.c
index 0a00638a9ebb..5a016f66f5d2 100644
--- a/tools/perf/tests/open-syscall-tp-fields.c
+++ b/tools/perf/tests/open-syscall-tp-fields.c
@@ -85,7 +85,7 @@ int test__syscall_open_tp_fields(void)
err = perf_evsel__parse_sample(evsel, event, &sample);
if (err) {
pr_err("Can't parse sample, err = %d\n", err);
- goto out_munmap;
+ goto out_delete_evlist;
}

tp_flags = perf_evsel__intval(evsel, &sample, "flags");
@@ -93,7 +93,7 @@ int test__syscall_open_tp_fields(void)
if (flags != tp_flags) {
pr_debug("%s: Expected flags=%#x, got %#x\n",
__func__, flags, tp_flags);
- goto out_munmap;
+ goto out_delete_evlist;
}

goto out_ok;
@@ -105,13 +105,11 @@ int test__syscall_open_tp_fields(void)

if (++nr_polls > 5) {
pr_debug("%s: no events!\n", __func__);
- goto out_munmap;
+ goto out_delete_evlist;
}
}
out_ok:
err = 0;
-out_munmap:
- perf_evlist__munmap(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
out:
diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c
index 682978e66efe..39cc7c3c0d0c 100644
--- a/tools/perf/tests/perf-record.c
+++ b/tools/perf/tests/perf-record.c
@@ -165,7 +165,7 @@ int test__PERF_RECORD(void)
if (verbose)
perf_event__fprintf(event, stderr);
pr_debug("Couldn't parse sample\n");
- goto out_err;
+ goto out_delete_evlist;
}

if (verbose) {
@@ -302,8 +302,6 @@ found_exit:
pr_debug("PERF_RECORD_MMAP for %s missing!\n", "[vdso]");
++errs;
}
-out_err:
- perf_evlist__munmap(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
out:
diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c
index 3d50f2d2a4d5..47146d388dbf 100644
--- a/tools/perf/tests/perf-time-to-tsc.c
+++ b/tools/perf/tests/perf-time-to-tsc.c
@@ -166,7 +166,6 @@ next_event:
out_err:
if (evlist) {
perf_evlist__disable(evlist);
- perf_evlist__munmap(evlist);
perf_evlist__delete(evlist);
}

diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c
index b366f0edca79..983d6b8562a8 100644
--- a/tools/perf/tests/sw-clock.c
+++ b/tools/perf/tests/sw-clock.c
@@ -90,7 +90,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
err = perf_evlist__parse_sample(evlist, event, &sample);
if (err < 0) {
pr_debug("Error during parse sample\n");
- goto out_unmap_evlist;
+ goto out_delete_evlist;
}

total_periods += sample.period;
@@ -105,8 +105,6 @@ next_event:
err = -1;
}

-out_unmap_evlist:
- perf_evlist__munmap(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
return err;
diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c
index 5511a0a929cd..5ff3db318f12 100644
--- a/tools/perf/tests/task-exit.c
+++ b/tools/perf/tests/task-exit.c
@@ -112,7 +112,6 @@ retry:
err = -1;
}

- perf_evlist__munmap(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
return err;
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index a083bdc4680e..0810f5ca77d7 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -107,6 +107,7 @@ void perf_evlist__exit(struct perf_evlist *evlist)

void perf_evlist__delete(struct perf_evlist *evlist)
{
+ perf_evlist__munmap(evlist);
perf_evlist__close(evlist);
cpu_map__delete(evlist->cpus);
thread_map__delete(evlist->threads);
@@ -587,6 +588,9 @@ void perf_evlist__munmap(struct perf_evlist *evlist)
{
int i;

+ if (evlist->mmap == NULL)
+ return;
+
for (i = 0; i < evlist->nr_mmaps; i++)
__perf_evlist__munmap(evlist, i);

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:06 PM1/13/14
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

Its too big, better have a separate function for it so that the main
logic gets shorter/clearer.

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-ahh6vfzyh8...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-report.c | 56 ++++++++++++++++++++++++---------------------
1 file changed, 30 insertions(+), 26 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index bf8dd2e893e4..f2ff8609e98e 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -412,14 +412,41 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
return 0;
}

+static void report__warn_kptr_restrict(const struct report *rep)
+{
+ struct map *kernel_map = rep->session->machines.host.vmlinux_maps[MAP__FUNCTION];
+ struct kmap *kernel_kmap = map__kmap(kernel_map);
+
+ if (kernel_map == NULL ||
+ (kernel_map->dso->hit &&
+ (kernel_kmap->ref_reloc_sym == NULL ||
+ kernel_kmap->ref_reloc_sym->addr == 0))) {
+ const char *desc =
+ "As no suitable kallsyms nor vmlinux was found, kernel samples\n"
+ "can't be resolved.";
+
+ if (kernel_map) {
+ const struct dso *kdso = kernel_map->dso;
+ if (!RB_EMPTY_ROOT(&kdso->symbols[MAP__FUNCTION])) {
+ desc = "If some relocation was applied (e.g. "
+ "kexec) symbols may be misresolved.";
+ }
+ }
+
+ ui__warning(
+"Kernel address maps (/proc/{kallsyms,modules}) were restricted.\n\n"
+"Check /proc/sys/kernel/kptr_restrict before running 'perf record'.\n\n%s\n\n"
+"Samples in kernel modules can't be resolved as well.\n\n",
+ desc);
+ }
+}
+
static int __cmd_report(struct report *rep)
{
int ret = -EINVAL;
u64 nr_samples;
struct perf_session *session = rep->session;
struct perf_evsel *pos;
- struct map *kernel_map;
- struct kmap *kernel_kmap;
const char *help = "For a higher level overview, try: perf report --sort comm,dso";
struct ui_progress prog;
struct perf_data_file *file = session->file;
@@ -444,30 +471,7 @@ static int __cmd_report(struct report *rep)
if (ret)
return ret;

- kernel_map = session->machines.host.vmlinux_maps[MAP__FUNCTION];
- kernel_kmap = map__kmap(kernel_map);
- if (kernel_map == NULL ||
- (kernel_map->dso->hit &&
- (kernel_kmap->ref_reloc_sym == NULL ||
- kernel_kmap->ref_reloc_sym->addr == 0))) {
- const char *desc =
- "As no suitable kallsyms nor vmlinux was found, kernel samples\n"
- "can't be resolved.";
-
- if (kernel_map) {
- const struct dso *kdso = kernel_map->dso;
- if (!RB_EMPTY_ROOT(&kdso->symbols[MAP__FUNCTION])) {
- desc = "If some relocation was applied (e.g. "
- "kexec) symbols may be misresolved.";
- }
- }
-
- ui__warning(
-"Kernel address maps (/proc/{kallsyms,modules}) were restricted.\n\n"
-"Check /proc/sys/kernel/kptr_restrict before running 'perf record'.\n\n%s\n\n"
-"Samples in kernel modules can't be resolved as well.\n\n",
- desc);
- }
+ report__warn_kptr_restrict(rep);

if (use_browser == 0) {
if (verbose > 3)

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:05 PM1/13/14
to
From: Jiri Olsa <jo...@redhat.com>

I need to use arch related setup in the tests/make, so moving arch setup
into Makefile.arch.

Signed-off-by: Jiri Olsa <jo...@redhat.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/1388759553-12974-1-...@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/config/Makefile | 52 ++++++++++++++---------------------------
tools/perf/config/Makefile.arch | 22 +++++++++++++++++
2 files changed, 40 insertions(+), 34 deletions(-)
create mode 100644 tools/perf/config/Makefile.arch

diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 14faeeb0d752..f2bc659d20af 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -1,28 +1,26 @@
-uname_M := $(shell uname -m 2>/dev/null || echo not)

-ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
- -e s/arm.*/arm/ -e s/sa110/arm/ \
- -e s/s390x/s390/ -e s/parisc64/parisc/ \
- -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
- -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ )
-NO_PERF_REGS := 1
-CFLAGS := $(EXTRA_CFLAGS) $(EXTRA_WARNINGS)
+ifeq ($(src-perf),)
+src-perf := $(srctree)/tools/perf
+endif

-# Additional ARCH settings for x86
-ifeq ($(ARCH),i386)
- override ARCH := x86
- NO_PERF_REGS := 0
- LIBUNWIND_LIBS = -lunwind -lunwind-x86
+ifeq ($(obj-perf),)
+obj-perf := $(OUTPUT)
endif

-ifeq ($(ARCH),x86_64)
- override ARCH := x86
- IS_X86_64 := 0
- ifeq (, $(findstring m32,$(CFLAGS)))
- IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -x c - | tail -n 1)
- endif
+ifneq ($(obj-perf),)
+obj-perf := $(abspath $(obj-perf))/
+endif
+
+LIB_INCLUDE := $(srctree)/tools/lib/
+CFLAGS := $(EXTRA_CFLAGS) $(EXTRA_WARNINGS)
+
+include $(src-perf)/config/Makefile.arch
+
+NO_PERF_REGS := 1
+
+# Additional ARCH settings for x86
+ifeq ($(ARCH),x86)
ifeq (${IS_X86_64}, 1)
- 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
@@ -64,20 +62,6 @@ ifeq ($(NO_PERF_REGS),0)
CFLAGS += -DHAVE_PERF_REGS_SUPPORT
endif

-ifeq ($(src-perf),)
-src-perf := $(srctree)/tools/perf
-endif
-
-ifeq ($(obj-perf),)
-obj-perf := $(OUTPUT)
-endif
-
-ifneq ($(obj-perf),)
-obj-perf := $(abspath $(obj-perf))/
-endif
-
-LIB_INCLUDE := $(srctree)/tools/lib/
-
# include ARCH specific config
-include $(src-perf)/arch/$(ARCH)/Makefile

diff --git a/tools/perf/config/Makefile.arch b/tools/perf/config/Makefile.arch
new file mode 100644
index 000000000000..fef8ae922800
--- /dev/null
+++ b/tools/perf/config/Makefile.arch
@@ -0,0 +1,22 @@
+
+uname_M := $(shell uname -m 2>/dev/null || echo not)
+
+ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
+ -e s/arm.*/arm/ -e s/sa110/arm/ \
+ -e s/s390x/s390/ -e s/parisc64/parisc/ \
+ -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
+ -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ )
+
+# Additional ARCH settings for x86
+ifeq ($(ARCH),i386)
+ override ARCH := x86
+endif
+
+ifeq ($(ARCH),x86_64)
+ override ARCH := x86
+ IS_X86_64 := 0
+ ifeq (, $(findstring m32,$(CFLAGS)))
+ IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -x c - | tail -n 1)
+ RAW_ARCH := x86_64
+ endif
+endif

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:05 PM1/13/14
to
From: Namhyung Kim <namh...@kernel.org>

Since it uses unlikely() macro inside WARN()

Signed-off-by: Namhyung Kim <namh...@kernel.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namhyu...@lge.com>
Cc: Steven Rostedt <ros...@goodmis.org>
Link: http://lkml.kernel.org/r/1389276059-8829-5-gi...@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/include/asm/bug.h | 2 ++
1 file changed, 2 insertions(+)

diff --git a/tools/include/asm/bug.h b/tools/include/asm/bug.h
index eca78df7b8f2..9e5f4846967f 100644
--- a/tools/include/asm/bug.h
+++ b/tools/include/asm/bug.h
@@ -1,6 +1,8 @@
#ifndef _TOOLS_ASM_BUG_H
#define _TOOLS_ASM_BUG_H

+#include <linux/compiler.h>
+
#define __WARN_printf(arg...) do { fprintf(stderr, arg); } while (0)

#define WARN(condition, format...) ({ \

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:05 PM1/13/14
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

We need to call the evlist destructor when failing to parse events.

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-ilslu69s7v...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/tests/parse-events.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
index e4ce8aed29d3..41dee5e67f63 100644
--- a/tools/perf/tests/parse-events.c
+++ b/tools/perf/tests/parse-events.c
@@ -1385,10 +1385,10 @@ static int test_event(struct evlist_test *e)
if (ret) {
pr_debug("failed to parse event '%s', err %d\n",
e->name, ret);
- return ret;
+ } else {
+ ret = e->check(evlist);
}
-
- ret = e->check(evlist);
+
perf_evlist__delete(evlist);

return ret;

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:05 PM1/13/14
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

Initial struct stats:

/* size: 368, cachelines: 6, members: 24 */
/* sum members: 353, holes: 3, sum holes: 15 */
/* last cacheline: 48 bytes */

After reorg:

[acme@ssdandy linux]$ pahole -C trace ~/bin/trace | tail -4
/* size: 360, cachelines: 6, members: 24 */
/* padding: 7 */
/* last cacheline: 40 bytes */
};
[acme@ssdandy linux]$

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-6jimc80yu8...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-trace.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 399b4b91b456..4bd44aba343e 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1160,26 +1160,27 @@ struct trace {
struct record_opts opts;
struct machine *host;
u64 base_time;
- bool full_time;
FILE *output;
unsigned long nr_events;
struct strlist *ev_qualifier;
- bool not_ev_qualifier;
- bool live;
const char *last_vfs_getname;
struct intlist *tid_list;
struct intlist *pid_list;
+ double duration_filter;
+ double runtime_ms;
+ struct {
+ u64 vfs_getname,
+ proc_getname;
+ } stats;
+ bool not_ev_qualifier;
+ bool live;
+ bool full_time;
bool sched;
bool multiple_threads;
bool summary;
bool summary_only;
bool show_comm;
bool show_tool_stats;
- double duration_filter;
- double runtime_ms;
- struct {
- u64 vfs_getname, proc_getname;
- } stats;
};

static int trace__set_fd_pathname(struct thread *thread, int fd, const char *pathname)

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:05 PM1/13/14
to
From: Ramkumar Ramachandra <arta...@gmail.com>

In

$ perf diff -c ratio

color the Ratio column using value_color_snprintf(), a new function that
operates exactly like percent_color_snprintf().

At first glance, it looks like percent_color_snprintf() can be turned
into a non-variadic function simplifying things; however, 53805ec (perf
tools: Remove cast of non-variadic function to variadic, 2013-10-31)
explains why it needs to be a variadic function.

Signed-off-by: Ramkumar Ramachandra <arta...@gmail.com>
Acked-by: Jiri Olsa <jo...@redhat.com>
Cc: Jiri Olsa <jo...@redhat.com>
Link: http://lkml.kernel.org/r/1388388861-7931-4-gi...@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-diff.c | 20 ++++++++++++++++++++
tools/perf/util/color.c | 10 +++++++---
tools/perf/util/color.h | 1 +
3 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 6c3f220115ac..73d8bffdd484 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -795,6 +795,17 @@ static int __hpp__color_compare(struct perf_hpp_fmt *fmt,
scnprintf(pfmt, 20, "%%%+d.2f%%%%", dfmt->header_width - 1);
return percent_color_snprintf(hpp->buf, hpp->size,
pfmt, diff);
+ case COMPUTE_RATIO:
+ if (he->dummy)
+ goto dummy_print;
+ if (pair->diff.computed)
+ diff = pair->diff.period_ratio;
+ else
+ diff = compute_ratio(he, pair);
+
+ scnprintf(pfmt, 20, "%%%d.6f", dfmt->header_width);
+ return value_color_snprintf(hpp->buf, hpp->size,
+ pfmt, diff);
default:
BUG_ON(1);
}
@@ -809,6 +820,12 @@ static int hpp__color_delta(struct perf_hpp_fmt *fmt,
return __hpp__color_compare(fmt, hpp, he, COMPUTE_DELTA);
}

+static int hpp__color_ratio(struct perf_hpp_fmt *fmt,
+ struct perf_hpp *hpp, struct hist_entry *he)
+{
+ return __hpp__color_compare(fmt, hpp, he, COMPUTE_RATIO);
+}
+
static void
hpp__entry_unpair(struct hist_entry *he, int idx, char *buf, size_t size)
{
@@ -987,6 +1004,9 @@ static void data__hpp_register(struct data__file *d, int idx)
case PERF_HPP_DIFF__DELTA:
fmt->color = hpp__color_delta;
break;
+ case PERF_HPP_DIFF__RATIO:
+ fmt->color = hpp__color_ratio;
+ break;
default:
break;
}
diff --git a/tools/perf/util/color.c b/tools/perf/util/color.c
index 8cda46c43e74..87b8672eb413 100644
--- a/tools/perf/util/color.c
+++ b/tools/perf/util/color.c
@@ -319,15 +319,19 @@ int percent_color_fprintf(FILE *fp, const char *fmt, double percent)
return r;
}

+int value_color_snprintf(char *bf, size_t size, const char *fmt, double value)
+{
+ const char *color = get_percent_color(value);
+ return color_snprintf(bf, size, color, fmt, value);
+}
+
int percent_color_snprintf(char *bf, size_t size, const char *fmt, ...)
{
va_list args;
double percent;
- const char *color;

va_start(args, fmt);
percent = va_arg(args, double);
va_end(args);
- color = get_percent_color(percent);
- return color_snprintf(bf, size, color, fmt, percent);
+ return value_color_snprintf(bf, size, fmt, percent);
}
diff --git a/tools/perf/util/color.h b/tools/perf/util/color.h
index fced3840e99c..7ff30a62a132 100644
--- a/tools/perf/util/color.h
+++ b/tools/perf/util/color.h
@@ -39,6 +39,7 @@ int color_fprintf(FILE *fp, const char *color, const char *fmt, ...);
int color_snprintf(char *bf, size_t size, const char *color, const char *fmt, ...);
int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...);
int color_fwrite_lines(FILE *fp, const char *color, size_t count, const char *buf);
+int value_color_snprintf(char *bf, size_t size, const char *fmt, double value);
int percent_color_snprintf(char *bf, size_t size, const char *fmt, ...);
int percent_color_fprintf(FILE *fp, const char *fmt, double percent);
const char *get_percent_color(double percent);

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:05 PM1/13/14
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

Initial struct:

[acme@ssdandy linux]$ pahole -C perf_session_env ~/bin/perf
struct perf_session_env {
char * hostname; /* 0 8 */
char * os_release; /* 8 8 */
char * version; /* 16 8 */
char * arch; /* 24 8 */
int nr_cpus_online; /* 32 4 */
int nr_cpus_avail; /* 36 4 */
char * cpu_desc; /* 40 8 */
char * cpuid; /* 48 8 */
long long unsigned int total_mem; /* 56 8 */
/* --- cacheline 1 boundary (64 bytes) --- */
int nr_cmdline; /* 64 4 */

/* XXX 4 bytes hole, try to pack */

char * cmdline; /* 72 8 */
int nr_sibling_cores; /* 80 4 */

/* XXX 4 bytes hole, try to pack */

char * sibling_cores; /* 88 8 */
int nr_sibling_threads; /* 96 4 */

/* XXX 4 bytes hole, try to pack */

char * sibling_threads; /* 104 8 */
int nr_numa_nodes; /* 112 4 */

/* XXX 4 bytes hole, try to pack */

char * numa_nodes; /* 120 8 */
/* --- cacheline 2 boundary (128 bytes) --- */
int nr_pmu_mappings; /* 128 4 */

/* XXX 4 bytes hole, try to pack */

char * pmu_mappings; /* 136 8 */
int nr_groups; /* 144 4 */

/* size: 152, cachelines: 3, members: 20 */
/* sum members: 128, holes: 5, sum holes: 20 */
/* padding: 4 */
/* last cacheline: 24 bytes */
};
[acme@ssdandy linux]$

[acme@ssdandy linux]$ pahole -C perf_session_env --reorganize --show_reorg_steps ~/bin/perf | grep ^/ | grep -v Final
/* Moving 'nr_sibling_cores' from after 'cmdline' to after 'nr_cmdline' */
/* Moving 'nr_numa_nodes' from after 'sibling_threads' to after 'nr_sibling_threads' */
/* Moving 'nr_groups' from after 'pmu_mappings' to after 'nr_pmu_mappings' */
[acme@ssdandy linux]$

Final struct stats:

[acme@ssdandy linux]$ pahole -C perf_session_env --reorganize --show_reorg_steps ~/bin/perf | tail -4
/* --- cacheline 2 boundary (128 bytes) --- */

/* size: 128, cachelines: 2, members: 20 */
}; /* saved 24 bytes and 1 cacheline! */
[acme@ssdandy linux]$

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-3d9tshamlo...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/header.h | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 307c9aed972e..a2d047bdf4ef 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -77,16 +77,16 @@ struct perf_session_env {
unsigned long long total_mem;

int nr_cmdline;
- char *cmdline;
int nr_sibling_cores;
- char *sibling_cores;
int nr_sibling_threads;
- char *sibling_threads;
int nr_numa_nodes;
- char *numa_nodes;
int nr_pmu_mappings;
- char *pmu_mappings;
int nr_groups;
+ char *cmdline;
+ char *sibling_cores;
+ char *sibling_threads;
+ char *numa_nodes;
+ char *pmu_mappings;
};

struct perf_header {

Arnaldo Carvalho de Melo

unread,
Jan 13, 2014, 4:00:05 PM1/13/14
to
From: Arnaldo Carvalho de Melo <ac...@redhat.com>

To unclutter the main function.

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-agvxwpazlu...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-report.c | 79 ++++++++++++++++++++++++++-------------------
1 file changed, 46 insertions(+), 33 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index f2ff8609e98e..03941ad8fc46 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -441,13 +441,57 @@ static void report__warn_kptr_restrict(const struct report *rep)
}
}

+static int report__gtk_browse_hists(struct report *rep, const char *help)
+{
+ int (*hist_browser)(struct perf_evlist *evlist, const char *help,
+ struct hist_browser_timer *timer, float min_pcnt);
+
+ hist_browser = dlsym(perf_gtk_handle, "perf_evlist__gtk_browse_hists");
+
+ if (hist_browser == NULL) {
+ ui__error("GTK browser not found!\n");
+ return -1;
+ }
+
+ return hist_browser(rep->session->evlist, help, NULL, rep->min_percent);
+}
+
+static int report__browse_hists(struct report *rep)
+{
+ int ret;
+ struct perf_session *session = rep->session;
+ struct perf_evlist *evlist = session->evlist;
+ const char *help = "For a higher level overview, try: perf report --sort comm,dso";
+
+ switch (use_browser) {
+ case 1:
+ ret = perf_evlist__tui_browse_hists(evlist, help, NULL,
+ rep->min_percent,
+ &session->header.env);
+ /*
+ * Usually "ret" is the last pressed key, and we only
+ * care if the key notifies us to switch data file.
+ */
+ if (ret != K_SWITCH_INPUT_DATA)
+ ret = 0;
+ break;
+ case 2:
+ ret = report__gtk_browse_hists(rep, help);
+ break;
+ default:
+ ret = perf_evlist__tty_browse_hists(evlist, rep, help);
+ break;
+ }
+
+ return ret;
+}
+
static int __cmd_report(struct report *rep)
{
int ret = -EINVAL;
u64 nr_samples;
struct perf_session *session = rep->session;
struct perf_evsel *pos;
- const char *help = "For a higher level overview, try: perf report --sort comm,dso";
struct ui_progress prog;
struct perf_data_file *file = session->file;

@@ -524,38 +568,7 @@ static int __cmd_report(struct report *rep)
list_for_each_entry(pos, &session->evlist->entries, node)
hists__output_resort(&pos->hists);

- if (use_browser > 0) {
- if (use_browser == 1) {
- ret = perf_evlist__tui_browse_hists(session->evlist,
- help, NULL,
- rep->min_percent,
- &session->header.env);
- /*
- * Usually "ret" is the last pressed key, and we only
- * care if the key notifies us to switch data file.
- */
- if (ret != K_SWITCH_INPUT_DATA)
- ret = 0;
-
- } else if (use_browser == 2) {
- int (*hist_browser)(struct perf_evlist *,
- const char *,
- struct hist_browser_timer *,
- float min_pcnt);
-
- hist_browser = dlsym(perf_gtk_handle,
- "perf_evlist__gtk_browse_hists");
- if (hist_browser == NULL) {
- ui__error("GTK browser not found!\n");
- return ret;
- }
- hist_browser(session->evlist, help, NULL,
- rep->min_percent);
- }
- } else
- perf_evlist__tty_browse_hists(session->evlist, rep, help);
-
- return ret;
+ return report__browse_hists(rep);
}

static int

Ingo Molnar

unread,
Jan 14, 2014, 8:50:02 AM1/14/14
to

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

> Andi Kleen (2):
> perf stat: Fix --delay option in man page
> perf record: Add --initial-delay option

Hm, so we now have two options that do something similar, one named
--delay, the other --initial-delay? That looks rather inconsistent.

Furthermore, it looks silly to rename things --initial-delay just to
preserve a rarely used option, --no-delay. Instead the better option
would be to rename --no-delay to --no-buffering, and use --delay and
use it consistently within the tools.

Thanks,

Ingo

Arnaldo Carvalho de Melo

unread,
Jan 14, 2014, 9:10:02 AM1/14/14
to
Em Tue, Jan 14, 2014 at 02:41:01PM +0100, Ingo Molnar escreveu:
> * Arnaldo Carvalho de Melo <ac...@infradead.org> wrote:

> > Andi Kleen (2):
> > perf stat: Fix --delay option in man page
> > perf record: Add --initial-delay option

> Hm, so we now have two options that do something similar, one named
> --delay, the other --initial-delay? That looks rather inconsistent.

> Furthermore, it looks silly to rename things --initial-delay just to
> preserve a rarely used option, --no-delay. Instead the better option
> would be to rename --no-delay to --no-buffering, and use --delay and
> use it consistently within the tools.

Ok, agreed, I'll do that, adding a patch that renames the old option,
then reworking Andi's patches to use --delay consistently.

- Arnaldo

Arnaldo Carvalho de Melo

unread,
Jan 14, 2014, 9:10:02 AM1/14/14
to
From: Ramkumar Ramachandra <arta...@gmail.com>

Color the numbers in the Delta column using percent_color_snprintf().

Generalize the coloring function so that we can accommodate all three
comparison methods in future patches: delta, ratio, and wdiff.

Signed-off-by: Ramkumar Ramachandra <arta...@gmail.com>
Acked-by: Jiri Olsa <jo...@redhat.com>
Cc: Jiri Olsa <jo...@redhat.com>
Link: http://lkml.kernel.org/r/1388388861-7931-3-gi...@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-diff.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 48 insertions(+), 1 deletion(-)

diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 987cac3b4bba..6c3f220115ac 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -770,6 +770,45 @@ static int hpp__entry_baseline(struct hist_entry *he, char *buf, size_t size)
return ret;
}

+static int __hpp__color_compare(struct perf_hpp_fmt *fmt,
+ struct perf_hpp *hpp, struct hist_entry *he,
+ int comparison_method)
+{
+ struct diff_hpp_fmt *dfmt =
+ container_of(fmt, struct diff_hpp_fmt, fmt);
+ struct hist_entry *pair = get_pair_fmt(he, dfmt);
+ double diff;
+ char pfmt[20] = " ";
+
+ if (!pair)
+ goto dummy_print;
+
+ switch (comparison_method) {
+ case COMPUTE_DELTA:
+ if (pair->diff.computed)
+ diff = pair->diff.period_ratio_delta;
+ else
+ diff = compute_delta(he, pair);
+
+ if (fabs(diff) < 0.01)
+ goto dummy_print;
+ scnprintf(pfmt, 20, "%%%+d.2f%%%%", dfmt->header_width - 1);
+ return percent_color_snprintf(hpp->buf, hpp->size,
+ pfmt, diff);
+ default:
+ BUG_ON(1);
+ }
+dummy_print:
+ return scnprintf(hpp->buf, hpp->size, "%*s",
+ dfmt->header_width, pfmt);
+}
+
+static int hpp__color_delta(struct perf_hpp_fmt *fmt,
+ struct perf_hpp *hpp, struct hist_entry *he)
+{
+ return __hpp__color_compare(fmt, hpp, he, COMPUTE_DELTA);
+}
+
static void
hpp__entry_unpair(struct hist_entry *he, int idx, char *buf, size_t size)
{
@@ -941,8 +980,16 @@ static void data__hpp_register(struct data__file *d, int idx)
fmt->entry = hpp__entry_global;

/* TODO more colors */
- if (idx == PERF_HPP_DIFF__BASELINE)
+ switch (idx) {
+ case PERF_HPP_DIFF__BASELINE:
fmt->color = hpp__color_baseline;
+ break;
+ case PERF_HPP_DIFF__DELTA:
+ fmt->color = hpp__color_delta;
+ break;
+ default:
+ break;
+ }

init_header(d, dfmt);
perf_hpp__column_register(fmt);
--
1.8.1.4

Arnaldo Carvalho de Melo

unread,
Jan 14, 2014, 9:10:02 AM1/14/14
to
From: Ramkumar Ramachandra <arta...@gmail.com>

Make percent_color_snprintf() handle negative values correctly.

Signed-off-by: Ramkumar Ramachandra <arta...@gmail.com>
Acked-by: Jiri Olsa <jo...@redhat.com>
Cc: Jiri Olsa <jo...@redhat.com>
Link: http://lkml.kernel.org/r/1388388861-7931-2-gi...@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/color.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/color.c b/tools/perf/util/color.c
index 66e44a5019d5..8cda46c43e74 100644
--- a/tools/perf/util/color.c
+++ b/tools/perf/util/color.c
@@ -1,6 +1,7 @@
#include <linux/kernel.h>
#include "cache.h"
#include "color.h"
+#include <math.h>

int perf_use_color_default = -1;

@@ -298,10 +299,10 @@ const char *get_percent_color(double percent)
* entries in green - and keep the low overhead places
* normal:
*/
- if (percent >= MIN_RED)
+ if (fabs(percent) >= MIN_RED)
color = PERF_COLOR_RED;
else {
- if (percent > MIN_GREEN)
+ if (fabs(percent) > MIN_GREEN)
color = PERF_COLOR_GREEN;
}
return color;

Ingo Molnar

unread,
Jan 14, 2014, 11:30:01 AM1/14/14
to

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

> Em Tue, Jan 14, 2014 at 02:41:01PM +0100, Ingo Molnar escreveu:
> > * Arnaldo Carvalho de Melo <ac...@infradead.org> wrote:
>
> > > Andi Kleen (2):
> > > perf stat: Fix --delay option in man page
> > > perf record: Add --initial-delay option
>
> > Hm, so we now have two options that do something similar, one named
> > --delay, the other --initial-delay? That looks rather inconsistent.
>
> > Furthermore, it looks silly to rename things --initial-delay just to
> > preserve a rarely used option, --no-delay. Instead the better option
> > would be to rename --no-delay to --no-buffering, and use --delay and
> > use it consistently within the tools.
>
> Ok, agreed, I'll do that, adding a patch that renames the old option,
> then reworking Andi's patches to use --delay consistently.

Ok, thanks - I'll pull the existing lineup meanwhile, it's not a
showstopper.

Thanks,

Ingo

tip-bot for Arnaldo Carvalho de Melo

unread,
Jan 14, 2014, 11:40:02 AM1/14/14
to
Commit-ID: 983874d173568f584a5988888645725496c09f24
Gitweb: http://git.kernel.org/tip/983874d173568f584a5988888645725496c09f24
Author: Arnaldo Carvalho de Melo <ac...@redhat.com>
AuthorDate: Fri, 3 Jan 2014 17:25:49 -0300
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Mon, 13 Jan 2014 10:06:22 -0300

perf evlist: Auto unmap on destructor

Removing further boilerplate after making sure perf_evlist__munmap can
be called multiple times for the same evlist.

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-o0luenuld4...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-record.c | 2 --
tools/perf/builtin-trace.c | 1 -
tools/perf/tests/code-reading.c | 1 -
tools/perf/tests/keep-tracking.c | 1 -
tools/perf/tests/mmap-basic.c | 10 ++++------
tools/perf/tests/open-syscall-tp-fields.c | 8 +++-----
tools/perf/tests/perf-record.c | 4 +---
tools/perf/tests/perf-time-to-tsc.c | 1 -
tools/perf/tests/sw-clock.c | 4 +---
tools/perf/tests/task-exit.c | 1 -
tools/perf/util/evlist.c | 4 ++++
11 files changed, 13 insertions(+), 24 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index b7f5e43..cb00b53 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -968,8 +968,6 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
}

err = __cmd_record(&record, argc, argv);
-
- perf_evlist__munmap(rec->evlist);
out_symbol_exit:
symbol__exit();
return err;
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index aa8a5f4..399b4b9 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1993,7 +1993,6 @@ out_disable:
}
}

- perf_evlist__munmap(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
out:
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 2c0ce72..653a8fe 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -540,7 +540,6 @@ static int do_test_code_reading(bool try_kcore)
err = TEST_CODE_READING_OK;
out_err:
if (evlist) {
- perf_evlist__munmap(evlist);
perf_evlist__delete(evlist);
} else {
cpu_map__delete(cpus);
diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c
index dd1c677..497957f 100644
--- a/tools/perf/tests/keep-tracking.c
+++ b/tools/perf/tests/keep-tracking.c
@@ -142,7 +142,6 @@ int test__keep_tracking(void)
out_err:
if (evlist) {
perf_evlist__disable(evlist);
- perf_evlist__munmap(evlist);
perf_evlist__delete(evlist);
} else {
cpu_map__delete(cpus);
diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c
index 111dd4a..aef25f0 100644
index 0a00638..5a016f6 100644
index 682978e..39cc7c3 100644
--- a/tools/perf/tests/perf-record.c
+++ b/tools/perf/tests/perf-record.c
@@ -165,7 +165,7 @@ int test__PERF_RECORD(void)
if (verbose)
perf_event__fprintf(event, stderr);
pr_debug("Couldn't parse sample\n");
- goto out_err;
+ goto out_delete_evlist;
}

if (verbose) {
@@ -302,8 +302,6 @@ found_exit:
pr_debug("PERF_RECORD_MMAP for %s missing!\n", "[vdso]");
++errs;
}
-out_err:
- perf_evlist__munmap(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
out:
diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c
index 3d50f2d..47146d3 100644
--- a/tools/perf/tests/perf-time-to-tsc.c
+++ b/tools/perf/tests/perf-time-to-tsc.c
@@ -166,7 +166,6 @@ next_event:
out_err:
if (evlist) {
perf_evlist__disable(evlist);
- perf_evlist__munmap(evlist);
perf_evlist__delete(evlist);
}

diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c
index b366f0e..983d6b8 100644
--- a/tools/perf/tests/sw-clock.c
+++ b/tools/perf/tests/sw-clock.c
@@ -90,7 +90,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
err = perf_evlist__parse_sample(evlist, event, &sample);
if (err < 0) {
pr_debug("Error during parse sample\n");
- goto out_unmap_evlist;
+ goto out_delete_evlist;
}

total_periods += sample.period;
@@ -105,8 +105,6 @@ next_event:
err = -1;
}

-out_unmap_evlist:
- perf_evlist__munmap(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
return err;
diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c
index 5511a0a..5ff3db3 100644
--- a/tools/perf/tests/task-exit.c
+++ b/tools/perf/tests/task-exit.c
@@ -112,7 +112,6 @@ retry:
err = -1;
}

- perf_evlist__munmap(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
return err;
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index a083bdc..0810f5c 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -107,6 +107,7 @@ void perf_evlist__exit(struct perf_evlist *evlist)

void perf_evlist__delete(struct perf_evlist *evlist)
{
+ perf_evlist__munmap(evlist);
perf_evlist__close(evlist);
cpu_map__delete(evlist->cpus);
thread_map__delete(evlist->threads);
@@ -587,6 +588,9 @@ void perf_evlist__munmap(struct perf_evlist *evlist)
{
int i;

+ if (evlist->mmap == NULL)
+ return;
+
for (i = 0; i < evlist->nr_mmaps; i++)
__perf_evlist__munmap(evlist, i);

tip-bot for Arnaldo Carvalho de Melo

unread,
Jan 14, 2014, 11:40:03 AM1/14/14
to
Commit-ID: 735f7e0bbebe755d707182188c4a5e88c581fc1c
Gitweb: http://git.kernel.org/tip/735f7e0bbebe755d707182188c4a5e88c581fc1c
Author: Arnaldo Carvalho de Melo <ac...@redhat.com>
AuthorDate: Fri, 3 Jan 2014 14:56:49 -0300
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Mon, 13 Jan 2014 10:06:21 -0300

perf evlist: Move the SIGUSR1 error reporting logic to prepare_workload

So that we have the boilerplate in the preparation method, instead of
open coded in tools wanting the reporting when the exec fails.

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-purbdzcphd...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-record.c | 16 ++--------------
tools/perf/builtin-stat.c | 17 ++---------------
tools/perf/builtin-trace.c | 2 +-
tools/perf/tests/perf-record.c | 3 +--
tools/perf/tests/task-exit.c | 19 ++++++++++++++-----
tools/perf/util/evlist.c | 12 ++++++++++--
tools/perf/util/evlist.h | 3 ++-
7 files changed, 32 insertions(+), 40 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index f987d38..ea7c306 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -390,7 +390,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
if (forks) {
err = perf_evlist__prepare_workload(evsel_list, &opts->target,
argv, file->is_pipe,
- true);
+ workload_exec_failed_signal);
if (err < 0) {
pr_err("Couldn't run the workload!\n");
goto out_delete_session;
@@ -507,20 +507,8 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
/*
* Let the child rip
*/
- if (forks) {
- struct sigaction act = {
- .sa_flags = SA_SIGINFO,
- .sa_sigaction = workload_exec_failed_signal,
- };
- /*
- * perf_evlist__prepare_workload will, after we call
- * perf_evlist__start_Workload, send a SIGUSR1 if the exec call
- * fails, that we will catch in workload_signal to flip
- * workload_exec_errno.
- */
- sigaction(SIGUSR1, &act, NULL);
+ if (forks)
perf_evlist__start_workload(evsel_list);
- }

for (;;) {
int hits = rec->samples;
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 9d0d52d..f8456ca 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -58,7 +58,6 @@
#include "util/thread.h"
#include "util/thread_map.h"

-#include <signal.h>
#include <stdlib.h>
#include <sys/prctl.h>
#include <locale.h>
@@ -542,8 +541,8 @@ static int __run_perf_stat(int argc, const char **argv)
}

if (forks) {
- if (perf_evlist__prepare_workload(evsel_list, &target, argv,
- false, true) < 0) {
+ if (perf_evlist__prepare_workload(evsel_list, &target, argv, false,
+ workload_exec_failed_signal) < 0) {
perror("failed to prepare workload");
return -1;
}
@@ -598,18 +597,6 @@ static int __run_perf_stat(int argc, const char **argv)
clock_gettime(CLOCK_MONOTONIC, &ref_time);

if (forks) {
- struct sigaction act = {
- .sa_flags = SA_SIGINFO,
- .sa_sigaction = workload_exec_failed_signal,
- };
- /*
- * perf_evlist__prepare_workload will, after we call
- * perf_evlist__start_Workload, send a SIGUSR1 if the exec call
- * fails, that we will catch in workload_signal to flip
- * workload_exec_errno.
- */
- sigaction(SIGUSR1, &act, NULL);
-
perf_evlist__start_workload(evsel_list);
handle_initial_delay();

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index c5b4bc5..5498eac 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1895,7 +1895,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)

if (forks) {
err = perf_evlist__prepare_workload(evlist, &trace->opts.target,
- argv, false, false);
+ argv, false, NULL);
if (err < 0) {
fprintf(trace->output, "Couldn't run the workload!\n");
goto out_delete_maps;
diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c
index eeba562..fa0ed35 100644
--- a/tools/perf/tests/perf-record.c
+++ b/tools/perf/tests/perf-record.c
@@ -83,8 +83,7 @@ int test__PERF_RECORD(void)
* so that we have time to open the evlist (calling sys_perf_event_open
* on all the fds) and then mmap them.
*/
- err = perf_evlist__prepare_workload(evlist, &opts.target, argv,
- false, false);
+ err = perf_evlist__prepare_workload(evlist, &opts.target, argv, false, NULL);
if (err < 0) {
pr_debug("Couldn't run the workload!\n");
goto out_delete_maps;
diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c
index d09ab57..44e339d 100644
--- a/tools/perf/tests/task-exit.c
+++ b/tools/perf/tests/task-exit.c
@@ -9,12 +9,21 @@
static int exited;
static int nr_exit;

-static void sig_handler(int sig)
+static void sig_handler(int sig __maybe_unused)
{
exited = 1;
+}

- if (sig == SIGUSR1)
- nr_exit = -1;
+/*
+ * perf_evlist__prepare_workload will send a SIGUSR1 if the fork fails, since
+ * we asked by setting its exec_error to this handler.
+ */
+static void workload_exec_failed_signal(int signo __maybe_unused,
+ siginfo_t *info __maybe_unused,
+ void *ucontext __maybe_unused)
+{
+ exited = 1;
+ nr_exit = -1;
}

/*
@@ -35,7 +44,6 @@ int test__task_exit(void)
const char *argv[] = { "true", NULL };

signal(SIGCHLD, sig_handler);
- signal(SIGUSR1, sig_handler);

evlist = perf_evlist__new_default();
if (evlist == NULL) {
@@ -57,7 +65,8 @@ int test__task_exit(void)
goto out_delete_maps;
}

- err = perf_evlist__prepare_workload(evlist, &target, argv, false, true);
+ err = perf_evlist__prepare_workload(evlist, &target, argv, false,
+ workload_exec_failed_signal);
if (err < 0) {
pr_debug("Couldn't run the workload!\n");
goto out_delete_maps;
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 4a30c87..96b3ef5 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1029,7 +1029,7 @@ out_err:

int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *target,
const char *argv[], bool pipe_output,
- bool want_signal)
+ void (*exec_error)(int signo, siginfo_t *info, void *ucontext))
{
int child_ready_pipe[2], go_pipe[2];
char bf;
@@ -1073,7 +1073,7 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *tar

execvp(argv[0], (char **)argv);

- if (want_signal) {
+ if (exec_error) {
union sigval val;

val.sival_int = errno;
@@ -1084,6 +1084,14 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *tar
exit(-1);
}

+ if (exec_error) {
+ struct sigaction act = {
+ .sa_flags = SA_SIGINFO,
+ .sa_sigaction = exec_error,
+ };
+ sigaction(SIGUSR1, &act, NULL);
+ }
+
if (target__none(target))
evlist->threads->map[0] = evlist->workload.pid;

diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 2fe5195..18d1222c 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -103,7 +103,8 @@ int record_opts__config(struct record_opts *opts);
int perf_evlist__prepare_workload(struct perf_evlist *evlist,
struct target *target,
const char *argv[], bool pipe_output,
- bool want_signal);
+ void (*exec_error)(int signo, siginfo_t *info,
+ void *ucontext));
int perf_evlist__start_workload(struct perf_evlist *evlist);

int perf_evlist__parse_mmap_pages(const struct option *opt,

tip-bot for Arnaldo Carvalho de Melo

unread,
Jan 14, 2014, 11:40:03 AM1/14/14
to
Commit-ID: 2d4352c077b98215771cc081626c7a69289c4fac
Gitweb: http://git.kernel.org/tip/2d4352c077b98215771cc081626c7a69289c4fac
Author: Arnaldo Carvalho de Melo <ac...@redhat.com>
AuthorDate: Fri, 3 Jan 2014 17:30:04 -0300
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Mon, 13 Jan 2014 10:06:22 -0300

perf tests: Fixup leak on error path in parse events test

We need to call the evlist destructor when failing to parse events.

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-ilslu69s7v...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/tests/parse-events.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
index e4ce8ae..41dee5e 100644
--- a/tools/perf/tests/parse-events.c
+++ b/tools/perf/tests/parse-events.c
@@ -1385,10 +1385,10 @@ static int test_event(struct evlist_test *e)
if (ret) {
pr_debug("failed to parse event '%s', err %d\n",
e->name, ret);
- return ret;
+ } else {
+ ret = e->check(evlist);
}
-
- ret = e->check(evlist);
+
perf_evlist__delete(evlist);

return ret;

tip-bot for Arnaldo Carvalho de Melo

unread,
Jan 14, 2014, 11:40:03 AM1/14/14
to
Commit-ID: 03ad9747c5f2169556467101e96bc390c5aa4b83
Gitweb: http://git.kernel.org/tip/03ad9747c5f2169556467101e96bc390c5aa4b83
Author: Arnaldo Carvalho de Melo <ac...@redhat.com>
AuthorDate: Fri, 3 Jan 2014 15:56:06 -0300
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Mon, 13 Jan 2014 10:06:21 -0300

perf evlist: Move destruction of maps to evlist destructor

Instead of requiring tools to do an extra destructor call just before
calling perf_evlist__delete.

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-0jd2ptzyik...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-kvm.c | 4 +---
tools/perf/builtin-record.c | 4 +---
tools/perf/builtin-stat.c | 8 +++-----
tools/perf/builtin-top.c | 6 ++----
tools/perf/builtin-trace.c | 6 ++----
tools/perf/tests/code-reading.c | 5 ++---
tools/perf/tests/keep-tracking.c | 5 ++---
tools/perf/tests/mmap-basic.c | 2 ++
tools/perf/tests/open-syscall-tp-fields.c | 4 +---
tools/perf/tests/perf-record.c | 10 ++++------
tools/perf/tests/perf-time-to-tsc.c | 4 ----
tools/perf/tests/sw-clock.c | 10 ++++------
tools/perf/tests/task-exit.c | 9 ++++-----
tools/perf/util/evlist.c | 12 ++++--------
tools/perf/util/evlist.h | 1 -
15 files changed, 32 insertions(+), 58 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index a6ec105..858b11b 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -1556,10 +1556,8 @@ out:
if (kvm->session)
perf_session__delete(kvm->session);
kvm->session = NULL;
- if (kvm->evlist) {
- perf_evlist__delete_maps(kvm->evlist);
+ if (kvm->evlist)
perf_evlist__delete(kvm->evlist);
- }

return err;
}
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 6dcb8aa..5149b41 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -964,15 +964,13 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)

if (record_opts__config(&rec->opts)) {
err = -EINVAL;
- goto out_free_fd;
+ goto out_symbol_exit;
}

err = __cmd_record(&record, argc, argv);

perf_evlist__munmap(rec->evlist);
perf_evlist__close(rec->evlist);
-out_free_fd:
- perf_evlist__delete_maps(rec->evlist);
out_symbol_exit:
symbol__exit();
return err;
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index f8456ca..6ca0766 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1782,14 +1782,14 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
if (interval && interval < 100) {
pr_err("print interval must be >= 100ms\n");
parse_options_usage(stat_usage, options, "I", 1);
- goto out_free_maps;
+ goto out;
}

if (perf_evlist__alloc_stats(evsel_list, interval))
- goto out_free_maps;
+ goto out;

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

/*
* We dont want to block the signals - that would cause
@@ -1821,8 +1821,6 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
print_stat(argc, argv);

perf_evlist__free_stats(evsel_list);
-out_free_maps:
- perf_evlist__delete_maps(evsel_list);
out:
perf_evlist__delete(evsel_list);
return status;
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 172e91a..e0fd0aa 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -1171,7 +1171,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
if (!top.evlist->nr_entries &&
perf_evlist__add_default(top.evlist) < 0) {
ui__error("Not enough memory for event selector list\n");
- goto out_delete_maps;
+ goto out_delete_evlist;
}

symbol_conf.nr_events = top.evlist->nr_entries;
@@ -1181,7 +1181,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)

if (record_opts__config(opts)) {
status = -EINVAL;
- goto out_delete_maps;
+ goto out_delete_evlist;
}

top.sym_evsel = perf_evlist__first(top.evlist);
@@ -1206,8 +1206,6 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)

status = __cmd_top(&top);

-out_delete_maps:
- perf_evlist__delete_maps(top.evlist);
out_delete_evlist:
perf_evlist__delete(top.evlist);

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 5498eac..f4ddd14 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1885,7 +1885,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
err = trace__symbols_init(trace, evlist);
if (err < 0) {
fprintf(trace->output, "Problems initializing symbol libraries!\n");
- goto out_delete_maps;
+ goto out_delete_evlist;
}

perf_evlist__config(evlist, &trace->opts);
@@ -1898,7 +1898,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
argv, false, NULL);
if (err < 0) {
fprintf(trace->output, "Couldn't run the workload!\n");
- goto out_delete_maps;
+ goto out_delete_evlist;
}
}

@@ -1996,8 +1996,6 @@ out_disable:
perf_evlist__munmap(evlist);
out_close_evlist:
perf_evlist__close(evlist);
-out_delete_maps:
- perf_evlist__delete_maps(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
out:
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 4248d1e..ddbc775 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -543,11 +543,10 @@ out_err:
perf_evlist__munmap(evlist);
perf_evlist__close(evlist);
perf_evlist__delete(evlist);
- }
- if (cpus)
+ } else {
cpu_map__delete(cpus);
- if (threads)
thread_map__delete(threads);
+ }
machines__destroy_kernel_maps(&machines);
machine__delete_threads(machine);
machines__exit(&machines);
diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c
index 27eb751..f9bc1fc 100644
--- a/tools/perf/tests/keep-tracking.c
+++ b/tools/perf/tests/keep-tracking.c
@@ -145,11 +145,10 @@ out_err:
perf_evlist__munmap(evlist);
perf_evlist__close(evlist);
perf_evlist__delete(evlist);
- }
- if (cpus)
+ } else {
cpu_map__delete(cpus);
- if (threads)
thread_map__delete(threads);
+ }

return err;
}
diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c
index d64ab79..bbb334d 100644
--- a/tools/perf/tests/mmap-basic.c
+++ b/tools/perf/tests/mmap-basic.c
@@ -143,6 +143,8 @@ out_close_fd:
perf_evsel__close_fd(evsels[i], 1, threads->nr);
out_free_evlist:
perf_evlist__delete(evlist);
+ cpus = NULL;
+ threads = NULL;
out_free_cpus:
cpu_map__delete(cpus);
out_free_threads:
diff --git a/tools/perf/tests/open-syscall-tp-fields.c b/tools/perf/tests/open-syscall-tp-fields.c
index 774620a..595b577 100644
--- a/tools/perf/tests/open-syscall-tp-fields.c
+++ b/tools/perf/tests/open-syscall-tp-fields.c
@@ -48,7 +48,7 @@ int test__syscall_open_tp_fields(void)
err = perf_evlist__open(evlist);
if (err < 0) {
pr_debug("perf_evlist__open: %s\n", strerror(errno));
- goto out_delete_maps;
+ goto out_delete_evlist;
}

err = perf_evlist__mmap(evlist, UINT_MAX, false);
@@ -114,8 +114,6 @@ out_munmap:
perf_evlist__munmap(evlist);
out_close_evlist:
perf_evlist__close(evlist);
-out_delete_maps:
- perf_evlist__delete_maps(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
out:
diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c
index fa0ed35..266da9d 100644
--- a/tools/perf/tests/perf-record.c
+++ b/tools/perf/tests/perf-record.c
@@ -86,7 +86,7 @@ int test__PERF_RECORD(void)
err = perf_evlist__prepare_workload(evlist, &opts.target, argv, false, NULL);
if (err < 0) {
pr_debug("Couldn't run the workload!\n");
- goto out_delete_maps;
+ goto out_delete_evlist;
}

/*
@@ -101,7 +101,7 @@ int test__PERF_RECORD(void)
err = sched__get_first_possible_cpu(evlist->workload.pid, &cpu_mask);
if (err < 0) {
pr_debug("sched__get_first_possible_cpu: %s\n", strerror(errno));
- goto out_delete_maps;
+ goto out_delete_evlist;
}

cpu = err;
@@ -111,7 +111,7 @@ int test__PERF_RECORD(void)
*/
if (sched_setaffinity(evlist->workload.pid, cpu_mask_size, &cpu_mask) < 0) {
pr_debug("sched_setaffinity: %s\n", strerror(errno));
- goto out_delete_maps;
+ goto out_delete_evlist;
}

/*
@@ -121,7 +121,7 @@ int test__PERF_RECORD(void)
err = perf_evlist__open(evlist);
if (err < 0) {
pr_debug("perf_evlist__open: %s\n", strerror(errno));
- goto out_delete_maps;
+ goto out_delete_evlist;
}

/*
@@ -306,8 +306,6 @@ out_err:
perf_evlist__munmap(evlist);
out_close_evlist:
perf_evlist__close(evlist);
-out_delete_maps:
- perf_evlist__delete_maps(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
out:
diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c
index c6398b9..97d08ff 100644
--- a/tools/perf/tests/perf-time-to-tsc.c
+++ b/tools/perf/tests/perf-time-to-tsc.c
@@ -170,10 +170,6 @@ out_err:
perf_evlist__close(evlist);
perf_evlist__delete(evlist);
}
- if (cpus)
- cpu_map__delete(cpus);
- if (threads)
- thread_map__delete(threads);

return err;
}
diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c
index 6664a7c..266d381 100644
--- a/tools/perf/tests/sw-clock.c
+++ b/tools/perf/tests/sw-clock.c
@@ -45,7 +45,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
evsel = perf_evsel__new(&attr);
if (evsel == NULL) {
pr_debug("perf_evsel__new\n");
- goto out_free_evlist;
+ goto out_delete_evlist;
}
perf_evlist__add(evlist, evsel);

@@ -54,7 +54,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
if (!evlist->cpus || !evlist->threads) {
err = -ENOMEM;
pr_debug("Not enough memory to create thread/cpu maps\n");
- goto out_delete_maps;
+ goto out_delete_evlist;
}

if (perf_evlist__open(evlist)) {
@@ -63,7 +63,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
err = -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;
+ goto out_delete_evlist;
}

err = perf_evlist__mmap(evlist, 128, true);
@@ -109,9 +109,7 @@ out_unmap_evlist:
perf_evlist__munmap(evlist);
out_close_evlist:
perf_evlist__close(evlist);
-out_delete_maps:
- perf_evlist__delete_maps(evlist);
-out_free_evlist:
+out_delete_evlist:
perf_evlist__delete(evlist);
return err;
}
diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c
index 44e339d..fdeb2aa 100644
--- a/tools/perf/tests/task-exit.c
+++ b/tools/perf/tests/task-exit.c
@@ -62,14 +62,14 @@ int test__task_exit(void)
if (!evlist->cpus || !evlist->threads) {
err = -ENOMEM;
pr_debug("Not enough memory to create thread/cpu maps\n");
- goto out_delete_maps;
+ goto out_delete_evlist;
}

err = perf_evlist__prepare_workload(evlist, &target, argv, false,
workload_exec_failed_signal);
if (err < 0) {
pr_debug("Couldn't run the workload!\n");
- goto out_delete_maps;
+ goto out_delete_evlist;
}

evsel = perf_evlist__first(evlist);
@@ -83,7 +83,7 @@ int test__task_exit(void)
err = perf_evlist__open(evlist);
if (err < 0) {
pr_debug("Couldn't open the evlist: %s\n", strerror(-err));
- goto out_delete_maps;
+ goto out_delete_evlist;
}

if (perf_evlist__mmap(evlist, 128, true) < 0) {
@@ -115,8 +115,7 @@ retry:
perf_evlist__munmap(evlist);
out_close_evlist:
perf_evlist__close(evlist);
-out_delete_maps:
- perf_evlist__delete_maps(evlist);
+out_delete_evlist:
perf_evlist__delete(evlist);
return err;
}
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 96b3ef5..143eaf0 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -107,6 +107,10 @@ void perf_evlist__exit(struct perf_evlist *evlist)

void perf_evlist__delete(struct perf_evlist *evlist)
{
+ cpu_map__delete(evlist->cpus);
+ thread_map__delete(evlist->threads);
+ evlist->cpus = NULL;
+ evlist->threads = NULL;
perf_evlist__purge(evlist);
perf_evlist__exit(evlist);
free(evlist);
@@ -833,14 +837,6 @@ out_delete_threads:
return -1;
}

-void perf_evlist__delete_maps(struct perf_evlist *evlist)
-{
- cpu_map__delete(evlist->cpus);
- thread_map__delete(evlist->threads);
- evlist->cpus = NULL;
- evlist->threads = NULL;
-}
-
int perf_evlist__apply_filters(struct perf_evlist *evlist)
{
struct perf_evsel *evsel;
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 18d1222c..518e521 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -135,7 +135,6 @@ static inline void perf_evlist__set_maps(struct perf_evlist *evlist,
}

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);

void __perf_evlist__set_leader(struct list_head *list);

tip-bot for Arnaldo Carvalho de Melo

unread,
Jan 14, 2014, 11:40:03 AM1/14/14
to
Commit-ID: 41cde47675de62ee0f3877c00ab44373b2b2f4ca
Gitweb: http://git.kernel.org/tip/41cde47675de62ee0f3877c00ab44373b2b2f4ca
Author: Arnaldo Carvalho de Melo <ac...@redhat.com>
AuthorDate: Fri, 3 Jan 2014 17:34:42 -0300
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Mon, 13 Jan 2014 10:06:22 -0300

perf stat: Remove misplaced __maybe_unused

That 'argc' argument _is_ being used.

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-t2gsxc15zu...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-stat.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 6ca0766..b27b264 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -645,7 +645,7 @@ static int __run_perf_stat(int argc, const char **argv)
return WEXITSTATUS(status);
}

-static int run_perf_stat(int argc __maybe_unused, const char **argv)
+static int run_perf_stat(int argc, const char **argv)
{
int ret;

tip-bot for Arnaldo Carvalho de Melo

unread,
Jan 14, 2014, 11:40:04 AM1/14/14
to
Commit-ID: f33cbe72e6166b97d6fa2400cb00a885b47999d7
Gitweb: http://git.kernel.org/tip/f33cbe72e6166b97d6fa2400cb00a885b47999d7
Author: Arnaldo Carvalho de Melo <ac...@redhat.com>
AuthorDate: Thu, 2 Jan 2014 15:11:25 -0300
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Mon, 13 Jan 2014 10:06:21 -0300

perf evlist: Send the errno in the signal when workload fails

When a tool uses perf_evlist__start_workload and the supplied workload
fails (e.g.: its binary wasn't found), perror was being used to print
the error reason.

This is undesirable, as the caller may be a GUI, when it wants to have
total control of the error reporting process.

So move to using sigaction(SA_SIGINFO) + siginfo_t->sa_value->sival_int
to communicate to the caller the errno and let it print it using the UI
of its choosing.

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-epgcv7kjq8...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-record.c | 39 +++++++++++++++++++++++++++++++++++++--
tools/perf/builtin-stat.c | 21 +++++++++++++++------
tools/perf/util/evlist.c | 11 ++++++++---
3 files changed, 60 insertions(+), 11 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 6ec0cbc..f987d38 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -341,6 +341,22 @@ static void record__init_features(struct record *rec)
perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
}

+static volatile int workload_exec_errno;
+
+/*
+ * perf_evlist__prepare_workload will send a SIGUSR1
+ * if the fork fails, since we asked by setting its
+ * want_signal to true.
+ */
+static void workload_exec_failed_signal(int signo, siginfo_t *info,
+ void *ucontext __maybe_unused)
+{
+ workload_exec_errno = info->si_value.sival_int;
+ done = 1;
+ signr = signo;
+ child_finished = 1;
+}
+
static int __cmd_record(struct record *rec, int argc, const char **argv)
{
int err;
@@ -359,7 +375,6 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
on_exit(record__sig_exit, rec);
signal(SIGCHLD, sig_handler);
signal(SIGINT, sig_handler);
- signal(SIGUSR1, sig_handler);
signal(SIGTERM, sig_handler);

session = perf_session__new(file, false, NULL);
@@ -492,8 +507,20 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
/*
* Let the child rip
*/
- if (forks)
+ if (forks) {
+ struct sigaction act = {
+ .sa_flags = SA_SIGINFO,
+ .sa_sigaction = workload_exec_failed_signal,
+ };
+ /*
+ * perf_evlist__prepare_workload will, after we call
+ * perf_evlist__start_Workload, send a SIGUSR1 if the exec call
+ * fails, that we will catch in workload_signal to flip
+ * workload_exec_errno.
+ */
+ sigaction(SIGUSR1, &act, NULL);
perf_evlist__start_workload(evsel_list);
+ }

for (;;) {
int hits = rec->samples;
@@ -521,6 +548,14 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
}
}

+ if (forks && workload_exec_errno) {
+ char msg[512];
+ const char *emsg = strerror_r(workload_exec_errno, msg, sizeof(msg));
+ pr_err("Workload failed: %s\n", emsg);
+ err = -1;
+ goto out_delete_session;
+ }
+
if (quiet || signr == SIGUSR1)
return 0;

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 1c76c7a..9d0d52d 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -58,6 +58,7 @@
#include "util/thread.h"
#include "util/thread_map.h"

+#include <signal.h>
#include <stdlib.h>
#include <sys/prctl.h>
#include <locale.h>
@@ -509,16 +510,17 @@ static void handle_initial_delay(void)
}
}

-static volatile bool workload_exec_failed;
+static volatile int workload_exec_errno;

/*
* perf_evlist__prepare_workload will send a SIGUSR1
* if the fork fails, since we asked by setting its
* want_signal to true.
*/
-static void workload_exec_failed_signal(int signo __maybe_unused)
+static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *info,
+ void *ucontext __maybe_unused)
{
- workload_exec_failed = true;
+ workload_exec_errno = info->si_value.sival_int;
}

static int __run_perf_stat(int argc, const char **argv)
@@ -596,13 +598,17 @@ static int __run_perf_stat(int argc, const char **argv)
clock_gettime(CLOCK_MONOTONIC, &ref_time);

if (forks) {
+ struct sigaction act = {
+ .sa_flags = SA_SIGINFO,
+ .sa_sigaction = workload_exec_failed_signal,
+ };
/*
* perf_evlist__prepare_workload will, after we call
* perf_evlist__start_Workload, send a SIGUSR1 if the exec call
* fails, that we will catch in workload_signal to flip
- * workload_exec_failed.
+ * workload_exec_errno.
*/
- signal(SIGUSR1, workload_exec_failed_signal);
+ sigaction(SIGUSR1, &act, NULL);

perf_evlist__start_workload(evsel_list);
handle_initial_delay();
@@ -615,8 +621,11 @@ static int __run_perf_stat(int argc, const char **argv)
}
wait(&status);

- if (workload_exec_failed)
+ if (workload_exec_errno) {
+ const char *emsg = strerror_r(workload_exec_errno, msg, sizeof(msg));
+ pr_err("Workload failed: %s\n", emsg);
return -1;
+ }

if (WIFSIGNALED(status))
psignal(WTERMSIG(status), argv[0]);
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index b08a7ec..4a30c87 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1073,9 +1073,14 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *tar

execvp(argv[0], (char **)argv);

- perror(argv[0]);
- if (want_signal)
- kill(getppid(), SIGUSR1);
+ if (want_signal) {
+ union sigval val;
+
+ val.sival_int = errno;
+ if (sigqueue(getppid(), SIGUSR1, val))
+ perror(argv[0]);
+ } else
+ perror(argv[0]);
exit(-1);

tip-bot for Arnaldo Carvalho de Melo

unread,
Jan 14, 2014, 11:40:04 AM1/14/14
to
Commit-ID: 98eafce6bda705529e90d33b7f23706b346a6c8a
Gitweb: http://git.kernel.org/tip/98eafce6bda705529e90d33b7f23706b346a6c8a
Author: Arnaldo Carvalho de Melo <ac...@redhat.com>
AuthorDate: Mon, 6 Jan 2014 15:43:02 -0300
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Mon, 13 Jan 2014 10:06:23 -0300

perf trace: Pack 'struct trace'

Initial struct stats:

/* size: 368, cachelines: 6, members: 24 */
/* sum members: 353, holes: 3, sum holes: 15 */
/* last cacheline: 48 bytes */

After reorg:

[acme@ssdandy linux]$ pahole -C trace ~/bin/trace | tail -4
/* size: 360, cachelines: 6, members: 24 */
/* padding: 7 */
/* last cacheline: 40 bytes */
};
[acme@ssdandy linux]$

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-6jimc80yu8...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-trace.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 399b4b9..4bd44ab 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c

tip-bot for Arnaldo Carvalho de Melo

unread,
Jan 14, 2014, 11:40:04 AM1/14/14
to
Commit-ID: 3ba4d2e1a8235d862657ded9f20b3170b477768b
Gitweb: http://git.kernel.org/tip/3ba4d2e1a8235d862657ded9f20b3170b477768b
Author: Arnaldo Carvalho de Melo <ac...@redhat.com>
AuthorDate: Mon, 6 Jan 2014 15:28:35 -0300
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Mon, 13 Jan 2014 10:06:23 -0300

perf header: Pack 'struct perf_session_env'
/* last cacheline: 24 bytes */
};
[acme@ssdandy linux]$

[acme@ssdandy linux]$ pahole -C perf_session_env --reorganize --show_reorg_steps ~/bin/perf | grep ^/ | grep -v Final
/* Moving 'nr_sibling_cores' from after 'cmdline' to after 'nr_cmdline' */
/* Moving 'nr_numa_nodes' from after 'sibling_threads' to after 'nr_sibling_threads' */
/* Moving 'nr_groups' from after 'pmu_mappings' to after 'nr_pmu_mappings' */
[acme@ssdandy linux]$

Final struct stats:

[acme@ssdandy linux]$ pahole -C perf_session_env --reorganize --show_reorg_steps ~/bin/perf | tail -4
/* --- cacheline 2 boundary (128 bytes) --- */

/* size: 128, cachelines: 2, members: 20 */
}; /* saved 24 bytes and 1 cacheline! */
[acme@ssdandy linux]$

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-3d9tshamlo...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/util/header.h | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 307c9ae..a2d047b 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -77,16 +77,16 @@ struct perf_session_env {
unsigned long long total_mem;

int nr_cmdline;
- char *cmdline;
int nr_sibling_cores;
- char *sibling_cores;
int nr_sibling_threads;
- char *sibling_threads;
int nr_numa_nodes;
- char *numa_nodes;
int nr_pmu_mappings;
- char *pmu_mappings;
int nr_groups;
+ char *cmdline;
+ char *sibling_cores;
+ char *sibling_threads;
+ char *numa_nodes;
+ char *pmu_mappings;
};

struct perf_header {

tip-bot for Arnaldo Carvalho de Melo

unread,
Jan 14, 2014, 11:40:04 AM1/14/14
to
Commit-ID: f26e1c7cb279051d83e0b671f48b30fe88c2c788
Gitweb: http://git.kernel.org/tip/f26e1c7cb279051d83e0b671f48b30fe88c2c788
Author: Arnaldo Carvalho de Melo <ac...@redhat.com>
AuthorDate: Fri, 3 Jan 2014 16:54:12 -0300
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Mon, 13 Jan 2014 10:06:22 -0300

perf evlist: Close fds on destructor

Since it is safe to call perf_evlist__close() multiple times, autoclose
it and remove the calls to the close from existing tools, reducing the
tooling boilerplate.

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-2kq9v7p1ru...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-record.c | 1 -
tools/perf/builtin-trace.c | 4 +---
tools/perf/tests/code-reading.c | 1 -
tools/perf/tests/keep-tracking.c | 1 -
tools/perf/tests/mmap-basic.c | 11 ++++-------
tools/perf/tests/open-syscall-tp-fields.c | 4 +---
tools/perf/tests/perf-record.c | 4 +---
tools/perf/tests/perf-time-to-tsc.c | 1 -
tools/perf/tests/sw-clock.c | 4 +---
tools/perf/tests/task-exit.c | 4 +---
tools/perf/util/evlist.c | 1 +
11 files changed, 10 insertions(+), 26 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 5149b41..b7f5e43 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -970,7 +970,6 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
err = __cmd_record(&record, argc, argv);

perf_evlist__munmap(rec->evlist);
- perf_evlist__close(rec->evlist);
out_symbol_exit:
symbol__exit();
return err;
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index f4ddd14..aa8a5f4 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1909,7 +1909,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
err = perf_evlist__mmap(evlist, trace->opts.mmap_pages, false);
if (err < 0) {
fprintf(trace->output, "Couldn't mmap the events: %s\n", strerror(errno));
- goto out_close_evlist;
+ goto out_delete_evlist;
}

perf_evlist__enable(evlist);
@@ -1994,8 +1994,6 @@ out_disable:
}

perf_evlist__munmap(evlist);
-out_close_evlist:
- perf_evlist__close(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
out:
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index ddbc775..2c0ce72 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -541,7 +541,6 @@ static int do_test_code_reading(bool try_kcore)
out_err:
if (evlist) {
perf_evlist__munmap(evlist);
- perf_evlist__close(evlist);
perf_evlist__delete(evlist);
} else {
cpu_map__delete(cpus);
diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c
index f9bc1fc..dd1c677 100644
--- a/tools/perf/tests/keep-tracking.c
+++ b/tools/perf/tests/keep-tracking.c
@@ -143,7 +143,6 @@ out_err:
if (evlist) {
perf_evlist__disable(evlist);
perf_evlist__munmap(evlist);
- perf_evlist__close(evlist);
perf_evlist__delete(evlist);
} else {
cpu_map__delete(cpus);
diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c
index bbb334d..111dd4a 100644
--- a/tools/perf/tests/mmap-basic.c
+++ b/tools/perf/tests/mmap-basic.c
@@ -68,7 +68,7 @@ int test__basic_mmap(void)
evsels[i] = perf_evsel__newtp("syscalls", name);
if (evsels[i] == NULL) {
pr_debug("perf_evsel__new\n");
- goto out_free_evlist;
+ goto out_delete_evlist;
}

evsels[i]->attr.wakeup_events = 1;
@@ -80,7 +80,7 @@ int test__basic_mmap(void)
pr_debug("failed to open counter: %s, "
"tweak /proc/sys/kernel/perf_event_paranoid?\n",
strerror(errno));
- goto out_close_fd;
+ goto out_delete_evlist;
}

nr_events[i] = 0;
@@ -90,7 +90,7 @@ int test__basic_mmap(void)
if (perf_evlist__mmap(evlist, 128, true) < 0) {
pr_debug("failed to mmap events: %d (%s)\n", errno,
strerror(errno));
- goto out_close_fd;
+ goto out_delete_evlist;
}

for (i = 0; i < nsyscalls; ++i)
@@ -138,10 +138,7 @@ int test__basic_mmap(void)

out_munmap:
perf_evlist__munmap(evlist);
-out_close_fd:
- for (i = 0; i < nsyscalls; ++i)
- perf_evsel__close_fd(evsels[i], 1, threads->nr);
-out_free_evlist:
+out_delete_evlist:
perf_evlist__delete(evlist);
cpus = NULL;
threads = NULL;
diff --git a/tools/perf/tests/open-syscall-tp-fields.c b/tools/perf/tests/open-syscall-tp-fields.c
index 595b577..0a00638 100644
--- a/tools/perf/tests/open-syscall-tp-fields.c
+++ b/tools/perf/tests/open-syscall-tp-fields.c
@@ -54,7 +54,7 @@ int test__syscall_open_tp_fields(void)
err = perf_evlist__mmap(evlist, UINT_MAX, false);
if (err < 0) {
pr_debug("perf_evlist__mmap: %s\n", strerror(errno));
- goto out_close_evlist;
+ goto out_delete_evlist;
}

perf_evlist__enable(evlist);
@@ -112,8 +112,6 @@ out_ok:
err = 0;
out_munmap:
perf_evlist__munmap(evlist);
-out_close_evlist:
- perf_evlist__close(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
out:
diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c
index 266da9d..682978e 100644
--- a/tools/perf/tests/perf-record.c
+++ b/tools/perf/tests/perf-record.c
@@ -132,7 +132,7 @@ int test__PERF_RECORD(void)
err = perf_evlist__mmap(evlist, opts.mmap_pages, false);
if (err < 0) {
pr_debug("perf_evlist__mmap: %s\n", strerror(errno));
- goto out_close_evlist;
+ goto out_delete_evlist;
}

/*
@@ -304,8 +304,6 @@ found_exit:
}
out_err:
perf_evlist__munmap(evlist);
-out_close_evlist:
- perf_evlist__close(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
out:
diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c
index 97d08ff..3d50f2d 100644
--- a/tools/perf/tests/perf-time-to-tsc.c
+++ b/tools/perf/tests/perf-time-to-tsc.c
@@ -167,7 +167,6 @@ out_err:
if (evlist) {
perf_evlist__disable(evlist);
perf_evlist__munmap(evlist);
- perf_evlist__close(evlist);
perf_evlist__delete(evlist);
}

diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c
index 266d381..b366f0e 100644
--- a/tools/perf/tests/sw-clock.c
+++ b/tools/perf/tests/sw-clock.c
@@ -70,7 +70,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
if (err < 0) {
pr_debug("failed to mmap event: %d (%s)\n", errno,
strerror(errno));
- goto out_close_evlist;
+ goto out_delete_evlist;
}

perf_evlist__enable(evlist);
@@ -107,8 +107,6 @@ next_event:

out_unmap_evlist:
perf_evlist__munmap(evlist);
-out_close_evlist:
- perf_evlist__close(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
return err;
diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c
index fdeb2aa..5511a0a 100644
--- a/tools/perf/tests/task-exit.c
+++ b/tools/perf/tests/task-exit.c
@@ -89,7 +89,7 @@ int test__task_exit(void)
if (perf_evlist__mmap(evlist, 128, true) < 0) {
pr_debug("failed to mmap events: %d (%s)\n", errno,
strerror(errno));
- goto out_close_evlist;
+ goto out_delete_evlist;
}

perf_evlist__start_workload(evlist);
@@ -113,8 +113,6 @@ retry:
}

perf_evlist__munmap(evlist);
-out_close_evlist:
- perf_evlist__close(evlist);
out_delete_evlist:
perf_evlist__delete(evlist);
return err;
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 143eaf0..a083bdc 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -107,6 +107,7 @@ void perf_evlist__exit(struct perf_evlist *evlist)

void perf_evlist__delete(struct perf_evlist *evlist)
{
+ perf_evlist__close(evlist);
cpu_map__delete(evlist->cpus);
thread_map__delete(evlist->threads);
evlist->cpus = NULL;

tip-bot for Arnaldo Carvalho de Melo

unread,
Jan 14, 2014, 11:40:03 AM1/14/14
to
Commit-ID: 3e2be2da8f76ef5b2e8e59c3dc8acd24640b4af4
Gitweb: http://git.kernel.org/tip/3e2be2da8f76ef5b2e8e59c3dc8acd24640b4af4
Author: Arnaldo Carvalho de Melo <ac...@redhat.com>
AuthorDate: Fri, 3 Jan 2014 15:03:26 -0300
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Mon, 13 Jan 2014 10:06:21 -0300

perf record: Remove old evsel_list usage

To be consistent with other places, use just 'evlist' for the evsel list
variable, and since we have it in 'struct record', use it directly from
there.

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-396bnfvmlx...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-record.c | 43 +++++++++++++++++++------------------------
1 file changed, 19 insertions(+), 24 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index ea7c306..6dcb8aa 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -324,7 +324,6 @@ out:

static void record__init_features(struct record *rec)
{
- struct perf_evlist *evsel_list = rec->evlist;
struct perf_session *session = rec->session;
int feat;

@@ -334,7 +333,7 @@ static void record__init_features(struct record *rec)
if (rec->no_buildid)
perf_header__clear_feat(&session->header, HEADER_BUILD_ID);

- if (!have_tracepoints(&evsel_list->entries))
+ if (!have_tracepoints(&rec->evlist->entries))
perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);

if (!rec->opts.branch_stack)
@@ -365,7 +364,6 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
struct machine *machine;
struct perf_tool *tool = &rec->tool;
struct record_opts *opts = &rec->opts;
- struct perf_evlist *evsel_list = rec->evlist;
struct perf_data_file *file = &rec->file;
struct perf_session *session;
bool disabled = false;
@@ -388,7 +386,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
record__init_features(rec);

if (forks) {
- err = perf_evlist__prepare_workload(evsel_list, &opts->target,
+ err = perf_evlist__prepare_workload(rec->evlist, &opts->target,
argv, file->is_pipe,
workload_exec_failed_signal);
if (err < 0) {
@@ -402,7 +400,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
goto out_delete_session;
}

- if (!evsel_list->nr_groups)
+ if (!rec->evlist->nr_groups)
perf_header__clear_feat(&session->header, HEADER_GROUP_DESC);

/*
@@ -415,7 +413,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
if (err < 0)
goto out_delete_session;
} else {
- err = perf_session__write_header(session, evsel_list,
+ err = perf_session__write_header(session, rec->evlist,
file->fd, false);
if (err < 0)
goto out_delete_session;
@@ -439,7 +437,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
goto out_delete_session;
}

- if (have_tracepoints(&evsel_list->entries)) {
+ if (have_tracepoints(&rec->evlist->entries)) {
/*
* FIXME err <= 0 here actually means that
* there were no tracepoints so its not really
@@ -448,7 +446,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
* return this more properly and also
* propagate errors that now are calling die()
*/
- err = perf_event__synthesize_tracing_data(tool, file->fd, evsel_list,
+ err = perf_event__synthesize_tracing_data(tool, file->fd, rec->evlist,
process_synthesized_event);
if (err <= 0) {
pr_err("Couldn't record tracing data.\n");
@@ -480,7 +478,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
perf_event__synthesize_guest_os, tool);
}

- err = __machine__synthesize_threads(machine, tool, &opts->target, evsel_list->threads,
+ err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads,
process_synthesized_event, opts->sample_address);
if (err != 0)
goto out_delete_session;
@@ -502,13 +500,13 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
* so don't spoil it by prematurely enabling them.
*/
if (!target__none(&opts->target))
- perf_evlist__enable(evsel_list);
+ perf_evlist__enable(rec->evlist);

/*
* Let the child rip
*/
if (forks)
- perf_evlist__start_workload(evsel_list);
+ perf_evlist__start_workload(rec->evlist);

for (;;) {
int hits = rec->samples;
@@ -521,7 +519,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
if (hits == rec->samples) {
if (done)
break;
- err = poll(evsel_list->pollfd, evsel_list->nr_fds, -1);
+ err = poll(rec->evlist->pollfd, rec->evlist->nr_fds, -1);
waking++;
}

@@ -531,7 +529,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
* disable events in this case.
*/
if (done && !disabled && !target__none(&opts->target)) {
- perf_evlist__disable(evsel_list);
+ perf_evlist__disable(rec->evlist);
disabled = true;
}
}
@@ -901,16 +899,13 @@ const struct option record_options[] = {
int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
{
int err = -ENOMEM;
- struct perf_evlist *evsel_list;
struct record *rec = &record;
char errbuf[BUFSIZ];

- evsel_list = perf_evlist__new();
- if (evsel_list == NULL)
+ rec->evlist = perf_evlist__new();
+ if (rec->evlist == NULL)
return -ENOMEM;

- rec->evlist = evsel_list;
-
argc = parse_options(argc, argv, record_options, record_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
if (!argc && target__none(&rec->opts.target))
@@ -937,8 +932,8 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
if (rec->no_buildid_cache || rec->no_buildid)
disable_buildid_cache();

- if (evsel_list->nr_entries == 0 &&
- perf_evlist__add_default(evsel_list) < 0) {
+ if (rec->evlist->nr_entries == 0 &&
+ perf_evlist__add_default(rec->evlist) < 0) {
pr_err("Not enough memory for event selector list\n");
goto out_symbol_exit;
}
@@ -964,7 +959,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
}

err = -ENOMEM;
- if (perf_evlist__create_maps(evsel_list, &rec->opts.target) < 0)
+ if (perf_evlist__create_maps(rec->evlist, &rec->opts.target) < 0)
usage_with_options(record_usage, record_options);

if (record_opts__config(&rec->opts)) {
@@ -974,10 +969,10 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)

err = __cmd_record(&record, argc, argv);

- perf_evlist__munmap(evsel_list);
- perf_evlist__close(evsel_list);
+ perf_evlist__munmap(rec->evlist);
+ perf_evlist__close(rec->evlist);
out_free_fd:
- perf_evlist__delete_maps(evsel_list);
+ perf_evlist__delete_maps(rec->evlist);
out_symbol_exit:
symbol__exit();
return err;

tip-bot for Arnaldo Carvalho de Melo

unread,
Jan 14, 2014, 11:50:01 AM1/14/14
to
Commit-ID: c023f534c31f69a658fc21d619116ad12c7be464
Gitweb: http://git.kernel.org/tip/c023f534c31f69a658fc21d619116ad12c7be464
Author: Arnaldo Carvalho de Melo <ac...@redhat.com>
AuthorDate: Fri, 10 Jan 2014 16:25:05 -0300
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Mon, 13 Jan 2014 10:06:26 -0300

perf tools: Include tools/lib/api/ in MANIFEST

When 553873e1df63 renamed tools/lib/lk to tools/lib/api we forgot to
do the switch in tools/perf/MANIFEST, breaking tarball building:

[acme@ssdandy linux]$ make perf-targz-src-pkg
TAR
[acme@ssdandy linux]$ tar xf perf-3.13.0-rc4.tar.gz -C /tmp/tmp.OgdYyvp77p/
[acme@ssdandy linux]$ make -C /tmp/tmp.OgdYyvp77p/perf-3.13.0-rc4/tools/perf
make: Entering directory
`/tmp/tmp.OgdYyvp77p/perf-3.13.0-rc4/tools/perf'
BUILD: Doing 'make -j8' parallel build
FLEX util/pmu-flex.c
CC util/evlist.o
CC util/evsel.o
util/evsel.c:12:28: fatal error: api/fs/debugfs.h: No such file or directory compilation terminated.
In file included from util/cache.h:5:0,
<SNIP>

Fix it.

Cc: Adrian Hunter <adrian...@intel.com>
Cc: Borislav Petkov <b...@suse.de>
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-1wwjs01rt3...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/MANIFEST | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST
index 4e53535..f41572d 100644
--- a/tools/perf/MANIFEST
+++ b/tools/perf/MANIFEST
@@ -1,7 +1,7 @@
tools/perf
tools/scripts
tools/lib/traceevent
-tools/lib/lk
+tools/lib/api
tools/lib/symbol/kallsyms.c
tools/lib/symbol/kallsyms.h
tools/include/asm/bug.h

tip-bot for Arnaldo Carvalho de Melo

unread,
Jan 14, 2014, 11:50:02 AM1/14/14
to
Commit-ID: 0050f7aa182e3e8ed34dd6cc4318e52b3df6347a
Gitweb: http://git.kernel.org/tip/0050f7aa182e3e8ed34dd6cc4318e52b3df6347a
Author: Arnaldo Carvalho de Melo <ac...@redhat.com>
AuthorDate: Fri, 10 Jan 2014 10:37:27 -0300
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Mon, 13 Jan 2014 10:06:25 -0300

perf evlist: Introduce evlist__for_each() & friends

For the common evsel list traversal, so that it becomes more compact.

Use the opportunity to start ditching the 'perf_' from 'perf_evlist__',
as discussed, as the whole conversion touches a lot of places, lets do
it piecemeal when we have the chance due to other work, like in this
case.

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-qnkx7dzm2h...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-annotate.c | 2 +-
tools/perf/builtin-diff.c | 7 ++--
tools/perf/builtin-evlist.c | 2 +-
tools/perf/builtin-inject.c | 2 +-
tools/perf/builtin-kvm.c | 2 +-
tools/perf/builtin-record.c | 2 +-
tools/perf/builtin-report.c | 8 ++--
tools/perf/builtin-script.c | 5 +--
tools/perf/builtin-stat.c | 32 ++++++++--------
tools/perf/builtin-top.c | 8 ++--
tools/perf/tests/evsel-roundtrip-name.c | 2 +-
tools/perf/tests/hists_link.c | 4 +-
tools/perf/tests/mmap-basic.c | 2 +-
tools/perf/tests/parse-events.c | 4 +-
tools/perf/ui/browsers/hists.c | 5 ++-
tools/perf/ui/gtk/hists.c | 2 +-
tools/perf/util/cgroup.c | 4 +-
tools/perf/util/evlist.c | 40 ++++++++++----------
tools/perf/util/evlist.h | 65 +++++++++++++++++++++++++++++++++
tools/perf/util/header.c | 19 +++++-----
tools/perf/util/parse-events.c | 5 +--
tools/perf/util/python.c | 3 +-
tools/perf/util/record.c | 6 +--
tools/perf/util/session.c | 6 +--
24 files changed, 151 insertions(+), 86 deletions(-)

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index ab65057..0da603b 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -232,7 +232,7 @@ static int __cmd_annotate(struct perf_annotate *ann)
perf_session__fprintf_dsos(session, stdout);

total_nr_samples = 0;
- list_for_each_entry(pos, &session->evlist->entries, node) {
+ evlist__for_each(session->evlist, pos) {
struct hists *hists = &pos->hists;
u32 nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];

diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index e6a0844..987cac3 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -356,9 +356,10 @@ static struct perf_evsel *evsel_match(struct perf_evsel *evsel,
{
struct perf_evsel *e;

- list_for_each_entry(e, &evlist->entries, node)
+ evlist__for_each(evlist, e) {
if (perf_evsel__match2(evsel, e))
return e;
+ }

return NULL;
}
@@ -367,7 +368,7 @@ static void perf_evlist__collapse_resort(struct perf_evlist *evlist)
{
struct perf_evsel *evsel;

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
struct hists *hists = &evsel->hists;

hists__collapse_resort(hists, NULL);
@@ -614,7 +615,7 @@ static void data_process(void)
struct perf_evsel *evsel_base;
bool first = true;

- list_for_each_entry(evsel_base, &evlist_base->entries, node) {
+ evlist__for_each(evlist_base, evsel_base) {
struct data__file *d;
int i;

diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c
index 20b0f12..c99e0de 100644
--- a/tools/perf/builtin-evlist.c
+++ b/tools/perf/builtin-evlist.c
@@ -29,7 +29,7 @@ static int __cmd_evlist(const char *file_name, struct perf_attr_details *details
if (session == NULL)
return -ENOMEM;

- list_for_each_entry(pos, &session->evlist->entries, node)
+ evlist__for_each(session->evlist, pos)
perf_evsel__fprintf(pos, details, stdout);

perf_session__delete(session);
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index c9f6d74..b346601 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -369,7 +369,7 @@ static int __cmd_inject(struct perf_inject *inject)

inject->tool.ordered_samples = true;

- list_for_each_entry(evsel, &session->evlist->entries, node) {
+ evlist__for_each(session->evlist, evsel) {
const char *name = perf_evsel__name(evsel);

if (!strcmp(name, "sched:sched_switch")) {
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 858b11b..a735051 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -1174,7 +1174,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm)
* Note: exclude_{guest,host} do not apply here.
* This command processes KVM tracepoints from host only
*/
- list_for_each_entry(pos, &evlist->entries, node) {
+ evlist__for_each(evlist, pos) {
struct perf_event_attr *attr = &pos->attr;

/* make sure these *are* set */
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index cb00b53..8860015 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -183,7 +183,7 @@ static int record__open(struct record *rec)

perf_evlist__config(evlist, opts);

- list_for_each_entry(pos, &evlist->entries, node) {
+ evlist__for_each(evlist, pos) {
try_again:
if (perf_evsel__open(pos, evlist->cpus, evlist->threads) < 0) {
if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) {
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index cff9465..46864dd 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -384,7 +384,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
{
struct perf_evsel *pos;

- list_for_each_entry(pos, &evlist->entries, node) {
+ evlist__for_each(evlist, pos) {
struct hists *hists = &pos->hists;
const char *evname = perf_evsel__name(pos);

@@ -495,7 +495,7 @@ static u64 report__collapse_hists(struct report *rep)
* Count number of histogram entries to use when showing progress,
* reusing nr_samples variable.
*/
- list_for_each_entry(pos, &rep->session->evlist->entries, node)
+ evlist__for_each(rep->session->evlist, pos)
nr_samples += pos->hists.nr_entries;

ui_progress__init(&prog, nr_samples, "Merging related events...");
@@ -505,7 +505,7 @@ static u64 report__collapse_hists(struct report *rep)
*/
nr_samples = 0;

- list_for_each_entry(pos, &rep->session->evlist->entries, node) {
+ evlist__for_each(rep->session->evlist, pos) {
struct hists *hists = &pos->hists;

if (pos->idx == 0)
@@ -582,7 +582,7 @@ static int __cmd_report(struct report *rep)
return 0;
}

- list_for_each_entry(pos, &session->evlist->entries, node)
+ evlist__for_each(session->evlist, pos)
hists__output_resort(&pos->hists);

return report__browse_hists(rep);
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 6040000..9e9c91f 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -603,7 +603,7 @@ static int process_attr(struct perf_tool *tool, union perf_event *event,
if (evsel->attr.type >= PERF_TYPE_MAX)
return 0;

- list_for_each_entry(pos, &evlist->entries, node) {
+ evlist__for_each(evlist, pos) {
if (pos->attr.type == evsel->attr.type && pos != evsel)
return 0;
}
@@ -1309,8 +1309,7 @@ static int check_ev_match(char *dir_name, char *scriptname,
snprintf(evname, len + 1, "%s", p);

match = 0;
- list_for_each_entry(pos,
- &session->evlist->entries, node) {
+ evlist__for_each(session->evlist, pos) {
if (!strcmp(perf_evsel__name(pos), evname)) {
match = 1;
break;
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index b27b264..8b0e1c9 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -214,7 +214,7 @@ static void perf_evlist__free_stats(struct perf_evlist *evlist)
{
struct perf_evsel *evsel;

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
perf_evsel__free_stat_priv(evsel);
perf_evsel__free_counts(evsel);
perf_evsel__free_prev_raw_counts(evsel);
@@ -225,7 +225,7 @@ static int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw)
{
struct perf_evsel *evsel;

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
if (perf_evsel__alloc_stat_priv(evsel) < 0 ||
perf_evsel__alloc_counts(evsel, perf_evsel__nr_cpus(evsel)) < 0 ||
(alloc_raw && perf_evsel__alloc_prev_raw_counts(evsel) < 0))
@@ -259,7 +259,7 @@ static void perf_stat__reset_stats(struct perf_evlist *evlist)
{
struct perf_evsel *evsel;

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
perf_evsel__reset_stat_priv(evsel);
perf_evsel__reset_counts(evsel, perf_evsel__nr_cpus(evsel));
}
@@ -326,13 +326,13 @@ static struct perf_evsel *nth_evsel(int n)

/* Assumes this only called when evsel_list does not change anymore. */
if (!array) {
- list_for_each_entry(ev, &evsel_list->entries, node)
+ evlist__for_each(evsel_list, ev)
array_len++;
array = malloc(array_len * sizeof(void *));
if (!array)
exit(ENOMEM);
j = 0;
- list_for_each_entry(ev, &evsel_list->entries, node)
+ evlist__for_each(evsel_list, ev)
array[j++] = ev;
}
if (n < array_len)
@@ -440,13 +440,13 @@ static void print_interval(void)
char prefix[64];

if (aggr_mode == AGGR_GLOBAL) {
- list_for_each_entry(counter, &evsel_list->entries, node) {
+ evlist__for_each(evsel_list, counter) {
ps = counter->priv;
memset(ps->res_stats, 0, sizeof(ps->res_stats));
read_counter_aggr(counter);
}
} else {
- list_for_each_entry(counter, &evsel_list->entries, node) {
+ evlist__for_each(evsel_list, counter) {
ps = counter->priv;
memset(ps->res_stats, 0, sizeof(ps->res_stats));
read_counter(counter);
@@ -483,12 +483,12 @@ static void print_interval(void)
print_aggr(prefix);
break;
case AGGR_NONE:
- list_for_each_entry(counter, &evsel_list->entries, node)
+ evlist__for_each(evsel_list, counter)
print_counter(counter, prefix);
break;
case AGGR_GLOBAL:
default:
- list_for_each_entry(counter, &evsel_list->entries, node)
+ evlist__for_each(evsel_list, counter)
print_counter_aggr(counter, prefix);
}

@@ -504,7 +504,7 @@ static void handle_initial_delay(void)
nthreads = thread_map__nr(evsel_list->threads);

usleep(initial_delay * 1000);
- list_for_each_entry(counter, &evsel_list->entries, node)
+ evlist__for_each(evsel_list, counter)
perf_evsel__enable(counter, ncpus, nthreads);
}
}
@@ -552,7 +552,7 @@ static int __run_perf_stat(int argc, const char **argv)
if (group)
perf_evlist__set_leader(evsel_list);

- list_for_each_entry(counter, &evsel_list->entries, node) {
+ evlist__for_each(evsel_list, counter) {
if (create_perf_stat_counter(counter) < 0) {
/*
* PPC returns ENXIO for HW counters until 2.6.37
@@ -630,13 +630,13 @@ static int __run_perf_stat(int argc, const char **argv)
update_stats(&walltime_nsecs_stats, t1 - t0);

if (aggr_mode == AGGR_GLOBAL) {
- list_for_each_entry(counter, &evsel_list->entries, node) {
+ evlist__for_each(evsel_list, counter) {
read_counter_aggr(counter);
perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter),
thread_map__nr(evsel_list->threads));
}
} else {
- list_for_each_entry(counter, &evsel_list->entries, node) {
+ evlist__for_each(evsel_list, counter) {
read_counter(counter);
perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter), 1);
}
@@ -1117,7 +1117,7 @@ static void print_aggr(char *prefix)

for (s = 0; s < aggr_map->nr; s++) {
id = aggr_map->map[s];
- list_for_each_entry(counter, &evsel_list->entries, node) {
+ evlist__for_each(evsel_list, counter) {
val = ena = run = 0;
nr = 0;
for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
@@ -1328,11 +1328,11 @@ static void print_stat(int argc, const char **argv)
print_aggr(NULL);
break;
case AGGR_GLOBAL:
- list_for_each_entry(counter, &evsel_list->entries, node)
+ evlist__for_each(evsel_list, counter)
print_counter_aggr(counter, NULL);
break;
case AGGR_NONE:
- list_for_each_entry(counter, &evsel_list->entries, node)
+ evlist__for_each(evsel_list, counter)
print_counter(counter, NULL);
break;
default:
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index e0fd0aa..569dd87 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -482,7 +482,7 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c)

fprintf(stderr, "\nAvailable events:");

- list_for_each_entry(top->sym_evsel, &top->evlist->entries, node)
+ evlist__for_each(top->evlist, top->sym_evsel)
fprintf(stderr, "\n\t%d %s", top->sym_evsel->idx, perf_evsel__name(top->sym_evsel));

prompt_integer(&counter, "Enter details event counter");
@@ -493,7 +493,7 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c)
sleep(1);
break;
}
- list_for_each_entry(top->sym_evsel, &top->evlist->entries, node)
+ evlist__for_each(top->evlist, top->sym_evsel)
if (top->sym_evsel->idx == counter)
break;
} else
@@ -575,7 +575,7 @@ static void *display_thread_tui(void *arg)
* Zooming in/out UIDs. For now juse use whatever the user passed
* via --uid.
*/
- list_for_each_entry(pos, &top->evlist->entries, node)
+ evlist__for_each(top->evlist, pos)
pos->hists.uid_filter_str = top->record_opts.target.uid_str;

perf_evlist__tui_browse_hists(top->evlist, help, &hbt, top->min_percent,
@@ -858,7 +858,7 @@ static int perf_top__start_counters(struct perf_top *top)

perf_evlist__config(evlist, opts);

- list_for_each_entry(counter, &evlist->entries, node) {
+ evlist__for_each(evlist, counter) {
try_again:
if (perf_evsel__open(counter, top->evlist->cpus,
top->evlist->threads) < 0) {
diff --git a/tools/perf/tests/evsel-roundtrip-name.c b/tools/perf/tests/evsel-roundtrip-name.c
index 0197bda..465cdbc 100644
--- a/tools/perf/tests/evsel-roundtrip-name.c
+++ b/tools/perf/tests/evsel-roundtrip-name.c
@@ -79,7 +79,7 @@ static int __perf_evsel__name_array_test(const char *names[], int nr_names)
}

err = 0;
- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
if (strcmp(perf_evsel__name(evsel), names[evsel->idx])) {
--err;
pr_debug("%s != %s\n", perf_evsel__name(evsel), names[evsel->idx]);
diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c
index 173bf42..2b6519e 100644
--- a/tools/perf/tests/hists_link.c
+++ b/tools/perf/tests/hists_link.c
@@ -208,7 +208,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
* However the second evsel also has a collapsed entry for
* "bash [libc] malloc" so total 9 entries will be in the tree.
*/
- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
for (k = 0; k < ARRAY_SIZE(fake_common_samples); k++) {
const union perf_event event = {
.header = {
@@ -466,7 +466,7 @@ int test__hists_link(void)
if (err < 0)
goto out;

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
hists__collapse_resort(&evsel->hists, NULL);

if (verbose > 2)
diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c
index aef25f0..1422634 100644
--- a/tools/perf/tests/mmap-basic.c
+++ b/tools/perf/tests/mmap-basic.c
@@ -126,7 +126,7 @@ int test__basic_mmap(void)
}

err = 0;
- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) {
pr_debug("expected %d %s events, got %d\n",
expected_nr_events[evsel->idx],
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
index 41dee5e..4db0ae6 100644
--- a/tools/perf/tests/parse-events.c
+++ b/tools/perf/tests/parse-events.c
@@ -30,7 +30,7 @@ static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist)
TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1);
TEST_ASSERT_VAL("wrong number of groups", 0 == evlist->nr_groups);

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
TEST_ASSERT_VAL("wrong type",
PERF_TYPE_TRACEPOINT == evsel->attr.type);
TEST_ASSERT_VAL("wrong sample_type",
@@ -201,7 +201,7 @@ test__checkevent_tracepoint_multi_modifier(struct perf_evlist *evlist)

TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1);

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
TEST_ASSERT_VAL("wrong exclude_user",
!evsel->attr.exclude_user);
TEST_ASSERT_VAL("wrong exclude_kernel",
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index a7045ea..b720b92 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -1938,7 +1938,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,

ui_helpline__push("Press ESC to exit");

- list_for_each_entry(pos, &evlist->entries, node) {
+ evlist__for_each(evlist, pos) {
const char *ev_name = perf_evsel__name(pos);
size_t line_len = strlen(ev_name) + 7;

@@ -1970,9 +1970,10 @@ single_entry:
struct perf_evsel *pos;

nr_entries = 0;
- list_for_each_entry(pos, &evlist->entries, node)
+ evlist__for_each(evlist, pos) {
if (perf_evsel__is_group_leader(pos))
nr_entries++;
+ }

if (nr_entries == 1)
goto single_entry;
diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c
index 2ca66cc..5b95c44 100644
--- a/tools/perf/ui/gtk/hists.c
+++ b/tools/perf/ui/gtk/hists.c
@@ -375,7 +375,7 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist,

gtk_container_add(GTK_CONTAINER(window), vbox);

- list_for_each_entry(pos, &evlist->entries, node) {
+ evlist__for_each(evlist, pos) {
struct hists *hists = &pos->hists;
const char *evname = perf_evsel__name(pos);
GtkWidget *scrolled_window;
diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c
index 0922aa4..88f7be3 100644
--- a/tools/perf/util/cgroup.c
+++ b/tools/perf/util/cgroup.c
@@ -81,7 +81,7 @@ static int add_cgroup(struct perf_evlist *evlist, char *str)
/*
* check if cgrp is already defined, if so we reuse it
*/
- list_for_each_entry(counter, &evlist->entries, node) {
+ evlist__for_each(evlist, counter) {
cgrp = counter->cgrp;
if (!cgrp)
continue;
@@ -110,7 +110,7 @@ static int add_cgroup(struct perf_evlist *evlist, char *str)
* if add cgroup N, then need to find event N
*/
n = 0;
- list_for_each_entry(counter, &evlist->entries, node) {
+ evlist__for_each(evlist, counter) {
if (n == nr_cgroups)
goto found;
n++;
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 0810f5c..40bd2c0 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -81,7 +81,7 @@ static void perf_evlist__update_id_pos(struct perf_evlist *evlist)
{
struct perf_evsel *evsel;

- list_for_each_entry(evsel, &evlist->entries, node)
+ evlist__for_each(evlist, evsel)
perf_evsel__calc_id_pos(evsel);

perf_evlist__set_id_pos(evlist);
@@ -91,7 +91,7 @@ static void perf_evlist__purge(struct perf_evlist *evlist)
{
struct perf_evsel *pos, *n;

- list_for_each_entry_safe(pos, n, &evlist->entries, node) {
+ evlist__for_each_safe(evlist, n, pos) {
list_del_init(&pos->node);
perf_evsel__delete(pos);
}
@@ -148,7 +148,7 @@ void __perf_evlist__set_leader(struct list_head *list)

leader->nr_members = evsel->idx - leader->idx + 1;

- list_for_each_entry(evsel, list, node) {
+ __evlist__for_each(list, evsel) {
evsel->leader = leader;
}
}
@@ -207,7 +207,7 @@ static int perf_evlist__add_attrs(struct perf_evlist *evlist,
return 0;

out_delete_partial_list:
- list_for_each_entry_safe(evsel, n, &head, node)
+ __evlist__for_each_safe(&head, n, evsel)
perf_evsel__delete(evsel);
return -1;
}
@@ -228,7 +228,7 @@ perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id)
{
struct perf_evsel *evsel;

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
if (evsel->attr.type == PERF_TYPE_TRACEPOINT &&
(int)evsel->attr.config == id)
return evsel;
@@ -243,7 +243,7 @@ perf_evlist__find_tracepoint_by_name(struct perf_evlist *evlist,
{
struct perf_evsel *evsel;

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
if ((evsel->attr.type == PERF_TYPE_TRACEPOINT) &&
(strcmp(evsel->name, name) == 0))
return evsel;
@@ -273,7 +273,7 @@ void perf_evlist__disable(struct perf_evlist *evlist)
int nr_threads = thread_map__nr(evlist->threads);

for (cpu = 0; cpu < nr_cpus; cpu++) {
- list_for_each_entry(pos, &evlist->entries, node) {
+ evlist__for_each(evlist, pos) {
if (!perf_evsel__is_group_leader(pos) || !pos->fd)
continue;
for (thread = 0; thread < nr_threads; thread++)
@@ -291,7 +291,7 @@ void perf_evlist__enable(struct perf_evlist *evlist)
int nr_threads = thread_map__nr(evlist->threads);

for (cpu = 0; cpu < nr_cpus; cpu++) {
- list_for_each_entry(pos, &evlist->entries, node) {
+ evlist__for_each(evlist, pos) {
if (!perf_evsel__is_group_leader(pos) || !pos->fd)
continue;
for (thread = 0; thread < nr_threads; thread++)
@@ -630,7 +630,7 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
{
struct perf_evsel *evsel;

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
int fd = FD(evsel, cpu, thread);

if (*output == -1) {
@@ -806,7 +806,7 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
pr_debug("mmap size %zuB\n", evlist->mmap_len);
mask = evlist->mmap_len - page_size - 1;

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
evsel->sample_id == NULL &&
perf_evsel__alloc_id(evsel, cpu_map__nr(cpus), threads->nr) < 0)
@@ -849,7 +849,7 @@ int perf_evlist__apply_filters(struct perf_evlist *evlist)
const int ncpus = cpu_map__nr(evlist->cpus),
nthreads = thread_map__nr(evlist->threads);

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
if (evsel->filter == NULL)
continue;

@@ -868,7 +868,7 @@ int perf_evlist__set_filter(struct perf_evlist *evlist, const char *filter)
const int ncpus = cpu_map__nr(evlist->cpus),
nthreads = thread_map__nr(evlist->threads);

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
err = perf_evsel__set_filter(evsel, ncpus, nthreads, filter);
if (err)
break;
@@ -887,7 +887,7 @@ bool perf_evlist__valid_sample_type(struct perf_evlist *evlist)
if (evlist->id_pos < 0 || evlist->is_pos < 0)
return false;

- list_for_each_entry(pos, &evlist->entries, node) {
+ evlist__for_each(evlist, pos) {
if (pos->id_pos != evlist->id_pos ||
pos->is_pos != evlist->is_pos)
return false;
@@ -903,7 +903,7 @@ u64 __perf_evlist__combined_sample_type(struct perf_evlist *evlist)
if (evlist->combined_sample_type)
return evlist->combined_sample_type;

- list_for_each_entry(evsel, &evlist->entries, node)
+ evlist__for_each(evlist, evsel)
evlist->combined_sample_type |= evsel->attr.sample_type;

return evlist->combined_sample_type;
@@ -921,7 +921,7 @@ bool perf_evlist__valid_read_format(struct perf_evlist *evlist)
u64 read_format = first->attr.read_format;
u64 sample_type = first->attr.sample_type;

- list_for_each_entry_continue(pos, &evlist->entries, node) {
+ evlist__for_each(evlist, pos) {
if (read_format != pos->attr.read_format)
return false;
}
@@ -978,7 +978,7 @@ bool perf_evlist__valid_sample_id_all(struct perf_evlist *evlist)
{
struct perf_evsel *first = perf_evlist__first(evlist), *pos = first;

- list_for_each_entry_continue(pos, &evlist->entries, node) {
+ evlist__for_each_continue(evlist, pos) {
if (first->attr.sample_id_all != pos->attr.sample_id_all)
return false;
}
@@ -1004,7 +1004,7 @@ void perf_evlist__close(struct perf_evlist *evlist)
int ncpus = cpu_map__nr(evlist->cpus);
int nthreads = thread_map__nr(evlist->threads);

- list_for_each_entry_reverse(evsel, &evlist->entries, node)
+ evlist__for_each_reverse(evlist, evsel)
perf_evsel__close(evsel, ncpus, nthreads);
}

@@ -1015,7 +1015,7 @@ int perf_evlist__open(struct perf_evlist *evlist)

perf_evlist__update_id_pos(evlist);

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
err = perf_evsel__open(evsel, evlist->cpus, evlist->threads);
if (err < 0)
goto out_err;
@@ -1154,7 +1154,7 @@ size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp)
struct perf_evsel *evsel;
size_t printed = 0;

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
printed += fprintf(fp, "%s%s", evsel->idx ? ", " : "",
perf_evsel__name(evsel));
}
@@ -1233,7 +1233,7 @@ void perf_evlist__to_front(struct perf_evlist *evlist,
if (move_evsel == perf_evlist__first(evlist))
return;

- list_for_each_entry_safe(evsel, n, &evlist->entries, node) {
+ evlist__for_each_safe(evlist, n, evsel) {
if (evsel->leader == move_evsel->leader)
list_move_tail(&evsel->node, &move);
}
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 518e521..f5173cd 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -196,5 +196,70 @@ bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str);
void perf_evlist__to_front(struct perf_evlist *evlist,
struct perf_evsel *move_evsel);

+/**
+ * __evlist__for_each - iterate thru all the evsels
+ * @list: list_head instance to iterate
+ * @evsel: struct evsel iterator
+ */
+#define __evlist__for_each(list, evsel) \
+ list_for_each_entry(evsel, list, node)
+
+/**
+ * evlist__for_each - iterate thru all the evsels
+ * @evlist: evlist instance to iterate
+ * @evsel: struct evsel iterator
+ */
+#define evlist__for_each(evlist, evsel) \
+ __evlist__for_each(&(evlist)->entries, evsel)
+
+/**
+ * __evlist__for_each_continue - continue iteration thru all the evsels
+ * @list: list_head instance to iterate
+ * @evsel: struct evsel iterator
+ */
+#define __evlist__for_each_continue(list, evsel) \
+ list_for_each_entry_continue(evsel, list, node)
+
+/**
+ * evlist__for_each_continue - continue iteration thru all the evsels
+ * @evlist: evlist instance to iterate
+ * @evsel: struct evsel iterator
+ */
+#define evlist__for_each_continue(evlist, evsel) \
+ __evlist__for_each_continue(&(evlist)->entries, evsel)
+
+/**
+ * __evlist__for_each_reverse - iterate thru all the evsels in reverse order
+ * @list: list_head instance to iterate
+ * @evsel: struct evsel iterator
+ */
+#define __evlist__for_each_reverse(list, evsel) \
+ list_for_each_entry_reverse(evsel, list, node)
+
+/**
+ * evlist__for_each_reverse - iterate thru all the evsels in reverse order
+ * @evlist: evlist instance to iterate
+ * @evsel: struct evsel iterator
+ */
+#define evlist__for_each_reverse(evlist, evsel) \
+ __evlist__for_each_reverse(&(evlist)->entries, evsel)
+
+/**
+ * __evlist__for_each_safe - safely iterate thru all the evsels
+ * @list: list_head instance to iterate
+ * @tmp: struct evsel temp iterator
+ * @evsel: struct evsel iterator
+ */
+#define __evlist__for_each_safe(list, tmp, evsel) \
+ list_for_each_entry_safe(evsel, tmp, list, node)
+
+/**
+ * evlist__for_each_safe - safely iterate thru all the evsels
+ * @evlist: evlist instance to iterate
+ * @evsel: struct evsel iterator
+ * @tmp: struct evsel temp iterator
+ */
+#define evlist__for_each_safe(evlist, tmp, evsel) \
+ __evlist__for_each_safe(&(evlist)->entries, tmp, evsel)

#endif /* __PERF_EVLIST_H */
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index a4a60b7..bb3e0ed 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -643,8 +643,7 @@ static int write_event_desc(int fd, struct perf_header *h __maybe_unused,
if (ret < 0)
return ret;

- list_for_each_entry(evsel, &evlist->entries, node) {
-
+ evlist__for_each(evlist, evsel) {
ret = do_write(fd, &evsel->attr, sz);
if (ret < 0)
return ret;
@@ -1092,7 +1091,7 @@ static int write_group_desc(int fd, struct perf_header *h __maybe_unused,
if (ret < 0)
return ret;

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
if (perf_evsel__is_group_leader(evsel) &&
evsel->nr_members > 1) {
const char *name = evsel->group_name ?: "{anon_group}";
@@ -1487,7 +1486,7 @@ static void print_group_desc(struct perf_header *ph, int fd __maybe_unused,

session = container_of(ph, struct perf_session, header);

- list_for_each_entry(evsel, &session->evlist->entries, node) {
+ evlist__for_each(session->evlist, evsel) {
if (perf_evsel__is_group_leader(evsel) &&
evsel->nr_members > 1) {
fprintf(fp, "# group: %s{%s", evsel->group_name ?: "",
@@ -1768,7 +1767,7 @@ perf_evlist__find_by_index(struct perf_evlist *evlist, int idx)
{
struct perf_evsel *evsel;

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
if (evsel->idx == idx)
return evsel;
}
@@ -2071,7 +2070,7 @@ static int process_group_desc(struct perf_file_section *section __maybe_unused,
session->evlist->nr_groups = nr_groups;

i = nr = 0;
- list_for_each_entry(evsel, &session->evlist->entries, node) {
+ evlist__for_each(session->evlist, evsel) {
if (evsel->idx == (int) desc[i].leader_idx) {
evsel->leader = evsel;
/* {anon_group} is a dummy name */
@@ -2298,7 +2297,7 @@ int perf_session__write_header(struct perf_session *session,

lseek(fd, sizeof(f_header), SEEK_SET);

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(session->evlist, evsel) {
evsel->id_offset = lseek(fd, 0, SEEK_CUR);
err = do_write(fd, evsel->id, evsel->ids * sizeof(u64));
if (err < 0) {
@@ -2309,7 +2308,7 @@ int perf_session__write_header(struct perf_session *session,

attr_offset = lseek(fd, 0, SEEK_CUR);

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
f_attr = (struct perf_file_attr){
.attr = evsel->attr,
.ids = {
@@ -2742,7 +2741,7 @@ static int perf_evlist__prepare_tracepoint_events(struct perf_evlist *evlist,
{
struct perf_evsel *pos;

- list_for_each_entry(pos, &evlist->entries, node) {
+ evlist__for_each(evlist, pos) {
if (pos->attr.type == PERF_TYPE_TRACEPOINT &&
perf_evsel__prepare_tracepoint_event(pos, pevent))
return -1;
@@ -2890,7 +2889,7 @@ int perf_event__synthesize_attrs(struct perf_tool *tool,
struct perf_evsel *evsel;
int err = 0;

- list_for_each_entry(evsel, &session->evlist->entries, node) {
+ evlist__for_each(session->evlist, evsel) {
err = perf_event__synthesize_attr(tool, &evsel->attr, evsel->ids,
evsel->id, process);
if (err) {
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 0153435..a7f1b6a 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -820,8 +820,7 @@ int parse_events__modifier_event(struct list_head *list, char *str, bool add)
if (!add && get_event_modifier(&mod, str, NULL))
return -EINVAL;

- list_for_each_entry(evsel, list, node) {
-
+ __evlist__for_each(list, evsel) {
if (add && get_event_modifier(&mod, str, evsel))
return -EINVAL;

@@ -845,7 +844,7 @@ int parse_events_name(struct list_head *list, char *name)
{
struct perf_evsel *evsel;

- list_for_each_entry(evsel, list, node) {
+ __evlist__for_each(list, evsel) {
if (!evsel->name)
evsel->name = strdup(name);
}
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index 4bf8ace..122669c 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -908,9 +908,10 @@ static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i)
if (i >= pevlist->evlist.nr_entries)
return NULL;

- list_for_each_entry(pos, &pevlist->evlist.entries, node)
+ evlist__for_each(&pevlist->evlist, pos) {
if (i-- == 0)
break;
+ }

return Py_BuildValue("O", container_of(pos, struct pyrf_evsel, evsel));
}
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
index 104a475..3737625 100644
--- a/tools/perf/util/record.c
+++ b/tools/perf/util/record.c
@@ -89,19 +89,19 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts)
if (evlist->cpus->map[0] < 0)
opts->no_inherit = true;

- list_for_each_entry(evsel, &evlist->entries, node)
+ evlist__for_each(evlist, evsel)
perf_evsel__config(evsel, opts);

if (evlist->nr_entries > 1) {
struct perf_evsel *first = perf_evlist__first(evlist);

- list_for_each_entry(evsel, &evlist->entries, node) {
+ evlist__for_each(evlist, evsel) {
if (evsel->attr.sample_type == first->attr.sample_type)
continue;
use_sample_identifier = perf_can_sample_identifier();
break;
}
- list_for_each_entry(evsel, &evlist->entries, node)
+ evlist__for_each(evlist, evsel)
perf_evsel__set_sample_id(evsel, use_sample_identifier);
}

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 8ffe29c..7acc03e 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1384,7 +1384,7 @@ bool perf_session__has_traces(struct perf_session *session, const char *msg)
{
struct perf_evsel *evsel;

- list_for_each_entry(evsel, &session->evlist->entries, node) {
+ evlist__for_each(session->evlist, evsel) {
if (evsel->attr.type == PERF_TYPE_TRACEPOINT)
return true;
}
@@ -1442,7 +1442,7 @@ size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp)

ret += events_stats__fprintf(&session->stats, fp);

- list_for_each_entry(pos, &session->evlist->entries, node) {
+ evlist__for_each(session->evlist, pos) {
ret += fprintf(fp, "%s stats:\n", perf_evsel__name(pos));
ret += events_stats__fprintf(&pos->hists.stats, fp);
}
@@ -1464,7 +1464,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
{
struct perf_evsel *pos;

- list_for_each_entry(pos, &session->evlist->entries, node) {
+ evlist__for_each(session->evlist, pos) {
if (pos->attr.type == type)
return pos;

tip-bot for Arnaldo Carvalho de Melo

unread,
Jan 14, 2014, 11:50:03 AM1/14/14
to
Commit-ID: fad2918ed5171e6299a9b4b885d0459f35ee7377
Gitweb: http://git.kernel.org/tip/fad2918ed5171e6299a9b4b885d0459f35ee7377
Author: Arnaldo Carvalho de Melo <ac...@redhat.com>
AuthorDate: Wed, 8 Jan 2014 10:10:00 -0300
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Mon, 13 Jan 2014 10:06:25 -0300

perf report: Move logic to warn about kptr_restrict'ed kernels to separate function

Its too big, better have a separate function for it so that the main
logic gets shorter/clearer.

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-ahh6vfzyh8...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-report.c | 56 ++++++++++++++++++++++++---------------------
1 file changed, 30 insertions(+), 26 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index bf8dd2e..f2ff860 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
static int __cmd_report(struct report *rep)
{
int ret = -EINVAL;
u64 nr_samples;
struct perf_session *session = rep->session;
struct perf_evsel *pos;
- struct map *kernel_map;
- struct kmap *kernel_kmap;
const char *help = "For a higher level overview, try: perf report --sort comm,dso";
struct ui_progress prog;
struct perf_data_file *file = session->file;

tip-bot for Arnaldo Carvalho de Melo

unread,
Jan 14, 2014, 11:50:03 AM1/14/14
to
Commit-ID: f6d8b0571c9ac8f273d18c112c2fc3c9533c9f0a
Gitweb: http://git.kernel.org/tip/f6d8b0571c9ac8f273d18c112c2fc3c9533c9f0a
Author: Arnaldo Carvalho de Melo <ac...@redhat.com>
AuthorDate: Wed, 8 Jan 2014 14:45:24 -0300
Committer: Arnaldo Carvalho de Melo <ac...@redhat.com>
CommitDate: Mon, 13 Jan 2014 10:06:25 -0300

perf report: Move histogram entries collapsing to separate function

Further uncluttering the main 'report' function by group related code in
separate function.

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-b594zsbwke...@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <ac...@redhat.com>
---
tools/perf/builtin-report.c | 73 ++++++++++++++++++++++++++++-----------------
1 file changed, 45 insertions(+), 28 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 03941ad..cff9465 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -486,13 +486,55 @@ static int report__browse_hists(struct report *rep)
return ret;
}

+static u64 report__collapse_hists(struct report *rep)
+{
+ struct ui_progress prog;
+ struct perf_evsel *pos;
+ u64 nr_samples = 0;
+ /*
+ * Count number of histogram entries to use when showing progress,
+ * reusing nr_samples variable.
+ */
+ list_for_each_entry(pos, &rep->session->evlist->entries, node)
+ nr_samples += pos->hists.nr_entries;
+
+ ui_progress__init(&prog, nr_samples, "Merging related events...");
+ /*
+ * Count total number of samples, will be used to check if this
+ * session had any.
+ */
+ nr_samples = 0;
+
+ list_for_each_entry(pos, &rep->session->evlist->entries, node) {
+ struct hists *hists = &pos->hists;
+
+ if (pos->idx == 0)
+ hists->symbol_filter_str = rep->symbol_filter_str;
+
+ hists__collapse_resort(hists, &prog);
+ nr_samples += hists->stats.nr_events[PERF_RECORD_SAMPLE];
+
+ /* Non-group events are considered as leader */
+ if (symbol_conf.event_group &&
+ !perf_evsel__is_group_leader(pos)) {
+ struct hists *leader_hists = &pos->leader->hists;
+
+ hists__match(leader_hists, hists);
+ hists__link(leader_hists, hists);
+ }
+ }
+
+ ui_progress__finish();
+
+ return nr_samples;
+}
+
static int __cmd_report(struct report *rep)
{
- int ret = -EINVAL;
+ int ret;
u64 nr_samples;
struct perf_session *session = rep->session;
struct perf_evsel *pos;
- struct ui_progress prog;
struct perf_data_file *file = session->file;

signal(SIGINT, sig_handler);
@@ -530,32 +572,7 @@ static int __cmd_report(struct report *rep)
}
}

- nr_samples = 0;
- list_for_each_entry(pos, &session->evlist->entries, node)
- nr_samples += pos->hists.nr_entries;
-
- ui_progress__init(&prog, nr_samples, "Merging related events...");
-
- nr_samples = 0;
- list_for_each_entry(pos, &session->evlist->entries, node) {
- struct hists *hists = &pos->hists;
-
- if (pos->idx == 0)
- hists->symbol_filter_str = rep->symbol_filter_str;
-
- hists__collapse_resort(hists, &prog);
- nr_samples += hists->stats.nr_events[PERF_RECORD_SAMPLE];
-
- /* Non-group events are considered as leader */
- if (symbol_conf.event_group &&
- !perf_evsel__is_group_leader(pos)) {
- struct hists *leader_hists = &pos->leader->hists;
-
- hists__match(leader_hists, hists);
- hists__link(leader_hists, hists);
- }
- }
- ui_progress__finish();
+ nr_samples = report__collapse_hists(rep);

if (session_done())
return 0;
It is loading more messages.
0 new messages