From: Alexey Budankov <alexey.budankov@linux.intel.com>
To: Arnaldo Carvalho de Melo <acme@kernel.org>,
Ingo Molnar <mingo@redhat.com>,
Peter Zijlstra <peterz@infradead.org>
Cc: Jiri Olsa <jolsa@redhat.com>, Namhyung Kim <namhyung@kernel.org>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
Andi Kleen <ak@linux.intel.com>,
linux-kernel <linux-kernel@vger.kernel.org>
Subject: [PATCH v1 2/3] perf record: apply affinity masks when reading mmap buffers
Date: Wed, 12 Dec 2018 10:40:22 +0300 [thread overview]
Message-ID: <6e5df6f0-5dfa-265e-73cd-803de96ac9b2@linux.intel.com> (raw)
In-Reply-To: <42c2dcb4-7e6f-fcdb-7c87-e55ccb9884b0@linux.intel.com>
Build node cpu masks for mmap data buffers. Bind AIO data buffers
to nodes according to kernel data buffers location. Apply node cpu
masks to trace reading thread every time it references memory cross
node or cross cpu.
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
---
tools/perf/builtin-record.c | 9 +++++++++
tools/perf/util/evlist.c | 6 +++++-
tools/perf/util/mmap.c | 38 ++++++++++++++++++++++++++++++++++++-
tools/perf/util/mmap.h | 1 +
4 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 4979719e54ae..1a1438c73f96 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -532,6 +532,9 @@ static int record__mmap_evlist(struct record *rec,
struct record_opts *opts = &rec->opts;
char msg[512];
+ if (opts->affinity != PERF_AFFINITY_SYS)
+ cpu__setup_cpunode_map();
+
if (perf_evlist__mmap_ex(evlist, opts->mmap_pages,
opts->auxtrace_mmap_pages,
opts->auxtrace_snapshot_mode,
@@ -751,6 +754,12 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli
struct perf_mmap *map = &maps[i];
if (map->base) {
+ if (rec->opts.affinity != PERF_AFFINITY_SYS &&
+ !CPU_EQUAL(&rec->affinity_mask, &map->affinity_mask)) {
+ CPU_ZERO(&rec->affinity_mask);
+ CPU_OR(&rec->affinity_mask, &rec->affinity_mask, &map->affinity_mask);
+ sched_setaffinity(0, sizeof(rec->affinity_mask), &rec->affinity_mask);
+ }
if (!record__aio_enabled(rec)) {
if (perf_mmap__push(map, rec, record__pushfn) != 0) {
rc = -1;
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 60e825be944a..5ca5bb5ea0db 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1028,7 +1028,11 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages,
* Its value is decided by evsel's write_backward.
* So &mp should not be passed through const pointer.
*/
- struct mmap_params mp = { .nr_cblocks = nr_cblocks, .affinity = affinity };
+ struct mmap_params mp = {
+ .nr_cblocks = nr_cblocks,
+ .affinity = affinity,
+ .cpu_map = cpus
+ };
if (!evlist->mmap)
evlist->mmap = perf_evlist__alloc_mmap(evlist, false);
diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c
index e68ba754a8e2..0d017ea85dcb 100644
--- a/tools/perf/util/mmap.c
+++ b/tools/perf/util/mmap.c
@@ -10,6 +10,9 @@
#include <sys/mman.h>
#include <inttypes.h>
#include <asm/bug.h>
+#ifdef HAVE_LIBNUMA_SUPPORT
+#include <numaif.h>
+#endif
#include "debug.h"
#include "event.h"
#include "mmap.h"
@@ -177,11 +180,27 @@ static int perf_mmap__aio_mmap(struct perf_mmap *map, struct mmap_params *mp)
}
delta_max = sysconf(_SC_AIO_PRIO_DELTA_MAX);
for (i = 0; i < map->aio.nr_cblocks; ++i) {
+#ifndef HAVE_LIBNUMA_SUPPORT
map->aio.data[i] = malloc(perf_mmap__mmap_len(map));
+#else
+ size_t mmap_len = perf_mmap__mmap_len(map);
+ map->aio.data[i] = mmap(NULL, mmap_len,
+ PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
+#endif
if (!map->aio.data[i]) {
pr_debug2("failed to allocate data buffer area, error %m");
return -1;
}
+#ifdef HAVE_LIBNUMA_SUPPORT
+ if (mp->affinity != PERF_AFFINITY_SYS && cpu__max_node() > 1) {
+ unsigned long node_mask = 1UL << cpu__get_node(map->cpu);
+ if (mbind(map->aio.data[i], mmap_len, MPOL_BIND, &node_mask, 1, 0)) {
+ pr_debug2("failed to bind [%p-%p] to node %d\n",
+ map->aio.data[i], map->aio.data[i] + mmap_len,
+ cpu__get_node(map->cpu));
+ }
+ }
+#endif
/*
* Use cblock.aio_fildes value different from -1
* to denote started aio write operation on the
@@ -209,8 +228,13 @@ static void perf_mmap__aio_munmap(struct perf_mmap *map)
{
int i;
- for (i = 0; i < map->aio.nr_cblocks; ++i)
+ for (i = 0; i < map->aio.nr_cblocks; ++i) {
+#ifndef HAVE_LIBNUMA_SUPPORT
zfree(&map->aio.data[i]);
+#else
+ munmap(map->aio.data[i], perf_mmap__mmap_len(map));
+#endif
+ }
if (map->aio.data)
zfree(&map->aio.data);
zfree(&map->aio.cblocks);
@@ -316,6 +340,7 @@ void perf_mmap__munmap(struct perf_mmap *map)
int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int fd, int cpu)
{
+ int c, nr_cpus, node;
/*
* The last one will be done at perf_mmap__consume(), so that we
* make sure we don't prevent tools from consuming every last event in
@@ -344,6 +369,17 @@ int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int fd, int c
map->cpu = cpu;
CPU_ZERO(&map->affinity_mask);
+ if (mp->affinity == PERF_AFFINITY_NODE && cpu__max_node() > 1) {
+ nr_cpus = cpu_map__nr(mp->cpu_map);
+ node = cpu__get_node(map->cpu);
+ for (c = 0; c < nr_cpus; c++) {
+ if (cpu__get_node(c) == node) {
+ CPU_SET(c, &map->affinity_mask);
+ }
+ }
+ } else if (mp->affinity == PERF_AFFINITY_CPU) {
+ CPU_SET(map->cpu, &map->affinity_mask);
+ }
if (auxtrace_mmap__mmap(&map->auxtrace_mmap,
&mp->auxtrace_mp, map->base, fd))
diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h
index e566c19b242b..b3f724fad22e 100644
--- a/tools/perf/util/mmap.h
+++ b/tools/perf/util/mmap.h
@@ -72,6 +72,7 @@ enum bkw_mmap_state {
struct mmap_params {
int prot, mask, nr_cblocks, affinity;
struct auxtrace_mmap_params auxtrace_mp;
+ const struct cpu_map *cpu_map;
};
int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int fd, int cpu);
next prev parent reply other threads:[~2018-12-12 7:40 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-12 7:30 [PATCH v1 0/3] Reduce NUMA related overhead in perf record profiling on large server systems Alexey Budankov
2018-12-12 7:40 ` Alexey Budankov [this message]
2018-12-12 12:14 ` [PATCH v1 2/3] perf record: apply affinity masks when reading mmap buffers Jiri Olsa
2018-12-13 6:26 ` Alexey Budankov
2018-12-12 12:15 ` Jiri Olsa
2018-12-13 7:04 ` Alexey Budankov
2018-12-12 12:15 ` Jiri Olsa
2018-12-13 6:26 ` Alexey Budankov
2018-12-12 7:44 ` [PATCH v1 3/3] perf record: implement --affinity=node|cpu option Alexey Budankov
2018-12-12 7:54 ` [PATCH v1 1/3] perf record: allocate affinity masks Alexey Budankov
[not found] ` <afb88628-7a04-3c36-2bc9-b5f5774f8e8f@linux.intel.com>
2018-12-12 12:15 ` Jiri Olsa
2018-12-13 6:26 ` Alexey Budankov
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=6e5df6f0-5dfa-265e-73cd-803de96ac9b2@linux.intel.com \
--to=alexey.budankov@linux.intel.com \
--cc=acme@kernel.org \
--cc=ak@linux.intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=jolsa@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
/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