2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-20 19:23:57 +08:00

perf evlist: Switch to libperf's mmap interface

Switch to the libperf mmap interface by calling directly
perf_evlist__mmap_ops() and removing perf's evlist__mmap_per_*
functions.

By switching to libperf perf_evlist__mmap() we need to operate over
'struct perf_mmap' in evlist__add_pollfd, so make the related changes
there.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Michael Petlan <mpetlan@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lore.kernel.org/lkml/20191007125344.14268-22-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Jiri Olsa 2019-10-07 14:53:29 +02:00 committed by Arnaldo Carvalho de Melo
parent b80132b12a
commit 923d0f1868

View File

@ -431,10 +431,10 @@ int evlist__add_pollfd(struct evlist *evlist, int fd)
static void perf_evlist__munmap_filtered(struct fdarray *fda, int fd,
void *arg __maybe_unused)
{
struct mmap *map = fda->priv[fd].ptr;
struct perf_mmap *map = fda->priv[fd].ptr;
if (map)
perf_mmap__put(&map->core);
perf_mmap__put(map);
}
int evlist__filter_pollfd(struct evlist *evlist, short revents_and_mask)
@ -448,22 +448,6 @@ int evlist__poll(struct evlist *evlist, int timeout)
return perf_evlist__poll(&evlist->core, timeout);
}
static void perf_evlist__set_sid_idx(struct evlist *evlist,
struct evsel *evsel, int idx, int cpu,
int thread)
{
struct perf_sample_id *sid = SID(evsel, cpu, thread);
sid->idx = idx;
if (evlist->core.cpus && cpu >= 0)
sid->cpu = evlist->core.cpus->map[cpu];
else
sid->cpu = -1;
if (!evsel->core.system_wide && evlist->core.threads && thread >= 0)
sid->tid = perf_thread_map__pid(evlist->core.threads, thread);
else
sid->tid = -1;
}
struct perf_sample_id *perf_evlist__id2sid(struct evlist *evlist, u64 id)
{
struct hlist_head *head;
@ -652,93 +636,6 @@ static struct mmap *evlist__alloc_mmap(struct evlist *evlist,
return map;
}
static bool
perf_evlist__should_poll(struct evlist *evlist __maybe_unused,
struct evsel *evsel)
{
if (evsel->core.attr.write_backward)
return false;
return true;
}
static int evlist__mmap_per_evsel(struct evlist *evlist, int idx,
struct mmap_params *mp, int cpu_idx,
int thread, int *_output, int *_output_overwrite)
{
struct evsel *evsel;
int revent;
int evlist_cpu = cpu_map__cpu(evlist->core.cpus, cpu_idx);
evlist__for_each_entry(evlist, evsel) {
struct mmap *maps = evlist->mmap;
int *output = _output;
int fd;
int cpu;
mp->core.prot = PROT_READ | PROT_WRITE;
if (evsel->core.attr.write_backward) {
output = _output_overwrite;
maps = evlist->overwrite_mmap;
if (!maps) {
maps = evlist__alloc_mmap(evlist, true);
if (!maps)
return -1;
evlist->overwrite_mmap = maps;
if (evlist->bkw_mmap_state == BKW_MMAP_NOTREADY)
perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_RUNNING);
}
mp->core.prot &= ~PROT_WRITE;
}
if (evsel->core.system_wide && thread)
continue;
cpu = perf_cpu_map__idx(evsel->core.cpus, evlist_cpu);
if (cpu == -1)
continue;
fd = FD(evsel, cpu, thread);
if (*output == -1) {
*output = fd;
if (mmap__mmap(&maps[idx], mp, *output, evlist_cpu) < 0)
return -1;
} else {
if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, *output) != 0)
return -1;
perf_mmap__get(&maps[idx].core);
}
revent = perf_evlist__should_poll(evlist, evsel) ? POLLIN : 0;
/*
* The system_wide flag causes a selected event to be opened
* always without a pid. Consequently it will never get a
* POLLHUP, but it is used for tracking in combination with
* other events, so it should not need to be polled anyway.
* Therefore don't add it for polling.
*/
if (!evsel->core.system_wide &&
perf_evlist__add_pollfd(&evlist->core, fd, &maps[idx], revent) < 0) {
perf_mmap__put(&maps[idx].core);
return -1;
}
if (evsel->core.attr.read_format & PERF_FORMAT_ID) {
if (perf_evlist__id_add_fd(&evlist->core, &evsel->core, cpu, thread,
fd) < 0)
return -1;
perf_evlist__set_sid_idx(evlist, evsel, idx, cpu,
thread);
}
}
return 0;
}
static void
perf_evlist__mmap_cb_idx(struct perf_evlist *_evlist,
struct perf_mmap_param *_mp,
@ -783,61 +680,6 @@ perf_evlist__mmap_cb_mmap(struct perf_mmap *_map, struct perf_mmap_param *_mp,
return mmap__mmap(map, mp, output, cpu);
}
static int evlist__mmap_per_cpu(struct evlist *evlist,
struct mmap_params *mp)
{
int cpu, thread;
int nr_cpus = perf_cpu_map__nr(evlist->core.cpus);
int nr_threads = perf_thread_map__nr(evlist->core.threads);
pr_debug2("perf event ring buffer mmapped per cpu\n");
for (cpu = 0; cpu < nr_cpus; cpu++) {
int output = -1;
int output_overwrite = -1;
auxtrace_mmap_params__set_idx(&mp->auxtrace_mp, evlist, cpu,
true);
for (thread = 0; thread < nr_threads; thread++) {
if (evlist__mmap_per_evsel(evlist, cpu, mp, cpu,
thread, &output, &output_overwrite))
goto out_unmap;
}
}
return 0;
out_unmap:
evlist__munmap_nofree(evlist);
return -1;
}
static int evlist__mmap_per_thread(struct evlist *evlist,
struct mmap_params *mp)
{
int thread;
int nr_threads = perf_thread_map__nr(evlist->core.threads);
pr_debug2("perf event ring buffer mmapped per thread\n");
for (thread = 0; thread < nr_threads; thread++) {
int output = -1;
int output_overwrite = -1;
auxtrace_mmap_params__set_idx(&mp->auxtrace_mp, evlist, thread,
false);
if (evlist__mmap_per_evsel(evlist, thread, mp, 0, thread,
&output, &output_overwrite))
goto out_unmap;
}
return 0;
out_unmap:
evlist__munmap_nofree(evlist);
return -1;
}
unsigned long perf_event_mlock_kb_in_pages(void)
{
unsigned long pages;
@ -965,9 +807,6 @@ int evlist__mmap_ex(struct evlist *evlist, unsigned int pages,
bool auxtrace_overwrite, int nr_cblocks, int affinity, int flush,
int comp_level)
{
struct evsel *evsel;
const struct perf_cpu_map *cpus = evlist->core.cpus;
const struct perf_thread_map *threads = evlist->core.threads;
/*
* Delay setting mp.prot: set it before calling perf_mmap__mmap.
* Its value is decided by evsel's write_backward.
@ -979,7 +818,7 @@ int evlist__mmap_ex(struct evlist *evlist, unsigned int pages,
.flush = flush,
.comp_level = comp_level
};
struct perf_evlist_mmap_ops ops __maybe_unused = {
struct perf_evlist_mmap_ops ops = {
.idx = perf_evlist__mmap_cb_idx,
.get = perf_evlist__mmap_cb_get,
.mmap = perf_evlist__mmap_cb_mmap,
@ -1000,17 +839,7 @@ int evlist__mmap_ex(struct evlist *evlist, unsigned int pages,
auxtrace_mmap_params__init(&mp.auxtrace_mp, evlist->core.mmap_len,
auxtrace_pages, auxtrace_overwrite);
evlist__for_each_entry(evlist, evsel) {
if ((evsel->core.attr.read_format & PERF_FORMAT_ID) &&
evsel->core.sample_id == NULL &&
perf_evsel__alloc_id(&evsel->core, perf_cpu_map__nr(cpus), threads->nr) < 0)
return -ENOMEM;
}
if (perf_cpu_map__empty(cpus))
return evlist__mmap_per_thread(evlist, &mp);
return evlist__mmap_per_cpu(evlist, &mp);
return perf_evlist__mmap_ops(&evlist->core, &ops, &mp.core);
}
int evlist__mmap(struct evlist *evlist, unsigned int pages)