| .. | .. |
|---|
| 15 | 15 | #define PAGE_SIZE sysconf(_SC_PAGESIZE) |
|---|
| 16 | 16 | |
|---|
| 17 | 17 | #define GUP_FAST_BENCHMARK _IOWR('g', 1, struct gup_benchmark) |
|---|
| 18 | +#define GUP_BENCHMARK _IOWR('g', 2, struct gup_benchmark) |
|---|
| 19 | + |
|---|
| 20 | +/* Similar to above, but use FOLL_PIN instead of FOLL_GET. */ |
|---|
| 21 | +#define PIN_FAST_BENCHMARK _IOWR('g', 3, struct gup_benchmark) |
|---|
| 22 | +#define PIN_BENCHMARK _IOWR('g', 4, struct gup_benchmark) |
|---|
| 23 | +#define PIN_LONGTERM_BENCHMARK _IOWR('g', 5, struct gup_benchmark) |
|---|
| 24 | + |
|---|
| 25 | +/* Just the flags we need, copied from mm.h: */ |
|---|
| 26 | +#define FOLL_WRITE 0x01 /* check pte is writable */ |
|---|
| 18 | 27 | |
|---|
| 19 | 28 | struct gup_benchmark { |
|---|
| 20 | | - __u64 delta_usec; |
|---|
| 29 | + __u64 get_delta_usec; |
|---|
| 30 | + __u64 put_delta_usec; |
|---|
| 21 | 31 | __u64 addr; |
|---|
| 22 | 32 | __u64 size; |
|---|
| 23 | 33 | __u32 nr_pages_per_call; |
|---|
| .. | .. |
|---|
| 29 | 39 | { |
|---|
| 30 | 40 | struct gup_benchmark gup; |
|---|
| 31 | 41 | unsigned long size = 128 * MB; |
|---|
| 32 | | - int i, fd, opt, nr_pages = 1, thp = -1, repeats = 1, write = 0; |
|---|
| 42 | + int i, fd, filed, opt, nr_pages = 1, thp = -1, repeats = 1, write = 0; |
|---|
| 43 | + int cmd = GUP_FAST_BENCHMARK, flags = MAP_PRIVATE; |
|---|
| 44 | + char *file = "/dev/zero"; |
|---|
| 33 | 45 | char *p; |
|---|
| 34 | 46 | |
|---|
| 35 | | - while ((opt = getopt(argc, argv, "m:r:n:tT")) != -1) { |
|---|
| 47 | + while ((opt = getopt(argc, argv, "m:r:n:f:abtTLUuwSH")) != -1) { |
|---|
| 36 | 48 | switch (opt) { |
|---|
| 49 | + case 'a': |
|---|
| 50 | + cmd = PIN_FAST_BENCHMARK; |
|---|
| 51 | + break; |
|---|
| 52 | + case 'b': |
|---|
| 53 | + cmd = PIN_BENCHMARK; |
|---|
| 54 | + break; |
|---|
| 55 | + case 'L': |
|---|
| 56 | + cmd = PIN_LONGTERM_BENCHMARK; |
|---|
| 57 | + break; |
|---|
| 37 | 58 | case 'm': |
|---|
| 38 | 59 | size = atoi(optarg) * MB; |
|---|
| 39 | 60 | break; |
|---|
| .. | .. |
|---|
| 49 | 70 | case 'T': |
|---|
| 50 | 71 | thp = 0; |
|---|
| 51 | 72 | break; |
|---|
| 73 | + case 'U': |
|---|
| 74 | + cmd = GUP_BENCHMARK; |
|---|
| 75 | + break; |
|---|
| 76 | + case 'u': |
|---|
| 77 | + cmd = GUP_FAST_BENCHMARK; |
|---|
| 78 | + break; |
|---|
| 52 | 79 | case 'w': |
|---|
| 53 | 80 | write = 1; |
|---|
| 81 | + break; |
|---|
| 82 | + case 'f': |
|---|
| 83 | + file = optarg; |
|---|
| 84 | + break; |
|---|
| 85 | + case 'S': |
|---|
| 86 | + flags &= ~MAP_PRIVATE; |
|---|
| 87 | + flags |= MAP_SHARED; |
|---|
| 88 | + break; |
|---|
| 89 | + case 'H': |
|---|
| 90 | + flags |= (MAP_HUGETLB | MAP_ANONYMOUS); |
|---|
| 54 | 91 | break; |
|---|
| 55 | 92 | default: |
|---|
| 56 | 93 | return -1; |
|---|
| 57 | 94 | } |
|---|
| 58 | 95 | } |
|---|
| 59 | 96 | |
|---|
| 97 | + filed = open(file, O_RDWR|O_CREAT); |
|---|
| 98 | + if (filed < 0) { |
|---|
| 99 | + perror("open"); |
|---|
| 100 | + exit(filed); |
|---|
| 101 | + } |
|---|
| 102 | + |
|---|
| 60 | 103 | gup.nr_pages_per_call = nr_pages; |
|---|
| 61 | | - gup.flags = write; |
|---|
| 104 | + if (write) |
|---|
| 105 | + gup.flags |= FOLL_WRITE; |
|---|
| 62 | 106 | |
|---|
| 63 | 107 | fd = open("/sys/kernel/debug/gup_benchmark", O_RDWR); |
|---|
| 64 | | - if (fd == -1) |
|---|
| 65 | | - perror("open"), exit(1); |
|---|
| 108 | + if (fd == -1) { |
|---|
| 109 | + perror("open"); |
|---|
| 110 | + exit(1); |
|---|
| 111 | + } |
|---|
| 66 | 112 | |
|---|
| 67 | | - p = mmap(NULL, size, PROT_READ | PROT_WRITE, |
|---|
| 68 | | - MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); |
|---|
| 69 | | - if (p == MAP_FAILED) |
|---|
| 70 | | - perror("mmap"), exit(1); |
|---|
| 113 | + p = mmap(NULL, size, PROT_READ | PROT_WRITE, flags, filed, 0); |
|---|
| 114 | + if (p == MAP_FAILED) { |
|---|
| 115 | + perror("mmap"); |
|---|
| 116 | + exit(1); |
|---|
| 117 | + } |
|---|
| 71 | 118 | gup.addr = (unsigned long)p; |
|---|
| 72 | 119 | |
|---|
| 73 | 120 | if (thp == 1) |
|---|
| .. | .. |
|---|
| 80 | 127 | |
|---|
| 81 | 128 | for (i = 0; i < repeats; i++) { |
|---|
| 82 | 129 | gup.size = size; |
|---|
| 83 | | - if (ioctl(fd, GUP_FAST_BENCHMARK, &gup)) |
|---|
| 84 | | - perror("ioctl"), exit(1); |
|---|
| 130 | + if (ioctl(fd, cmd, &gup)) { |
|---|
| 131 | + perror("ioctl"); |
|---|
| 132 | + exit(1); |
|---|
| 133 | + } |
|---|
| 85 | 134 | |
|---|
| 86 | | - printf("Time: %lld us", gup.delta_usec); |
|---|
| 135 | + printf("Time: get:%lld put:%lld us", gup.get_delta_usec, |
|---|
| 136 | + gup.put_delta_usec); |
|---|
| 87 | 137 | if (gup.size != size) |
|---|
| 88 | 138 | printf(", truncated (size: %lld)", gup.size); |
|---|
| 89 | 139 | printf("\n"); |
|---|