Allocate and bind AIO user space buffers to the memory nodes that mmap kernel buffers are bound to.
Signed-off-by: Alexey Budankov <alexey.budan...@linux.intel.com> --- Changes in v2: - implemented perf_mmap__aio_alloc, perf_mmap__aio_free, perf_mmap__aio_bind and put HAVE_LIBNUMA_SUPPORT #ifdefs in there --- tools/perf/util/mmap.c | 49 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index e68ba754a8e2..742fa9a8e498 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" @@ -154,6 +157,46 @@ void __weak auxtrace_mmap_params__set_idx(struct auxtrace_mmap_params *mp __mayb } #ifdef HAVE_AIO_SUPPORT + +#ifdef HAVE_LIBNUMA_SUPPORT +static void perf_mmap__aio_alloc(void **data, size_t len) +{ + *data = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); +} + +static void perf_mmap__aio_free(void **data, size_t len) +{ + munmap(*data, len); + *data = NULL; +} + +static void perf_mmap__aio_bind(void *data, size_t len, int cpu, int affinity) +{ + if (affinity != PERF_AFFINITY_SYS && cpu__max_node() > 1) { + unsigned long node_mask = 1UL << cpu__get_node(cpu); + if (mbind(data, len, MPOL_BIND, &node_mask, 1, 0)) { + pr_debug2("failed to bind [%p-%p] to node %d\n", + data, data + len, cpu__get_node(cpu)); + } + } +} +#else +static void perf_mmap__aio_alloc(void **data, size_t len) +{ + *data = malloc(len); +} + +static void perf_mmap__aio_free(void **data, size_t len __maybe_unused) +{ + zfree(data); +} + +static void perf_mmap__aio_bind(void *data __maybe_unused, size_t len __maybe_unused, + int cpu __maybe_unused, int affinity __maybe_unused) +{ +} +#endif + static int perf_mmap__aio_mmap(struct perf_mmap *map, struct mmap_params *mp) { int delta_max, i, prio; @@ -177,11 +220,13 @@ 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) { - map->aio.data[i] = malloc(perf_mmap__mmap_len(map)); + size_t mmap_len = perf_mmap__mmap_len(map); + perf_mmap__aio_alloc(&(map->aio.data[i]), mmap_len); if (!map->aio.data[i]) { pr_debug2("failed to allocate data buffer area, error %m"); return -1; } + perf_mmap__aio_bind(map->aio.data[i], mmap_len, map->cpu, mp->affinity); /* * Use cblock.aio_fildes value different from -1 * to denote started aio write operation on the @@ -210,7 +255,7 @@ static void perf_mmap__aio_munmap(struct perf_mmap *map) int i; for (i = 0; i < map->aio.nr_cblocks; ++i) - zfree(&map->aio.data[i]); + perf_mmap__aio_free(&(map->aio.data[i]), perf_mmap__mmap_len(map)); if (map->aio.data) zfree(&map->aio.data); zfree(&map->aio.cblocks);