Skip to content

Commit

Permalink
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/acme/linux into perf/core

Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:

 * Improve warning message when libunwind devel packages not present, from Jiri Olsa

 * Remove perf_event_attr needless version inflation, from Jiri Olsa

 * Introduce libtraceevent strerror like error reporting facility, from Namhyung Kim

 * Add pmu mappings to perf.data header and use event names from cmd line, from Robert Richter

Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
  • Loading branch information
Ingo Molnar committed Aug 24, 2012
2 parents d57c5d5 + f63fe79 commit 734e9a2
Show file tree
Hide file tree
Showing 14 changed files with 487 additions and 101 deletions.
4 changes: 2 additions & 2 deletions include/linux/perf_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,8 @@ enum perf_event_read_format {
#define PERF_ATTR_SIZE_VER0 64 /* sizeof first published struct */
#define PERF_ATTR_SIZE_VER1 72 /* add: config2 */
#define PERF_ATTR_SIZE_VER2 80 /* add: branch_sample_type */
#define PERF_ATTR_SIZE_VER3 88 /* add: sample_regs_user */
#define PERF_ATTR_SIZE_VER4 96 /* add: sample_stack_user */
#define PERF_ATTR_SIZE_VER3 96 /* add: sample_regs_user */
/* add: sample_stack_user */

/*
* Hardware event_id to monitor via a performance monitoring event:
Expand Down
104 changes: 81 additions & 23 deletions tools/lib/traceevent/event-parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -4686,9 +4686,8 @@ static int find_event_handle(struct pevent *pevent, struct event_format *event)
*
* /sys/kernel/debug/tracing/events/.../.../format
*/
int pevent_parse_event(struct pevent *pevent,
const char *buf, unsigned long size,
const char *sys)
enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf,
unsigned long size, const char *sys)
{
struct event_format *event;
int ret;
Expand All @@ -4697,38 +4696,45 @@ int pevent_parse_event(struct pevent *pevent,

event = alloc_event();
if (!event)
return -ENOMEM;
return PEVENT_ERRNO__MEM_ALLOC_FAILED;

event->name = event_read_name();
if (!event->name) {
/* Bad event? */
free(event);
return -1;
ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
goto event_alloc_failed;
}

if (strcmp(sys, "ftrace") == 0) {

event->flags |= EVENT_FL_ISFTRACE;

if (strcmp(event->name, "bprint") == 0)
event->flags |= EVENT_FL_ISBPRINT;
}

event->id = event_read_id();
if (event->id < 0)
die("failed to read event id");
if (event->id < 0) {
ret = PEVENT_ERRNO__READ_ID_FAILED;
/*
* This isn't an allocation error actually.
* But as the ID is critical, just bail out.
*/
goto event_alloc_failed;
}

event->system = strdup(sys);
if (!event->system)
die("failed to allocate system");
if (!event->system) {
ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
goto event_alloc_failed;
}

/* Add pevent to event so that it can be referenced */
event->pevent = pevent;

ret = event_read_format(event);
if (ret < 0) {
do_warning("failed to read event format for %s", event->name);
goto event_failed;
ret = PEVENT_ERRNO__READ_FORMAT_FAILED;
goto event_parse_failed;
}

/*
Expand All @@ -4740,10 +4746,9 @@ int pevent_parse_event(struct pevent *pevent,

ret = event_read_print(event);
if (ret < 0) {
do_warning("failed to read event print fmt for %s",
event->name);
show_warning = 1;
goto event_failed;
ret = PEVENT_ERRNO__READ_PRINT_FAILED;
goto event_parse_failed;
}
show_warning = 1;

Expand All @@ -4754,20 +4759,19 @@ int pevent_parse_event(struct pevent *pevent,
struct print_arg *arg, **list;

/* old ftrace had no args */

list = &event->print_fmt.args;
for (field = event->format.fields; field; field = field->next) {
arg = alloc_arg();
*list = arg;
list = &arg->next;
arg->type = PRINT_FIELD;
arg->field.name = strdup(field->name);
if (!arg->field.name) {
do_warning("failed to allocate field name");
event->flags |= EVENT_FL_FAILED;
return -1;
free_arg(arg);
return PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED;
}
arg->field.field = field;
*list = arg;
list = &arg->next;
}
return 0;
}
Expand All @@ -4778,11 +4782,65 @@ int pevent_parse_event(struct pevent *pevent,

return 0;

event_failed:
event_parse_failed:
event->flags |= EVENT_FL_FAILED;
/* still add it even if it failed */
add_event(pevent, event);
return -1;
return ret;

event_alloc_failed:
free(event->system);
free(event->name);
free(event);
return ret;
}

#undef _PE
#define _PE(code, str) str
static const char * const pevent_error_str[] = {
PEVENT_ERRORS
};
#undef _PE

int pevent_strerror(struct pevent *pevent, enum pevent_errno errnum,
char *buf, size_t buflen)
{
int idx;
const char *msg;

if (errnum >= 0) {
msg = strerror_r(errnum, buf, buflen);
if (msg != buf) {
size_t len = strlen(msg);
char *c = mempcpy(buf, msg, min(buflen-1, len));
*c = '\0';
}
return 0;
}

if (errnum <= __PEVENT_ERRNO__START ||
errnum >= __PEVENT_ERRNO__END)
return -1;

idx = errnum - __PEVENT_ERRNO__START - 1;
msg = pevent_error_str[idx];

switch (errnum) {
case PEVENT_ERRNO__MEM_ALLOC_FAILED:
case PEVENT_ERRNO__PARSE_EVENT_FAILED:
case PEVENT_ERRNO__READ_ID_FAILED:
case PEVENT_ERRNO__READ_FORMAT_FAILED:
case PEVENT_ERRNO__READ_PRINT_FAILED:
case PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED:
snprintf(buf, buflen, "%s", msg);
break;

default:
/* cannot reach here */
break;
}

return 0;
}

int get_field_val(struct trace_seq *s, struct format_field *field,
Expand Down
34 changes: 32 additions & 2 deletions tools/lib/traceevent/event-parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,34 @@ enum pevent_flag {
PEVENT_NSEC_OUTPUT = 1, /* output in NSECS */
};

#define PEVENT_ERRORS \
_PE(MEM_ALLOC_FAILED, "failed to allocate memory"), \
_PE(PARSE_EVENT_FAILED, "failed to parse event"), \
_PE(READ_ID_FAILED, "failed to read event id"), \
_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")

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

/*
* Choose an arbitrary negative big number not to clash with standard
* errno since SUS requires the errno has distinct positive values.
* See 'Issue 6' in the link below.
*
* http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html
*/
__PEVENT_ERRNO__START = -100000,

PEVENT_ERRORS,

__PEVENT_ERRNO__END,
};
#undef _PE

struct cmdline;
struct cmdline_list;
struct func_map;
Expand Down Expand Up @@ -509,8 +537,8 @@ void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size,
int long_size);

