From: Arnaldo Carvalho de Melo <acme@infradead.org>
To: Ingo Molnar <mingo@elte.hu>
Cc: linux-kernel@vger.kernel.org,
Arnaldo Carvalho de Melo <acme@redhat.com>,
Frederic Weisbecker <fweisbec@gmail.com>,
Ingo Molnar <mingo@elte.hu>, Mike Galbraith <efault@gmx.de>,
Paul Mackerras <paulus@samba.org>,
Peter Zijlstra <peterz@infradead.org>,
Stephane Eranian <eranian@google.com>,
Tom Zanussi <tzanussi@gmail.com>
Subject: [PATCH 06/29] perf record: Use perf_evsel__open
Date: Tue, 25 Jan 2011 15:21:29 -0200 [thread overview]
Message-ID: <1295976112-2796-7-git-send-email-acme@infradead.org> (raw)
In-Reply-To: <1295976112-2796-1-git-send-email-acme@infradead.org>
From: Arnaldo Carvalho de Melo <acme@redhat.com>
Now its time to factor out the mmap handling bits into the perf_evsel
class.
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/builtin-record.c | 233 +++++++++++++++++++++----------------------
1 files changed, 113 insertions(+), 120 deletions(-)
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 1614d89..ec43f2e 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -72,8 +72,6 @@ static struct perf_evlist *evsel_list;
static long samples = 0;
static u64 bytes_written = 0;
-static int nr_cpu = 0;
-
static int file_new = 1;
static off_t post_processing_offset;
@@ -208,8 +206,6 @@ static void sig_atexit(void)
kill(getpid(), signr);
}
-static int group_fd;
-
static struct perf_header_attr *get_header_attr(struct perf_event_attr *a, int nr)
{
struct perf_header_attr *h_attr;
@@ -234,7 +230,6 @@ static void create_counter(struct perf_evlist *evlist,
char *filter = evsel->filter;
struct perf_event_attr *attr = &evsel->attr;
struct perf_header_attr *h_attr;
- int track = !evsel->idx; /* only the first counter needs these */
int thread_index;
int ret;
struct {
@@ -243,19 +238,77 @@ static void create_counter(struct perf_evlist *evlist,
u64 time_running;
u64 id;
} read_data;
- /*
- * Check if parse_single_tracepoint_event has already asked for
- * PERF_SAMPLE_TIME.
- *
- * XXX this is kludgy but short term fix for problems introduced by
- * eac23d1c that broke 'perf script' by having different sample_types
- * when using multiple tracepoint events when we use a perf binary
- * that tries to use sample_id_all on an older kernel.
- *
- * We need to move counter creation to perf_session, support
- * different sample_types, etc.
- */
- bool time_needed = attr->sample_type & PERF_SAMPLE_TIME;
+
+ for (thread_index = 0; thread_index < threads->nr; thread_index++) {
+ h_attr = get_header_attr(attr, evsel->idx);
+ if (h_attr == NULL)
+ die("nomem\n");
+
+ if (!file_new) {
+ if (memcmp(&h_attr->attr, attr, sizeof(*attr))) {
+ fprintf(stderr, "incompatible append\n");
+ exit(-1);
+ }
+ }
+
+ if (read(FD(evsel, cpu, thread_index), &read_data, sizeof(read_data)) == -1) {
+ perror("Unable to read perf file descriptor");
+ exit(-1);
+ }
+
+ if (perf_header_attr__add_id(h_attr, read_data.id) < 0) {
+ pr_warning("Not enough memory to add id\n");
+ exit(-1);
+ }
+
+ assert(FD(evsel, cpu, thread_index) >= 0);
+ fcntl(FD(evsel, cpu, thread_index), F_SETFL, O_NONBLOCK);
+
+ if (evsel->idx || thread_index) {
+ struct perf_evsel *first;
+ first = list_entry(evlist->entries.next, struct perf_evsel, node);
+ ret = ioctl(FD(evsel, cpu, thread_index),
+ PERF_EVENT_IOC_SET_OUTPUT,
+ FD(first, cpu, 0));
+ if (ret) {
+ error("failed to set output: %d (%s)\n", errno,
+ strerror(errno));
+ exit(-1);
+ }
+ } else {
+ mmap_array[cpu].prev = 0;
+ mmap_array[cpu].mask = mmap_pages*page_size - 1;
+ mmap_array[cpu].base = mmap(NULL, (mmap_pages+1)*page_size,
+ PROT_READ | PROT_WRITE, MAP_SHARED, FD(evsel, cpu, thread_index), 0);
+ if (mmap_array[cpu].base == MAP_FAILED) {
+ error("failed to mmap with %d (%s)\n", errno, strerror(errno));
+ exit(-1);
+ }
+
+ evlist->pollfd[evlist->nr_fds].fd = FD(evsel, cpu, thread_index);
+ evlist->pollfd[evlist->nr_fds].events = POLLIN;
+ evlist->nr_fds++;
+ }
+
+ if (filter != NULL) {
+ ret = ioctl(FD(evsel, cpu, thread_index),
+ PERF_EVENT_IOC_SET_FILTER, filter);
+ if (ret) {
+ error("failed to set filter with %d (%s)\n", errno,
+ strerror(errno));
+ exit(-1);
+ }
+ }
+ }
+
+ if (!sample_type)
+ sample_type = attr->sample_type;
+}
+
+static void config_attr(struct perf_evsel *evsel, struct perf_evlist *evlist)
+{
+ struct perf_event_attr *attr = &evsel->attr;
+ int track = !evsel->idx; /* only the first counter needs these */
attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
PERF_FORMAT_TOTAL_TIME_RUNNING |
@@ -315,19 +368,39 @@ static void create_counter(struct perf_evlist *evlist,
attr->mmap = track;
attr->comm = track;
- attr->inherit = !no_inherit;
+
if (target_pid == -1 && target_tid == -1 && !system_wide) {
attr->disabled = 1;
attr->enable_on_exec = 1;
}
-retry_sample_id:
- attr->sample_id_all = sample_id_all_avail ? 1 : 0;
+}
- for (thread_index = 0; thread_index < threads->nr; thread_index++) {
-try_again:
- FD(evsel, nr_cpu, thread_index) = sys_perf_event_open(attr, threads->map[thread_index], cpu, group_fd, 0);
+static void open_counters(struct perf_evlist *evlist)
+{
+ struct perf_evsel *pos;
+ int cpu;
+
+ list_for_each_entry(pos, &evlist->entries, node) {
+ struct perf_event_attr *attr = &pos->attr;
+ /*
+ * Check if parse_single_tracepoint_event has already asked for
+ * PERF_SAMPLE_TIME.
+ *
+ * XXX this is kludgy but short term fix for problems introduced by
+ * eac23d1c that broke 'perf script' by having different sample_types
+ * when using multiple tracepoint events when we use a perf binary
+ * that tries to use sample_id_all on an older kernel.
+ *
+ * We need to move counter creation to perf_session, support
+ * different sample_types, etc.
+ */
+ bool time_needed = attr->sample_type & PERF_SAMPLE_TIME;
- if (FD(evsel, nr_cpu, thread_index) < 0) {
+ config_attr(pos, evlist);
+retry_sample_id:
+ attr->sample_id_all = sample_id_all_avail ? 1 : 0;
+try_again:
+ if (perf_evsel__open(pos, cpus, threads, group, !no_inherit) < 0) {
int err = errno;
if (err == EPERM || err == EACCES)
@@ -364,7 +437,7 @@ try_again:
}
printf("\n");
error("sys_perf_event_open() syscall returned with %d (%s). /bin/dmesg may provide additional information.\n",
- FD(evsel, nr_cpu, thread_index), strerror(err));
+ err, strerror(err));
#if defined(__i386__) || defined(__x86_64__)
if (attr->type == PERF_TYPE_HARDWARE && err == EOPNOTSUPP)
@@ -375,90 +448,13 @@ try_again:
#endif
die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
- exit(-1);
- }
-
- h_attr = get_header_attr(attr, evsel->idx);
- if (h_attr == NULL)
- die("nomem\n");
-
- if (!file_new) {
- if (memcmp(&h_attr->attr, attr, sizeof(*attr))) {
- fprintf(stderr, "incompatible append\n");
- exit(-1);
- }
- }
-
- if (read(FD(evsel, nr_cpu, thread_index), &read_data, sizeof(read_data)) == -1) {
- perror("Unable to read perf file descriptor");
- exit(-1);
- }
-
- if (perf_header_attr__add_id(h_attr, read_data.id) < 0) {
- pr_warning("Not enough memory to add id\n");
- exit(-1);
- }
-
- assert(FD(evsel, nr_cpu, thread_index) >= 0);
- fcntl(FD(evsel, nr_cpu, thread_index), F_SETFL, O_NONBLOCK);
-
- /*
- * First counter acts as the group leader:
- */
- if (group && group_fd == -1)
- group_fd = FD(evsel, nr_cpu, thread_index);
-
- if (evsel->idx || thread_index) {
- struct perf_evsel *first;
- first = list_entry(evlist->entries.next, struct perf_evsel, node);
- ret = ioctl(FD(evsel, nr_cpu, thread_index),
- PERF_EVENT_IOC_SET_OUTPUT,
- FD(first, nr_cpu, 0));
- if (ret) {
- error("failed to set output: %d (%s)\n", errno,
- strerror(errno));
- exit(-1);
- }
- } else {
- mmap_array[nr_cpu].prev = 0;
- mmap_array[nr_cpu].mask = mmap_pages*page_size - 1;
- mmap_array[nr_cpu].base = mmap(NULL, (mmap_pages+1)*page_size,
- PROT_READ | PROT_WRITE, MAP_SHARED, FD(evsel, nr_cpu, thread_index), 0);
- if (mmap_array[nr_cpu].base == MAP_FAILED) {
- error("failed to mmap with %d (%s)\n", errno, strerror(errno));
- exit(-1);
- }
-
- evlist->pollfd[evlist->nr_fds].fd = FD(evsel, nr_cpu, thread_index);
- evlist->pollfd[evlist->nr_fds].events = POLLIN;
- evlist->nr_fds++;
- }
-
- if (filter != NULL) {
- ret = ioctl(FD(evsel, nr_cpu, thread_index),
- PERF_EVENT_IOC_SET_FILTER, filter);
- if (ret) {
- error("failed to set filter with %d (%s)\n", errno,
- strerror(errno));
- exit(-1);
- }
}
}
- if (!sample_type)
- sample_type = attr->sample_type;
-}
-
-static void open_counters(struct perf_evlist *evlist, int cpu)
-{
- struct perf_evsel *pos;
-
- group_fd = -1;
-
- list_for_each_entry(pos, &evlist->entries, node)
- create_counter(evlist, pos, cpu);
-
- nr_cpu++;
+ for (cpu = 0; cpu < cpus->nr; ++cpu) {
+ list_for_each_entry(pos, &evlist->entries, node)
+ create_counter(evlist, pos, cpu);
+ }
}
static int process_buildids(void)
@@ -533,7 +529,7 @@ static void mmap_read_all(void)
{
int i;
- for (i = 0; i < nr_cpu; i++) {
+ for (i = 0; i < cpus->nr; i++) {
if (mmap_array[i].base)
mmap_read(&mmap_array[i]);
}
@@ -673,12 +669,7 @@ static int __cmd_record(int argc, const char **argv)
close(child_ready_pipe[0]);
}
- if (!system_wide && no_inherit && !cpu_list) {
- open_counters(evsel_list, -1);
- } else {
- for (i = 0; i < cpus->nr; i++)
- open_counters(evsel_list, cpus->map[i]);
- }
+ open_counters(evsel_list);
perf_session__set_sample_type(session, sample_type);
@@ -795,7 +786,7 @@ static int __cmd_record(int argc, const char **argv)
}
if (done) {
- for (i = 0; i < nr_cpu; i++) {
+ for (i = 0; i < cpus->nr; i++) {
struct perf_evsel *pos;
list_for_each_entry(pos, &evsel_list->entries, node) {
@@ -933,11 +924,13 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
usage_with_options(record_usage, record_options);
}
- cpus = cpu_map__new(cpu_list);
- if (cpus == NULL) {
- perror("failed to parse CPUs map");
- return -1;
- }
+ if (target_tid != -1)
+ cpus = cpu_map__dummy_new();
+ else
+ cpus = cpu_map__new(cpu_list);
+
+ if (cpus == NULL)
+ usage_with_options(record_usage, record_options);
list_for_each_entry(pos, &evsel_list->entries, node) {
if (perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0)
--
1.6.2.5
next prev parent reply other threads:[~2011-01-25 17:22 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-01-25 17:21 [GIT PULL 00/29] perf/core improvements for 2.6.39 Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 01/29] perf evsel: Introduce perf_evlist Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 02/29] perf evlist: Adopt the pollfd array Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 03/29] perf evsel: Support event groups Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 04/29] perf evsel: Allow specifying if the inherit bit should be set Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 05/29] perf top: Use perf_evsel__open Arnaldo Carvalho de Melo
2011-01-25 17:21 ` Arnaldo Carvalho de Melo [this message]
2011-01-25 17:21 ` [PATCH 07/29] perf evsel: Introduce mmap support Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 08/29] perf record: Use struct perf_mmap and helpers Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 09/29] perf record: Move perf_mmap__write_tail to perf.h Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 10/29] perf evlist: Move the mmap array from perf_evsel Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 11/29] perf record: Use perf_evlist__mmap Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 12/29] perf tools: Add missing cpu_map__delete() Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 13/29] perf test: Check counts on all cpus in test__open_syscall_event_on_all_cpus Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 14/29] perf test: check if cpu_map__new() return NULL Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 15/29] perf evlist: Steal mmap reading routine from 'perf top' Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 16/29] perf test: Add test for the evlist mmap routines Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 17/29] perf callchain: Feed callchains into a cursor Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 18/29] perf callchain: Rename cumul_hits into callchain_cumul_hits Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 19/29] perf callchain: Rename register_callchain_param into callchain_register_param Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 20/29] perf callchain: Don't give arbitrary gender to callchain tree nodes Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 21/29] perf top: Add native_safe_halt to skip symbols Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 22/29] perf probe: Introduce lines walker interface Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 23/29] perf probe: Enable to put probe inline function call site Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 24/29] perf probe: Add --funcs to show available functions in symtab Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 25/29] perf record: auto detect when stdout is a pipe Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 26/29] perf tools: Pass the struct opt to the wildcard parsing routine Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 27/29] perf threads: Move thread_map to separate file Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 28/29] perf tools: Move event__parse_sample to evsel.c Arnaldo Carvalho de Melo
2011-01-25 17:21 ` [PATCH 29/29] perf evsel: Introduce perf_evsel__{in,ex}it Arnaldo Carvalho de Melo
2011-01-26 6:52 ` [GIT PULL 00/29] perf/core improvements for 2.6.39 Ingo Molnar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1295976112-2796-7-git-send-email-acme@infradead.org \
--to=acme@infradead.org \
--cc=acme@redhat.com \
--cc=efault@gmx.de \
--cc=eranian@google.com \
--cc=fweisbec@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=paulus@samba.org \
--cc=peterz@infradead.org \
--cc=tzanussi@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®