From: Kan Liang <kan.li...@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.li...@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

Reply via email to