summaryrefslogtreecommitdiffstats
path: root/tools/perf/util
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util')
-rw-r--r--tools/perf/util/event.c56
-rw-r--r--tools/perf/util/event.h4
-rw-r--r--tools/perf/util/evlist.c77
-rw-r--r--tools/perf/util/evlist.h5
-rw-r--r--tools/perf/util/evsel.c13
-rw-r--r--tools/perf/util/evsel.h23
-rw-r--r--tools/perf/util/header.c4
-rw-r--r--tools/perf/util/machine.c14
-rw-r--r--tools/perf/util/machine.h12
-rw-r--r--tools/perf/util/parse-events.c6
-rw-r--r--tools/perf/util/sort.c13
-rw-r--r--tools/perf/util/target.c54
-rw-r--r--tools/perf/util/target.h45
-rw-r--r--tools/perf/util/top.c2
-rw-r--r--tools/perf/util/unwind.c9
-rw-r--r--tools/perf/util/unwind.h5
16 files changed, 209 insertions, 133 deletions
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index ec9ae11..bb788c1 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -170,7 +170,8 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
union perf_event *event,
pid_t pid, pid_t tgid,
perf_event__handler_t process,
- struct machine *machine)
+ struct machine *machine,
+ bool mmap_data)
{
char filename[PATH_MAX];
FILE *fp;
@@ -188,10 +189,6 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
}
event->header.type = PERF_RECORD_MMAP;
- /*
- * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c
- */
- event->header.misc = PERF_RECORD_MISC_USER;
while (1) {
char bf[BUFSIZ];
@@ -212,12 +209,22 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
&event->mmap.start, &event->mmap.len, prot,
&event->mmap.pgoff,
execname);
-
- if (n != 5)
+ /*
+ * Anon maps don't have the execname.
+ */
+ if (n < 4)
continue;
+ /*
+ * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c
+ */
+ event->header.misc = PERF_RECORD_MISC_USER;
- if (prot[2] != 'x')
- continue;
+ if (prot[2] != 'x') {
+ if (!mmap_data || prot[0] != 'r')
+ continue;
+
+ event->header.misc |= PERF_RECORD_MISC_MMAP_DATA;
+ }
if (!strcmp(execname, ""))
strcpy(execname, anonstr);
@@ -304,20 +311,21 @@ static int __event__synthesize_thread(union perf_event *comm_event,
pid_t pid, int full,
perf_event__handler_t process,
struct perf_tool *tool,
- struct machine *machine)
+ struct machine *machine, bool mmap_data)
{
pid_t tgid = perf_event__synthesize_comm(tool, comm_event, pid, full,
process, machine);
if (tgid == -1)
return -1;
return perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid,
- process, machine);
+ process, machine, mmap_data);
}
int perf_event__synthesize_thread_map(struct perf_tool *tool,
struct thread_map *threads,
perf_event__handler_t process,
- struct machine *machine)
+ struct machine *machine,
+ bool mmap_data)
{
union perf_event *comm_event, *mmap_event;
int err = -1, thread, j;
@@ -334,7 +342,8 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool,
for (thread = 0; thread < threads->nr; ++thread) {
if (__event__synthesize_thread(comm_event, mmap_event,
threads->map[thread], 0,
- process, tool, machine)) {
+ process, tool, machine,
+ mmap_data)) {
err = -1;
break;
}
@@ -356,10 +365,10 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool,
/* if not, generate events for it */
if (need_leader &&
- __event__synthesize_thread(comm_event,
- mmap_event,
- comm_event->comm.pid, 0,
- process, tool, machine)) {
+ __event__synthesize_thread(comm_event, mmap_event,
+ comm_event->comm.pid, 0,
+ process, tool, machine,
+ mmap_data)) {
err = -1;
break;
}
@@ -374,7 +383,7 @@ out:
int perf_event__synthesize_threads(struct perf_tool *tool,
perf_event__handler_t process,
- struct machine *machine)
+ struct machine *machine, bool mmap_data)
{
DIR *proc;
struct dirent dirent, *next;
@@ -404,7 +413,7 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
* one thread couldn't be synthesized.
*/
__event__synthesize_thread(comm_event, mmap_event, pid, 1,
- process, tool, machine);
+ process, tool, machine, mmap_data);
}
err = 0;
@@ -528,19 +537,22 @@ int perf_event__process_lost(struct perf_tool *tool __maybe_unused,
size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp)
{
- return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 "]: %s\n",
+ return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 "]: %c %s\n",
event->mmap.pid, event->mmap.tid, event->mmap.start,
- event->mmap.len, event->mmap.pgoff, event->mmap.filename);
+ event->mmap.len, event->mmap.pgoff,
+ (event->header.misc & PERF_RECORD_MISC_MMAP_DATA) ? 'r' : 'x',
+ event->mmap.filename);
}
size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp)
{
return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64
- " %02x:%02x %"PRIu64" %"PRIu64"]: %s\n",
+ " %02x:%02x %"PRIu64" %"PRIu64"]: %c %s\n",
event->mmap2.pid, event->mmap2.tid, event->mmap2.start,
event->mmap2.len, event->mmap2.pgoff, event->mmap2.maj,
event->mmap2.min, event->mmap2.ino,
event->mmap2.ino_generation,
+ (event->header.misc & PERF_RECORD_MISC_MMAP_DATA) ? 'r' : 'x',
event->mmap2.filename);
}
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index f8d70f3..30fec99 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -208,10 +208,10 @@ typedef int (*perf_event__handler_t)(struct perf_tool *tool,
int perf_event__synthesize_thread_map(struct perf_tool *tool,
struct thread_map *threads,
perf_event__handler_t process,
- struct machine *machine);
+ struct machine *machine, bool mmap_data);
int perf_event__synthesize_threads(struct perf_tool *tool,
perf_event__handler_t process,
- struct machine *machine);
+ struct machine *machine, bool mmap_data);
int perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
perf_event__handler_t process,
struct machine *machine,
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index b939221..bbc746a 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -117,6 +117,8 @@ void perf_evlist__delete(struct perf_evlist *evlist)
void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry)
{
list_add_tail(&entry->node, &evlist->entries);
+ entry->idx = evlist->nr_entries;
+
if (!evlist->nr_entries++)
perf_evlist__set_id_pos(evlist);
}
@@ -165,7 +167,7 @@ int perf_evlist__add_default(struct perf_evlist *evlist)
event_attr_init(&attr);
- evsel = perf_evsel__new(&attr, 0);
+ evsel = perf_evsel__new(&attr);
if (evsel == NULL)
goto error;
@@ -190,7 +192,7 @@ static int perf_evlist__add_attrs(struct perf_evlist *evlist,
size_t i;
for (i = 0; i < nr_attrs; i++) {
- evsel = perf_evsel__new(attrs + i, evlist->nr_entries + i);
+ evsel = perf_evsel__new_idx(attrs + i, evlist->nr_entries + i);
if (evsel == NULL)
goto out_delete_partial_list;
list_add_tail(&evsel->node, &head);
@@ -249,9 +251,8 @@ perf_evlist__find_tracepoint_by_name(struct perf_evlist *evlist,
int perf_evlist__add_newtp(struct perf_evlist *evlist,
const char *sys, const char *name, void *handler)
{
- struct perf_evsel *evsel;
+ struct perf_evsel *evsel = perf_evsel__newtp(sys, name);
- evsel = perf_evsel__newtp(sys, name, evlist->nr_entries);
if (evsel == NULL)
return -1;
@@ -704,12 +705,10 @@ static size_t perf_evlist__mmap_size(unsigned long pages)
return (pages + 1) * page_size;
}
-int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str,
- int unset __maybe_unused)
+static long parse_pages_arg(const char *str, unsigned long min,
+ unsigned long max)
{
- unsigned int *mmap_pages = opt->value;
unsigned long pages, val;
- size_t size;
static struct parse_tag tags[] = {
{ .tag = 'B', .mult = 1 },
{ .tag = 'K', .mult = 1 << 10 },
@@ -718,33 +717,49 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str,
{ .tag = 0 },
};
+ if (str == NULL)
+ return -EINVAL;
+
val = parse_tag_value(str, tags);
if (val != (unsigned long) -1) {
/* we got file size value */
pages = PERF_ALIGN(val, page_size) / page_size;
- if (pages < (1UL << 31) && !is_power_of_2(pages)) {
- pages = next_pow2(pages);
- pr_info("rounding mmap pages size to %lu (%lu pages)\n",
- pages * page_size, pages);
- }
} else {
/* we got pages count value */
char *eptr;
pages = strtoul(str, &eptr, 10);
- if (*eptr != '\0') {
- pr_err("failed to parse --mmap_pages/-m value\n");
- return -1;
- }
+ if (*eptr != '\0')
+ return -EINVAL;
}
- if (pages > UINT_MAX || pages > SIZE_MAX / page_size) {
- pr_err("--mmap_pages/-m value too big\n");
- return -1;
+ if ((pages == 0) && (min == 0)) {
+ /* leave number of pages at 0 */
+ } else if (pages < (1UL << 31) && !is_power_of_2(pages)) {
+ /* round pages up to next power of 2 */
+ pages = next_pow2(pages);
+ pr_info("rounding mmap pages size to %lu bytes (%lu pages)\n",
+ pages * page_size, pages);
}
- size = perf_evlist__mmap_size(pages);
- if (!size) {
- pr_err("--mmap_pages/-m value must be a power of two.");
+ if (pages > max)
+ return -EINVAL;
+
+ return pages;
+}
+
+int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str,
+ int unset __maybe_unused)
+{
+ unsigned int *mmap_pages = opt->value;
+ unsigned long max = UINT_MAX;
+ long pages;
+
+ if (max < SIZE_MAX / page_size)
+ max = SIZE_MAX / page_size;
+
+ pages = parse_pages_arg(str, 1, max);
+ if (pages < 0) {
+ pr_err("Invalid argument for --mmap_pages/-m\n");
return -1;
}
@@ -796,8 +811,7 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
return perf_evlist__mmap_per_cpu(evlist, prot, mask);
}
-int perf_evlist__create_maps(struct perf_evlist *evlist,
- struct perf_target *target)
+int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
{
evlist->threads = thread_map__new_str(target->pid, target->tid,
target->uid);
@@ -805,9 +819,11 @@ int perf_evlist__create_maps(struct perf_evlist *evlist,
if (evlist->threads == NULL)
return -1;
- if (perf_target__has_task(target))
+ if (target->force_per_cpu)
+ evlist->cpus = cpu_map__new(target->cpu_list);
+ else if (target__has_task(target))
evlist->cpus = cpu_map__dummy_new();
- else if (!perf_target__has_cpu(target) && !target->uses_mmap)
+ else if (!target__has_cpu(target) && !target->uses_mmap)
evlist->cpus = cpu_map__dummy_new();
else
evlist->cpus = cpu_map__new(target->cpu_list);
@@ -1016,8 +1032,7 @@ out_err:
return err;
}
-int perf_evlist__prepare_workload(struct perf_evlist *evlist,
- struct perf_target *target,
+int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *target,
const char *argv[], bool pipe_output,
bool want_signal)
{
@@ -1069,7 +1084,7 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist,
exit(-1);
}
- if (perf_target__none(target))
+ if (target__none(target))
evlist->threads->map[0] = evlist->workload.pid;
close(child_ready_pipe[1]);
@@ -1135,7 +1150,7 @@ size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp)
perf_evsel__name(evsel));
}
- return printed + fprintf(fp, "\n");;
+ return printed + fprintf(fp, "\n");
}
int perf_evlist__strerror_tp(struct perf_evlist *evlist __maybe_unused,
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index ecaa582..649d6ea 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -102,7 +102,7 @@ void perf_evlist__config(struct perf_evlist *evlist,
int perf_record_opts__config(struct perf_record_opts *opts);
int perf_evlist__prepare_workload(struct perf_evlist *evlist,
- struct perf_target *target,
+ struct target *target,
const char *argv[], bool pipe_output,
bool want_signal);
int perf_evlist__start_workload(struct perf_evlist *evlist);
@@ -134,8 +134,7 @@ static inline void perf_evlist__set_maps(struct perf_evlist *evlist,
evlist->threads = threads;
}
-int perf_evlist__create_maps(struct perf_evlist *evlist,
- struct perf_target *target);
+int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target);
void perf_evlist__delete_maps(struct perf_evlist *evlist);
int perf_evlist__apply_filters(struct perf_evlist *evlist);
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 5280820..46dd4c2 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -168,7 +168,7 @@ void perf_evsel__init(struct perf_evsel *evsel,
perf_evsel__calc_id_pos(evsel);
}
-struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx)
+struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx)
{
struct perf_evsel *evsel = zalloc(sizeof(*evsel));
@@ -219,7 +219,7 @@ out:
return format;
}
-struct perf_evsel *perf_evsel__newtp(const char *sys, const char *name, int idx)
+struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int idx)
{
struct perf_evsel *evsel = zalloc(sizeof(*evsel));
@@ -645,7 +645,7 @@ void perf_evsel__config(struct perf_evsel *evsel,
}
}
- if (perf_target__has_cpu(&opts->target))
+ if (target__has_cpu(&opts->target) || opts->target.force_per_cpu)
perf_evsel__set_sample_bit(evsel, CPU);
if (opts->period)
@@ -653,7 +653,7 @@ void perf_evsel__config(struct perf_evsel *evsel,
if (!perf_missing_features.sample_id_all &&
(opts->sample_time || !opts->no_inherit ||
- perf_target__has_cpu(&opts->target)))
+ target__has_cpu(&opts->target) || opts->target.force_per_cpu))
perf_evsel__set_sample_bit(evsel, TIME);
if (opts->raw_samples) {
@@ -696,7 +696,7 @@ void perf_evsel__config(struct perf_evsel *evsel,
* Setting enable_on_exec for independent events and
* group leaders for traced executed by perf.
*/
- if (perf_target__none(&opts->target) && perf_evsel__is_group_leader(evsel))
+ if (target__none(&opts->target) && perf_evsel__is_group_leader(evsel))
attr->enable_on_exec = 1;
}
@@ -2006,8 +2006,7 @@ bool perf_evsel__fallback(struct perf_evsel *evsel, int err,
return false;
}
-int perf_evsel__open_strerror(struct perf_evsel *evsel,
- struct perf_target *target,
+int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
int err, char *msg, size_t size)
{
switch (err) {
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 64ec8e1..1ea7c92 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -96,8 +96,19 @@ struct thread_map;
struct perf_evlist;
struct perf_record_opts;
-struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx);
-struct perf_evsel *perf_evsel__newtp(const char *sys, const char *name, int idx);
+struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx);
+
+static inline struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr)
+{
+ return perf_evsel__new_idx(attr, 0);
+}
+
+struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int idx);
+
+static inline struct perf_evsel *perf_evsel__newtp(const char *sys, const char *name)
+{
+ return perf_evsel__newtp_idx(sys, name, 0);
+}
struct event_format *event_format__new(const char *sys, const char *name);
@@ -268,6 +279,11 @@ static inline struct perf_evsel *perf_evsel__next(struct perf_evsel *evsel)
return list_entry(evsel->node.next, struct perf_evsel, node);
}
+static inline struct perf_evsel *perf_evsel__prev(struct perf_evsel *evsel)
+{
+ return list_entry(evsel->node.prev, struct perf_evsel, node);
+}
+
/**
* perf_evsel__is_group_leader - Return whether given evsel is a leader event
*
@@ -307,8 +323,7 @@ int perf_evsel__fprintf(struct perf_evsel *evsel,
bool perf_evsel__fallback(struct perf_evsel *evsel, int err,
char *msg, size_t msgsize);
-int perf_evsel__open_strerror(struct perf_evsel *evsel,
- struct perf_target *target,
+int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
int err, char *msg, size_t size);
static inline int perf_evsel__group_idx(struct perf_evsel *evsel)
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 26d9520..369c036 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -2797,7 +2797,7 @@ int perf_session__read_header(struct perf_session *session)
perf_event__attr_swap(&f_attr.attr);
tmp = lseek(fd, 0, SEEK_CUR);
- evsel = perf_evsel__new(&f_attr.attr, i);
+ evsel = perf_evsel__new(&f_attr.attr);
if (evsel == NULL)
goto out_delete_evlist;
@@ -2916,7 +2916,7 @@ int perf_event__process_attr(struct perf_tool *tool __maybe_unused,
return -ENOMEM;
}
- evsel = perf_evsel__new(&event->attr.attr, evlist->nr_entries);
+ evsel = perf_evsel__new(&event->attr.attr);
if (evsel == NULL)
return -ENOMEM;
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index ce034c1..84cdb07 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1368,7 +1368,7 @@ int machine__resolve_callchain(struct machine *machine,
return unwind__get_entries(unwind_entry, &callchain_cursor, machine,
thread, evsel->attr.sample_regs_user,
- sample);
+ sample, max_stack);
}
@@ -1394,3 +1394,15 @@ int machine__for_each_thread(struct machine *machine,
}
return rc;
}
+
+int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool,
+ struct target *target, struct thread_map *threads,
+ perf_event__handler_t process, bool data_mmap)
+{
+ if (target__has_task(target))
+ return perf_event__synthesize_thread_map(tool, threads, process, machine, data_mmap);
+ else if (target__has_cpu(target))
+ return perf_event__synthesize_threads(tool, process, machine, data_mmap);
+ /* command specified */
+ return 0;
+}
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index 2389ba8..4771330 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -4,6 +4,7 @@
#include <sys/types.h>
#include <linux/rbtree.h>
#include "map.h"
+#include "event.h"
struct addr_location;
struct branch_stack;
@@ -178,4 +179,15 @@ int machine__for_each_thread(struct machine *machine,
int (*fn)(struct thread *thread, void *p),
void *priv);
+int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool,
+ struct target *target, struct thread_map *threads,
+ perf_event__handler_t process, bool data_mmap);
+static inline
+int machine__synthesize_threads(struct machine *machine, struct target *target,
+ struct thread_map *threads, bool data_mmap)
+{
+ return __machine__synthesize_threads(machine, NULL, target, threads,
+ perf_event__process, data_mmap);
+}
+
#endif /* __PERF_MACHINE_H */
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index c90e55c..6de6f89 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -277,7 +277,7 @@ static int __add_event(struct list_head *list, int *idx,
event_attr_init(attr);
- evsel = perf_evsel__new(attr, (*idx)++);
+ evsel = perf_evsel__new_idx(attr, (*idx)++);
if (!evsel)
return -ENOMEM;
@@ -378,7 +378,7 @@ static int add_tracepoint(struct list_head *list, int *idx,
{
struct perf_evsel *evsel;
- evsel = perf_evsel__newtp(sys_name, evt_name, (*idx)++);
+ evsel = perf_evsel__newtp_idx(sys_name, evt_name, (*idx)++);
if (!evsel)
return -ENOMEM;
@@ -1097,7 +1097,7 @@ static bool is_event_supported(u8 type, unsigned config)
.threads = { 0 },
};
- evsel = perf_evsel__new(&attr, 0);
+ evsel = perf_evsel__new(&attr);
if (evsel) {
ret = perf_evsel__open(evsel, NULL, &tmap.map) >= 0;
perf_evsel__delete(evsel);
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 3c1b75c..8b0bb1f 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -1137,6 +1137,8 @@ static void sort_entry__setup_elide(struct sort_entry *se,
void sort__setup_elide(FILE *output)
{
+ struct sort_entry *se;
+
sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
"dso", output);
sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list,
@@ -1172,4 +1174,15 @@ void sort__setup_elide(FILE *output)
"snoop", output);
}
+ /*
+ * It makes no sense to elide all of sort entries.
+ * Just revert them to show up again.
+ */
+ list_for_each_entry(se, &hist_entry__sort_list, list) {
+ if (!se->elide)
+ return;
+ }
+
+ list_for_each_entry(se, &hist_entry__sort_list, list)
+ se->elide = false;
}
diff --git a/tools/perf/util/target.c b/tools/perf/util/target.c
index 065528b..3c778a0 100644
--- a/tools/perf/util/target.c
+++ b/tools/perf/util/target.c
@@ -13,9 +13,9 @@
#include <string.h>
-enum perf_target_errno perf_target__validate(struct perf_target *target)
+enum target_errno target__validate(struct target *target)
{
- enum perf_target_errno ret = PERF_ERRNO_TARGET__SUCCESS;
+ enum target_errno ret = TARGET_ERRNO__SUCCESS;
if (target->pid)
target->tid = target->pid;
@@ -23,42 +23,42 @@ enum perf_target_errno perf_target__validate(struct perf_target *target)
/* CPU and PID are mutually exclusive */
if (target->tid && target->cpu_list) {
target->cpu_list = NULL;
- if (ret == PERF_ERRNO_TARGET__SUCCESS)
- ret = PERF_ERRNO_TARGET__PID_OVERRIDE_CPU;
+ if (ret == TARGET_ERRNO__SUCCESS)
+ ret = TARGET_ERRNO__PID_OVERRIDE_CPU;
}
/* UID and PID are mutually exclusive */
if (target->tid && target->uid_str) {
target->uid_str = NULL;
- if (ret == PERF_ERRNO_TARGET__SUCCESS)
- ret = PERF_ERRNO_TARGET__PID_OVERRIDE_UID;
+ if (ret == TARGET_ERRNO__SUCCESS)
+ ret = TARGET_ERRNO__PID_OVERRIDE_UID;
}
/* UID and CPU are mutually exclusive */
if (target->uid_str && target->cpu_list) {
target->cpu_list = NULL;
- if (ret == PERF_ERRNO_TARGET__SUCCESS)
- ret = PERF_ERRNO_TARGET__UID_OVERRIDE_CPU;
+ if (ret == TARGET_ERRNO__SUCCESS)
+ ret = TARGET_ERRNO__UID_OVERRIDE_CPU;
}
/* PID and SYSTEM are mutually exclusive */
if (target->tid && target->system_wide) {
target->system_wide = false;
- if (ret == PERF_ERRNO_TARGET__SUCCESS)
- ret = PERF_ERRNO_TARGET__PID_OVERRIDE_SYSTEM;
+ if (ret == TARGET_ERRNO__SUCCESS)
+ ret = TARGET_ERRNO__PID_OVERRIDE_SYSTEM;
}
/* UID and SYSTEM are mutually exclusive */
if (target->uid_str && target->system_wide) {
target->system_wide = false;
- if (ret == PERF_ERRNO_TARGET__SUCCESS)
- ret = PERF_ERRNO_TARGET__UID_OVERRIDE_SYSTEM;
+ if (ret == TARGET_ERRNO__SUCCESS)
+ ret = TARGET_ERRNO__UID_OVERRIDE_SYSTEM;
}
return ret;
}
-enum perf_target_errno perf_target__parse_uid(struct perf_target *target)
+enum target_errno target__parse_uid(struct target *target)
{
struct passwd pwd, *result;
char buf[1024];
@@ -66,7 +66,7 @@ enum perf_target_errno perf_target__parse_uid(struct perf_target *target)
target->uid = UINT_MAX;
if (str == NULL)
- return PERF_ERRNO_TARGET__SUCCESS;
+ return TARGET_ERRNO__SUCCESS;
/* Try user name first */
getpwnam_r(str, &pwd, buf, sizeof(buf), &result);
@@ -79,22 +79,22 @@ enum perf_target_errno perf_target__parse_uid(struct perf_target *target)
int uid = strtol(str, &endptr, 10);
if (*endptr != '\0')
- return PERF_ERRNO_TARGET__INVALID_UID;
+ return TARGET_ERRNO__INVALID_UID;
getpwuid_r(uid, &pwd, buf, sizeof(buf), &result);
if (result == NULL)
- return PERF_ERRNO_TARGET__USER_NOT_FOUND;
+ return TARGET_ERRNO__USER_NOT_FOUND;
}
target->uid = result->pw_uid;
- return PERF_ERRNO_TARGET__SUCCESS;
+ return TARGET_ERRNO__SUCCESS;
}
/*
- * This must have a same ordering as the enum perf_target_errno.
+ * This must have a same ordering as the enum target_errno.
*/
-static const char *perf_target__error_str[] = {
+static const char *target__error_str[] = {
"PID/TID switch overriding CPU",
"PID/TID switch overriding UID",
"UID switch overriding CPU",
@@ -104,7 +104,7 @@ static const char *perf_target__error_str[] = {
"Problems obtaining information for user %s",
};
-int perf_target__strerror(struct perf_target *target, int errnum,
+int target__strerror(struct target *target, int errnum,
char *buf, size_t buflen)
{
int idx;
@@ -124,21 +124,19 @@ int perf_target__strerror(struct perf_target *target, int errnum,
return 0;
}
- if (errnum < __PERF_ERRNO_TARGET__START ||
- errnum >= __PERF_ERRNO_TARGET__END)
+ if (errnum < __TARGET_ERRNO__START || errnum >= __TARGET_ERRNO__END)
return -1;
- idx = errnum - __PERF_ERRNO_TARGET__START;
- msg = perf_target__error_str[idx];
+ idx = errnum - __TARGET_ERRNO__START;
+ msg = target__error_str[idx];
switch (errnum) {
- case PERF_ERRNO_TARGET__PID_OVERRIDE_CPU
- ... PERF_ERRNO_TARGET__UID_OVERRIDE_SYSTEM:
+ case TARGET_ERRNO__PID_OVERRIDE_CPU ... TARGET_ERRNO__UID_OVERRIDE_SYSTEM:
snprintf(buf, buflen, "%s", msg);
break;
- case PERF_ERRNO_TARGET__INVALID_UID:
- case PERF_ERRNO_TARGET__USER_NOT_FOUND:
+ case TARGET_ERRNO__INVALID_UID:
+ case TARGET_ERRNO__USER_NOT_FOUND:
snprintf(buf, buflen, msg, target->uid_str);
break;
diff --git a/tools/perf/util/target.h b/tools/perf/util/target.h
index a4be857..2d0c506 100644
--- a/tools/perf/util/target.h
+++ b/tools/perf/util/target.h
@@ -4,7 +4,7 @@
#include <stdbool.h>
#include <sys/types.h>
-struct perf_target {
+struct target {
const char *pid;
const char *tid;
const char *cpu_list;
@@ -12,10 +12,11 @@ struct perf_target {
uid_t uid;
bool system_wide;
bool uses_mmap;
+ bool force_per_cpu;
};
-enum perf_target_errno {
- PERF_ERRNO_TARGET__SUCCESS = 0,
+enum target_errno {
+ TARGET_ERRNO__SUCCESS = 0,
/*
* Choose an arbitrary negative big number not to clash with standard
@@ -24,42 +25,40 @@ enum perf_target_errno {
*
* http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html
*/
- __PERF_ERRNO_TARGET__START = -10000,
+ __TARGET_ERRNO__START = -10000,
+ /* for target__validate() */
+ TARGET_ERRNO__PID_OVERRIDE_CPU = __TARGET_ERRNO__START,
+ TARGET_ERRNO__PID_OVERRIDE_UID,
+ TARGET_ERRNO__UID_OVERRIDE_CPU,
+ TARGET_ERRNO__PID_OVERRIDE_SYSTEM,
+ TARGET_ERRNO__UID_OVERRIDE_SYSTEM,
- /* for perf_target__validate() */
- PERF_ERRNO_TARGET__PID_OVERRIDE_CPU = __PERF_ERRNO_TARGET__START,
- PERF_ERRNO_TARGET__PID_OVERRIDE_UID,
- PERF_ERRNO_TARGET__UID_OVERRIDE_CPU,
- PERF_ERRNO_TARGET__PID_OVERRIDE_SYSTEM,
- PERF_ERRNO_TARGET__UID_OVERRIDE_SYSTEM,
+ /* for target__parse_uid() */
+ TARGET_ERRNO__INVALID_UID,
+ TARGET_ERRNO__USER_NOT_FOUND,
- /* for perf_target__parse_uid() */
- PERF_ERRNO_TARGET__INVALID_UID,
- PERF_ERRNO_TARGET__USER_NOT_FOUND,
-
- __PERF_ERRNO_TARGET__END,
+ __TARGET_ERRNO__END,
};
-enum perf_target_errno perf_target__validate(struct perf_target *target);
-enum perf_target_errno perf_target__parse_uid(struct perf_target *target);
+enum target_errno target__validate(struct target *target);
+enum target_errno target__parse_uid(struct target *target);
-int perf_target__strerror(struct perf_target *target, int errnum, char *buf,
- size_t buflen);
+int target__strerror(struct target *target, int errnum, char *buf, size_t buflen);
-static inline bool perf_target__has_task(struct perf_target *target)
+static inline bool target__has_task(struct target *target)
{
return target->tid || target->pid || target->uid_str;
}
-static inline bool perf_target__has_cpu(struct perf_target *target)
+static inline bool target__has_cpu(struct target *target)
{
return target->system_wide || target->cpu_list;
}
-static inline bool perf_target__none(struct perf_target *target)
+static inline bool target__none(struct target *target)
{
- return !perf_target__has_task(target) && !perf_target__has_cpu(target);
+ return !target__has_task(target) && !target__has_cpu(target);
}
#endif /* _PERF_TARGET_H */
diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c
index f857b51..ce793c7 100644
--- a/tools/perf/util/top.c
+++ b/tools/perf/util/top.c
@@ -27,7 +27,7 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size)
float ksamples_per_sec;
float esamples_percent;
struct perf_record_opts *opts = &top->record_opts;
- struct perf_target *target = &opts->target;
+ struct target *target = &opts->target;
size_t ret = 0;
if (top->samples) {
diff --git a/tools/perf/util/unwind.c b/tools/perf/util/unwind.c
index 5390d0b..0efd539 100644
--- a/tools/perf/util/unwind.c
+++ b/tools/perf/util/unwind.c
@@ -559,7 +559,7 @@ static unw_accessors_t accessors = {
};
static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
- void *arg)
+ void *arg, int max_stack)
{
unw_addr_space_t addr_space;
unw_cursor_t c;
@@ -575,7 +575,7 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
if (ret)
display_error(ret);
- while (!ret && (unw_step(&c) > 0)) {
+ while (!ret && (unw_step(&c) > 0) && max_stack--) {
unw_word_t ip;
unw_get_reg(&c, UNW_REG_IP, &ip);
@@ -588,7 +588,8 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
struct machine *machine, struct thread *thread,
- u64 sample_uregs, struct perf_sample *data)
+ u64 sample_uregs, struct perf_sample *data,
+ int max_stack)
{
unw_word_t ip;
struct unwind_info ui = {
@@ -610,5 +611,5 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
if (ret)
return -ENOMEM;
- return get_entries(&ui, cb, arg);
+ return get_entries(&ui, cb, arg, max_stack);
}
diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h
index ec0c71a..d5966f49 100644
--- a/tools/perf/util/unwind.h
+++ b/tools/perf/util/unwind.h
@@ -18,7 +18,7 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
struct machine *machine,
struct thread *thread,
u64 sample_uregs,
- struct perf_sample *data);
+ struct perf_sample *data, int max_stack);
int unwind__arch_reg_id(int regnum);
#else
static inline int
@@ -27,7 +27,8 @@ unwind__get_entries(unwind_entry_cb_t cb __maybe_unused,
struct machine *machine __maybe_unused,
struct thread *thread __maybe_unused,
u64 sample_uregs __maybe_unused,
- struct perf_sample *data __maybe_unused)
+ struct perf_sample *data __maybe_unused,
+ int max_stack __maybe_unused)
{
return 0;
}
OpenPOWER on IntegriCloud