int pevent_parse_event(struct pevent *pevent, const char *buf,
unsigned long size, const char *sys);
enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf,
unsigned long size, const char *sys);

void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event,
const char *name, struct pevent_record *record,
Expand Down Expand Up @@ -561,6 +589,8 @@ int pevent_data_pid(struct pevent *pevent, struct pevent_record *rec);
const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid);
void pevent_event_info(struct trace_seq *s, struct event_format *event,
struct pevent_record *record);
int pevent_strerror(struct pevent *pevent, enum pevent_errno errnum,
char *buf, size_t buflen);

struct event_format **pevent_list_events(struct pevent *pevent, enum event_sort_type);
struct format_field **pevent_event_common_fields(struct event_format *event);
Expand Down
6 changes: 6 additions & 0 deletions tools/lib/traceevent/event-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ void __vdie(const char *fmt, ...);
void __vwarning(const char *fmt, ...);
void __vpr_stat(const char *fmt, ...);

#define min(x, y) ({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })

static inline char *strim(char *string)
{
char *ret;
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ endif

FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(ALL_CFLAGS) $(LIBUNWIND_LDFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS)
ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND)),y)
msg := $(warning No libunwind found. Please install libunwind >= 0.99);
msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99);
NO_LIBUNWIND := 1
endif # Libunwind support
endif # NO_LIBUNWIND
Expand Down
Loading

0 comments on commit 734e9a2

Please sign in to comment.