]>
Commit | Line | Data |
---|---|---|
64c349f4 KS |
1 | #include <fcntl.h> |
2 | #include <stdio.h> | |
3 | #include <stdlib.h> | |
4 | #include <unistd.h> | |
5 | ||
6 | #include <sys/ioctl.h> | |
7 | #include <sys/mman.h> | |
8 | #include <sys/prctl.h> | |
9 | #include <sys/stat.h> | |
10 | #include <sys/types.h> | |
11 | ||
12 | #include <linux/types.h> | |
13 | ||
14 | #define MB (1UL << 20) | |
15 | #define PAGE_SIZE sysconf(_SC_PAGESIZE) | |
16 | ||
17 | #define GUP_FAST_BENCHMARK _IOWR('g', 1, struct gup_benchmark) | |
714a3a1e KB |
18 | #define GUP_LONGTERM_BENCHMARK _IOWR('g', 2, struct gup_benchmark) |
19 | #define GUP_BENCHMARK _IOWR('g', 3, struct gup_benchmark) | |
64c349f4 KS |
20 | |
21 | struct gup_benchmark { | |
26db3d09 KB |
22 | __u64 get_delta_usec; |
23 | __u64 put_delta_usec; | |
64c349f4 KS |
24 | __u64 addr; |
25 | __u64 size; | |
26 | __u32 nr_pages_per_call; | |
27 | __u32 flags; | |
28 | }; | |
29 | ||
30 | int main(int argc, char **argv) | |
31 | { | |
32 | struct gup_benchmark gup; | |
33 | unsigned long size = 128 * MB; | |
aeb85ed4 | 34 | int i, fd, filed, opt, nr_pages = 1, thp = -1, repeats = 1, write = 0; |
0dd8666a | 35 | int cmd = GUP_FAST_BENCHMARK, flags = MAP_PRIVATE; |
aeb85ed4 | 36 | char *file = "/dev/zero"; |
64c349f4 KS |
37 | char *p; |
38 | ||
3821b76c | 39 | while ((opt = getopt(argc, argv, "m:r:n:f:tTLUSH")) != -1) { |
64c349f4 KS |
40 | switch (opt) { |
41 | case 'm': | |
42 | size = atoi(optarg) * MB; | |
43 | break; | |
44 | case 'r': | |
45 | repeats = atoi(optarg); | |
46 | break; | |
47 | case 'n': | |
48 | nr_pages = atoi(optarg); | |
49 | break; | |
50 | case 't': | |
51 | thp = 1; | |
52 | break; | |
53 | case 'T': | |
54 | thp = 0; | |
55 | break; | |
714a3a1e KB |
56 | case 'L': |
57 | cmd = GUP_LONGTERM_BENCHMARK; | |
58 | break; | |
59 | case 'U': | |
60 | cmd = GUP_BENCHMARK; | |
61 | break; | |
64c349f4 KS |
62 | case 'w': |
63 | write = 1; | |
319e0bec | 64 | break; |
aeb85ed4 KB |
65 | case 'f': |
66 | file = optarg; | |
67 | break; | |
0dd8666a KB |
68 | case 'S': |
69 | flags &= ~MAP_PRIVATE; | |
70 | flags |= MAP_SHARED; | |
71 | break; | |
3821b76c KB |
72 | case 'H': |
73 | flags |= MAP_HUGETLB; | |
74 | break; | |
64c349f4 KS |
75 | default: |
76 | return -1; | |
77 | } | |
78 | } | |
79 | ||
aeb85ed4 KB |
80 | filed = open(file, O_RDWR|O_CREAT); |
81 | if (filed < 0) { | |
82 | perror("open"); | |
83 | exit(filed); | |
84 | } | |
85 | ||
64c349f4 KS |
86 | gup.nr_pages_per_call = nr_pages; |
87 | gup.flags = write; | |
88 | ||
89 | fd = open("/sys/kernel/debug/gup_benchmark", O_RDWR); | |
90 | if (fd == -1) | |
91 | perror("open"), exit(1); | |
92 | ||
0dd8666a | 93 | p = mmap(NULL, size, PROT_READ | PROT_WRITE, flags, filed, 0); |
64c349f4 KS |
94 | if (p == MAP_FAILED) |
95 | perror("mmap"), exit(1); | |
96 | gup.addr = (unsigned long)p; | |
97 | ||
98 | if (thp == 1) | |
99 | madvise(p, size, MADV_HUGEPAGE); | |
100 | else if (thp == 0) | |
101 | madvise(p, size, MADV_NOHUGEPAGE); | |
102 | ||
103 | for (; (unsigned long)p < gup.addr + size; p += PAGE_SIZE) | |
104 | p[0] = 0; | |
105 | ||
106 | for (i = 0; i < repeats; i++) { | |
107 | gup.size = size; | |
714a3a1e | 108 | if (ioctl(fd, cmd, &gup)) |
64c349f4 KS |
109 | perror("ioctl"), exit(1); |
110 | ||
26db3d09 KB |
111 | printf("Time: get:%lld put:%lld us", gup.get_delta_usec, |
112 | gup.put_delta_usec); | |
64c349f4 KS |
113 | if (gup.size != size) |
114 | printf(", truncated (size: %lld)", gup.size); | |
115 | printf("\n"); | |
116 | } | |
117 | ||
118 | return 0; | |
119 | } |