From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Ingo Molnar <mingo@kernel.org>
Cc: linux-kernel@vger.kernel.org, Wang Nan <wangnan0@huawei.com>,
He Kuang <hekuang@huawei.com>,
Masami Hiramatsu <mhiramat@kernel.org>,
Namhyung Kim <namhyung@kernel.org>,
Nilay Vaish <nilayvaish@gmail.com>, Zefan Li <lizefan@huawei.com>,
pi3orama@163.com, Arnaldo Carvalho de Melo <acme@redhat.com>
Subject: [PATCH 10/24] perf evlist: Update mmap related APIs and helpers
Date: Fri, 15 Jul 2016 17:50:44 -0300 [thread overview]
Message-ID: <1468615858-24936-11-git-send-email-acme@kernel.org> (raw)
In-Reply-To: <1468615858-24936-1-git-send-email-acme@kernel.org>
From: Wang Nan <wangnan0@huawei.com>
Currently, the evlist mmap related helpers and APIs accept evlist and
idx, and dereference 'struct perf_mmap' by evlist->mmap[idx]. This is
unnecessary, and force each evlist contains only one mmap array.
Following commits are going to introduce multiple mmap arrays to a
evlist. This patch refators these APIs and helpers, introduces
functions accept perf_mmap pointer directly. New helpers and APIs are
decoupled with perf_evlist, and become perf_mmap functions (so they have
perf_mmap prefix).
Old functions are reimplemented with new functions. Some of them will be
removed in following commits.
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: He Kuang <hekuang@huawei.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Nilay Vaish <nilayvaish@gmail.com>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1468485287-33422-4-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/evlist.c | 139 ++++++++++++++++++++++++++++++++---------------
tools/perf/util/evlist.h | 12 ++++
2 files changed, 108 insertions(+), 43 deletions(-)
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 6803f5ccd15e..a4137e02eab8 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -29,6 +29,7 @@
static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx);
static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx);
+static void perf_mmap__munmap(struct perf_mmap *map);
#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
#define SID(e, x, y) xyarray__entry(e->sample_id, x, y)
@@ -781,9 +782,8 @@ broken_event:
return event;
}
-union perf_event *perf_evlist__mmap_read_forward(struct perf_evlist *evlist, int idx)
+union perf_event *perf_mmap__read_forward(struct perf_mmap *md, bool check_messup)
{
- struct perf_mmap *md = &evlist->mmap[idx];
u64 head;
u64 old = md->prev;
@@ -795,13 +795,12 @@ union perf_event *perf_evlist__mmap_read_forward(struct perf_evlist *evlist, int
head = perf_mmap__read_head(md);
- return perf_mmap__read(md, evlist->overwrite, old, head, &md->prev);
+ return perf_mmap__read(md, check_messup, old, head, &md->prev);
}
union perf_event *
-perf_evlist__mmap_read_backward(struct perf_evlist *evlist, int idx)
+perf_mmap__read_backward(struct perf_mmap *md)
{
- struct perf_mmap *md = &evlist->mmap[idx];
u64 head, end;
u64 start = md->prev;
@@ -836,6 +835,31 @@ perf_evlist__mmap_read_backward(struct perf_evlist *evlist, int idx)
return perf_mmap__read(md, false, start, end, &md->prev);
}
+union perf_event *perf_evlist__mmap_read_forward(struct perf_evlist *evlist, int idx)
+{
+ struct perf_mmap *md = &evlist->mmap[idx];
+
+ /*
+ * Check messup is required for forward overwritable ring buffer:
+ * memory pointed by md->prev can be overwritten in this case.
+ * No need for read-write ring buffer: kernel stop outputting when
+ * it hit md->prev (perf_mmap__consume()).
+ */
+ return perf_mmap__read_forward(md, evlist->overwrite);
+}
+
+union perf_event *perf_evlist__mmap_read_backward(struct perf_evlist *evlist, int idx)
+{
+ struct perf_mmap *md = &evlist->mmap[idx];
+
+ /*
+ * No need to check messup for backward ring buffer:
+ * We can always read arbitrary long data from a backward
+ * ring buffer unless we forget to pause it before reading.
+ */
+ return perf_mmap__read_backward(md);
+}
+
union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
{
if (!evlist->backward)
@@ -843,9 +867,8 @@ union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
return perf_evlist__mmap_read_backward(evlist, idx);
}
-void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx)
+void perf_mmap__read_catchup(struct perf_mmap *md)
{
- struct perf_mmap *md = &evlist->mmap[idx];
u64 head;
if (!atomic_read(&md->refcnt))
@@ -855,38 +878,54 @@ void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx)
md->prev = head;
}
+void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx)
+{
+ perf_mmap__read_catchup(&evlist->mmap[idx]);
+}
+
static bool perf_mmap__empty(struct perf_mmap *md)
{
return perf_mmap__read_head(md) == md->prev && !md->auxtrace_mmap.base;
}
-static void perf_evlist__mmap_get(struct perf_evlist *evlist, int idx)
+static void perf_mmap__get(struct perf_mmap *map)
{
- atomic_inc(&evlist->mmap[idx].refcnt);
+ atomic_inc(&map->refcnt);
}
-static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx)
+static void perf_mmap__put(struct perf_mmap *md)
{
- struct perf_mmap *md = &evlist->mmap[idx];
-
BUG_ON(md->base && atomic_read(&md->refcnt) == 0);
if (atomic_dec_and_test(&md->refcnt))
- __perf_evlist__munmap(evlist, idx);
+ perf_mmap__munmap(md);
}
-void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx)
+static void perf_evlist__mmap_get(struct perf_evlist *evlist, int idx)
{
- struct perf_mmap *md = &evlist->mmap[idx];
+ perf_mmap__get(&evlist->mmap[idx]);
+}
+
+static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx)
+{
+ perf_mmap__put(&evlist->mmap[idx]);
+}
- if (!evlist->overwrite) {
+void perf_mmap__consume(struct perf_mmap *md, bool overwrite)
+{
+ if (!overwrite) {
u64 old = md->prev;
perf_mmap__write_tail(md, old);
}
if (atomic_read(&md->refcnt) == 1 && perf_mmap__empty(md))
- perf_evlist__mmap_put(evlist, idx);
+ perf_mmap__put(md);
+}
+
+void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx)
+{
+ perf_mmap__consume(&evlist->mmap[idx], evlist->overwrite);
}
int __weak auxtrace_mmap__mmap(struct auxtrace_mmap *mm __maybe_unused,
@@ -917,15 +956,20 @@ void __weak auxtrace_mmap_params__set_idx(
{
}
-static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx)
+static void perf_mmap__munmap(struct perf_mmap *map)
{
- if (evlist->mmap[idx].base != NULL) {
- munmap(evlist->mmap[idx].base, evlist->mmap_len);
- evlist->mmap[idx].base = NULL;
- evlist->mmap[idx].fd = -1;
- atomic_set(&evlist->mmap[idx].refcnt, 0);
+ if (map->base != NULL) {
+ munmap(map->base, perf_mmap__mmap_len(map));
+ map->base = NULL;
+ map->fd = -1;
+ atomic_set(&map->refcnt, 0);
}
- auxtrace_mmap__munmap(&evlist->mmap[idx].auxtrace_mmap);
+ auxtrace_mmap__munmap(&map->auxtrace_mmap);
+}
+
+static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx)
+{
+ perf_mmap__munmap(&evlist->mmap[idx]);
}
void perf_evlist__munmap(struct perf_evlist *evlist)
@@ -941,20 +985,21 @@ void perf_evlist__munmap(struct perf_evlist *evlist)
zfree(&evlist->mmap);
}
-static int perf_evlist__alloc_mmap(struct perf_evlist *evlist)
+static struct perf_mmap *perf_evlist__alloc_mmap(struct perf_evlist *evlist)
{
int i;
+ struct perf_mmap *map;
evlist->nr_mmaps = cpu_map__nr(evlist->cpus);
if (cpu_map__empty(evlist->cpus))
evlist->nr_mmaps = thread_map__nr(evlist->threads);
- evlist->mmap = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap));
- if (!evlist->mmap)
- return -ENOMEM;
+ map = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap));
+ if (!map)
+ return NULL;
for (i = 0; i < evlist->nr_mmaps; i++)
- evlist->mmap[i].fd = -1;
- return 0;
+ map[i].fd = -1;
+ return map;
}
struct mmap_params {
@@ -963,8 +1008,8 @@ struct mmap_params {
struct auxtrace_mmap_params auxtrace_mp;
};
-static int __perf_evlist__mmap(struct perf_evlist *evlist, int idx,
- struct mmap_params *mp, int fd)
+static int perf_mmap__mmap(struct perf_mmap *map,
+ struct mmap_params *mp, int fd)
{
/*
* The last one will be done at perf_evlist__mmap_consume(), so that we
@@ -979,26 +1024,32 @@ static int __perf_evlist__mmap(struct perf_evlist *evlist, int idx,
* evlist layer can't just drop it when filtering events in
* perf_evlist__filter_pollfd().
*/
- atomic_set(&evlist->mmap[idx].refcnt, 2);
- evlist->mmap[idx].prev = 0;
- evlist->mmap[idx].mask = mp->mask;
- evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, mp->prot,
- MAP_SHARED, fd, 0);
- if (evlist->mmap[idx].base == MAP_FAILED) {
+ atomic_set(&map->refcnt, 2);
+ map->prev = 0;
+ map->mask = mp->mask;
+ map->base = mmap(NULL, perf_mmap__mmap_len(map), mp->prot,
+ MAP_SHARED, fd, 0);
+ if (map->base == MAP_FAILED) {
pr_debug2("failed to mmap perf event ring buffer, error %d\n",
errno);
- evlist->mmap[idx].base = NULL;
+ map->base = NULL;
return -1;
}
- evlist->mmap[idx].fd = fd;
+ map->fd = fd;
- if (auxtrace_mmap__mmap(&evlist->mmap[idx].auxtrace_mmap,
- &mp->auxtrace_mp, evlist->mmap[idx].base, fd))
+ if (auxtrace_mmap__mmap(&map->auxtrace_mmap,
+ &mp->auxtrace_mp, map->base, fd))
return -1;
return 0;
}
+static int __perf_evlist__mmap(struct perf_evlist *evlist, int idx,
+ struct mmap_params *mp, int fd)
+{
+ return perf_mmap__mmap(&evlist->mmap[idx], mp, fd);
+}
+
static bool
perf_evlist__should_poll(struct perf_evlist *evlist __maybe_unused,
struct perf_evsel *evsel)
@@ -1248,7 +1299,9 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages,
.prot = PROT_READ | (overwrite ? 0 : PROT_WRITE),
};
- if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0)
+ if (!evlist->mmap)
+ evlist->mmap = perf_evlist__alloc_mmap(evlist);
+ if (!evlist->mmap)
return -ENOMEM;
if (evlist->pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0)
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index afd087761a47..9e680c62c980 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -35,6 +35,12 @@ struct perf_mmap {
char event_copy[PERF_SAMPLE_MAX_SIZE] __attribute__((aligned(8)));
};
+static inline size_t
+perf_mmap__mmap_len(struct perf_mmap *map)
+{
+ return map->mask + 1 + page_size;
+}
+
struct perf_evlist {
struct list_head entries;
struct hlist_head heads[PERF_EVLIST__HLIST_SIZE];
@@ -129,6 +135,12 @@ struct perf_evsel *perf_evlist__id2evsel_strict(struct perf_evlist *evlist,
struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id);
+union perf_event *perf_mmap__read_forward(struct perf_mmap *map, bool check_messup);
+union perf_event *perf_mmap__read_backward(struct perf_mmap *map);
+
+void perf_mmap__read_catchup(struct perf_mmap *md);
+void perf_mmap__consume(struct perf_mmap *md, bool overwrite);
+
union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx);
union perf_event *perf_evlist__mmap_read_forward(struct perf_evlist *evlist,
--
2.7.4
next prev parent reply other threads:[~2016-07-15 20:52 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-07-15 20:50 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
2016-07-15 20:50 ` [PATCH 01/24] tools lib traceevent: Add correct header for ipv6 definitions Arnaldo Carvalho de Melo
2016-07-15 20:50 ` [PATCH 02/24] perf tools: Do not provide dup sched_getcpu() prototype on Android Arnaldo Carvalho de Melo
2016-07-15 20:50 ` [PATCH 03/24] tools: Make "__always_inline" just "inline" " Arnaldo Carvalho de Melo
2016-07-15 20:50 ` [PATCH 04/24] perf tools: Just pr_debug() about not being able to read cacheline_size Arnaldo Carvalho de Melo
2016-07-15 20:50 ` [PATCH 05/24] perf tools: Bail out at "--sort dcacheline" and cacheline_size not known Arnaldo Carvalho de Melo
2016-07-15 20:50 ` [PATCH 06/24] tools lib api fs: Use base 0 in filename__read_ull Arnaldo Carvalho de Melo
2016-07-15 20:50 ` [PATCH 07/24] perf evlist: Drop redundant evsel->overwrite indicator Arnaldo Carvalho de Melo
2016-07-15 20:50 ` [PATCH 08/24] tools: Simplify BITS_PER_LONG define Arnaldo Carvalho de Melo
2016-07-15 20:50 ` [PATCH 09/24] tools lib fd array: Allow associating a pointer cookie with each entry Arnaldo Carvalho de Melo
2016-07-15 20:50 ` Arnaldo Carvalho de Melo [this message]
2016-07-15 20:50 ` [PATCH 11/24] perf record: Decouple record__mmap_read() and evlist Arnaldo Carvalho de Melo
2016-07-15 20:50 ` [PATCH 12/24] perf evlist: Record mmap cookie into fdarray private field Arnaldo Carvalho de Melo
2016-07-15 20:50 ` [PATCH 13/24] perf evlist: Extract common code in mmap failure processing Arnaldo Carvalho de Melo
2016-07-15 20:50 ` [PATCH 14/24] perf evlist: Introduce backward_mmap array for evlist Arnaldo Carvalho de Melo
2016-07-15 20:50 ` [PATCH 15/24] perf evlist: Map backward events to backward_mmap Arnaldo Carvalho de Melo
2016-07-15 20:50 ` [PATCH 16/24] perf evlist: Drop evlist->backward Arnaldo Carvalho de Melo
2016-07-15 20:50 ` [PATCH 17/24] perf evlist: Setup backward mmap state machine Arnaldo Carvalho de Melo
2016-07-15 20:50 ` [PATCH 18/24] perf record: Read from overwritable ring buffer Arnaldo Carvalho de Melo
2016-07-15 20:50 ` [PATCH 19/24] perf evlist: Make {pause,resume} internal helpers Arnaldo Carvalho de Melo
2016-07-15 20:50 ` [PATCH 20/24] perf tools: Enable overwrite settings Arnaldo Carvalho de Melo
2016-07-15 20:50 ` [PATCH 21/24] perf session: Don't warn about out of order event if write_backward is used Arnaldo Carvalho de Melo
2016-07-15 20:50 ` [PATCH 22/24] perf record: Add --tail-synthesize option Arnaldo Carvalho de Melo
2016-07-15 20:50 ` [PATCH 23/24] objtool: Add -I$(srctree)/tools/arch/$(ARCH)/include/uapi Arnaldo Carvalho de Melo
2016-07-15 20:50 ` [PATCH 24/24] objtool: Initialize variable to silence old compiler Arnaldo Carvalho de Melo
2016-07-16 20:39 ` [GIT PULL 00/24] perf/core improvements and fixes 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=1468615858-24936-11-git-send-email-acme@kernel.org \
--to=acme@kernel.org \
--cc=acme@redhat.com \
--cc=hekuang@huawei.com \
--cc=linux-kernel@vger.kernel.org \
--cc=lizefan@huawei.com \
--cc=mhiramat@kernel.org \
--cc=mingo@kernel.org \
--cc=namhyung@kernel.org \
--cc=nilayvaish@gmail.com \
--cc=pi3orama@163.com \
--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;
as well as URLs for NNTP newsgroup(s).