Skip to content

Commit

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

Pull perf fixes from Arnaldo Carvalho de Melo:

 * Endianness fixes from Jiri Olsa

 * Fixes for make perf tarball

 * Fix for DSO name in perf script callchains, from David Ahern

 * Segfault fixes for perf top --callchain, from Namhyung Kim

 * Minor function result fixes from Srikar Dronamraju

 * Add missing 3rd ioctl parameter, from Namhyung Kim

 * Fix pager usage in minimal embedded systems, from Avik Sil

Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
  • Loading branch information
Ingo Molnar committed Jun 6, 2012
2 parents f9ba717 + cb7225f commit 02e0304
Show file tree
Hide file tree
Showing 21 changed files with 214 additions and 58 deletions.
4 changes: 2 additions & 2 deletions include/linux/perf_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,8 @@ enum perf_event_type {
PERF_RECORD_MAX, /* non-ABI */
};

#define PERF_MAX_STACK_DEPTH 255

enum perf_callchain_context {
PERF_CONTEXT_HV = (__u64)-32,
PERF_CONTEXT_KERNEL = (__u64)-128,
Expand Down Expand Up @@ -609,8 +611,6 @@ struct perf_guest_info_callbacks {
#include <linux/sysfs.h>
#include <asm/local.h>

#define PERF_MAX_STACK_DEPTH 255

struct perf_callchain_entry {
__u64 nr;
__u64 ip[PERF_MAX_STACK_DEPTH];
Expand Down
1 change: 0 additions & 1 deletion kernel/events/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -3181,7 +3181,6 @@ static void perf_event_for_each(struct perf_event *event,
event = event->group_leader;

perf_event_for_each_child(event, func);
func(event);
list_for_each_entry(sibling, &event->sibling_list, group_entry)
perf_event_for_each_child(sibling, func);
mutex_unlock(&ctx->mutex);
Expand Down
2 changes: 2 additions & 0 deletions tools/perf/MANIFEST
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
tools/perf
tools/scripts
tools/lib/traceevent
include/linux/const.h
include/linux/perf_event.h
include/linux/rbtree.h
Expand Down
4 changes: 2 additions & 2 deletions tools/perf/builtin-report.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ static int perf_evsel__add_hist_entry(struct perf_evsel *evsel,

if (symbol_conf.use_callchain) {
err = callchain_append(he->callchain,
&evsel->hists.callchain_cursor,
&callchain_cursor,
sample->period);
if (err)
return err;
Expand All @@ -162,7 +162,7 @@ static int perf_evsel__add_hist_entry(struct perf_evsel *evsel,
* so we don't allocated the extra space needed because the stdio
* code will not use it.
*/
if (al->sym != NULL && use_browser > 0) {
if (he->ms.sym != NULL && use_browser > 0) {
struct annotation *notes = symbol__annotation(he->ms.sym);

assert(evsel != NULL);
Expand Down
8 changes: 4 additions & 4 deletions tools/perf/builtin-stat.c
Original file line number Diff line number Diff line change
Expand Up @@ -1129,7 +1129,7 @@ static int add_default_attributes(void)
return 0;

if (!evsel_list->nr_entries) {
if (perf_evlist__add_attrs_array(evsel_list, default_attrs) < 0)
if (perf_evlist__add_default_attrs(evsel_list, default_attrs) < 0)
return -1;
}

Expand All @@ -1139,21 +1139,21 @@ static int add_default_attributes(void)
return 0;

/* Append detailed run extra attributes: */
if (perf_evlist__add_attrs_array(evsel_list, detailed_attrs) < 0)
if (perf_evlist__add_default_attrs(evsel_list, detailed_attrs) < 0)
return -1;

if (detailed_run < 2)
return 0;

/* Append very detailed run extra attributes: */
if (perf_evlist__add_attrs_array(evsel_list, very_detailed_attrs) < 0)
if (perf_evlist__add_default_attrs(evsel_list, very_detailed_attrs) < 0)
return -1;

if (detailed_run < 3)
return 0;

/* Append very, very detailed run extra attributes: */
return perf_evlist__add_attrs_array(evsel_list, very_very_detailed_attrs);
return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs);
}

int cmd_stat(int argc, const char **argv, const char *prefix __used)
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/builtin-top.c
Original file line number Diff line number Diff line change
Expand Up @@ -787,7 +787,7 @@ static void perf_event__process_sample(struct perf_tool *tool,
}

if (symbol_conf.use_callchain) {
err = callchain_append(he->callchain, &evsel->hists.callchain_cursor,
err = callchain_append(he->callchain, &callchain_cursor,
sample->period);
if (err)
return;
Expand Down
7 changes: 4 additions & 3 deletions tools/perf/design.txt
Original file line number Diff line number Diff line change
Expand Up @@ -409,14 +409,15 @@ Counters can be enabled and disabled in two ways: via ioctl and via
prctl. When a counter is disabled, it doesn't count or generate
events but does continue to exist and maintain its count value.

An individual counter or counter group can be enabled with
An individual counter can be enabled with

ioctl(fd, PERF_EVENT_IOC_ENABLE);
ioctl(fd, PERF_EVENT_IOC_ENABLE, 0);

or disabled with

ioctl(fd, PERF_EVENT_IOC_DISABLE);
ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);

For a counter group, pass PERF_IOC_FLAG_GROUP as the third argument.
Enabling or disabling the leader of a group enables or disables the
whole group; that is, while the group leader is disabled, none of the
counters in the group will count. Enabling or disabling a member of a
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/ui/browsers/annotate.c
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@ static int annotate_browser__run(struct annotate_browser *browser, int evidx,
"q/ESC/CTRL+C Exit\n\n"
"-> Go to target\n"
"<- Exit\n"
"h Cycle thru hottest instructions\n"
"H Cycle thru hottest instructions\n"
"j Toggle showing jump to target arrows\n"
"J Toggle showing number of jump sources on targets\n"
"n Search next string\n"
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/util/PERF-VERSION-GEN
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ LF='
# First check if there is a .git to get the version from git describe
# otherwise try to get the version from the kernel makefile
if test -d ../../.git -o -f ../../.git &&
VN=$(git describe --abbrev=4 HEAD 2>/dev/null) &&
VN=$(git describe --match 'v[0-9].[0-9]*' --abbrev=4 HEAD 2>/dev/null) &&
case "$VN" in
*$LF*) (exit 1) ;;
v[0-9]*)
Expand Down
2 changes: 2 additions & 0 deletions tools/perf/util/callchain.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include "util.h"
#include "callchain.h"

__thread struct callchain_cursor callchain_cursor;

bool ip_callchain__valid(struct ip_callchain *chain,
const union perf_event *event)
{
Expand Down
2 changes: 2 additions & 0 deletions tools/perf/util/callchain.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ struct callchain_cursor {
struct callchain_cursor_node *curr;
};

extern __thread struct callchain_cursor callchain_cursor;

static inline void callchain_init(struct callchain_root *root)
{
INIT_LIST_HEAD(&root->node.siblings);
Expand Down
17 changes: 15 additions & 2 deletions tools/perf/util/evlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,17 @@ int perf_evlist__add_attrs(struct perf_evlist *evlist,
return -1;
}

int __perf_evlist__add_default_attrs(struct perf_evlist *evlist,
struct perf_event_attr *attrs, size_t nr_attrs)
{
size_t i;

for (i = 0; i < nr_attrs; i++)
event_attr_init(attrs + i);

return perf_evlist__add_attrs(evlist, attrs, nr_attrs);
}

static int trace_event__id(const char *evname)
{
char *filename, *colon;
Expand Down Expand Up @@ -263,7 +274,8 @@ void perf_evlist__disable(struct perf_evlist *evlist)
for (cpu = 0; cpu < evlist->cpus->nr; cpu++) {
list_for_each_entry(pos, &evlist->entries, node) {
for (thread = 0; thread < evlist->threads->nr; thread++)
ioctl(FD(pos, cpu, thread), PERF_EVENT_IOC_DISABLE);
ioctl(FD(pos, cpu, thread),
PERF_EVENT_IOC_DISABLE, 0);
}
}
}
Expand All @@ -276,7 +288,8 @@ void perf_evlist__enable(struct perf_evlist *evlist)
for (cpu = 0; cpu < evlist->cpus->nr; cpu++) {
list_for_each_entry(pos, &evlist->entries, node) {
for (thread = 0; thread < evlist->threads->nr; thread++)
ioctl(FD(pos, cpu, thread), PERF_EVENT_IOC_ENABLE);
ioctl(FD(pos, cpu, thread),
PERF_EVENT_IOC_ENABLE, 0);
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions tools/perf/util/evlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry);
int perf_evlist__add_default(struct perf_evlist *evlist);
int perf_evlist__add_attrs(struct perf_evlist *evlist,
struct perf_event_attr *attrs, size_t nr_attrs);
int __perf_evlist__add_default_attrs(struct perf_evlist *evlist,
struct perf_event_attr *attrs, size_t nr_attrs);
int perf_evlist__add_tracepoints(struct perf_evlist *evlist,
const char *tracepoints[], size_t nr_tracepoints);
int perf_evlist__set_tracepoints_handlers(struct perf_evlist *evlist,
Expand All @@ -62,6 +64,8 @@ int perf_evlist__set_tracepoints_handlers(struct perf_evlist *evlist,

#define perf_evlist__add_attrs_array(evlist, array) \
perf_evlist__add_attrs(evlist, array, ARRAY_SIZE(array))
#define perf_evlist__add_default_attrs(evlist, array) \
__perf_evlist__add_default_attrs(evlist, array, ARRAY_SIZE(array))

#define perf_evlist__add_tracepoints_array(evlist, array) \
perf_evlist__add_tracepoints(evlist, array, ARRAY_SIZE(array))
Expand Down
29 changes: 22 additions & 7 deletions tools/perf/util/evsel.c
Original file line number Diff line number Diff line change
Expand Up @@ -494,16 +494,24 @@ int perf_evsel__open_per_thread(struct perf_evsel *evsel,
}

static int perf_event__parse_id_sample(const union perf_event *event, u64 type,
struct perf_sample *sample)
struct perf_sample *sample,
bool swapped)
{
const u64 *array = event->sample.array;
union u64_swap u;

array += ((event->header.size -
sizeof(event->header)) / sizeof(u64)) - 1;

if (type & PERF_SAMPLE_CPU) {
u32 *p = (u32 *)array;
sample->cpu = *p;
u.val64 = *array;
if (swapped) {
/* undo swap of u64, then swap on individual u32s */
u.val64 = bswap_64(u.val64);
u.val32[0] = bswap_32(u.val32[0]);
}

sample->cpu = u.val32[0];
array--;
}

Expand All @@ -523,9 +531,16 @@ static int perf_event__parse_id_sample(const union perf_event *event, u64 type,
}

if (type & PERF_SAMPLE_TID) {
u32 *p = (u32 *)array;
sample->pid = p[0];
sample->tid = p[1];
u.val64 = *array;
if (swapped) {
/* undo swap of u64, then swap on individual u32s */
u.val64 = bswap_64(u.val64);
u.val32[0] = bswap_32(u.val32[0]);
u.val32[1] = bswap_32(u.val32[1]);
}

sample->pid = u.val32[0];
sample->tid = u.val32[1];
}

return 0;
Expand Down Expand Up @@ -562,7 +577,7 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,
if (event->header.type != PERF_RECORD_SAMPLE) {
if (!sample_id_all)
return 0;
return perf_event__parse_id_sample(event, type, data);
return perf_event__parse_id_sample(event, type, data, swapped);
}

array = event->sample.array;
Expand Down
7 changes: 4 additions & 3 deletions tools/perf/util/hist.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ void hist_entry__free(struct hist_entry *he)
* collapse the histogram
*/

static bool hists__collapse_insert_entry(struct hists *hists,
static bool hists__collapse_insert_entry(struct hists *hists __used,
struct rb_root *root,
struct hist_entry *he)
{
Expand All @@ -397,8 +397,9 @@ static bool hists__collapse_insert_entry(struct hists *hists,
iter->period += he->period;
iter->nr_events += he->nr_events;
if (symbol_conf.use_callchain) {
callchain_cursor_reset(&hists->callchain_cursor);
callchain_merge(&hists->callchain_cursor, iter->callchain,
callchain_cursor_reset(&callchain_cursor);
callchain_merge(&callchain_cursor,
iter->callchain,
he->callchain);
}
hist_entry__free(he);
Expand Down
2 changes: 0 additions & 2 deletions tools/perf/util/hist.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,6 @@ struct hists {
struct events_stats stats;
u64 event_stream;
u16 col_len[HISTC_NR_COLS];
/* Best would be to reuse the session callchain cursor */
struct callchain_cursor callchain_cursor;
};

struct hist_entry *__hists__add_entry(struct hists *self,
Expand Down
4 changes: 4 additions & 0 deletions tools/perf/util/pager.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ void setup_pager(void)
}
if (!pager)
pager = getenv("PAGER");
if (!pager) {
if (!access("/usr/bin/pager", X_OK))
pager = "/usr/bin/pager";
}
if (!pager)
pager = "less";
else if (!*pager || !strcmp(pager, "cat"))
Expand Down
8 changes: 2 additions & 6 deletions tools/perf/util/probe-event.c
Original file line number Diff line number Diff line change
Expand Up @@ -2164,16 +2164,12 @@ int del_perf_probe_events(struct strlist *dellist)

error:
if (kfd >= 0) {
if (namelist)
strlist__delete(namelist);

strlist__delete(namelist);
close(kfd);
}

if (ufd >= 0) {
if (unamelist)
strlist__delete(unamelist);

strlist__delete(unamelist);
close(ufd);
}

Expand Down
Loading

0 comments on commit 02e0304

Please sign in to comment.