9 #include "../../../../mm/gup_test.h"
11 #define MB (1UL << 20)
12 #define PAGE_SIZE sysconf(_SC_PAGESIZE)
14 /* Just the flags we need, copied from mm.h: */
15 #define FOLL_WRITE 0x01 /* check pte is writable */
17 static char *cmd_to_str(unsigned long cmd
)
20 case GUP_FAST_BENCHMARK
:
21 return "GUP_FAST_BENCHMARK";
22 case PIN_FAST_BENCHMARK
:
23 return "PIN_FAST_BENCHMARK";
24 case PIN_LONGTERM_BENCHMARK
:
25 return "PIN_LONGTERM_BENCHMARK";
27 return "GUP_BASIC_TEST";
29 return "PIN_BASIC_TEST";
30 case DUMP_USER_PAGES_TEST
:
31 return "DUMP_USER_PAGES_TEST";
33 return "Unknown command";
36 int main(int argc
, char **argv
)
38 struct gup_test gup
= { 0 };
39 unsigned long size
= 128 * MB
;
40 int i
, fd
, filed
, opt
, nr_pages
= 1, thp
= -1, repeats
= 1, write
= 0;
41 unsigned long cmd
= GUP_FAST_BENCHMARK
;
42 int flags
= MAP_PRIVATE
;
43 char *file
= "/dev/zero";
46 while ((opt
= getopt(argc
, argv
, "m:r:n:F:f:abctTLUuwSH")) != -1) {
49 cmd
= PIN_FAST_BENCHMARK
;
55 cmd
= PIN_LONGTERM_BENCHMARK
;
58 cmd
= DUMP_USER_PAGES_TEST
;
60 * Dump page 0 (index 1). May be overridden later, by
61 * user's non-option arguments.
63 * .which_pages is zero-based, so that zero can mean "do
66 gup
.which_pages
[0] = 1;
69 /* strtol, so you can pass flags in hex form */
70 gup
.flags
= strtol(optarg
, 0, 0);
73 size
= atoi(optarg
) * MB
;
76 repeats
= atoi(optarg
);
79 nr_pages
= atoi(optarg
);
91 cmd
= GUP_FAST_BENCHMARK
;
100 flags
&= ~MAP_PRIVATE
;
104 flags
|= (MAP_HUGETLB
| MAP_ANONYMOUS
);
112 int extra_arg_count
= 0;
116 * ./gup_test -c 0 1 0x1001
118 * ...to dump pages 0, 1, and 4097
121 while ((optind
< argc
) &&
122 (extra_arg_count
< GUP_TEST_MAX_PAGES_TO_DUMP
)) {
124 * Do the 1-based indexing here, so that the user can
125 * use normal 0-based indexing on the command line.
127 long page_index
= strtol(argv
[optind
], 0, 0) + 1;
129 gup
.which_pages
[extra_arg_count
] = page_index
;
135 filed
= open(file
, O_RDWR
|O_CREAT
);
141 gup
.nr_pages_per_call
= nr_pages
;
143 gup
.flags
|= FOLL_WRITE
;
145 fd
= open("/sys/kernel/debug/gup_test", O_RDWR
);
151 p
= mmap(NULL
, size
, PROT_READ
| PROT_WRITE
, flags
, filed
, 0);
152 if (p
== MAP_FAILED
) {
156 gup
.addr
= (unsigned long)p
;
159 madvise(p
, size
, MADV_HUGEPAGE
);
161 madvise(p
, size
, MADV_NOHUGEPAGE
);
163 for (; (unsigned long)p
< gup
.addr
+ size
; p
+= PAGE_SIZE
)
166 /* Only report timing information on the *_BENCHMARK commands: */
167 if ((cmd
== PIN_FAST_BENCHMARK
) || (cmd
== GUP_FAST_BENCHMARK
) ||
168 (cmd
== PIN_LONGTERM_BENCHMARK
)) {
169 for (i
= 0; i
< repeats
; i
++) {
171 if (ioctl(fd
, cmd
, &gup
))
172 perror("ioctl"), exit(1);
174 printf("%s: Time: get:%lld put:%lld us",
175 cmd_to_str(cmd
), gup
.get_delta_usec
,
177 if (gup
.size
!= size
)
178 printf(", truncated (size: %lld)", gup
.size
);
183 if (ioctl(fd
, cmd
, &gup
)) {
188 printf("%s: done\n", cmd_to_str(cmd
));
189 if (gup
.size
!= size
)
190 printf("Truncated (size: %lld)\n", gup
.size
);