diff options
author | Alexey Budankov <alexey.budankov@linux.intel.com> | 2019-01-22 12:48:54 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2019-02-06 08:00:39 -0500 |
commit | c44a8b44ca9f156a5395597109987d1c462ba655 (patch) | |
tree | 9bc147164fa2dbc3a917ec8d71e2ae6f49c9502f | |
parent | 9d2ed64587c045304efe8872b0258c30803d370c (diff) |
perf record: Bind the AIO user space buffers to nodes
Allocate and bind AIO user space buffers to the memory nodes that mmap
kernel buffers are bound to.
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Reviewed-by: Jiri Olsa <jolsa@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/5a5adebc-afe0-4806-81cd-180d49ec043f@linux.intel.com
[ Do not use 'index' as a variable name, it is a define in older glibcs ]
Link: http://lkml.kernel.org/r/20190205151526.GC10613@kernel.org
[ Add -lnuma to the python build when -DHAVE_LIBNUMA_SUPPORT is present, fixing 'perf test python' ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/util/mmap.c | 77 | ||||
-rw-r--r-- | tools/perf/util/setup.py | 5 |
2 files changed, 78 insertions, 4 deletions
diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index e68ba754a8e2..d882f43148c3 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c | |||
@@ -10,6 +10,9 @@ | |||
10 | #include <sys/mman.h> | 10 | #include <sys/mman.h> |
11 | #include <inttypes.h> | 11 | #include <inttypes.h> |
12 | #include <asm/bug.h> | 12 | #include <asm/bug.h> |
13 | #ifdef HAVE_LIBNUMA_SUPPORT | ||
14 | #include <numaif.h> | ||
15 | #endif | ||
13 | #include "debug.h" | 16 | #include "debug.h" |
14 | #include "event.h" | 17 | #include "event.h" |
15 | #include "mmap.h" | 18 | #include "mmap.h" |
@@ -154,9 +157,72 @@ void __weak auxtrace_mmap_params__set_idx(struct auxtrace_mmap_params *mp __mayb | |||
154 | } | 157 | } |
155 | 158 | ||
156 | #ifdef HAVE_AIO_SUPPORT | 159 | #ifdef HAVE_AIO_SUPPORT |
160 | |||
161 | #ifdef HAVE_LIBNUMA_SUPPORT | ||
162 | static int perf_mmap__aio_alloc(struct perf_mmap *map, int idx) | ||
163 | { | ||
164 | map->aio.data[idx] = mmap(NULL, perf_mmap__mmap_len(map), PROT_READ|PROT_WRITE, | ||
165 | MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); | ||
166 | if (map->aio.data[idx] == MAP_FAILED) { | ||
167 | map->aio.data[idx] = NULL; | ||
168 | return -1; | ||
169 | } | ||
170 | |||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | static void perf_mmap__aio_free(struct perf_mmap *map, int idx) | ||
175 | { | ||
176 | if (map->aio.data[idx]) { | ||
177 | munmap(map->aio.data[idx], perf_mmap__mmap_len(map)); | ||
178 | map->aio.data[idx] = NULL; | ||
179 | } | ||
180 | } | ||
181 | |||
182 | static int perf_mmap__aio_bind(struct perf_mmap *map, int idx, int cpu, int affinity) | ||
183 | { | ||
184 | void *data; | ||
185 | size_t mmap_len; | ||
186 | unsigned long node_mask; | ||
187 | |||
188 | if (affinity != PERF_AFFINITY_SYS && cpu__max_node() > 1) { | ||
189 | data = map->aio.data[idx]; | ||
190 | mmap_len = perf_mmap__mmap_len(map); | ||
191 | node_mask = 1UL << cpu__get_node(cpu); | ||
192 | if (mbind(data, mmap_len, MPOL_BIND, &node_mask, 1, 0)) { | ||
193 | pr_err("Failed to bind [%p-%p] AIO buffer to node %d: error %m\n", | ||
194 | data, data + mmap_len, cpu__get_node(cpu)); | ||
195 | return -1; | ||
196 | } | ||
197 | } | ||
198 | |||
199 | return 0; | ||
200 | } | ||
201 | #else | ||
202 | static int perf_mmap__aio_alloc(struct perf_mmap *map, int idx) | ||
203 | { | ||
204 | map->aio.data[idx] = malloc(perf_mmap__mmap_len(map)); | ||
205 | if (map->aio.data[idx] == NULL) | ||
206 | return -1; | ||
207 | |||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | static void perf_mmap__aio_free(struct perf_mmap *map, int idx) | ||
212 | { | ||
213 | zfree(&(map->aio.data[idx])); | ||
214 | } | ||
215 | |||
216 | static int perf_mmap__aio_bind(struct perf_mmap *map __maybe_unused, int idx __maybe_unused, | ||
217 | int cpu __maybe_unused, int affinity __maybe_unused) | ||
218 | { | ||
219 | return 0; | ||
220 | } | ||
221 | #endif | ||
222 | |||
157 | static int perf_mmap__aio_mmap(struct perf_mmap *map, struct mmap_params *mp) | 223 | static int perf_mmap__aio_mmap(struct perf_mmap *map, struct mmap_params *mp) |
158 | { | 224 | { |
159 | int delta_max, i, prio; | 225 | int delta_max, i, prio, ret; |
160 | 226 | ||
161 | map->aio.nr_cblocks = mp->nr_cblocks; | 227 | map->aio.nr_cblocks = mp->nr_cblocks; |
162 | if (map->aio.nr_cblocks) { | 228 | if (map->aio.nr_cblocks) { |
@@ -177,11 +243,14 @@ static int perf_mmap__aio_mmap(struct perf_mmap *map, struct mmap_params *mp) | |||
177 | } | 243 | } |
178 | delta_max = sysconf(_SC_AIO_PRIO_DELTA_MAX); | 244 | delta_max = sysconf(_SC_AIO_PRIO_DELTA_MAX); |
179 | for (i = 0; i < map->aio.nr_cblocks; ++i) { | 245 | for (i = 0; i < map->aio.nr_cblocks; ++i) { |
180 | map->aio.data[i] = malloc(perf_mmap__mmap_len(map)); | 246 | ret = perf_mmap__aio_alloc(map, i); |
181 | if (!map->aio.data[i]) { | 247 | if (ret == -1) { |
182 | pr_debug2("failed to allocate data buffer area, error %m"); | 248 | pr_debug2("failed to allocate data buffer area, error %m"); |
183 | return -1; | 249 | return -1; |
184 | } | 250 | } |
251 | ret = perf_mmap__aio_bind(map, i, map->cpu, mp->affinity); | ||
252 | if (ret == -1) | ||
253 | return -1; | ||
185 | /* | 254 | /* |
186 | * Use cblock.aio_fildes value different from -1 | 255 | * Use cblock.aio_fildes value different from -1 |
187 | * to denote started aio write operation on the | 256 | * to denote started aio write operation on the |
@@ -210,7 +279,7 @@ static void perf_mmap__aio_munmap(struct perf_mmap *map) | |||
210 | int i; | 279 | int i; |
211 | 280 | ||
212 | for (i = 0; i < map->aio.nr_cblocks; ++i) | 281 | for (i = 0; i < map->aio.nr_cblocks; ++i) |
213 | zfree(&map->aio.data[i]); | 282 | perf_mmap__aio_free(map, i); |
214 | if (map->aio.data) | 283 | if (map->aio.data) |
215 | zfree(&map->aio.data); | 284 | zfree(&map->aio.data); |
216 | zfree(&map->aio.cblocks); | 285 | zfree(&map->aio.cblocks); |
diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py index d3ffc18424b5..5b5a167b43ce 100644 --- a/tools/perf/util/setup.py +++ b/tools/perf/util/setup.py | |||
@@ -53,9 +53,14 @@ ext_sources = [f.strip() for f in open('util/python-ext-sources') | |||
53 | # use full paths with source files | 53 | # use full paths with source files |
54 | ext_sources = list(map(lambda x: '%s/%s' % (src_perf, x) , ext_sources)) | 54 | ext_sources = list(map(lambda x: '%s/%s' % (src_perf, x) , ext_sources)) |
55 | 55 | ||
56 | extra_libraries = [] | ||
57 | if '-DHAVE_LIBNUMA_SUPPORT' in cflags: | ||
58 | extra_libraries = [ 'numa' ] | ||
59 | |||
56 | perf = Extension('perf', | 60 | perf = Extension('perf', |
57 | sources = ext_sources, | 61 | sources = ext_sources, |
58 | include_dirs = ['util/include'], | 62 | include_dirs = ['util/include'], |
63 | libraries = extra_libraries, | ||
59 | extra_compile_args = cflags, | 64 | extra_compile_args = cflags, |
60 | extra_objects = [libtraceevent, libapikfs], | 65 | extra_objects = [libtraceevent, libapikfs], |
61 | ) | 66 | ) |