diff options
author | Andy Lutomirski <luto@kernel.org> | 2017-06-26 18:19:03 -0700 |
---|---|---|
committer | Andy Lutomirski <luto@kernel.org> | 2017-06-26 18:19:03 -0700 |
commit | cb7f9f0592f8a75949919618f3b74121b3fc1a4a (patch) | |
tree | 2b3d5824b0bd44ce31e84c4335d5a4307d8d256e | |
parent | 61397cab91021109604e9365feff0bc112842f25 (diff) | |
download | misc-tests-cb7f9f0592f8a75949919618f3b74121b3fc1a4a.tar.gz |
Add madvise_bounce
Signed-off-by: Andy Lutomirski <luto@kernel.org>
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | madvise_bounce.cc | 86 |
2 files changed, 87 insertions, 1 deletions
@@ -5,7 +5,7 @@ SIMPLE_C_TARGETS := dump-vsyscall context_switch_latency kernel_pf user_visible_ SIMPLE_CC_TARGETS := evil-clock-test SPLIT_C_TARGETS := dump-vdso dump-vvar syscall_exit_regs dump_all_pmcs ntflag sysret_ss_attrs -SPLIT_CC_TARGETS := timing_test test_vsyscall test_vdso_parser +SPLIT_CC_TARGETS := timing_test test_vsyscall test_vdso_parser madvise_bounce ALL_TARGETS := $(SIMPLE_C_TARGETS) $(SIMPLE_CC_TARGETS) $(SPLIT_C_TARGETS:%=%_64) $(SPLIT_CC_TARGETS:%=%_64) $(SPLIT_C_TARGETS:%=%_32) $(SPLIT_CC_TARGETS:%=%_32) syscall32_from_64 segregs diff --git a/madvise_bounce.cc b/madvise_bounce.cc new file mode 100644 index 0000000..1888fc7 --- /dev/null +++ b/madvise_bounce.cc @@ -0,0 +1,86 @@ +#define __STDC_FORMAT_MACROS + +#include <sys/time.h> +#include <time.h> +#include <stdlib.h> +#include <sys/syscall.h> +#include <unistd.h> +#include <dlfcn.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> +#include <atomic> +#include <signal.h> +#include <pthread.h> +#include <err.h> +#include <sys/mman.h> + +void describe_clock(const char *name, int id) +{ + struct timespec res; + int ret = clock_getres(id, &res); + if (ret < 0) { + printf(" %d (%s) [failed to query resolution]\n", + id, name); + } else { + printf(" %d (%s) resolution = %" PRIu64 ".%09u\n", + id, name, + (uint64_t)res.tv_sec, (unsigned)res.tv_nsec); + } +} + +int main(int argc, char **argv) +{ + if (argc < 2) { + printf("Usage: %s <iters>\n", argv[0]); + + return 1; + } + + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + int cpu = 0; + + long loop_mult = 1; + char *loop_arg = strdup(argv[1]); + size_t loop_arg_len = strlen(loop_arg); + if (loop_arg_len && loop_arg[loop_arg_len-1] == 'k') { + loop_mult = 1000; + loop_arg[loop_arg_len-1] = '\0'; + } else if (loop_arg_len && loop_arg[loop_arg_len-1] == 'M') { + loop_mult = 1000000; + loop_arg[loop_arg_len-1] = '\0'; + } + size_t loops = (size_t)atol(argv[1]) * loop_mult; + free(loop_arg); + + char *buf = (char *)mmap(0, 4096, PROT_READ|PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | MAP_POPULATE, + -1, 0); + if (buf == MAP_FAILED) + err(1, "mmap"); + + timespec start; + clock_gettime(CLOCK_MONOTONIC, &start); + + for (size_t i = 0; i < loops; ++i) { + madvise(buf, 4096, MADV_DONTNEED); + buf[0] = 1; + + cpu = !cpu; + CPU_SET(cpu, &cpuset); + if (sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0) + err(1, "sched_setaffinity"); + CPU_CLR(cpu, &cpuset); + } + + timespec end; + clock_gettime(CLOCK_MONOTONIC, &end); + unsigned long long duration = (end.tv_nsec - start.tv_nsec) + 1000000000ULL * (end.tv_sec - start.tv_sec); + printf("%ld loops in %.5fs = %.2f nsec / loop\n", + (long)loops, float(duration) * 1e-9, + float(duration) / loops); + if (duration == 0) + printf("[WARN]\tThe apparent elapsed time was exactly 0. You have precision issues.\n"); + return 0; +} |