.. | .. |
---|
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"); |
---|