From: kan.liang@intel.com
To: acme@kernel.org, peterz@infradead.org, mingo@redhat.com,
linux-kernel@vger.kernel.org
Cc: jolsa@kernel.org, wangnan0@huawei.com, hekuang@huawei.com,
namhyung@kernel.org, alexander.shishkin@linux.intel.com,
adrian.hunter@intel.com, ak@linux.intel.com,
Kan Liang <kan.liang@intel.com>
Subject: [PATCH 01/10] perf record: new interfaces to read ring buffer to file
Date: Tue, 10 Oct 2017 10:20:14 -0700 [thread overview]
Message-ID: <1507656023-177125-2-git-send-email-kan.liang@intel.com> (raw)
In-Reply-To: <1507656023-177125-1-git-send-email-kan.liang@intel.com>
From: Kan Liang <kan.liang@intel.com>
Factor out the mmap_read related codes into separate functions and move
them to evlist.c
struct perf_mmap_read is introduced to store the specific range of ring
buffer information.
The way to read specific range of ring buffer into file is as below,
perf_mmap__read_init
perf_mmap__read_to_file
perf_mmap__consume
There is no functional change.
Signed-off-by: Kan Liang <kan.liang@intel.com>
---
tools/perf/builtin-record.c | 111 ++++++++------------------------------------
tools/perf/util/evlist.c | 111 ++++++++++++++++++++++++++++++++++++++++++++
tools/perf/util/evlist.h | 15 ++++++
3 files changed, 146 insertions(+), 91 deletions(-)
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 234fdf4..df555e9 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -105,6 +105,17 @@ static bool switch_output_time(struct record *rec)
trigger_is_ready(&switch_output_trigger);
}
+static void update_output_size(struct record *rec, size_t size)
+{
+ if (size == 0)
+ return;
+
+ rec->bytes_written += size;
+
+ if (switch_output_size(rec))
+ trigger_hit(&switch_output_trigger);
+}
+
static int record__write(struct record *rec, void *bf, size_t size)
{
if (perf_data_file__write(rec->session->file, bf, size) < 0) {
@@ -112,10 +123,7 @@ static int record__write(struct record *rec, void *bf, size_t size)
return -1;
}
- rec->bytes_written += size;
-
- if (switch_output_size(rec))
- trigger_hit(&switch_output_trigger);
+ update_output_size(rec, size);
return 0;
}
@@ -130,106 +138,27 @@ static int process_synthesized_event(struct perf_tool *tool,
}
static int
-backward_rb_find_range(void *buf, int mask, u64 head, u64 *start, u64 *end)
-{
- struct perf_event_header *pheader;
- u64 evt_head = head;
- int size = mask + 1;
-
- pr_debug2("backward_rb_find_range: buf=%p, head=%"PRIx64"\n", buf, head);
- pheader = (struct perf_event_header *)(buf + (head & mask));
- *start = head;
- while (true) {
- if (evt_head - head >= (unsigned int)size) {
- pr_debug("Finished reading backward ring buffer: rewind\n");
- if (evt_head - head > (unsigned int)size)
- evt_head -= pheader->size;
- *end = evt_head;
- return 0;
- }
-
- pheader = (struct perf_event_header *)(buf + (evt_head & mask));
-
- if (pheader->size == 0) {
- pr_debug("Finished reading backward ring buffer: get start\n");
- *end = evt_head;
- return 0;
- }
-
- evt_head += pheader->size;
- pr_debug3("move evt_head: %"PRIx64"\n", evt_head);
- }
- WARN_ONCE(1, "Shouldn't get here\n");
- return -1;
-}
-
-static int
-rb_find_range(void *data, int mask, u64 head, u64 old,
- u64 *start, u64 *end, bool backward)
-{
- if (!backward) {
- *start = old;
- *end = head;
- return 0;
- }
-
- return backward_rb_find_range(data, mask, head, start, end);
-}
-
-static int
record__mmap_read(struct record *rec, struct perf_mmap *md,
bool overwrite, bool backward)
{
- u64 head = perf_mmap__read_head(md);
- u64 old = md->prev;
- u64 end = head, start = old;
- unsigned char *data = md->base + page_size;
- unsigned long size;
- void *buf;
- int rc = 0;
+ struct perf_mmap_read read;
- if (rb_find_range(data, md->mask, head,
- old, &start, &end, backward))
+ if (perf_mmap__read_init(md, &read, overwrite, backward))
return -1;
- if (start == end)
+ if (read.start == read.end)
return 0;
rec->samples++;
- size = end - start;
- if (size > (unsigned long)(md->mask) + 1) {
- WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n");
-
- md->prev = head;
- perf_mmap__consume(md, overwrite || backward);
- return 0;
- }
-
- if ((start & md->mask) + size != (end & md->mask)) {
- buf = &data[start & md->mask];
- size = md->mask + 1 - (start & md->mask);
- start += size;
-
- if (record__write(rec, buf, size) < 0) {
- rc = -1;
- goto out;
- }
- }
+ if (perf_mmap__read_to_file(&read, rec->session->file) < 0)
+ return -1;
- buf = &data[start & md->mask];
- size = end - start;
- start += size;
+ update_output_size(rec, read.size);
- if (record__write(rec, buf, size) < 0) {
- rc = -1;
- goto out;
- }
-
- md->prev = head;
perf_mmap__consume(md, overwrite || backward);
-out:
- return rc;
+
+ return 0;
}
static volatile int done;
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 6a0d7ff..33b8837 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -704,6 +704,117 @@ static int perf_evlist__resume(struct perf_evlist *evlist)
return perf_evlist__set_paused(evlist, false);
}
+static int
+backward_rb_find_range(void *buf, int mask, u64 head, u64 *start, u64 *end)
+{
+ struct perf_event_header *pheader;
+ u64 evt_head = head;
+ int size = mask + 1;
+
+ pr_debug2("backward_rb_find_range: buf=%p, head=%"PRIx64"\n", buf, head);
+ pheader = (struct perf_event_header *)(buf + (head & mask));
+ *start = head;
+ while (true) {
+ if (evt_head - head >= (unsigned int)size) {
+ pr_debug("Finished reading backward ring buffer: rewind\n");
+ if (evt_head - head > (unsigned int)size)
+ evt_head -= pheader->size;
+ *end = evt_head;
+ return 0;
+ }
+
+ pheader = (struct perf_event_header *)(buf + (evt_head & mask));
+
+ if (pheader->size == 0) {
+ pr_debug("Finished reading backward ring buffer: get start\n");
+ *end = evt_head;
+ return 0;
+ }
+
+ evt_head += pheader->size;
+ pr_debug3("move evt_head: %"PRIx64"\n", evt_head);
+ }
+ WARN_ONCE(1, "Shouldn't get here\n");
+ return -1;
+}
+
+static int
+rb_find_range(void *data, int mask, u64 head, u64 old,
+ u64 *start, u64 *end, bool backward)
+{
+ if (!backward) {
+ *start = old;
+ *end = head;
+ return 0;
+ }
+
+ return backward_rb_find_range(data, mask, head, start, end);
+}
+
+/*
+ * Initialize struct perf_mmap_read
+ * Calculate the range of ring buffer to read
+ */
+int perf_mmap__read_init(struct perf_mmap *md, struct perf_mmap_read *read,
+ bool overwrite, bool backward)
+{
+ unsigned char *data = md->base + page_size;
+
+ read->md = md;
+ read->head = perf_mmap__read_head(md);
+ read->overwrite = overwrite;
+ read->backward = backward;
+ read->size = 0;
+ return rb_find_range(data, md->mask, read->head, md->prev,
+ &read->start, &read->end, backward);
+}
+
+/*
+ * Read the ring buffer in the range which specified in struct perf_mmap_read,
+ * and write to file.
+ * Used by perf record.
+ */
+int perf_mmap__read_to_file(struct perf_mmap_read *read,
+ struct perf_data_file *file)
+{
+ struct perf_mmap *md = read->md;
+ unsigned char *data = md->base + page_size;
+ unsigned long size;
+ void *buf;
+
+ size = read->end - read->start;
+ if (size > (unsigned long)(md->mask) + 1) {
+ WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n");
+ read->size = 0;
+ goto out;
+ }
+
+ if ((read->start & md->mask) + size != (read->end & md->mask)) {
+ buf = &data[read->start & md->mask];
+ size = md->mask + 1 - (read->start & md->mask);
+ read->start += size;
+ read->size += size;
+
+ if (perf_data_file__write(file, buf, size) < 0) {
+ pr_err("failed to write %s, error: %m\n", file->path);
+ return -1;
+ }
+ }
+
+ buf = &data[read->start & md->mask];
+ size = read->end - read->start;
+ read->start += size;
+ read->size += size;
+
+ if (perf_data_file__write(file, buf, size) < 0) {
+ pr_err("failed to write %s, error: %m\n", file->path);
+ return -1;
+ }
+out:
+ md->prev = read->head;
+ return 0;
+}
+
/* When check_messup is true, 'end' must points to a good entry */
static union perf_event *
perf_mmap__read(struct perf_mmap *md, bool check_messup, u64 start,
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index b1c14f1..1ce4857 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -39,6 +39,16 @@ struct perf_mmap {
char event_copy[PERF_SAMPLE_MAX_SIZE] __aligned(8);
};
+struct perf_mmap_read {
+ struct perf_mmap *md;
+ u64 head;
+ u64 start;
+ u64 end;
+ bool overwrite;
+ bool backward;
+ unsigned long size;
+};
+
static inline size_t
perf_mmap__mmap_len(struct perf_mmap *map)
{
@@ -193,6 +203,11 @@ void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx);
void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx);
+int perf_mmap__read_init(struct perf_mmap *md, struct perf_mmap_read *read,
+ bool overwrite, bool backward);
+int perf_mmap__read_to_file(struct perf_mmap_read *read,
+ struct perf_data_file *file);
+
int perf_evlist__open(struct perf_evlist *evlist);
void perf_evlist__close(struct perf_evlist *evlist);
--
2.5.5
next prev parent reply other threads:[~2017-10-10 17:20 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-10-10 17:20 [PATCH 00/10] new mmap_read interfaces for ring buffer kan.liang
2017-10-10 17:20 ` kan.liang [this message]
2017-10-10 18:24 ` [PATCH 01/10] perf record: new interfaces to read ring buffer to file Arnaldo Carvalho de Melo
2017-10-10 18:30 ` Arnaldo Carvalho de Melo
2017-10-11 4:12 ` Liang, Kan
2017-10-11 14:45 ` Arnaldo Carvalho de Melo
2017-10-11 15:16 ` Liang, Kan
2017-10-10 17:20 ` [PATCH 02/10] perf tool: fix: Don't discard prev in backward mode kan.liang
2017-10-10 18:14 ` Arnaldo Carvalho de Melo
2017-10-10 18:18 ` Liang, Kan
2017-10-13 12:55 ` Liang, Kan
2017-10-13 13:13 ` Arnaldo Carvalho de Melo
2017-10-13 13:14 ` Liang, Kan
2017-10-10 18:23 ` Wangnan (F)
2017-10-10 18:50 ` Wangnan (F)
2017-10-10 19:50 ` Liang, Kan
2017-10-10 20:18 ` Wangnan (F)
2017-10-11 2:12 ` Liang, Kan
2017-10-11 14:57 ` Liang, Kan
2017-10-12 1:11 ` Wangnan (F)
2017-10-12 12:49 ` Liang, Kan
2017-10-12 14:43 ` Wangnan (F)
2017-10-10 19:36 ` Liang, Kan
2017-10-10 17:20 ` [PATCH 03/10] perf tool: new iterfaces to read event from ring buffer kan.liang
2017-10-10 18:15 ` Arnaldo Carvalho de Melo
2017-10-10 18:28 ` Liang, Kan
2017-10-10 18:34 ` Arnaldo Carvalho de Melo
2017-10-10 18:36 ` Arnaldo Carvalho de Melo
2017-10-10 19:00 ` Arnaldo Carvalho de Melo
2017-10-10 19:10 ` Wangnan (F)
2017-10-10 19:17 ` Arnaldo Carvalho de Melo
2017-10-10 19:22 ` Wangnan (F)
2017-10-10 19:55 ` Liang, Kan
2017-10-10 19:59 ` Wangnan (F)
2017-10-10 17:20 ` [PATCH 04/10] perf tool: perf_mmap__read_init wrapper for evlist kan.liang
2017-10-10 17:20 ` [PATCH 05/10] perf top: apply new mmap_read interfaces kan.liang
2017-10-10 17:20 ` [PATCH 06/10] perf trace: " kan.liang
2017-10-10 17:20 ` [PATCH 07/10] perf kvm: " kan.liang
2017-10-10 17:20 ` [PATCH 08/10] perf python: " kan.liang
2017-10-10 17:20 ` [PATCH 09/10] perf tests: " kan.liang
2017-10-10 17:20 ` [PATCH 10/10] perf tool: remove stale " kan.liang
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=1507656023-177125-2-git-send-email-kan.liang@intel.com \
--to=kan.liang@intel.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=ak@linux.intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=hekuang@huawei.com \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
--cc=wangnan0@huawei.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®